From 802c03995ab8a83dc28d16a1ced545a8c048a5cf Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Thu, 5 Mar 2026 06:19:18 +0700 Subject: [PATCH] feat(order-processing): execute order item strategies during order creation and add kitchen ticket API with session management. --- .../Controllers/KitchenController.cs | 50 ++++++++++++++++++- .../Commands/CreateOrderCommandHandler.cs | 8 +++ .../Commands/PayOrderCommandHandler.cs | 36 ++----------- .../HttpClients/FnbEngineClient.cs | 2 +- 4 files changed, 62 insertions(+), 34 deletions(-) diff --git a/services/fnb-engine-net/src/FnbEngine.API/Controllers/KitchenController.cs b/services/fnb-engine-net/src/FnbEngine.API/Controllers/KitchenController.cs index b82b1aec..43c48043 100644 --- a/services/fnb-engine-net/src/FnbEngine.API/Controllers/KitchenController.cs +++ b/services/fnb-engine-net/src/FnbEngine.API/Controllers/KitchenController.cs @@ -6,6 +6,7 @@ using MediatR; using Microsoft.AspNetCore.Mvc; using FnbEngine.API.Application.Commands; using FnbEngine.API.Application.Queries; +using FnbEngine.Domain.AggregatesModel.SessionAggregate; namespace FnbEngine.API.Controllers; @@ -15,10 +16,12 @@ namespace FnbEngine.API.Controllers; public class KitchenController : ControllerBase { private readonly IMediator _mediator; + private readonly ISessionRepository _sessionRepository; - public KitchenController(IMediator mediator) + public KitchenController(IMediator mediator, ISessionRepository sessionRepository) { _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator)); + _sessionRepository = sessionRepository ?? throw new ArgumentNullException(nameof(sessionRepository)); } /// @@ -62,6 +65,42 @@ public class KitchenController : ControllerBase var result = await _mediator.Send(new UpdateTicketStatusCommand(id, request.Status), ct); return Ok(new ApiResponse { Success = true, Data = result }); } + + /// + /// EN: Create a kitchen ticket from order-service. + /// VI: Tạo phiếu bếp từ order-service. + /// + [HttpPost("tickets")] + [ProducesResponseType(typeof(CreateTicketResponse), 200)] + public async Task> CreateTicket( + [FromBody] CreateTicketRequest request, + CancellationToken ct = default) + { + // EN: Find or create an active session for this shop + // VI: Tìm hoặc tạo session hoạt động cho shop này + var sessions = await _sessionRepository.GetByShopAsync(request.ShopId, ct); + var activeSession = sessions.FirstOrDefault(s => s.Status == "Active"); + + if (activeSession == null) + { + activeSession = new Session(request.ShopId, request.ShopId, 1); + await _sessionRepository.AddAsync(activeSession, ct); + await _sessionRepository.UnitOfWork.SaveEntitiesAsync(ct); + } + + // EN: Create kitchen ticket via MediatR + // VI: Tạo phiếu bếp qua MediatR + var ticketId = await _mediator.Send(new CreateKitchenTicketCommand( + activeSession.Id, + request.ProductId, + request.ProductName, + null, + 0 + ), ct); + + return Ok(new CreateTicketResponse(ticketId)); + } + // ═══ RECIPE ENDPOINTS ═══ [HttpGet("recipes")] @@ -102,3 +141,12 @@ public class KitchenController : ControllerBase } public record UpdateStatusRequest(string Status); + +public record CreateTicketRequest( + Guid ProductId, + string ProductName, + Guid ShopId, + int Quantity, + string? Notes); + +public record CreateTicketResponse(Guid TicketId); diff --git a/services/order-service-net/src/OrderService.API/Application/Commands/CreateOrderCommandHandler.cs b/services/order-service-net/src/OrderService.API/Application/Commands/CreateOrderCommandHandler.cs index 7c563759..bc96433a 100644 --- a/services/order-service-net/src/OrderService.API/Application/Commands/CreateOrderCommandHandler.cs +++ b/services/order-service-net/src/OrderService.API/Application/Commands/CreateOrderCommandHandler.cs @@ -67,6 +67,14 @@ public class CreateOrderCommandHandler : IRequestHandler 0) diff --git a/services/order-service-net/src/OrderService.API/Application/Commands/PayOrderCommandHandler.cs b/services/order-service-net/src/OrderService.API/Application/Commands/PayOrderCommandHandler.cs index 2b3290ff..1c7cd643 100644 --- a/services/order-service-net/src/OrderService.API/Application/Commands/PayOrderCommandHandler.cs +++ b/services/order-service-net/src/OrderService.API/Application/Commands/PayOrderCommandHandler.cs @@ -4,27 +4,23 @@ using MediatR; using OrderService.Domain.AggregatesModel.OrderAggregate; using OrderService.Domain.Exceptions; -using OrderService.Domain.Strategies; namespace OrderService.API.Application.Commands; /// -/// EN: Handler for processing payment and executing order items via strategies. -/// VI: Handler xử lý thanh toán và thực thi order items qua strategies. +/// EN: Handler for processing payment. +/// VI: Handler xử lý thanh toán. /// public class PayOrderCommandHandler : IRequestHandler { private readonly IOrderRepository _orderRepository; - private readonly IEnumerable _strategies; private readonly ILogger _logger; public PayOrderCommandHandler( IOrderRepository orderRepository, - IEnumerable strategies, ILogger logger) { _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); - _strategies = strategies ?? throw new ArgumentNullException(nameof(strategies)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -55,21 +51,8 @@ public class PayOrderCommandHandler : IRequestHandler s.SupportedType == productType); - if (strategy == null) - { - throw new InvalidOperationException( - $"EN: No strategy found for product type / VI: Không tìm thấy strategy cho loại sản phẩm: {productType}"); - } - return strategy; - } } diff --git a/services/order-service-net/src/OrderService.API/Infrastructure/HttpClients/FnbEngineClient.cs b/services/order-service-net/src/OrderService.API/Infrastructure/HttpClients/FnbEngineClient.cs index aa5e7c75..df49f215 100644 --- a/services/order-service-net/src/OrderService.API/Infrastructure/HttpClients/FnbEngineClient.cs +++ b/services/order-service-net/src/OrderService.API/Infrastructure/HttpClients/FnbEngineClient.cs @@ -46,7 +46,7 @@ public class FnbEngineClient notes); var response = await _httpClient.PostAsJsonAsync( - "/api/v1/fnb/kitchen-tickets", + "/api/v1/kitchen/tickets", request, cancellationToken);