215 lines
8.2 KiB
Go
215 lines
8.2 KiB
Go
package handler
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"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"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type ProductHandler struct {
|
|
productService service.ProductService
|
|
productValidator validator.ProductValidator
|
|
}
|
|
|
|
func NewProductHandler(
|
|
productService service.ProductService,
|
|
productValidator validator.ProductValidator,
|
|
) *ProductHandler {
|
|
return &ProductHandler{
|
|
productService: productService,
|
|
productValidator: productValidator,
|
|
}
|
|
}
|
|
|
|
func (h *ProductHandler) CreateProduct(c *gin.Context) {
|
|
ctx := c.Request.Context()
|
|
contextInfo := appcontext.FromGinContext(ctx)
|
|
|
|
var req contract.CreateProductRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
logger.FromContext(c.Request.Context()).WithError(err).Error("ProductHandler::CreateProduct -> request binding failed")
|
|
validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error())
|
|
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "ProductHandler::CreateProduct")
|
|
return
|
|
}
|
|
|
|
validationError, validationErrorCode := h.productValidator.ValidateCreateProductRequest(&req)
|
|
if validationError != nil {
|
|
validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error())
|
|
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "ProductHandler::CreateProduct")
|
|
return
|
|
}
|
|
|
|
productResponse := h.productService.CreateProduct(ctx, contextInfo, &req)
|
|
if productResponse.HasErrors() {
|
|
errorResp := productResponse.GetErrors()[0]
|
|
logger.FromContext(ctx).WithError(errorResp).Error("ProductHandler::CreateProduct -> Failed to create product from service")
|
|
}
|
|
|
|
util.HandleResponse(c.Writer, c.Request, productResponse, "ProductHandler::CreateProduct")
|
|
}
|
|
|
|
func (h *ProductHandler) UpdateProduct(c *gin.Context) {
|
|
ctx := c.Request.Context()
|
|
|
|
productIDStr := c.Param("id")
|
|
productID, err := uuid.Parse(productIDStr)
|
|
if err != nil {
|
|
logger.FromContext(ctx).WithError(err).Error("ProductHandler::UpdateProduct -> Invalid product ID")
|
|
validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid product ID")
|
|
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "ProductHandler::UpdateProduct")
|
|
return
|
|
}
|
|
|
|
var req contract.UpdateProductRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
logger.FromContext(ctx).WithError(err).Error("ProductHandler::UpdateProduct -> request binding failed")
|
|
validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, "Invalid request body")
|
|
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "ProductHandler::UpdateProduct")
|
|
return
|
|
}
|
|
|
|
validationError, validationErrorCode := h.productValidator.ValidateUpdateProductRequest(&req)
|
|
if validationError != nil {
|
|
validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error())
|
|
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "ProductHandler::UpdateProduct")
|
|
return
|
|
}
|
|
|
|
productResponse := h.productService.UpdateProduct(ctx, productID, &req)
|
|
if productResponse.HasErrors() {
|
|
errorResp := productResponse.GetErrors()[0]
|
|
logger.FromContext(ctx).WithError(errorResp).Error("ProductHandler::UpdateProduct -> Failed to update product from service")
|
|
}
|
|
|
|
util.HandleResponse(c.Writer, c.Request, productResponse, "ProductHandler::UpdateProduct")
|
|
}
|
|
|
|
func (h *ProductHandler) DeleteProduct(c *gin.Context) {
|
|
ctx := c.Request.Context()
|
|
|
|
productIDStr := c.Param("id")
|
|
productID, err := uuid.Parse(productIDStr)
|
|
if err != nil {
|
|
logger.FromContext(ctx).WithError(err).Error("ProductHandler::DeleteProduct -> Invalid product ID")
|
|
validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid product ID")
|
|
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "ProductHandler::DeleteProduct")
|
|
return
|
|
}
|
|
|
|
productResponse := h.productService.DeleteProduct(ctx, productID)
|
|
if productResponse.HasErrors() {
|
|
errorResp := productResponse.GetErrors()[0]
|
|
logger.FromContext(ctx).WithError(errorResp).Error("ProductHandler::DeleteProduct -> Failed to delete product from service")
|
|
}
|
|
|
|
util.HandleResponse(c.Writer, c.Request, productResponse, "ProductHandler::DeleteProduct")
|
|
}
|
|
|
|
func (h *ProductHandler) GetProduct(c *gin.Context) {
|
|
ctx := c.Request.Context()
|
|
|
|
productIDStr := c.Param("id")
|
|
productID, err := uuid.Parse(productIDStr)
|
|
if err != nil {
|
|
logger.FromContext(ctx).WithError(err).Error("ProductHandler::GetProduct -> Invalid product ID")
|
|
validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid product ID")
|
|
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "ProductHandler::GetProduct")
|
|
return
|
|
}
|
|
|
|
productResponse := h.productService.GetProductByID(ctx, productID)
|
|
if productResponse.HasErrors() {
|
|
errorResp := productResponse.GetErrors()[0]
|
|
logger.FromContext(ctx).WithError(errorResp).Error("ProductHandler::GetProduct -> Failed to get product from service")
|
|
}
|
|
|
|
util.HandleResponse(c.Writer, c.Request, productResponse, "ProductHandler::GetProduct")
|
|
}
|
|
|
|
func (h *ProductHandler) ListProducts(c *gin.Context) {
|
|
ctx := c.Request.Context()
|
|
contextInfo := appcontext.FromGinContext(ctx)
|
|
|
|
req := &contract.ListProductsRequest{
|
|
Page: 1,
|
|
Limit: 10,
|
|
OrganizationID: &contextInfo.OrganizationID,
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
if search := c.Query("search"); search != "" {
|
|
req.Search = search
|
|
}
|
|
|
|
if businessType := c.Query("business_type"); businessType != "" {
|
|
req.BusinessType = businessType
|
|
}
|
|
|
|
if organizationIDStr := c.Query("organization_id"); organizationIDStr != "" {
|
|
if organizationID, err := uuid.Parse(organizationIDStr); err == nil {
|
|
req.OrganizationID = &organizationID
|
|
}
|
|
}
|
|
|
|
if categoryIDStr := c.Query("category_id"); categoryIDStr != "" {
|
|
if categoryID, err := uuid.Parse(categoryIDStr); err == nil {
|
|
req.CategoryID = &categoryID
|
|
}
|
|
}
|
|
|
|
if isActiveStr := c.Query("is_active"); isActiveStr != "" {
|
|
if isActive, err := strconv.ParseBool(isActiveStr); err == nil {
|
|
req.IsActive = &isActive
|
|
}
|
|
}
|
|
|
|
if minPriceStr := c.Query("min_price"); minPriceStr != "" {
|
|
if minPrice, err := strconv.ParseFloat(minPriceStr, 64); err == nil {
|
|
req.MinPrice = &minPrice
|
|
}
|
|
}
|
|
|
|
if maxPriceStr := c.Query("max_price"); maxPriceStr != "" {
|
|
if maxPrice, err := strconv.ParseFloat(maxPriceStr, 64); err == nil {
|
|
req.MaxPrice = &maxPrice
|
|
}
|
|
}
|
|
|
|
validationError, validationErrorCode := h.productValidator.ValidateListProductsRequest(req)
|
|
if validationError != nil {
|
|
logger.FromContext(ctx).WithError(validationError).Error("ProductHandler::ListProducts -> request validation failed")
|
|
validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error())
|
|
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "ProductHandler::ListProducts")
|
|
return
|
|
}
|
|
|
|
productsResponse := h.productService.ListProducts(ctx, req)
|
|
if productsResponse.HasErrors() {
|
|
errorResp := productsResponse.GetErrors()[0]
|
|
logger.FromContext(ctx).WithError(errorResp).Error("ProductHandler::ListProducts -> Failed to list products from service")
|
|
}
|
|
|
|
util.HandleResponse(c.Writer, c.Request, productsResponse, "ProductHandler::ListProducts")
|
|
}
|