package handler import ( "apskel-pos-be/internal/appcontext" "apskel-pos-be/internal/contract" "apskel-pos-be/internal/service" "apskel-pos-be/internal/transformer" "apskel-pos-be/internal/util" "apskel-pos-be/internal/validator" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type OrderHandler struct { orderService service.OrderService validator validator.OrderValidator transformer transformer.Transformer } func NewOrderHandler( orderService service.OrderService, validator validator.OrderValidator, transformer transformer.Transformer, ) *OrderHandler { return &OrderHandler{ orderService: orderService, validator: validator, transformer: transformer, } } func (h *OrderHandler) CreateOrder(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) var req contract.CreateOrderRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::CreateOrder", err.Error())}), "OrderHandler::CreateOrder") return } req.UserID = contextInfo.UserID modelReq := transformer.CreateOrderContractToModel(&req) response, err := h.orderService.CreateOrder(ctx, modelReq, contextInfo.OrganizationID) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::CreateOrder", err.Error())}), "OrderHandler::CreateOrder") return } contractResp := transformer.OrderModelToContract(response) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(contractResp), "OrderHandler::CreateOrder") } func (h *OrderHandler) GetOrderByID(c *gin.Context) { idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_id", "OrderHandler::GetOrderByID", err.Error())}), "OrderHandler::GetOrderByID") return } response, err := h.orderService.GetOrderByID(c.Request.Context(), id) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::GetOrderByID", err.Error())}), "OrderHandler::GetOrderByID") return } contractResp := transformer.OrderModelToContract(response) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(contractResp), "OrderHandler::GetOrderByID") } func (h *OrderHandler) UpdateOrder(c *gin.Context) { idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_id", "OrderHandler::UpdateOrder", err.Error())}), "OrderHandler::UpdateOrder") return } var req contract.UpdateOrderRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::UpdateOrder", err.Error())}), "OrderHandler::UpdateOrder") return } modelReq := transformer.UpdateOrderContractToModel(&req) response, err := h.orderService.UpdateOrder(c.Request.Context(), id, modelReq) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::UpdateOrder", err.Error())}), "OrderHandler::UpdateOrder") return } contractResp := transformer.OrderModelToContract(response) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(contractResp), "OrderHandler::UpdateOrder") } func (h *OrderHandler) AddToOrder(c *gin.Context) { idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_id", "OrderHandler::AddToOrder", err.Error())}), "OrderHandler::AddToOrder") return } var req contract.AddToOrderRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::AddToOrder", err.Error())}), "OrderHandler::AddToOrder") return } modelReq := transformer.AddToOrderContractToModel(&req) response, err := h.orderService.AddToOrder(c.Request.Context(), id, modelReq) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::AddToOrder", err.Error())}), "OrderHandler::AddToOrder") return } contractResp := transformer.AddToOrderModelToContract(response) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(contractResp), "OrderHandler::AddToOrder") } func (h *OrderHandler) ListOrders(c *gin.Context) { var query contract.ListOrdersQuery ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) if err := c.ShouldBindQuery(&query); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_query_parameters", "OrderHandler::ListOrders", err.Error())}), "OrderHandler::ListOrders") return } modelReq := transformer.ListOrdersQueryToModel(&query) if err := h.validator.Validate(modelReq); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("validation_failed", "OrderHandler::ListOrders", err.Error())}), "OrderHandler::ListOrders") return } modelReq.OrganizationID = &contextInfo.OrganizationID response, err := h.orderService.ListOrders(c.Request.Context(), modelReq) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::ListOrders", err.Error())}), "OrderHandler::ListOrders") return } contractResp := transformer.ListOrdersModelToContract(response) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(contractResp), "OrderHandler::ListOrders") } func (h *OrderHandler) VoidOrder(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) var req contract.VoidOrderRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::VoidOrder", err.Error())}), "OrderHandler::VoidOrder") return } userID := contextInfo.UserID if err := h.validator.Validate(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("validation_failed", "OrderHandler::VoidOrder", err.Error())}), "OrderHandler::VoidOrder") return } modelReq := transformer.VoidOrderContractToModel(&req) if err := h.orderService.VoidOrder(ctx, modelReq, userID); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::VoidOrder", err.Error())}), "OrderHandler::VoidOrder") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(map[string]string{"message": "Order voided successfully"}), "OrderHandler::VoidOrder") } func (h *OrderHandler) RefundOrder(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_id", "OrderHandler::RefundOrder", err.Error())}), "OrderHandler::RefundOrder") return } var req contract.RefundOrderRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::RefundOrder", err.Error())}), "OrderHandler::RefundOrder") return } userID := contextInfo.UserID modelReq := transformer.RefundOrderContractToModel(&req) if err := h.validator.Validate(modelReq); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("validation_failed", "OrderHandler::RefundOrder", err.Error())}), "OrderHandler::RefundOrder") return } if err := h.orderService.RefundOrder(ctx, id, modelReq, userID); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::RefundOrder", err.Error())}), "OrderHandler::RefundOrder") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(nil), "OrderHandler::RefundOrder") } func (h *OrderHandler) CreatePayment(c *gin.Context) { var req contract.CreatePaymentRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::CreatePayment", err.Error())}), "OrderHandler::CreatePayment") return } if err := h.validator.Validate(req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("validation_failed", "OrderHandler::CreatePayment", err.Error())}), "OrderHandler::CreatePayment") return } modelReq := transformer.CreatePaymentContractToModel(&req) response, err := h.orderService.CreatePayment(c.Request.Context(), modelReq) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::CreatePayment", err.Error())}), "OrderHandler::CreatePayment") return } contractResp := transformer.PaymentModelToContract(response) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(contractResp), "OrderHandler::CreatePayment") } func (h *OrderHandler) RefundPayment(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) idStr := c.Param("id") paymentID, err := uuid.Parse(idStr) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_id", "OrderHandler::RefundPayment", err.Error())}), "OrderHandler::RefundPayment") return } var req contract.RefundPaymentRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::RefundPayment", err.Error())}), "OrderHandler::RefundPayment") return } userID := contextInfo.UserID if userID == uuid.Nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("unauthorized", "OrderHandler::RefundPayment", "Invalid User ID in context")}), "OrderHandler::RefundPayment") return } if err := h.validator.Validate(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("validation_failed", "OrderHandler::RefundPayment", err.Error())}), "OrderHandler::RefundPayment") return } if err := h.orderService.RefundPayment(ctx, paymentID, req.RefundAmount, req.Reason, userID); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::RefundPayment", err.Error())}), "OrderHandler::RefundPayment") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(nil), "OrderHandler::RefundPayment") } func (h *OrderHandler) SetOrderCustomer(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) orderIDStr := c.Param("id") orderID, err := uuid.Parse(orderIDStr) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_id", "OrderHandler::SetOrderCustomer", "Invalid order ID")}), "OrderHandler::SetOrderCustomer") return } var req contract.SetOrderCustomerRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::SetOrderCustomer", err.Error())}), "OrderHandler::SetOrderCustomer") return } modelReq := transformer.SetOrderCustomerContractToModel(&req) response, err := h.orderService.SetOrderCustomer(ctx, orderID, modelReq, contextInfo.OrganizationID) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::SetOrderCustomer", err.Error())}), "OrderHandler::SetOrderCustomer") return } contractResp := transformer.SetOrderCustomerModelToContract(response) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(contractResp), "OrderHandler::SetOrderCustomer") } func (h *OrderHandler) SplitBill(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) var req contract.SplitBillRequest if err := c.ShouldBindJSON(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("invalid_request", "OrderHandler::SplitBill", err.Error())}), "OrderHandler::SplitBill") return } if err := h.validator.Validate(&req); err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("validation_failed", "OrderHandler::SplitBill", err.Error())}), "OrderHandler::SplitBill") return } req.OrganizationID = contextInfo.OrganizationID modelReq := transformer.SplitBillContractToModel(&req) response, err := h.orderService.SplitBill(c.Request.Context(), modelReq) if err != nil { util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{contract.NewResponseError("internal_error", "OrderHandler::SplitBill", err.Error())}), "OrderHandler::SplitBill") return } contractResp := transformer.SplitBillModelToContract(response) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(contractResp), "OrderHandler::SplitBill") }