package service import ( "context" "apskel-pos-be/internal/appcontext" "apskel-pos-be/internal/constants" "apskel-pos-be/internal/contract" "apskel-pos-be/internal/processor" "apskel-pos-be/internal/transformer" "github.com/google/uuid" ) type ProductService interface { CreateProduct(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateProductRequest) *contract.Response UpdateProduct(ctx context.Context, id uuid.UUID, req *contract.UpdateProductRequest) *contract.Response DeleteProduct(ctx context.Context, id uuid.UUID) *contract.Response GetProductByID(ctx context.Context, id uuid.UUID) *contract.Response ListProducts(ctx context.Context, req *contract.ListProductsRequest) *contract.Response } type ProductServiceImpl struct { productProcessor processor.ProductProcessor } func NewProductService(productProcessor processor.ProductProcessor) *ProductServiceImpl { return &ProductServiceImpl{ productProcessor: productProcessor, } } func (s *ProductServiceImpl) CreateProduct(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateProductRequest) *contract.Response { modelReq := transformer.CreateProductRequestToModel(apctx, req) productResponse, err := s.productProcessor.CreateProduct(ctx, modelReq) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.ProductModelResponseToResponse(productResponse) return contract.BuildSuccessResponse(contractResponse) } func (s *ProductServiceImpl) UpdateProduct(ctx context.Context, id uuid.UUID, req *contract.UpdateProductRequest) *contract.Response { modelReq := transformer.UpdateProductRequestToModel(req) productResponse, err := s.productProcessor.UpdateProduct(ctx, id, modelReq) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.ProductModelResponseToResponse(productResponse) return contract.BuildSuccessResponse(contractResponse) } func (s *ProductServiceImpl) DeleteProduct(ctx context.Context, id uuid.UUID) *contract.Response { err := s.productProcessor.DeleteProduct(ctx, id) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } return contract.BuildSuccessResponse(map[string]interface{}{ "message": "Product deleted successfully", }) } func (s *ProductServiceImpl) GetProductByID(ctx context.Context, id uuid.UUID) *contract.Response { productResponse, err := s.productProcessor.GetProductByID(ctx, id) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.ProductModelResponseToResponse(productResponse) return contract.BuildSuccessResponse(contractResponse) } func (s *ProductServiceImpl) ListProducts(ctx context.Context, req *contract.ListProductsRequest) *contract.Response { // Build filters filters := make(map[string]interface{}) if req.OrganizationID != nil { filters["organization_id"] = *req.OrganizationID } if req.CategoryID != nil { filters["category_id"] = *req.CategoryID } if req.BusinessType != "" { filters["business_type"] = req.BusinessType } if req.IsActive != nil { filters["is_active"] = *req.IsActive } if req.Search != "" { filters["search"] = req.Search } if req.MinPrice != nil { filters["price_min"] = *req.MinPrice } if req.MaxPrice != nil { filters["price_max"] = *req.MaxPrice } products, totalCount, err := s.productProcessor.ListProducts(ctx, filters, req.Page, req.Limit) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.ProductServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } // Convert to contract responses contractResponses := transformer.ProductsToResponses(products) // Calculate total pages totalPages := totalCount / req.Limit if totalCount%req.Limit > 0 { totalPages++ } listResponse := &contract.ListProductsResponse{ Products: contractResponses, TotalCount: totalCount, Page: req.Page, Limit: req.Limit, TotalPages: totalPages, } return contract.BuildSuccessResponse(listResponse) }