335 lines
9.3 KiB
Go
335 lines
9.3 KiB
Go
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
|
|
}
|