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 CategoryService interface { CreateCategory(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateCategoryRequest) *contract.Response UpdateCategory(ctx context.Context, id uuid.UUID, req *contract.UpdateCategoryRequest) *contract.Response DeleteCategory(ctx context.Context, id uuid.UUID) *contract.Response GetCategoryByID(ctx context.Context, id uuid.UUID) *contract.Response ListCategories(ctx context.Context, req *contract.ListCategoriesRequest) *contract.Response } type CategoryServiceImpl struct { categoryProcessor processor.CategoryProcessor } func NewCategoryService(categoryProcessor processor.CategoryProcessor) *CategoryServiceImpl { return &CategoryServiceImpl{ categoryProcessor: categoryProcessor, } } func (s *CategoryServiceImpl) CreateCategory(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreateCategoryRequest) *contract.Response { modelReq := transformer.CreateCategoryRequestToModel(apctx, req) categoryResponse, err := s.categoryProcessor.CreateCategory(ctx, modelReq) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.CategoryModelResponseToResponse(categoryResponse) return contract.BuildSuccessResponse(contractResponse) } func (s *CategoryServiceImpl) UpdateCategory(ctx context.Context, id uuid.UUID, req *contract.UpdateCategoryRequest) *contract.Response { modelReq := transformer.UpdateCategoryRequestToModel(req) categoryResponse, err := s.categoryProcessor.UpdateCategory(ctx, id, modelReq) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.CategoryModelResponseToResponse(categoryResponse) return contract.BuildSuccessResponse(contractResponse) } func (s *CategoryServiceImpl) DeleteCategory(ctx context.Context, id uuid.UUID) *contract.Response { err := s.categoryProcessor.DeleteCategory(ctx, id) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } return contract.BuildSuccessResponse(map[string]interface{}{ "message": "Category deleted successfully", }) } func (s *CategoryServiceImpl) GetCategoryByID(ctx context.Context, id uuid.UUID) *contract.Response { categoryResponse, err := s.categoryProcessor.GetCategoryByID(ctx, id) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.CategoryModelResponseToResponse(categoryResponse) return contract.BuildSuccessResponse(contractResponse) } func (s *CategoryServiceImpl) ListCategories(ctx context.Context, req *contract.ListCategoriesRequest) *contract.Response { // Build filters filters := make(map[string]interface{}) if req.OrganizationID != nil { filters["organization_id"] = *req.OrganizationID } if req.BusinessType != "" { filters["business_type"] = req.BusinessType } if req.Search != "" { filters["search"] = req.Search } categories, totalCount, err := s.categoryProcessor.ListCategories(ctx, filters, req.Page, req.Limit) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.CategoryServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } // Convert to contract responses contractResponses := transformer.CategoriesToResponses(categories) // Calculate total pages totalPages := totalCount / req.Limit if totalCount%req.Limit > 0 { totalPages++ } listResponse := &contract.ListCategoriesResponse{ Categories: contractResponses, TotalCount: totalCount, Page: req.Page, Limit: req.Limit, TotalPages: totalPages, } return contract.BuildSuccessResponse(listResponse) }