Compare commits

..

2 Commits

Author SHA1 Message Date
a89ff00d94 add filter order by outlet id 2026-05-14 15:15:32 +07:00
227f11359c Revert "add list order by outlet id"
This reverts commit 7a737d7f830faadcad8e7eaec09f160d436a0049.
2026-05-14 14:46:32 +07:00
5 changed files with 163 additions and 139 deletions

View File

@ -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

View File

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

View File

@ -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")
}

View File

@ -13,21 +13,21 @@ 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)
ListByOutletID(ctx context.Context, outletID uuid.UUID, limit, offset int) ([]*entities.Order, int64, error)
}
type OrderRepositoryImpl struct {
@ -44,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").
@ -64,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
}
@ -81,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,
@ -165,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,
@ -177,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,
@ -190,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,
@ -202,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
}
@ -271,27 +288,3 @@ func (r *OrderRepositoryImpl) GetNextOrderNumber(ctx context.Context, organizati
orderNumber := fmt.Sprintf("ORD/%04d%02d/%06d", year, month, sequence.SequenceNumber)
return orderNumber, nil
}
func (r *OrderRepositoryImpl) ListByOutletID(ctx context.Context, outletID uuid.UUID, limit, offset int) ([]*entities.Order, int64, error) {
var orders []*entities.Order
var total int64
query := r.db.WithContext(ctx).Model(&entities.Order{}).
Preload("Organization").
Preload("Outlet").
Preload("User").
Preload("OrderItems").
Preload("OrderItems.Product").
Preload("OrderItems.ProductVariant").
Preload("Payments").
Preload("Payments.PaymentMethod").
Preload("Payments.PaymentOrderItems").
Where("outlet_id = ?", outletID)
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
err := query.Limit(limit).Offset(offset).Order("created_at DESC").Find(&orders).Error
return orders, total, err
}

View File

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