apskel-pos-backend/internal/transformer/order_transformer.go
2025-08-08 22:33:08 +07:00

420 lines
12 KiB
Go

package transformer
import (
"apskel-pos-be/internal/constants"
"apskel-pos-be/internal/contract"
"apskel-pos-be/internal/models"
"apskel-pos-be/internal/util"
"strconv"
"github.com/google/uuid"
)
func CreateOrderContractToModel(req *contract.CreateOrderRequest) *models.CreateOrderRequest {
items := make([]models.CreateOrderItemRequest, len(req.OrderItems))
for i, item := range req.OrderItems {
items[i] = models.CreateOrderItemRequest{
ProductID: item.ProductID,
ProductVariantID: item.ProductVariantID,
Quantity: item.Quantity,
UnitPrice: item.UnitPrice, // Now optional
Modifiers: item.Modifiers,
Notes: item.Notes,
Metadata: item.Metadata,
}
}
return &models.CreateOrderRequest{
OutletID: req.OutletID,
UserID: req.UserID,
TableID: req.TableID,
TableNumber: req.TableNumber,
OrderType: constants.OrderType(req.OrderType),
OrderItems: items,
Notes: req.Notes,
CustomerName: req.CustomerName,
}
}
func UpdateOrderContractToModel(req *contract.UpdateOrderRequest) *models.UpdateOrderRequest {
var status *constants.OrderStatus
if req.Status != nil {
stats := constants.OrderStatus(*req.Status)
status = &stats
}
return &models.UpdateOrderRequest{
TableNumber: req.TableNumber,
Status: status,
DiscountAmount: req.DiscountAmount,
Notes: req.Notes,
Metadata: req.Metadata,
}
}
func AddToOrderContractToModel(req *contract.AddToOrderRequest) *models.AddToOrderRequest {
items := make([]models.CreateOrderItemRequest, len(req.OrderItems))
for i, item := range req.OrderItems {
items[i] = models.CreateOrderItemRequest{
ProductID: item.ProductID,
ProductVariantID: item.ProductVariantID,
Quantity: item.Quantity,
UnitPrice: item.UnitPrice, // Now optional
Modifiers: item.Modifiers,
Notes: item.Notes,
Metadata: item.Metadata,
}
}
return &models.AddToOrderRequest{
OrderItems: items,
Notes: req.Notes,
Metadata: req.Metadata,
}
}
func VoidOrderContractToModel(req *contract.VoidOrderRequest) *models.VoidOrderRequest {
items := make([]models.VoidItemRequest, len(req.Items))
for i, item := range req.Items {
items[i] = models.VoidItemRequest{
OrderItemID: item.OrderItemID,
Quantity: item.Quantity,
}
}
return &models.VoidOrderRequest{
OrderID: req.OrderID,
Reason: req.Reason,
Type: req.Type,
Items: items,
}
}
func OrderModelToContract(resp *models.OrderResponse) *contract.OrderResponse {
if resp == nil {
return nil
}
items := make([]contract.OrderItemResponse, len(resp.OrderItems))
for i, item := range resp.OrderItems {
items[i] = contract.OrderItemResponse{
ID: item.ID,
OrderID: item.OrderID,
ProductID: item.ProductID,
ProductName: item.ProductName,
ProductVariantID: item.ProductVariantID,
ProductVariantName: item.ProductVariantName,
Quantity: item.Quantity,
UnitPrice: item.UnitPrice,
TotalPrice: item.TotalPrice,
Modifiers: item.Modifiers,
Notes: item.Notes,
Metadata: item.Metadata,
Status: string(item.Status),
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
PrinterType: item.PrinterType,
PaidQuantity: item.PaidQuantity,
}
}
// Map payments
payments := make([]contract.PaymentResponse, len(resp.Payments))
for i, payment := range resp.Payments {
payments[i] = *PaymentModelToContract(&payment)
}
return &contract.OrderResponse{
ID: resp.ID,
OrderNumber: resp.OrderNumber,
OutletID: resp.OutletID,
UserID: resp.UserID,
TableNumber: resp.TableNumber,
OrderType: string(resp.OrderType),
Status: string(resp.Status),
Subtotal: resp.Subtotal,
TaxAmount: resp.TaxAmount,
DiscountAmount: resp.DiscountAmount,
TotalAmount: resp.TotalAmount,
TotalCost: resp.TotalCost,
RemainingAmount: resp.RemainingAmount,
PaymentStatus: string(resp.PaymentStatus),
RefundAmount: resp.RefundAmount,
IsVoid: resp.IsVoid,
IsRefund: resp.IsRefund,
VoidReason: resp.VoidReason,
VoidedAt: resp.VoidedAt,
VoidedBy: resp.VoidedBy,
RefundReason: resp.RefundReason,
RefundedAt: resp.RefundedAt,
RefundedBy: resp.RefundedBy,
Notes: resp.Notes,
Metadata: resp.Metadata,
CreatedAt: resp.CreatedAt,
UpdatedAt: resp.UpdatedAt,
OrderItems: items,
Payments: payments,
TotalPaid: resp.TotalPaid,
PaymentCount: resp.PaymentCount,
SplitType: resp.SplitType,
}
}
func AddToOrderModelToContract(resp *models.AddToOrderResponse) *contract.AddToOrderResponse {
if resp == nil {
return nil
}
items := make([]contract.OrderItemResponse, len(resp.AddedItems))
for i, item := range resp.AddedItems {
items[i] = contract.OrderItemResponse{
ID: item.ID,
OrderID: item.OrderID,
ProductID: item.ProductID,
ProductName: item.ProductName,
ProductVariantID: item.ProductVariantID,
ProductVariantName: item.ProductVariantName,
Quantity: item.Quantity,
UnitPrice: item.UnitPrice,
TotalPrice: item.TotalPrice,
Modifiers: item.Modifiers,
Notes: item.Notes,
Metadata: item.Metadata,
Status: string(item.Status),
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
}
}
return &contract.AddToOrderResponse{
OrderID: resp.OrderID,
OrderNumber: resp.OrderNumber,
AddedItems: items,
UpdatedOrder: *OrderModelToContract(&resp.UpdatedOrder),
}
}
func SetOrderCustomerContractToModel(req *contract.SetOrderCustomerRequest) *models.SetOrderCustomerRequest {
return &models.SetOrderCustomerRequest{
CustomerID: req.CustomerID,
}
}
func SetOrderCustomerModelToContract(resp *models.SetOrderCustomerResponse) *contract.SetOrderCustomerResponse {
if resp == nil {
return nil
}
return &contract.SetOrderCustomerResponse{
OrderID: resp.OrderID,
CustomerID: resp.CustomerID,
Message: resp.Message,
}
}
func ListOrdersQueryToModel(query *contract.ListOrdersQuery) *models.ListOrdersRequest {
req := &models.ListOrdersRequest{
Search: query.Search,
Page: query.Page,
Limit: query.Limit,
}
if query.OrganizationID != "" {
if organizationID, err := uuid.Parse(query.OrganizationID); err == nil {
req.OrganizationID = &organizationID
}
}
if query.OutletID != "" {
if outletID, err := uuid.Parse(query.OutletID); err == nil {
req.OutletID = &outletID
}
}
if query.UserID != "" {
if userID, err := uuid.Parse(query.UserID); err == nil {
req.UserID = &userID
}
}
if query.CustomerID != "" {
if customerID, err := uuid.Parse(query.CustomerID); err == nil {
req.CustomerID = &customerID
}
}
if query.OrderType != "" {
orderType := constants.OrderType(query.OrderType)
req.OrderType = &orderType
}
if query.Status != "" {
status := constants.OrderStatus(query.Status)
req.Status = &status
}
if query.PaymentStatus != "" {
paymentStatus := constants.PaymentStatus(query.PaymentStatus)
req.PaymentStatus = &paymentStatus
}
if query.IsVoid != "" {
if isVoid, err := strconv.ParseBool(query.IsVoid); err == nil {
req.IsVoid = &isVoid
}
}
if query.IsRefund != "" {
if isRefund, err := strconv.ParseBool(query.IsRefund); err == nil {
req.IsRefund = &isRefund
}
}
if dateFrom, dateTo, err := util.ParseDateRangeToJakartaTime(query.DateFrom, query.DateTo); err == nil {
req.DateFrom = dateFrom
req.DateTo = dateTo
}
return req
}
func ListOrdersModelToContract(resp *models.ListOrdersResponse) *contract.ListOrdersResponse {
if resp == nil {
return nil
}
orders := make([]contract.OrderResponse, len(resp.Orders))
for i, order := range resp.Orders {
orders[i] = *OrderModelToContract(&order)
}
payments := make([]contract.PaymentResponse, len(resp.Payments))
for i, payment := range resp.Payments {
payments[i] = *PaymentModelToContract(&payment)
}
return &contract.ListOrdersResponse{
Orders: orders,
Payments: payments,
TotalCount: resp.TotalCount,
Page: resp.Page,
Limit: resp.Limit,
TotalPages: resp.TotalPages,
}
}
// Payment-related transformers
func CreatePaymentContractToModel(req *contract.CreatePaymentRequest) *models.CreatePaymentRequest {
paymentOrderItems := make([]models.CreatePaymentOrderItemRequest, len(req.PaymentOrderItems))
for i, item := range req.PaymentOrderItems {
paymentOrderItems[i] = models.CreatePaymentOrderItemRequest{
OrderItemID: item.OrderItemID,
Amount: item.Amount,
}
}
return &models.CreatePaymentRequest{
OrderID: req.OrderID,
PaymentMethodID: req.PaymentMethodID,
Amount: req.Amount,
TransactionID: req.TransactionID,
SplitNumber: req.SplitNumber,
SplitTotal: req.SplitTotal,
SplitDescription: req.SplitDescription,
PaymentOrderItems: paymentOrderItems,
Metadata: req.Metadata,
}
}
func PaymentModelToContract(resp *models.PaymentResponse) *contract.PaymentResponse {
if resp == nil {
return nil
}
paymentOrderItems := make([]contract.PaymentOrderItemResponse, len(resp.PaymentOrderItems))
for i, item := range resp.PaymentOrderItems {
paymentOrderItems[i] = contract.PaymentOrderItemResponse{
ID: item.ID,
PaymentID: item.PaymentID,
OrderItemID: item.OrderItemID,
Amount: item.Amount,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
}
}
return &contract.PaymentResponse{
ID: resp.ID,
OrderID: resp.OrderID,
PaymentMethodID: resp.PaymentMethodID,
PaymentMethodName: resp.PaymentMethodName,
PaymentMethodType: string(resp.PaymentMethodType),
Amount: resp.Amount,
Status: string(resp.Status),
TransactionID: resp.TransactionID,
SplitNumber: resp.SplitNumber,
SplitTotal: resp.SplitTotal,
SplitType: resp.SplitType,
SplitDescription: resp.SplitDescription,
RefundAmount: resp.RefundAmount,
RefundReason: resp.RefundReason,
RefundedAt: resp.RefundedAt,
RefundedBy: resp.RefundedBy,
Metadata: resp.Metadata,
CreatedAt: resp.CreatedAt,
UpdatedAt: resp.UpdatedAt,
PaymentOrderItems: paymentOrderItems,
}
}
func RefundOrderContractToModel(req *contract.RefundOrderRequest) *models.RefundOrderRequest {
orderItems := make([]models.RefundOrderItemRequest, len(req.OrderItems))
for i, item := range req.OrderItems {
orderItems[i] = models.RefundOrderItemRequest{
OrderItemID: item.OrderItemID,
RefundQuantity: item.RefundQuantity,
RefundAmount: item.RefundAmount,
Reason: item.Reason,
}
}
return &models.RefundOrderRequest{
Reason: req.Reason,
RefundAmount: req.RefundAmount,
OrderItems: orderItems,
}
}
func SplitBillContractToModel(req *contract.SplitBillRequest) *models.SplitBillRequest {
items := make([]models.SplitBillItemRequest, len(req.Items))
for i, item := range req.Items {
items[i] = models.SplitBillItemRequest{
OrderItemID: item.OrderItemID,
Quantity: item.Quantity,
}
}
return &models.SplitBillRequest{
OrderID: req.OrderID,
PaymentMethodID: req.PaymentMethodID,
CustomerID: req.CustomerID,
Type: req.Type,
Items: items,
Amount: req.Amount,
OrganizationID: req.OrganizationID,
}
}
func SplitBillModelToContract(resp *models.SplitBillResponse) *contract.SplitBillResponse {
if resp == nil {
return nil
}
items := make([]contract.SplitBillItemResponse, len(resp.Items))
for i, item := range resp.Items {
items[i] = contract.SplitBillItemResponse{
OrderItemID: item.OrderItemID,
Amount: item.Amount,
}
}
return &contract.SplitBillResponse{
PaymentID: resp.PaymentID,
OrderID: resp.OrderID,
CustomerID: resp.CustomerID,
Type: resp.Type,
Amount: resp.Amount,
Items: items,
Message: resp.Message,
}
}