2025-07-18 20:10:29 +07:00
|
|
|
package models
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"apskel-pos-be/internal/constants"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Order struct {
|
2025-08-07 22:45:02 +07:00
|
|
|
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
|
|
|
|
|
RemainingAmount 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
|
2025-07-18 20:10:29 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
2025-08-08 22:33:08 +07:00
|
|
|
Quantity int // Quantity paid for this specific payment
|
2025-07-18 20:10:29 +07:00
|
|
|
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"`
|
2025-08-08 00:22:28 +07:00
|
|
|
TableID *uuid.UUID `validate:"omitempty"`
|
2025-07-18 20:10:29 +07:00
|
|
|
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"`
|
2025-08-08 22:33:08 +07:00
|
|
|
Quantity int `validate:"required,min=1"` // Quantity being paid for
|
2025-07-18 20:10:29 +07:00
|
|
|
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"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type OrderResponse struct {
|
2025-08-07 22:45:02 +07:00
|
|
|
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
|
|
|
|
|
RemainingAmount 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
|
|
|
|
|
TotalPaid float64
|
|
|
|
|
PaymentCount int
|
|
|
|
|
SplitType *string
|
2025-07-18 20:10:29 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
2025-08-06 00:02:49 +07:00
|
|
|
PrinterType string
|
2025-08-08 22:33:08 +07:00
|
|
|
PaidQuantity int
|
2025-07-18 20:10:29 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PaymentOrderItemResponse struct {
|
|
|
|
|
ID uuid.UUID
|
|
|
|
|
PaymentID uuid.UUID
|
|
|
|
|
OrderItemID uuid.UUID
|
2025-08-08 22:33:08 +07:00
|
|
|
Quantity int // Quantity paid for this specific payment
|
2025-07-18 20:10:29 +07:00
|
|
|
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
|
2025-08-07 22:45:02 +07:00
|
|
|
Payments []PaymentResponse
|
2025-07-18 20:10:29 +07:00
|
|
|
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
|
|
|
|
|
}
|