apskel-pos-backend/internal/handler/customer_handler.go

258 lines
12 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/constants"
"apskel-pos-be/internal/contract"
"apskel-pos-be/internal/logger"
"apskel-pos-be/internal/service"
"apskel-pos-be/internal/util"
"apskel-pos-be/internal/validator"
"strconv"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
type CustomerHandler struct {
customerService service.CustomerService
customerValidator validator.CustomerValidator
}
func NewCustomerHandler(
customerService service.CustomerService,
customerValidator validator.CustomerValidator,
) *CustomerHandler {
return &CustomerHandler{
customerService: customerService,
customerValidator: customerValidator,
}
}
func (h *CustomerHandler) CreateCustomer(c *gin.Context) {
ctx := c.Request.Context()
contextInfo := appcontext.FromGinContext(ctx)
var req contract.CreateCustomerRequest
if err := c.ShouldBindJSON(&req); err != nil {
logger.FromContext(c.Request.Context()).WithError(err).Error("CustomerHandler::CreateCustomer -> request binding failed")
validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::CreateCustomer")
return
}
validationError, validationErrorCode := h.customerValidator.ValidateCreateCustomerRequest(&req)
if validationError != nil {
logger.FromContext(c.Request.Context()).WithError(validationError).Error("CustomerHandler::CreateCustomer -> request validation failed")
validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::CreateCustomer")
return
}
organizationID := contextInfo.OrganizationID
customerResponse, err := h.customerService.CreateCustomer(c.Request.Context(), &req, organizationID)
if err != nil {
logger.FromContext(c.Request.Context()).WithError(err).Error("CustomerHandler::CreateCustomer -> Failed to create customer from service")
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CustomerServiceEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "CustomerHandler::CreateCustomer")
return
}
logger.FromContext(c.Request.Context()).Infof("CustomerHandler::CreateCustomer -> Successfully created customer = %+v", customerResponse)
util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(customerResponse), "CustomerHandler::CreateCustomer")
}
func (h *CustomerHandler) GetCustomer(c *gin.Context) {
ctx := c.Request.Context()
contextInfo := appcontext.FromGinContext(ctx)
customerID, err := uuid.Parse(c.Param("id"))
if err != nil {
logger.FromContext(ctx).WithError(err).Error("CustomerHandler::GetCustomer -> Invalid customer ID")
validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid customer ID")
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::GetCustomer")
return
}
organizationID := contextInfo.OrganizationID
customerResponse, err := h.customerService.GetCustomer(c.Request.Context(), customerID, organizationID)
if err != nil {
logger.FromContext(ctx).WithError(err).Error("CustomerHandler::GetCustomer -> Failed to get customer from service")
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CustomerServiceEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "CustomerHandler::GetCustomer")
return
}
util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(customerResponse), "CustomerHandler::GetCustomer")
}
func (h *CustomerHandler) ListCustomers(c *gin.Context) {
ctx := c.Request.Context()
contextInfo := appcontext.FromGinContext(ctx)
req := &contract.ListCustomersRequest{
Page: 1,
Limit: 10,
}
// Parse query parameters
if pageStr := c.Query("page"); pageStr != "" {
if page, err := strconv.Atoi(pageStr); err == nil {
req.Page = page
}
}
if limitStr := c.Query("limit"); limitStr != "" {
if limit, err := strconv.Atoi(limitStr); err == nil {
req.Limit = limit
}
}
req.Search = c.Query("search")
req.SortBy = c.Query("sort_by")
req.SortOrder = c.Query("sort_order")
if isActiveStr := c.Query("is_active"); isActiveStr != "" {
if isActive, err := strconv.ParseBool(isActiveStr); err == nil {
req.IsActive = &isActive
}
}
if isDefaultStr := c.Query("is_default"); isDefaultStr != "" {
if isDefault, err := strconv.ParseBool(isDefaultStr); err == nil {
req.IsDefault = &isDefault
}
}
validationError, validationErrorCode := h.customerValidator.ValidateListCustomersRequest(req)
if validationError != nil {
logger.FromContext(ctx).WithError(validationError).Error("CustomerHandler::ListCustomers -> request validation failed")
validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::ListCustomers")
return
}
organizationID := contextInfo.OrganizationID
customersResponse, err := h.customerService.ListCustomers(c.Request.Context(), req, organizationID)
if err != nil {
logger.FromContext(ctx).WithError(err).Error("CustomerHandler::ListCustomers -> Failed to list customers from service")
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CustomerServiceEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "CustomerHandler::ListCustomers")
return
}
util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(customersResponse), "CustomerHandler::ListCustomers")
}
func (h *CustomerHandler) UpdateCustomer(c *gin.Context) {
ctx := c.Request.Context()
contextInfo := appcontext.FromGinContext(ctx)
customerID, err := uuid.Parse(c.Param("id"))
if err != nil {
logger.FromContext(ctx).WithError(err).Error("CustomerHandler::UpdateCustomer -> Invalid customer ID")
validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid customer ID")
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::UpdateCustomer")
return
}
var req contract.UpdateCustomerRequest
if err := c.ShouldBindJSON(&req); err != nil {
logger.FromContext(c.Request.Context()).WithError(err).Error("CustomerHandler::UpdateCustomer -> request binding failed")
validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::UpdateCustomer")
return
}
validationError, validationErrorCode := h.customerValidator.ValidateUpdateCustomerRequest(&req)
if validationError != nil {
logger.FromContext(c.Request.Context()).WithError(validationError).Error("CustomerHandler::UpdateCustomer -> request validation failed")
validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::UpdateCustomer")
return
}
organizationID := contextInfo.OrganizationID
customerResponse, err := h.customerService.UpdateCustomer(c.Request.Context(), customerID, organizationID, &req)
if err != nil {
logger.FromContext(ctx).WithError(err).Error("CustomerHandler::UpdateCustomer -> Failed to update customer from service")
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CustomerServiceEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "CustomerHandler::UpdateCustomer")
return
}
util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(customerResponse), "CustomerHandler::UpdateCustomer")
}
func (h *CustomerHandler) DeleteCustomer(c *gin.Context) {
ctx := c.Request.Context()
contextInfo := appcontext.FromGinContext(ctx)
customerID, err := uuid.Parse(c.Param("id"))
if err != nil {
logger.FromContext(ctx).WithError(err).Error("CustomerHandler::DeleteCustomer -> Invalid customer ID")
validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid customer ID")
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::DeleteCustomer")
return
}
organizationID := contextInfo.OrganizationID
err = h.customerService.DeleteCustomer(c.Request.Context(), customerID, organizationID)
if err != nil {
logger.FromContext(ctx).WithError(err).Error("CustomerHandler::DeleteCustomer -> Failed to delete customer from service")
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CustomerServiceEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "CustomerHandler::DeleteCustomer")
return
}
util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(gin.H{"message": "Customer deleted successfully"}), "CustomerHandler::DeleteCustomer")
}
func (h *CustomerHandler) SetDefaultCustomer(c *gin.Context) {
ctx := c.Request.Context()
contextInfo := appcontext.FromGinContext(ctx)
var req contract.SetDefaultCustomerRequest
if err := c.ShouldBindJSON(&req); err != nil {
logger.FromContext(c.Request.Context()).WithError(err).Error("CustomerHandler::SetDefaultCustomer -> request binding failed")
validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::SetDefaultCustomer")
return
}
validationError, validationErrorCode := h.customerValidator.ValidateSetDefaultCustomerRequest(&req)
if validationError != nil {
logger.FromContext(c.Request.Context()).WithError(validationError).Error("CustomerHandler::SetDefaultCustomer -> request validation failed")
validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "CustomerHandler::SetDefaultCustomer")
return
}
organizationID := contextInfo.OrganizationID
customerResponse, err := h.customerService.SetDefaultCustomer(c.Request.Context(), req.CustomerID, organizationID)
if err != nil {
logger.FromContext(ctx).WithError(err).Error("CustomerHandler::SetDefaultCustomer -> Failed to set default customer from service")
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CustomerServiceEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "CustomerHandler::SetDefaultCustomer")
return
}
util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(customerResponse), "CustomerHandler::SetDefaultCustomer")
}
func (h *CustomerHandler) GetDefaultCustomer(c *gin.Context) {
ctx := c.Request.Context()
contextInfo := appcontext.FromGinContext(ctx)
organizationID := contextInfo.OrganizationID
customerResponse, err := h.customerService.GetDefaultCustomer(c.Request.Context(), organizationID)
if err != nil {
logger.FromContext(ctx).WithError(err).Error("CustomerHandler::GetDefaultCustomer -> Failed to get default customer from service")
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CustomerServiceEntity, err.Error())
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "CustomerHandler::GetDefaultCustomer")
return
}
util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(customerResponse), "CustomerHandler::GetDefaultCustomer")
}