package models import ( "apskel-pos-be/internal/constants" "time" "github.com/google/uuid" ) type Order struct { ID uuid.UUID OrganizationID uuid.UUID OutletID uuid.UUID UserID uuid.UUID CustomerID *uuid.UUID OrderNumber string TableNumber *string OrderType constants.OrderType Status constants.OrderStatus Subtotal float64 TaxAmount float64 DiscountAmount float64 TotalAmount float64 TotalCost float64 PaymentStatus constants.PaymentStatus RefundAmount float64 IsVoid bool IsRefund bool VoidReason *string VoidedAt *time.Time VoidedBy *uuid.UUID RefundReason *string RefundedAt *time.Time RefundedBy *uuid.UUID Metadata map[string]interface{} CreatedAt time.Time UpdatedAt time.Time } type OrderItem struct { ID uuid.UUID OrderID uuid.UUID ProductID uuid.UUID ProductVariantID *uuid.UUID Quantity int UnitPrice float64 TotalPrice float64 UnitCost float64 TotalCost float64 RefundAmount float64 RefundQuantity int IsPartiallyRefunded bool IsFullyRefunded bool RefundReason *string RefundedAt *time.Time RefundedBy *uuid.UUID Modifiers []map[string]interface{} Status constants.OrderItemStatus CreatedAt time.Time UpdatedAt time.Time } type PaymentOrderItem struct { ID uuid.UUID PaymentID uuid.UUID OrderItemID uuid.UUID Amount float64 CreatedAt time.Time UpdatedAt time.Time } type OrderSequence struct { ID uuid.UUID OrganizationID uuid.UUID OutletID uuid.UUID Year int Month int SequenceNumber int CreatedAt time.Time UpdatedAt time.Time } type CreateOrderRequest struct { OutletID uuid.UUID `validate:"required"` UserID uuid.UUID `validate:"required"` CustomerID *uuid.UUID `validate:"omitempty"` TableNumber *string `validate:"omitempty,max=50"` OrderType constants.OrderType `validate:"required"` OrderItems []CreateOrderItemRequest `validate:"required,min=1,dive"` Notes *string `validate:"omitempty,max=1000"` Metadata map[string]interface{} CustomerName *string `validate:"omitempty,max=255"` } type CreateOrderItemRequest struct { ProductID uuid.UUID `validate:"required"` ProductVariantID *uuid.UUID `validate:"omitempty"` Quantity int `validate:"required,min=1"` UnitPrice *float64 `validate:"omitempty,min=0"` // Optional, will use database price if not provided Modifiers []map[string]interface{} `validate:"omitempty"` Notes *string `validate:"omitempty,max=500"` Metadata map[string]interface{} `validate:"omitempty"` } type UpdateOrderRequest struct { TableNumber *string `validate:"omitempty,max=50"` Status *constants.OrderStatus `validate:"omitempty"` DiscountAmount *float64 `validate:"omitempty,min=0"` Notes *string `validate:"omitempty,max=1000"` Metadata map[string]interface{} } type CreatePaymentOrderItemRequest struct { OrderItemID uuid.UUID `validate:"required"` Amount float64 `validate:"required,min=0"` } type VoidOrderRequest struct { OrderID uuid.UUID `validate:"required"` Reason string `validate:"required"` Type string `validate:"required,oneof=ALL ITEM"` Items []VoidItemRequest `validate:"required_if=Type ITEM,dive"` } type VoidItemRequest struct { OrderItemID uuid.UUID `validate:"required"` Quantity int `validate:"required,min=1"` } type RefundOrderRequest struct { Reason *string `validate:"omitempty,max=255"` RefundAmount *float64 `validate:"omitempty,min=0"` OrderItems []RefundOrderItemRequest `validate:"omitempty,dive"` } type RefundOrderItemRequest struct { OrderItemID uuid.UUID `validate:"required"` RefundQuantity int `validate:"omitempty,min=1"` RefundAmount *float64 `validate:"omitempty,min=0"` Reason *string `validate:"omitempty,max=255"` } // Response DTOs type OrderResponse struct { ID uuid.UUID OrganizationID uuid.UUID OutletID uuid.UUID UserID uuid.UUID CustomerID *uuid.UUID OrderNumber string TableNumber *string OrderType constants.OrderType Status constants.OrderStatus Subtotal float64 TaxAmount float64 DiscountAmount float64 TotalAmount float64 TotalCost float64 PaymentStatus constants.PaymentStatus RefundAmount float64 IsVoid bool IsRefund bool VoidReason *string VoidedAt *time.Time VoidedBy *uuid.UUID RefundReason *string RefundedAt *time.Time RefundedBy *uuid.UUID Notes *string Metadata map[string]interface{} CreatedAt time.Time UpdatedAt time.Time OrderItems []OrderItemResponse Payments []PaymentResponse } type OrderItemResponse struct { ID uuid.UUID OrderID uuid.UUID ProductID uuid.UUID ProductName string ProductVariantID *uuid.UUID ProductVariantName *string Quantity int UnitPrice float64 TotalPrice float64 UnitCost float64 TotalCost float64 RefundAmount float64 RefundQuantity int IsPartiallyRefunded bool IsFullyRefunded bool RefundReason *string RefundedAt *time.Time RefundedBy *uuid.UUID Modifiers []map[string]interface{} Notes *string Metadata map[string]interface{} Status constants.OrderItemStatus CreatedAt time.Time UpdatedAt time.Time PrinterType string } type PaymentOrderItemResponse struct { ID uuid.UUID PaymentID uuid.UUID OrderItemID uuid.UUID Amount float64 CreatedAt time.Time UpdatedAt time.Time } type ListOrdersRequest struct { OrganizationID *uuid.UUID OutletID *uuid.UUID UserID *uuid.UUID CustomerID *uuid.UUID OrderType *constants.OrderType Status *constants.OrderStatus PaymentStatus *constants.PaymentStatus IsVoid *bool IsRefund *bool DateFrom *time.Time DateTo *time.Time Search string Page int `validate:"required,min=1"` Limit int `validate:"required,min=1,max=100"` } type ListOrdersResponse struct { Orders []OrderResponse TotalCount int Page int Limit int TotalPages int } func (o *Order) CanBeModified() bool { return o.Status == constants.OrderStatusPending || o.Status == constants.OrderStatusPreparing } func (o *Order) CanBeCancelled() bool { return o.Status == constants.OrderStatusPending || o.Status == constants.OrderStatusPreparing } func (o *Order) CalculateTotalAmount(taxRate float64) float64 { taxAmount := o.Subtotal * taxRate return o.Subtotal + taxAmount - o.DiscountAmount } func (o *Order) IsComplete() bool { return o.Status == constants.OrderStatusCompleted } func (o *Order) IsPaid() bool { return o.Status == constants.OrderStatusPaid } func (r *CreateOrderRequest) Validate() bool { return r.OrderType.IsValidOrderType() } // AddToOrderRequest represents the request to add items to an existing order type AddToOrderRequest struct { OrderItems []CreateOrderItemRequest `validate:"required,min=1,dive"` Notes *string `validate:"omitempty,max=1000"` Metadata map[string]interface{} `validate:"omitempty"` } // AddToOrderResponse represents the response when adding items to an existing order type AddToOrderResponse struct { OrderID uuid.UUID OrderNumber string AddedItems []OrderItemResponse UpdatedOrder OrderResponse } // SetOrderCustomerRequest represents the request to set customer for an order type SetOrderCustomerRequest struct { CustomerID uuid.UUID `validate:"required"` } // SetOrderCustomerResponse represents the response when setting customer for an order type SetOrderCustomerResponse struct { OrderID uuid.UUID CustomerID uuid.UUID Message string }