From a89ff00d9463283fcbd64930e03a243c28724ada Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 14 May 2026 15:15:32 +0700 Subject: [PATCH] add filter order by outlet id --- internal/handler/order_handler.go | 50 +++++++++++--- internal/processor/order_processor.go | 89 ++++++++++++------------- internal/processor/table_processor.go | 2 +- internal/repository/order_repository.go | 80 +++++++++++++--------- internal/service/order_service.go | 56 ++++++++-------- 5 files changed, 163 insertions(+), 114 deletions(-) diff --git a/internal/handler/order_handler.go b/internal/handler/order_handler.go index 0506e0b..7efaa8d 100644 --- a/internal/handler/order_handler.go +++ b/internal/handler/order_handler.go @@ -53,6 +53,14 @@ func (h *OrderHandler) CreateOrder(c *gin.Context) { } func (h *OrderHandler) GetOrderByID(c *gin.Context) { + ctx := c.Request.Context() + contextInfo := appcontext.FromGinContext(ctx) + + if contextInfo.OutletID == uuid.Nil { + util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::GetOrderByID", "outlet ID is required")}), "OrderHandler::GetOrderByID") + return + } + idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { @@ -60,7 +68,7 @@ func (h *OrderHandler) GetOrderByID(c *gin.Context) { return } - response, err := h.orderService.GetOrderByID(c.Request.Context(), id) + response, err := h.orderService.GetOrderByID(c.Request.Context(), id, contextInfo.OutletID) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::GetOrderByID", err.Error())}), "OrderHandler::GetOrderByID") return @@ -71,6 +79,14 @@ func (h *OrderHandler) GetOrderByID(c *gin.Context) { } func (h *OrderHandler) UpdateOrder(c *gin.Context) { + ctx := c.Request.Context() + contextInfo := appcontext.FromGinContext(ctx) + + if contextInfo.OutletID == uuid.Nil { + util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::UpdateOrder", "outlet ID is required")}), "OrderHandler::UpdateOrder") + return + } + idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { @@ -85,7 +101,7 @@ func (h *OrderHandler) UpdateOrder(c *gin.Context) { } modelReq := transformer.UpdateOrderContractToModel(&req) - response, err := h.orderService.UpdateOrder(c.Request.Context(), id, modelReq) + response, err := h.orderService.UpdateOrder(c.Request.Context(), id, modelReq, contextInfo.OutletID) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::UpdateOrder", err.Error())}), "OrderHandler::UpdateOrder") return @@ -96,6 +112,14 @@ func (h *OrderHandler) UpdateOrder(c *gin.Context) { } func (h *OrderHandler) AddToOrder(c *gin.Context) { + ctx := c.Request.Context() + contextInfo := appcontext.FromGinContext(ctx) + + if contextInfo.OutletID == uuid.Nil { + util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::AddToOrder", "outlet ID is required")}), "OrderHandler::AddToOrder") + return + } + idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { @@ -110,7 +134,7 @@ func (h *OrderHandler) AddToOrder(c *gin.Context) { } modelReq := transformer.AddToOrderContractToModel(&req) - response, err := h.orderService.AddToOrder(c.Request.Context(), id, modelReq) + response, err := h.orderService.AddToOrder(c.Request.Context(), id, modelReq, contextInfo.OutletID) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::AddToOrder", err.Error())}), "OrderHandler::AddToOrder") return @@ -167,7 +191,7 @@ func (h *OrderHandler) VoidOrder(c *gin.Context) { } modelReq := transformer.VoidOrderContractToModel(&req) - if err := h.orderService.VoidOrder(ctx, modelReq, userID); err != nil { + if err := h.orderService.VoidOrder(ctx, modelReq, userID, contextInfo.OutletID); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::VoidOrder", err.Error())}), "OrderHandler::VoidOrder") return } @@ -200,7 +224,7 @@ func (h *OrderHandler) RefundOrder(c *gin.Context) { return } - if err := h.orderService.RefundOrder(ctx, id, modelReq, userID); err != nil { + if err := h.orderService.RefundOrder(ctx, id, modelReq, userID, contextInfo.OutletID); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::RefundOrder", err.Error())}), "OrderHandler::RefundOrder") return } @@ -209,6 +233,14 @@ func (h *OrderHandler) RefundOrder(c *gin.Context) { } func (h *OrderHandler) CreatePayment(c *gin.Context) { + ctx := c.Request.Context() + contextInfo := appcontext.FromGinContext(ctx) + + if contextInfo.OutletID == uuid.Nil { + util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::CreatePayment", "outlet ID is required")}), "OrderHandler::CreatePayment") + return + } + var req contract.CreatePaymentRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::CreatePayment", err.Error())}), "OrderHandler::CreatePayment") @@ -222,7 +254,7 @@ func (h *OrderHandler) CreatePayment(c *gin.Context) { modelReq := transformer.CreatePaymentContractToModel(&req) - response, err := h.orderService.CreatePayment(c.Request.Context(), modelReq) + response, err := h.orderService.CreatePayment(c.Request.Context(), modelReq, contextInfo.OutletID) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::CreatePayment", err.Error())}), "OrderHandler::CreatePayment") return @@ -260,7 +292,7 @@ func (h *OrderHandler) RefundPayment(c *gin.Context) { return } - if err := h.orderService.RefundPayment(ctx, paymentID, req.RefundAmount, req.Reason, userID); err != nil { + if err := h.orderService.RefundPayment(ctx, paymentID, req.RefundAmount, req.Reason, userID, contextInfo.OutletID); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::RefundPayment", err.Error())}), "OrderHandler::RefundPayment") return } @@ -287,7 +319,7 @@ func (h *OrderHandler) SetOrderCustomer(c *gin.Context) { modelReq := transformer.SetOrderCustomerContractToModel(&req) - response, err := h.orderService.SetOrderCustomer(ctx, orderID, modelReq, contextInfo.OrganizationID) + response, err := h.orderService.SetOrderCustomer(ctx, orderID, modelReq, contextInfo.OrganizationID, contextInfo.OutletID) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::SetOrderCustomer", err.Error())}), "OrderHandler::SetOrderCustomer") return @@ -314,7 +346,7 @@ func (h *OrderHandler) SplitBill(c *gin.Context) { req.OrganizationID = contextInfo.OrganizationID modelReq := transformer.SplitBillContractToModel(&req) - response, err := h.orderService.SplitBill(c.Request.Context(), modelReq) + response, err := h.orderService.SplitBill(c.Request.Context(), modelReq, contextInfo.OutletID) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::SplitBill", err.Error())}), "OrderHandler::SplitBill") return diff --git a/internal/processor/order_processor.go b/internal/processor/order_processor.go index 26ee447..6902c1c 100644 --- a/internal/processor/order_processor.go +++ b/internal/processor/order_processor.go @@ -17,33 +17,33 @@ import ( type OrderProcessor interface { CreateOrder(ctx context.Context, req *models.CreateOrderRequest, organizationID uuid.UUID) (*models.OrderResponse, error) - AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest) (*models.AddToOrderResponse, error) - UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest) (*models.OrderResponse, error) - GetOrderByID(ctx context.Context, id uuid.UUID) (*models.OrderResponse, error) + AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest, outletID uuid.UUID) (*models.AddToOrderResponse, error) + UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest, outletID uuid.UUID) (*models.OrderResponse, error) + GetOrderByID(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*models.OrderResponse, error) ListOrders(ctx context.Context, req *models.ListOrdersRequest) (*models.ListOrdersResponse, error) - VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID) error - RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID) error - CreatePayment(ctx context.Context, req *models.CreatePaymentRequest) (*models.PaymentResponse, error) - RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID) error - SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID) (*models.SetOrderCustomerResponse, error) - SplitBill(ctx context.Context, req *models.SplitBillRequest) (*models.SplitBillResponse, error) + VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID, outletID uuid.UUID) error + RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID, outletID uuid.UUID) error + CreatePayment(ctx context.Context, req *models.CreatePaymentRequest, outletID uuid.UUID) (*models.PaymentResponse, error) + RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID, outletID uuid.UUID) error + SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID, outletID uuid.UUID) (*models.SetOrderCustomerResponse, error) + SplitBill(ctx context.Context, req *models.SplitBillRequest, outletID uuid.UUID) (*models.SplitBillResponse, error) } type OrderRepository interface { Create(ctx context.Context, order *entities.Order) error - GetByID(ctx context.Context, id uuid.UUID) (*entities.Order, error) - GetWithRelations(ctx context.Context, id uuid.UUID) (*entities.Order, error) + GetByID(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*entities.Order, error) + GetWithRelations(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*entities.Order, error) Update(ctx context.Context, order *entities.Order) error - UpdateStatusSuccess(ctx context.Context, id uuid.UUID, orderStatus entities.OrderStatus, paymentStatus entities.PaymentStatus) error + UpdateStatusSuccess(ctx context.Context, id uuid.UUID, orderStatus entities.OrderStatus, paymentStatus entities.PaymentStatus, outletID uuid.UUID) error Delete(ctx context.Context, id uuid.UUID) error List(ctx context.Context, filters map[string]interface{}, limit, offset int) ([]*entities.Order, int64, error) GetByOrderNumber(ctx context.Context, orderNumber string) (*entities.Order, error) ExistsByOrderNumber(ctx context.Context, orderNumber string) (bool, error) - VoidOrder(ctx context.Context, id uuid.UUID, reason string, voidedBy uuid.UUID) error - VoidOrderWithStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, reason string, voidedBy uuid.UUID) error - RefundOrder(ctx context.Context, id uuid.UUID, reason string, refundedBy uuid.UUID) error - UpdatePaymentStatus(ctx context.Context, id uuid.UUID, status entities.PaymentStatus) error - UpdateStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus) error + VoidOrder(ctx context.Context, id uuid.UUID, reason string, voidedBy uuid.UUID, outletID uuid.UUID) error + VoidOrderWithStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, reason string, voidedBy uuid.UUID, outletID uuid.UUID) error + RefundOrder(ctx context.Context, id uuid.UUID, reason string, refundedBy uuid.UUID, outletID uuid.UUID) error + UpdatePaymentStatus(ctx context.Context, id uuid.UUID, status entities.PaymentStatus, outletID uuid.UUID) error + UpdateStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, outletID uuid.UUID) error GetNextOrderNumber(ctx context.Context, organizationID, outletID uuid.UUID) (string, error) } @@ -260,7 +260,7 @@ func (p *OrderProcessorImpl) CreateOrder(ctx context.Context, req *models.Create } } - orderWithRelations, err := p.orderRepo.GetWithRelations(ctx, order.ID) + orderWithRelations, err := p.orderRepo.GetWithRelations(ctx, order.ID, uuid.Nil) if err != nil { return nil, fmt.Errorf("failed to retrieve created order: %w", err) } @@ -269,8 +269,8 @@ func (p *OrderProcessorImpl) CreateOrder(ctx context.Context, req *models.Create return response, nil } -func (p *OrderProcessorImpl) AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest) (*models.AddToOrderResponse, error) { - order, err := p.orderRepo.GetByID(ctx, orderID) +func (p *OrderProcessorImpl) AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest, outletID uuid.UUID) (*models.AddToOrderResponse, error) { + order, err := p.orderRepo.GetByID(ctx, orderID, outletID) if err != nil { return nil, fmt.Errorf("order not found: %w", err) } @@ -415,7 +415,7 @@ func (p *OrderProcessorImpl) AddToOrder(ctx context.Context, orderID uuid.UUID, addedItemResponses = append(addedItemResponses, itemResponse) } - orderWithRelations, err := p.orderRepo.GetWithRelations(ctx, orderID) + orderWithRelations, err := p.orderRepo.GetWithRelations(ctx, orderID, outletID) if err != nil { return nil, fmt.Errorf("failed to retrieve updated order: %w", err) } @@ -430,9 +430,8 @@ func (p *OrderProcessorImpl) AddToOrder(ctx context.Context, orderID uuid.UUID, }, nil } -func (p *OrderProcessorImpl) UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest) (*models.OrderResponse, error) { - // Get existing order - order, err := p.orderRepo.GetByID(ctx, id) +func (p *OrderProcessorImpl) UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest, outletID uuid.UUID) (*models.OrderResponse, error) { + order, err := p.orderRepo.GetByID(ctx, id, outletID) if err != nil { return nil, fmt.Errorf("order not found: %w", err) } @@ -477,11 +476,11 @@ func (p *OrderProcessorImpl) UpdateOrder(ctx context.Context, id uuid.UUID, req order.Status = entities.OrderStatusCompleted order.PaymentStatus = entities.PaymentStatusCompleted - if err := p.orderRepo.UpdateStatusSuccess(ctx, order.ID, order.Status, order.PaymentStatus); err != nil { + if err := p.orderRepo.UpdateStatusSuccess(ctx, order.ID, order.Status, order.PaymentStatus, outletID); err != nil { return nil, fmt.Errorf("failed to update order: %w", err) } - orderWithRelations, err := p.orderRepo.GetWithRelations(ctx, id) + orderWithRelations, err := p.orderRepo.GetWithRelations(ctx, id, outletID) if err != nil { return nil, fmt.Errorf("failed to retrieve updated order: %w", err) } @@ -490,8 +489,8 @@ func (p *OrderProcessorImpl) UpdateOrder(ctx context.Context, id uuid.UUID, req return response, nil } -func (p *OrderProcessorImpl) GetOrderByID(ctx context.Context, id uuid.UUID) (*models.OrderResponse, error) { - order, err := p.orderRepo.GetWithRelations(ctx, id) +func (p *OrderProcessorImpl) GetOrderByID(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*models.OrderResponse, error) { + order, err := p.orderRepo.GetWithRelations(ctx, id, outletID) if err != nil { return nil, fmt.Errorf("order not found: %w", err) } @@ -574,12 +573,12 @@ func (p *OrderProcessorImpl) ListOrders(ctx context.Context, req *models.ListOrd }, nil } -func (p *OrderProcessorImpl) VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID) error { +func (p *OrderProcessorImpl) VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID, outletID uuid.UUID) error { if req.OrderID != req.OrderID { return fmt.Errorf("order ID mismatch: path parameter does not match request body") } - order, err := p.orderRepo.GetByID(ctx, req.OrderID) + order, err := p.orderRepo.GetByID(ctx, req.OrderID, outletID) if err != nil { return fmt.Errorf("order not found: %w", err) } @@ -593,7 +592,7 @@ func (p *OrderProcessorImpl) VoidOrder(ctx context.Context, req *models.VoidOrde } if req.Type == "ALL" { - if err := p.orderRepo.VoidOrderWithStatus(ctx, req.OrderID, entities.OrderStatusCancelled, req.Reason, voidedBy); err != nil { + if err := p.orderRepo.VoidOrderWithStatus(ctx, req.OrderID, entities.OrderStatusCancelled, req.Reason, voidedBy, outletID); err != nil { return fmt.Errorf("failed to void order: %w", err) } } else if req.Type == "ITEM" { @@ -659,7 +658,7 @@ func (p *OrderProcessorImpl) VoidOrder(ctx context.Context, req *models.VoidOrde } if !hasActiveItems { - if err := p.orderRepo.VoidOrderWithStatus(ctx, req.OrderID, entities.OrderStatusCancelled, req.Reason, voidedBy); err != nil { + if err := p.orderRepo.VoidOrderWithStatus(ctx, req.OrderID, entities.OrderStatusCancelled, req.Reason, voidedBy, outletID); err != nil { return fmt.Errorf("failed to void order after all items voided: %w", err) } } @@ -670,8 +669,8 @@ func (p *OrderProcessorImpl) VoidOrder(ctx context.Context, req *models.VoidOrde return nil } -func (p *OrderProcessorImpl) RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID) error { - order, err := p.orderRepo.GetWithRelations(ctx, id) +func (p *OrderProcessorImpl) RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID, outletID uuid.UUID) error { + order, err := p.orderRepo.GetWithRelations(ctx, id, outletID) if err != nil { return fmt.Errorf("order not found: %w", err) } @@ -703,7 +702,7 @@ func (p *OrderProcessorImpl) RefundOrder(ctx context.Context, id uuid.UUID, req } // Mark order as refunded - if err := p.orderRepo.RefundOrder(ctx, id, reason, refundedBy); err != nil { + if err := p.orderRepo.RefundOrder(ctx, id, reason, refundedBy, outletID); err != nil { return fmt.Errorf("failed to mark order as refunded: %w", err) } @@ -757,7 +756,7 @@ func (p *OrderProcessorImpl) RefundOrder(ctx context.Context, id uuid.UUID, req } // Mark order as refunded - if err := p.orderRepo.RefundOrder(ctx, id, reason, refundedBy); err != nil { + if err := p.orderRepo.RefundOrder(ctx, id, reason, refundedBy, outletID); err != nil { return fmt.Errorf("failed to mark order as refunded: %w", err) } } @@ -765,8 +764,8 @@ func (p *OrderProcessorImpl) RefundOrder(ctx context.Context, id uuid.UUID, req return nil } -func (p *OrderProcessorImpl) CreatePayment(ctx context.Context, req *models.CreatePaymentRequest) (*models.PaymentResponse, error) { - order, err := p.orderRepo.GetByID(ctx, req.OrderID) +func (p *OrderProcessorImpl) CreatePayment(ctx context.Context, req *models.CreatePaymentRequest, outletID uuid.UUID) (*models.PaymentResponse, error) { + order, err := p.orderRepo.GetByID(ctx, req.OrderID, outletID) if err != nil { return nil, fmt.Errorf("order not found: %w", err) } @@ -803,7 +802,7 @@ func (p *OrderProcessorImpl) CreatePayment(ctx context.Context, req *models.Crea return response, nil } -func (p *OrderProcessorImpl) RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID) error { +func (p *OrderProcessorImpl) RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID, outletID uuid.UUID) error { payment, err := p.paymentRepo.GetByID(ctx, paymentID) if err != nil { return fmt.Errorf("payment not found: %w", err) @@ -875,7 +874,7 @@ func (p *OrderProcessorImpl) updateOrderStatus(ctx context.Context, orderID uuid PaymentStatus: entities.PaymentStatusCompleted, } - if err := p.orderRepo.UpdateStatusSuccess(ctx, orderID, orderUpdate.Status, orderUpdate.PaymentStatus); err != nil { + if err := p.orderRepo.UpdateStatusSuccess(ctx, orderID, orderUpdate.Status, orderUpdate.PaymentStatus, uuid.Nil); err != nil { return fmt.Errorf("failed to update order status: %w", err) } @@ -1071,7 +1070,7 @@ func (p *OrderProcessorImpl) processRefund(ctx context.Context, paymentID uuid.U } func (p *OrderProcessorImpl) updateOrderRefundAmount(ctx context.Context, orderID uuid.UUID, refundAmount float64) error { - order, err := p.orderRepo.GetByID(ctx, orderID) + order, err := p.orderRepo.GetByID(ctx, orderID, uuid.Nil) if err != nil { return fmt.Errorf("failed to get order: %w", err) } @@ -1084,8 +1083,8 @@ func (p *OrderProcessorImpl) updateOrderRefundAmount(ctx context.Context, orderI return nil } -func (p *OrderProcessorImpl) SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID) (*models.SetOrderCustomerResponse, error) { - order, err := p.orderRepo.GetByID(ctx, orderID) +func (p *OrderProcessorImpl) SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID, outletID uuid.UUID) (*models.SetOrderCustomerResponse, error) { + order, err := p.orderRepo.GetByID(ctx, orderID, outletID) if err != nil { return nil, fmt.Errorf("order not found: %w", err) } @@ -1119,8 +1118,8 @@ func (p *OrderProcessorImpl) SetOrderCustomer(ctx context.Context, orderID uuid. return response, nil } -func (p *OrderProcessorImpl) SplitBill(ctx context.Context, req *models.SplitBillRequest) (*models.SplitBillResponse, error) { - order, err := p.orderRepo.GetWithRelations(ctx, req.OrderID) +func (p *OrderProcessorImpl) SplitBill(ctx context.Context, req *models.SplitBillRequest, outletID uuid.UUID) (*models.SplitBillResponse, error) { + order, err := p.orderRepo.GetWithRelations(ctx, req.OrderID, outletID) if err != nil { return nil, fmt.Errorf("order not found: %w", err) } diff --git a/internal/processor/table_processor.go b/internal/processor/table_processor.go index 1dcea07..3753ff5 100644 --- a/internal/processor/table_processor.go +++ b/internal/processor/table_processor.go @@ -137,7 +137,7 @@ func (p *TableProcessor) OccupyTable(ctx context.Context, tableID uuid.UUID, req } // Verify order exists - _, err = p.orderRepo.GetByID(ctx, req.OrderID) + _, err = p.orderRepo.GetByID(ctx, req.OrderID, uuid.Nil) if err != nil { return nil, errors.New("order not found") } diff --git a/internal/repository/order_repository.go b/internal/repository/order_repository.go index 1ba460b..3b78eb5 100644 --- a/internal/repository/order_repository.go +++ b/internal/repository/order_repository.go @@ -13,19 +13,20 @@ import ( type OrderRepository interface { Create(ctx context.Context, order *entities.Order) error - GetByID(ctx context.Context, id uuid.UUID) (*entities.Order, error) - GetWithRelations(ctx context.Context, id uuid.UUID) (*entities.Order, error) + GetByID(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*entities.Order, error) + GetWithRelations(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*entities.Order, error) Update(ctx context.Context, order *entities.Order) error Delete(ctx context.Context, id uuid.UUID) error List(ctx context.Context, filters map[string]interface{}, limit, offset int) ([]*entities.Order, int64, error) ListBySessionID(ctx context.Context, sessionID string) ([]*entities.Order, error) GetByOrderNumber(ctx context.Context, orderNumber string) (*entities.Order, error) ExistsByOrderNumber(ctx context.Context, orderNumber string) (bool, error) - VoidOrder(ctx context.Context, id uuid.UUID, reason string, voidedBy uuid.UUID) error - VoidOrderWithStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, reason string, voidedBy uuid.UUID) error - RefundOrder(ctx context.Context, id uuid.UUID, reason string, refundedBy uuid.UUID) error - UpdatePaymentStatus(ctx context.Context, id uuid.UUID, status entities.PaymentStatus) error - UpdateStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus) error + VoidOrder(ctx context.Context, id uuid.UUID, reason string, voidedBy uuid.UUID, outletID uuid.UUID) error + VoidOrderWithStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, reason string, voidedBy uuid.UUID, outletID uuid.UUID) error + RefundOrder(ctx context.Context, id uuid.UUID, reason string, refundedBy uuid.UUID, outletID uuid.UUID) error + UpdatePaymentStatus(ctx context.Context, id uuid.UUID, status entities.PaymentStatus, outletID uuid.UUID) error + UpdateStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, outletID uuid.UUID) error + UpdateStatusSuccess(ctx context.Context, id uuid.UUID, orderStatus entities.OrderStatus, paymentStatus entities.PaymentStatus, outletID uuid.UUID) error GetNextOrderNumber(ctx context.Context, organizationID, outletID uuid.UUID) (string, error) } @@ -43,18 +44,27 @@ func (r *OrderRepositoryImpl) Create(ctx context.Context, order *entities.Order) return r.db.WithContext(ctx).Create(order).Error } -func (r *OrderRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.Order, error) { +func applyOutletFilter(query *gorm.DB, outletID uuid.UUID) *gorm.DB { + if outletID != uuid.Nil { + return query.Where("outlet_id = ?", outletID) + } + return query +} + +func (r *OrderRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*entities.Order, error) { var order entities.Order - err := r.db.WithContext(ctx).First(&order, "id = ?", id).Error + query := r.db.WithContext(ctx) + query = applyOutletFilter(query, outletID) + err := query.First(&order, "id = ?", id).Error if err != nil { return nil, err } return &order, nil } -func (r *OrderRepositoryImpl) GetWithRelations(ctx context.Context, id uuid.UUID) (*entities.Order, error) { +func (r *OrderRepositoryImpl) GetWithRelations(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*entities.Order, error) { var order entities.Order - err := r.db.WithContext(ctx). + query := r.db.WithContext(ctx). Preload("Organization"). Preload("Outlet"). Preload("User"). @@ -63,8 +73,9 @@ func (r *OrderRepositoryImpl) GetWithRelations(ctx context.Context, id uuid.UUID Preload("OrderItems.ProductVariant"). Preload("Payments"). Preload("Payments.PaymentMethod"). - Preload("Payments.PaymentOrderItems"). - First(&order, "id = ?", id).Error + Preload("Payments.PaymentOrderItems") + query = applyOutletFilter(query, outletID) + err := query.First(&order, "id = ?", id).Error if err != nil { return nil, err } @@ -80,10 +91,12 @@ func (r *OrderRepositoryImpl) UpdateStatusSuccess( id uuid.UUID, orderStatus entities.OrderStatus, paymentStatus entities.PaymentStatus, + outletID uuid.UUID, ) error { - return r.db.WithContext(ctx). - Model(&entities.Order{}). - Where("id = ?", id.String()). + query := r.db.WithContext(ctx). + Model(&entities.Order{}) + query = applyOutletFilter(query, outletID) + return query.Where("id = ?", id.String()). Updates(map[string]interface{}{ "status": orderStatus, "payment_status": paymentStatus, @@ -164,10 +177,11 @@ func (r *OrderRepositoryImpl) ExistsByOrderNumber(ctx context.Context, orderNumb return count > 0, err } -func (r *OrderRepositoryImpl) VoidOrder(ctx context.Context, id uuid.UUID, reason string, voidedBy uuid.UUID) error { +func (r *OrderRepositoryImpl) VoidOrder(ctx context.Context, id uuid.UUID, reason string, voidedBy uuid.UUID, outletID uuid.UUID) error { now := time.Now() - return r.db.WithContext(ctx).Model(&entities.Order{}). - Where("id = ?", id). + query := r.db.WithContext(ctx).Model(&entities.Order{}) + query = applyOutletFilter(query, outletID) + return query.Where("id = ?", id). Updates(map[string]interface{}{ "is_void": true, "void_reason": reason, @@ -176,10 +190,11 @@ func (r *OrderRepositoryImpl) VoidOrder(ctx context.Context, id uuid.UUID, reaso }).Error } -func (r *OrderRepositoryImpl) VoidOrderWithStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, reason string, voidedBy uuid.UUID) error { +func (r *OrderRepositoryImpl) VoidOrderWithStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, reason string, voidedBy uuid.UUID, outletID uuid.UUID) error { now := time.Now() - return r.db.WithContext(ctx).Model(&entities.Order{}). - Where("id = ?", id). + query := r.db.WithContext(ctx).Model(&entities.Order{}) + query = applyOutletFilter(query, outletID) + return query.Where("id = ?", id). Updates(map[string]interface{}{ "status": status, "is_void": true, @@ -189,10 +204,11 @@ func (r *OrderRepositoryImpl) VoidOrderWithStatus(ctx context.Context, id uuid.U }).Error } -func (r *OrderRepositoryImpl) RefundOrder(ctx context.Context, id uuid.UUID, reason string, refundedBy uuid.UUID) error { +func (r *OrderRepositoryImpl) RefundOrder(ctx context.Context, id uuid.UUID, reason string, refundedBy uuid.UUID, outletID uuid.UUID) error { now := time.Now() - return r.db.WithContext(ctx).Model(&entities.Order{}). - Where("id = ?", id). + query := r.db.WithContext(ctx).Model(&entities.Order{}) + query = applyOutletFilter(query, outletID) + return query.Where("id = ?", id). Updates(map[string]interface{}{ "is_refund": true, "refund_reason": reason, @@ -201,15 +217,17 @@ func (r *OrderRepositoryImpl) RefundOrder(ctx context.Context, id uuid.UUID, rea }).Error } -func (r *OrderRepositoryImpl) UpdatePaymentStatus(ctx context.Context, id uuid.UUID, status entities.PaymentStatus) error { - return r.db.WithContext(ctx).Model(&entities.Order{}). - Where("id = ?", id). +func (r *OrderRepositoryImpl) UpdatePaymentStatus(ctx context.Context, id uuid.UUID, status entities.PaymentStatus, outletID uuid.UUID) error { + query := r.db.WithContext(ctx).Model(&entities.Order{}) + query = applyOutletFilter(query, outletID) + return query.Where("id = ?", id). Update("payment_status", status).Error } -func (r *OrderRepositoryImpl) UpdateStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus) error { - return r.db.WithContext(ctx).Model(&entities.Order{}). - Where("id = ?", id). +func (r *OrderRepositoryImpl) UpdateStatus(ctx context.Context, id uuid.UUID, status entities.OrderStatus, outletID uuid.UUID) error { + query := r.db.WithContext(ctx).Model(&entities.Order{}) + query = applyOutletFilter(query, outletID) + return query.Where("id = ?", id). Update("status", status).Error } diff --git a/internal/service/order_service.go b/internal/service/order_service.go index f205d2d..fe220a1 100644 --- a/internal/service/order_service.go +++ b/internal/service/order_service.go @@ -23,16 +23,16 @@ type orderUserRepository interface { type OrderService interface { CreateOrder(ctx context.Context, req *models.CreateOrderRequest, organizationID uuid.UUID) (*models.OrderResponse, error) - AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest) (*models.AddToOrderResponse, error) - UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest) (*models.OrderResponse, error) - GetOrderByID(ctx context.Context, id uuid.UUID) (*models.OrderResponse, error) + AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest, outletID uuid.UUID) (*models.AddToOrderResponse, error) + UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest, outletID uuid.UUID) (*models.OrderResponse, error) + GetOrderByID(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*models.OrderResponse, error) ListOrders(ctx context.Context, req *models.ListOrdersRequest) (*models.ListOrdersResponse, error) - VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID) error - RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID) error - CreatePayment(ctx context.Context, req *models.CreatePaymentRequest) (*models.PaymentResponse, error) - RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID) error - SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID) (*models.SetOrderCustomerResponse, error) - SplitBill(ctx context.Context, req *models.SplitBillRequest) (*models.SplitBillResponse, error) + VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID, outletID uuid.UUID) error + RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID, outletID uuid.UUID) error + CreatePayment(ctx context.Context, req *models.CreatePaymentRequest, outletID uuid.UUID) (*models.PaymentResponse, error) + RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID, outletID uuid.UUID) error + SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID, outletID uuid.UUID) (*models.SetOrderCustomerResponse, error) + SplitBill(ctx context.Context, req *models.SplitBillRequest, outletID uuid.UUID) (*models.SplitBillResponse, error) } type OrderServiceImpl struct { @@ -216,7 +216,7 @@ func (s *OrderServiceImpl) createIngredientTransactions(ctx context.Context, ord return allTransactions, nil } -func (s *OrderServiceImpl) AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest) (*models.AddToOrderResponse, error) { +func (s *OrderServiceImpl) AddToOrder(ctx context.Context, orderID uuid.UUID, req *models.AddToOrderRequest, outletID uuid.UUID) (*models.AddToOrderResponse, error) { if orderID == uuid.Nil { return nil, fmt.Errorf("invalid order ID") } @@ -229,7 +229,7 @@ func (s *OrderServiceImpl) AddToOrder(ctx context.Context, orderID uuid.UUID, re var ingredientTransactions []*contract.CreateOrderIngredientTransactionRequest err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error { - addResp, err := s.orderProcessor.AddToOrder(txCtx, orderID, req) + addResp, err := s.orderProcessor.AddToOrder(txCtx, orderID, req, outletID) if err != nil { return fmt.Errorf("failed to add items to order: %w", err) } @@ -257,12 +257,12 @@ func (s *OrderServiceImpl) AddToOrder(ctx context.Context, orderID uuid.UUID, re return response, nil } -func (s *OrderServiceImpl) UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest) (*models.OrderResponse, error) { +func (s *OrderServiceImpl) UpdateOrder(ctx context.Context, id uuid.UUID, req *models.UpdateOrderRequest, outletID uuid.UUID) (*models.OrderResponse, error) { if err := s.validateUpdateOrderRequest(req); err != nil { return nil, fmt.Errorf("validation error: %w", err) } - response, err := s.orderProcessor.UpdateOrder(ctx, id, req) + response, err := s.orderProcessor.UpdateOrder(ctx, id, req, outletID) if err != nil { return nil, fmt.Errorf("failed to update order: %w", err) } @@ -270,12 +270,12 @@ func (s *OrderServiceImpl) UpdateOrder(ctx context.Context, id uuid.UUID, req *m return response, nil } -func (s *OrderServiceImpl) GetOrderByID(ctx context.Context, id uuid.UUID) (*models.OrderResponse, error) { +func (s *OrderServiceImpl) GetOrderByID(ctx context.Context, id uuid.UUID, outletID uuid.UUID) (*models.OrderResponse, error) { if id == uuid.Nil { return nil, fmt.Errorf("invalid order ID") } - response, err := s.orderProcessor.GetOrderByID(ctx, id) + response, err := s.orderProcessor.GetOrderByID(ctx, id, outletID) if err != nil { return nil, fmt.Errorf("failed to get order: %w", err) } @@ -296,7 +296,7 @@ func (s *OrderServiceImpl) ListOrders(ctx context.Context, req *models.ListOrder return response, nil } -func (s *OrderServiceImpl) VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID) error { +func (s *OrderServiceImpl) VoidOrder(ctx context.Context, req *models.VoidOrderRequest, voidedBy uuid.UUID, outletID uuid.UUID) error { if req.OrderID == uuid.Nil { return fmt.Errorf("invalid order ID") } @@ -305,7 +305,7 @@ func (s *OrderServiceImpl) VoidOrder(ctx context.Context, req *models.VoidOrderR return fmt.Errorf("invalid user ID") } - if err := s.orderProcessor.VoidOrder(ctx, req, voidedBy); err != nil { + if err := s.orderProcessor.VoidOrder(ctx, req, voidedBy, outletID); err != nil { return fmt.Errorf("failed to void order: %w", err) } @@ -316,7 +316,7 @@ func (s *OrderServiceImpl) VoidOrder(ctx context.Context, req *models.VoidOrderR return nil } -func (s *OrderServiceImpl) RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID) error { +func (s *OrderServiceImpl) RefundOrder(ctx context.Context, id uuid.UUID, req *models.RefundOrderRequest, refundedBy uuid.UUID, outletID uuid.UUID) error { // Validate inputs if id == uuid.Nil { return fmt.Errorf("invalid order ID") @@ -331,19 +331,19 @@ func (s *OrderServiceImpl) RefundOrder(ctx context.Context, id uuid.UUID, req *m } // Process order refund - if err := s.orderProcessor.RefundOrder(ctx, id, req, refundedBy); err != nil { + if err := s.orderProcessor.RefundOrder(ctx, id, req, refundedBy, outletID); err != nil { return fmt.Errorf("failed to refund order: %w", err) } return nil } -func (s *OrderServiceImpl) CreatePayment(ctx context.Context, req *models.CreatePaymentRequest) (*models.PaymentResponse, error) { +func (s *OrderServiceImpl) CreatePayment(ctx context.Context, req *models.CreatePaymentRequest, outletID uuid.UUID) (*models.PaymentResponse, error) { if err := s.validateCreatePaymentRequest(req); err != nil { return nil, fmt.Errorf("validation error: %w", err) } - response, err := s.orderProcessor.CreatePayment(ctx, req) + response, err := s.orderProcessor.CreatePayment(ctx, req, outletID) if err != nil { return nil, fmt.Errorf("failed to create payment: %w", err) } @@ -355,7 +355,7 @@ func (s *OrderServiceImpl) CreatePayment(ctx context.Context, req *models.Create return response, nil } -func (s *OrderServiceImpl) RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID) error { +func (s *OrderServiceImpl) RefundPayment(ctx context.Context, paymentID uuid.UUID, refundAmount float64, reason string, refundedBy uuid.UUID, outletID uuid.UUID) error { // Validate inputs if paymentID == uuid.Nil { return fmt.Errorf("invalid payment ID") @@ -368,14 +368,14 @@ func (s *OrderServiceImpl) RefundPayment(ctx context.Context, paymentID uuid.UUI } // Process payment refund - if err := s.orderProcessor.RefundPayment(ctx, paymentID, refundAmount, reason, refundedBy); err != nil { + if err := s.orderProcessor.RefundPayment(ctx, paymentID, refundAmount, reason, refundedBy, outletID); err != nil { return fmt.Errorf("failed to refund payment: %w", err) } return nil } -func (s *OrderServiceImpl) SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID) (*models.SetOrderCustomerResponse, error) { +func (s *OrderServiceImpl) SetOrderCustomer(ctx context.Context, orderID uuid.UUID, req *models.SetOrderCustomerRequest, organizationID uuid.UUID, outletID uuid.UUID) (*models.SetOrderCustomerResponse, error) { // Validate inputs if orderID == uuid.Nil { return nil, fmt.Errorf("invalid order ID") @@ -391,7 +391,7 @@ func (s *OrderServiceImpl) SetOrderCustomer(ctx context.Context, orderID uuid.UU } // Process setting customer for order - response, err := s.orderProcessor.SetOrderCustomer(ctx, orderID, req, organizationID) + response, err := s.orderProcessor.SetOrderCustomer(ctx, orderID, req, organizationID, outletID) if err != nil { return nil, fmt.Errorf("failed to set customer for order: %w", err) } @@ -584,12 +584,12 @@ func (s *OrderServiceImpl) validateSetOrderCustomerRequest(req *models.SetOrderC return nil } -func (s *OrderServiceImpl) SplitBill(ctx context.Context, req *models.SplitBillRequest) (*models.SplitBillResponse, error) { +func (s *OrderServiceImpl) SplitBill(ctx context.Context, req *models.SplitBillRequest, outletID uuid.UUID) (*models.SplitBillResponse, error) { if err := s.validateSplitBillRequest(req); err != nil { return nil, fmt.Errorf("validation error: %w", err) } - response, err := s.orderProcessor.SplitBill(ctx, req) + response, err := s.orderProcessor.SplitBill(ctx, req, outletID) if err != nil { return nil, fmt.Errorf("failed to split bill: %w", err) } @@ -680,7 +680,7 @@ func (s *OrderServiceImpl) occupyTableWithOrder(ctx context.Context, tableID, or } func (s *OrderServiceImpl) handleTableReleaseOnPayment(ctx context.Context, orderID uuid.UUID) error { - order, err := s.orderProcessor.GetOrderByID(ctx, orderID) + order, err := s.orderProcessor.GetOrderByID(ctx, orderID, uuid.Nil) if err != nil { return fmt.Errorf("failed to get order: %w", err) }