package http import ( "enaklo-pos-be/internal/common/errors" "enaklo-pos-be/internal/entity" "enaklo-pos-be/internal/handlers/request" "enaklo-pos-be/internal/handlers/response" "enaklo-pos-be/internal/services/v2/inprogress_order" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" "net/http" "strconv" ) type InProgressOrderHandler struct { service inprogress_order.InProgressOrderService } func NewInProgressOrderHandler(service inprogress_order.InProgressOrderService) *InProgressOrderHandler { return &InProgressOrderHandler{ service: service, } } func (h *InProgressOrderHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { route := group.Group("/inprogress-order") route.POST("/save", jwt, h.Save) route.POST("/add", jwt, h.Add) route.GET("/list", jwt, h.GetByPartnerID) } type CreateInProgressOrderRequest struct { CustomerID *int64 `json:"customer_id"` CustomerName string `json:"customer_name" validate:"required_without=CustomerID"` CustomerEmail string `json:"customer_email"` CustomerPhoneNumber string `json:"customer_phone_number"` PaymentMethod string `json:"payment_method"` OrderItems []InProgressOrderItemRequest `json:"order_items" validate:"required,min=1,dive"` OrderType string `json:"order_type"` PaymentProvider string `json:"payment_provider"` TableNumber string `json:"table_number"` InProgressOrderID int64 `json:"in_progress_order_id"` } type AddItemOrderRequest struct { OrderItems []InProgressOrderItemRequest `json:"order_items" validate:"required,min=1,dive"` InProgressOrderID int64 `json:"in_progress_order_id"` } type InProgressOrderItemRequest struct { ProductID int64 `json:"product_id" validate:"required"` Quantity int `json:"quantity" validate:"required,min=1"` } type UpdateInProgressOrderRequest struct { Status string `json:"status" validate:"required"` Amount float64 `json:"amount" validate:"required,min=0"` Fee float64 `json:"fee" validate:"min=0"` Total float64 `json:"total" validate:"required,min=0"` PaymentType string `json:"payment_type" validate:"required"` OrderItems []InProgressOrderItemRequest `json:"order_items" validate:"required,min=1,dive"` } func (h *InProgressOrderHandler) Save(c *gin.Context) { ctx := request.GetMyContext(c) userID := ctx.RequestedBy() partnerID := ctx.GetPartnerID() var req CreateInProgressOrderRequest if err := c.ShouldBindJSON(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } validate := validator.New() if err := validate.Struct(req); err != nil { response.ErrorWrapper(c, err) return } orderItems := make([]entity.OrderItemRequest, len(req.OrderItems)) for i, item := range req.OrderItems { orderItems[i] = entity.OrderItemRequest{ ProductID: item.ProductID, Quantity: item.Quantity, } } order := &entity.OrderRequest{ PartnerID: *partnerID, CustomerID: req.CustomerID, CustomerName: req.CustomerName, CreatedBy: userID, OrderItems: orderItems, TableNumber: req.TableNumber, OrderType: req.OrderType, ID: req.InProgressOrderID, Source: "POS", } _, err := h.service.Save(ctx, order) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusCreated, response.BaseResponse{ Success: true, Status: http.StatusCreated, }) } func (h *InProgressOrderHandler) Add(c *gin.Context) { ctx := request.GetMyContext(c) var req AddItemOrderRequest if err := c.ShouldBindJSON(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } validate := validator.New() if err := validate.Struct(req); err != nil { response.ErrorWrapper(c, err) return } orderItems := make([]entity.OrderItemRequest, len(req.OrderItems)) for i, item := range req.OrderItems { orderItems[i] = entity.OrderItemRequest{ ProductID: item.ProductID, Quantity: item.Quantity, } } _, err := h.service.AddItems(ctx, req.InProgressOrderID, orderItems) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusCreated, response.BaseResponse{ Success: true, Status: http.StatusCreated, }) } func mapToInProgressOrderResponse(order *entity.Order) map[string]interface{} { orderItems := make([]map[string]interface{}, len(order.OrderItems)) for i, item := range order.OrderItems { orderItems[i] = map[string]interface{}{ "id": item.ID, "item_id": item.ItemID, "quantity": item.Quantity, "name": item.Product.Name, "price": item.Product.Price, "image": item.Product.Image, } } return map[string]interface{}{ "id": order.ID, "partner_id": order.PartnerID, "customer_id": order.CustomerID, "customer_name": order.CustomerName, "payment_type": order.PaymentType, "source": order.Source, "created_by": order.CreatedBy, "created_at": order.CreatedAt, "updated_at": order.UpdatedAt, "order_items": orderItems, "table_number": order.TableNumber, } } func (h *InProgressOrderHandler) GetByPartnerID(c *gin.Context) { ctx := request.GetMyContext(c) limitStr := c.DefaultQuery("limit", "10") offsetStr := c.DefaultQuery("offset", "0") limit, err := strconv.Atoi(limitStr) if err != nil || limit < 0 { limit = 10 } offset, err := strconv.Atoi(offsetStr) if err != nil || offset < 0 { offset = 0 } orders, err := h.service.GetOrdersByPartnerID(ctx, *ctx.GetPartnerID(), limit, offset) if err != nil { response.ErrorWrapper(c, err) return } orderResponses := make([]map[string]interface{}, len(orders)) for i, order := range orders { orderResponses[i] = mapToInProgressOrderResponse(order) } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: map[string]interface{}{ "orders": orderResponses, "pagination": map[string]interface{}{ "limit": limit, "offset": offset, "count": len(orders), }, }, }) }