2025-08-06 00:02:49 +07:00

290 lines
8.3 KiB
Go

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
}