package mappers import ( "apskel-pos-be/internal/constants" "apskel-pos-be/internal/entities" "apskel-pos-be/internal/models" "github.com/google/uuid" ) func OrderEntityToResponse(order *entities.Order) *models.OrderResponse { if order == nil { return nil } response := &models.OrderResponse{ ID: order.ID, OrganizationID: order.OrganizationID, OutletID: order.OutletID, UserID: order.UserID, CustomerID: order.CustomerID, OrderNumber: order.OrderNumber, TableNumber: order.TableNumber, OrderType: constants.OrderType(order.OrderType), Status: constants.OrderStatus(order.Status), Subtotal: order.Subtotal, TaxAmount: order.TaxAmount, DiscountAmount: order.DiscountAmount, TotalAmount: order.TotalAmount, TotalCost: order.TotalCost, RemainingAmount: order.RemainingAmount, PaymentStatus: constants.PaymentStatus(order.PaymentStatus), RefundAmount: order.RefundAmount, IsVoid: order.IsVoid, IsRefund: order.IsRefund, VoidReason: order.VoidReason, VoidedAt: order.VoidedAt, VoidedBy: order.VoidedBy, RefundReason: order.RefundReason, RefundedAt: order.RefundedAt, RefundedBy: order.RefundedBy, Metadata: map[string]interface{}(order.Metadata), CreatedAt: order.CreatedAt, UpdatedAt: order.UpdatedAt, } // Calculate payment summary and determine split type var totalPaid float64 var paymentCount int var splitType *string if order.Payments != nil { paymentCount = len(order.Payments) for _, payment := range order.Payments { if payment.Status == entities.PaymentTransactionStatusCompleted { totalPaid += payment.Amount } // Determine split type from the first split payment if splitType == nil && payment.SplitType != nil && payment.SplitTotal > 1 { st := string(*payment.SplitType) splitType = &st } } } response.TotalPaid = totalPaid response.PaymentCount = paymentCount response.SplitType = splitType // Map order items if order.OrderItems != nil { response.OrderItems = make([]models.OrderItemResponse, len(order.OrderItems)) for i, item := range order.OrderItems { response.OrderItems[i] = *OrderItemEntityToResponse(&item) } } // Map payments if order.Payments != nil { response.Payments = make([]models.PaymentResponse, len(order.Payments)) for i, payment := range order.Payments { response.Payments[i] = *PaymentEntityToResponse(&payment) } } return response } func OrderItemEntityToResponse(item *entities.OrderItem) *models.OrderItemResponse { if item == nil { return nil } response := &models.OrderItemResponse{ ID: item.ID, OrderID: item.OrderID, ProductID: item.ProductID, ProductVariantID: item.ProductVariantID, Quantity: item.Quantity, UnitPrice: item.UnitPrice, TotalPrice: item.TotalPrice, UnitCost: item.UnitCost, TotalCost: item.TotalCost, RefundAmount: item.RefundAmount, RefundQuantity: item.RefundQuantity, IsPartiallyRefunded: item.IsPartiallyRefunded, IsFullyRefunded: item.IsFullyRefunded, RefundReason: item.RefundReason, RefundedAt: item.RefundedAt, RefundedBy: item.RefundedBy, Modifiers: []map[string]interface{}(item.Modifiers), Notes: item.Notes, Metadata: map[string]interface{}(item.Metadata), Status: constants.OrderItemStatus(item.Status), CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, PrinterType: item.Product.PrinterType, } if item.Product.ID != uuid.Nil { response.ProductName = item.Product.Name } if item.ProductVariant != nil { response.ProductVariantName = &item.ProductVariant.Name } return response } func PaymentEntityToResponse(payment *entities.Payment) *models.PaymentResponse { if payment == nil { return nil } response := &models.PaymentResponse{ ID: payment.ID, OrderID: payment.OrderID, PaymentMethodID: payment.PaymentMethodID, Amount: payment.Amount, Status: constants.PaymentTransactionStatus(payment.Status), TransactionID: payment.TransactionID, SplitNumber: payment.SplitNumber, SplitTotal: payment.SplitTotal, SplitType: (*string)(payment.SplitType), SplitDescription: payment.SplitDescription, RefundAmount: payment.RefundAmount, RefundReason: payment.RefundReason, RefundedAt: payment.RefundedAt, RefundedBy: payment.RefundedBy, Metadata: map[string]interface{}(payment.Metadata), CreatedAt: payment.CreatedAt, UpdatedAt: payment.UpdatedAt, } // Add payment method information if available if payment.PaymentMethod.ID != uuid.Nil { response.PaymentMethodName = payment.PaymentMethod.Name response.PaymentMethodType = constants.PaymentMethodType(payment.PaymentMethod.Type) } // Map payment order items if payment.PaymentOrderItems != nil { response.PaymentOrderItems = make([]models.PaymentOrderItemResponse, len(payment.PaymentOrderItems)) for i, item := range payment.PaymentOrderItems { response.PaymentOrderItems[i] = *PaymentOrderItemEntityToResponse(&item) } } return response } func PaymentOrderItemEntityToResponse(item *entities.PaymentOrderItem) *models.PaymentOrderItemResponse { if item == nil { return nil } return &models.PaymentOrderItemResponse{ ID: item.ID, PaymentID: item.PaymentID, OrderItemID: item.OrderItemID, Amount: item.Amount, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, } } // Request to Entity mappers func CreateOrderRequestToEntity(req *models.CreateOrderRequest, organizationID uuid.UUID) *entities.Order { if req == nil { return nil } order := &entities.Order{ OrganizationID: organizationID, OutletID: req.OutletID, UserID: req.UserID, CustomerID: req.CustomerID, TableNumber: req.TableNumber, OrderType: entities.OrderType(req.OrderType), Status: entities.OrderStatusPending, PaymentStatus: entities.PaymentStatusPending, IsVoid: false, IsRefund: false, Metadata: entities.Metadata(req.Metadata), } return order } func CreateOrderItemRequestToEntity(req *models.CreateOrderItemRequest) *entities.OrderItem { if req == nil { return nil } // UnitPrice will be set from database product price, not from request return &entities.OrderItem{ ProductID: req.ProductID, ProductVariantID: req.ProductVariantID, Quantity: req.Quantity, UnitPrice: 0, // Will be set from database product price Modifiers: entities.Modifiers(req.Modifiers), Notes: req.Notes, Metadata: entities.Metadata(req.Metadata), Status: entities.OrderItemStatusPending, } } func CreatePaymentRequestToEntity(req *models.CreatePaymentRequest) *entities.Payment { if req == nil { return nil } var splitType *entities.SplitType if req.SplitType != nil { st := entities.SplitType(*req.SplitType) splitType = &st } payment := &entities.Payment{ OrderID: req.OrderID, PaymentMethodID: req.PaymentMethodID, Amount: req.Amount, Status: entities.PaymentTransactionStatusPending, TransactionID: req.TransactionID, SplitNumber: req.SplitNumber, SplitTotal: req.SplitTotal, SplitType: splitType, SplitDescription: req.SplitDescription, Metadata: entities.Metadata(req.Metadata), } return payment } func CreatePaymentOrderItemRequestToEntity(req *models.CreatePaymentOrderItemRequest) *entities.PaymentOrderItem { if req == nil { return nil } return &entities.PaymentOrderItem{ OrderItemID: req.OrderItemID, Amount: req.Amount, } } // Update request to entity updates func UpdateOrderRequestToEntityUpdates(req *models.UpdateOrderRequest) map[string]interface{} { updates := make(map[string]interface{}) if req.TableNumber != nil { updates["table_number"] = *req.TableNumber } if req.Status != nil { updates["status"] = entities.OrderStatus(*req.Status) } if req.DiscountAmount != nil { updates["discount_amount"] = *req.DiscountAmount } if req.Metadata != nil { updates["metadata"] = entities.Metadata(req.Metadata) } return updates } // Helper functions for list responses func OrderEntitiesToResponses(orders []*entities.Order) []models.OrderResponse { if orders == nil { return nil } responses := make([]models.OrderResponse, len(orders)) for i, order := range orders { response := OrderEntityToResponse(order) if response != nil { responses[i] = *response } } return responses } func OrderItemEntitiesToResponses(items []*entities.OrderItem) []models.OrderItemResponse { if items == nil { return nil } responses := make([]models.OrderItemResponse, len(items)) for i, item := range items { response := OrderItemEntityToResponse(item) if response != nil { responses[i] = *response } } return responses } func PaymentEntitiesToResponses(payments []*entities.Payment) []models.PaymentResponse { if payments == nil { return nil } responses := make([]models.PaymentResponse, len(payments)) for i, payment := range payments { response := PaymentEntityToResponse(payment) if response != nil { responses[i] = *response } } return responses }