package entities import ( "fmt" "time" "github.com/google/uuid" "gorm.io/gorm" ) type OrderType string type OrderStatus string type PaymentStatus string const ( OrderTypeDineIn OrderType = "dine_in" OrderTypeTakeout OrderType = "takeout" OrderTypeDelivery OrderType = "delivery" ) const ( OrderStatusPending OrderStatus = "pending" OrderStatusPreparing OrderStatus = "preparing" OrderStatusReady OrderStatus = "ready" OrderStatusCompleted OrderStatus = "completed" OrderStatusCancelled OrderStatus = "cancelled" ) const ( PaymentStatusPending PaymentStatus = "pending" PaymentStatusCompleted PaymentStatus = "completed" PaymentStatusFailed PaymentStatus = "failed" PaymentStatusRefunded PaymentStatus = "refunded" PaymentStatusPartiallyRefunded PaymentStatus = "partial-refunded" ) type Order struct { ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"` OrganizationID uuid.UUID `gorm:"type:uuid;not null;index" json:"organization_id" validate:"required"` OutletID uuid.UUID `gorm:"type:uuid;not null;index" json:"outlet_id" validate:"required"` UserID uuid.UUID `gorm:"type:uuid;not null;index" json:"user_id" validate:"required"` CustomerID *uuid.UUID `gorm:"type:uuid;index" json:"customer_id"` OrderNumber string `gorm:"uniqueIndex;not null;size:50" json:"order_number" validate:"required"` TableNumber *string `gorm:"size:20" json:"table_number"` OrderType OrderType `gorm:"not null;size:50" json:"order_type" validate:"required,oneof=dine_in takeout delivery"` Status OrderStatus `gorm:"default:'pending';size:50" json:"status"` Subtotal float64 `gorm:"type:decimal(10,2);not null" json:"subtotal" validate:"required,min=0"` TaxAmount float64 `gorm:"type:decimal(10,2);not null" json:"tax_amount" validate:"required,min=0"` DiscountAmount float64 `gorm:"type:decimal(10,2);default:0.00" json:"discount_amount" validate:"min=0"` TotalAmount float64 `gorm:"type:decimal(10,2);not null" json:"total_amount" validate:"required,min=0"` TotalCost float64 `gorm:"type:decimal(10,2);default:0.00" json:"total_cost"` PaymentStatus PaymentStatus `gorm:"default:'pending';size:50" json:"payment_status"` RefundAmount float64 `gorm:"type:decimal(10,2);default:0.00" json:"refund_amount"` IsVoid bool `gorm:"default:false" json:"is_void"` IsRefund bool `gorm:"default:false" json:"is_refund"` VoidReason *string `gorm:"size:255" json:"void_reason,omitempty"` VoidedAt *time.Time `gorm:"" json:"voided_at,omitempty"` VoidedBy *uuid.UUID `gorm:"type:uuid" json:"voided_by,omitempty"` RefundReason *string `gorm:"size:255" json:"refund_reason,omitempty"` RefundedAt *time.Time `gorm:"" json:"refunded_at,omitempty"` RefundedBy *uuid.UUID `gorm:"type:uuid" json:"refunded_by,omitempty"` Metadata Metadata `gorm:"type:jsonb;default:'{}'" json:"metadata"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` Organization Organization `gorm:"foreignKey:OrganizationID" json:"organization,omitempty"` Outlet Outlet `gorm:"foreignKey:OutletID" json:"outlet,omitempty"` User User `gorm:"foreignKey:UserID" json:"user,omitempty"` OrderItems []OrderItem `gorm:"foreignKey:OrderID" json:"order_items,omitempty"` Payments []Payment `gorm:"foreignKey:OrderID" json:"payments,omitempty"` } func (o *Order) BeforeCreate(tx *gorm.DB) error { if o.ID == uuid.Nil { o.ID = uuid.New() } if o.OrderNumber == "" { timestamp := time.Now().Unix() o.OrderNumber = fmt.Sprintf("ORD/%d", timestamp) } return nil } func (Order) TableName() string { return "orders" } func (o *Order) CanBeModified() bool { return o.Status == OrderStatusPending } func (o *Order) CanBeCancelled() bool { return o.Status != OrderStatusCompleted && o.Status != OrderStatusCancelled } func (o *Order) GetTotalPaid() float64 { var total float64 for _, payment := range o.Payments { if payment.Status == PaymentTransactionStatusCompleted { total += payment.Amount } } return total } func (o *Order) IsFullyPaid() bool { return o.GetTotalPaid() >= o.TotalAmount }