297 lines
13 KiB
Go
Raw Normal View History

2025-07-18 20:10:29 +07:00
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
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
}
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)
// Parse order ID from URL parameter
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
}
// Parse request body
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
}
// Transform contract to model
modelReq := transformer.SetOrderCustomerContractToModel(&req)
// Call service
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
}
// Transform model to contract
contractResp := transformer.SetOrderCustomerModelToContract(response)
util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(contractResp), "OrderHandler::SetOrderCustomer")
}