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 ); }