using EcommerceDDD.QuoteManagement.Application.Quotes.AddingQuoteItem;
using EcommerceDDD.QuoteManagement.Application.Quotes.CancelingQuote;
using EcommerceDDD.QuoteManagement.Application.Quotes.ConfirmingQuote;
using EcommerceDDD.QuoteManagement.Application.Quotes.RemovingQuoteItem;
namespace EcommerceDDD.QuoteManagement.API.Controllers;
[Authorize]
[ApiController]
[ApiVersion(ApiVersions.V2)]
[Route("api/v{version:apiVersion}/quotes")]
public class QuotesController(
ICommandBus commandBus,
IQueryBus queryBus
) : CustomControllerBase(commandBus, queryBus)
{
///
/// Get the current customer's quote
///
///
[HttpGet]
[MapToApiVersion(ApiVersions.V2)]
[Authorize(Roles = Roles.Customer, Policy = Policies.CanRead)]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ApiResponse))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task GetOpenQuote(CancellationToken cancellationToken) =>
await Response(
GetCustomerOpenQuote.Create(), cancellationToken
);
///
/// Creates a quote for a customer
///
///
///
[HttpPost]
[MapToApiVersion(ApiVersions.V2)]
[Authorize(Roles = Roles.Customer, Policy = Policies.CanWrite)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task OpenQuoteForCustomer([FromBody] OpenQuoteRequest request,
CancellationToken cancellationToken) =>
await Response(
OpenQuote.Create(Currency.OfCode(request.CurrencyCode)),
cancellationToken
);
///
/// Get quote event history
///
///
///
[HttpGet, Route("{quoteId:guid}/history")]
[MapToApiVersion(ApiVersions.V2)]
[Authorize(Roles = Roles.Customer, Policy = Policies.CanRead)]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ApiResponse>))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task ListHistory([FromRoute] Guid quoteId,
CancellationToken cancellationToken) =>
await Response(
GetQuoteEventHistory.Create(QuoteId.Of(quoteId)),
cancellationToken
);
///
/// Add a quote item
///
///
///
///
[HttpPut, Route("{quoteId:guid}/items")]
[MapToApiVersion(ApiVersions.V2)]
[Authorize(Roles = Roles.Customer, Policy = Policies.CanWrite)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task AddItem([FromRoute] Guid quoteId,
[FromBody] AddQuoteItemRequest request, CancellationToken cancellationToken) =>
await Response(
AddQuoteItem.Create(
QuoteId.Of(quoteId),
ProductId.Of(request.ProductId),
request.Quantity
), cancellationToken
);
///
/// Delete a quote item
///
///
///
///
[HttpDelete, Route("{quoteId:guid}/items/{productId:guid}")]
[MapToApiVersion(ApiVersions.V2)]
[Authorize(Roles = Roles.Customer, Policy = Policies.CanDelete)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task RemoveItem([FromRoute] Guid quoteId, [FromRoute] Guid productId,
CancellationToken cancellationToken) =>
await Response(
RemoveQuoteItem.Create(QuoteId.Of(quoteId), ProductId.Of(productId)),
cancellationToken
);
///
/// Cancel a quote
///
///
///
[HttpDelete, Route("{quoteId:guid}")]
[MapToApiVersion(ApiVersions.V2)]
[Authorize(Roles = Roles.Customer, Policy = Policies.CanDelete)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task Cancel([FromRoute] Guid quoteId,
CancellationToken cancellationToken) =>
await Response(
CancelQuote.Create(QuoteId.Of(quoteId)),
cancellationToken
);
///
/// Confirms a quote | M2M only
///
///
///
[HttpPut, Route("{quoteId:guid}/confirm")]
[MapToApiVersion(ApiVersions.V2)]
[Authorize(Roles = Roles.M2MAccess, Policy = Policies.CanWrite)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task Confirm([FromRoute] Guid quoteId,
CancellationToken cancellationToken) =>
await Response(
ConfirmQuote.Create(
QuoteId.Of(quoteId)),
cancellationToken
);
///
/// Get a quote by quoteId | M2M only
///
///
[HttpGet, Route("{quoteId:guid?}/details")]
[MapToApiVersion(ApiVersions.V2)]
[Authorize(Roles = Roles.M2MAccess, Policy = Policies.CanRead)]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ApiResponse))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task GetQuoteDetails([FromRoute] Guid quoteId,
CancellationToken cancellationToken) =>
await Response(
GetQuoteById.Create(QuoteId.Of(quoteId)),
cancellationToken
);
}