init
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"apskel-pos-be/internal/entities"
|
||||
"apskel-pos-be/internal/mappers"
|
||||
"apskel-pos-be/internal/models"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type CategoryProcessor interface {
|
||||
CreateCategory(ctx context.Context, req *models.CreateCategoryRequest) (*models.CategoryResponse, error)
|
||||
UpdateCategory(ctx context.Context, id uuid.UUID, req *models.UpdateCategoryRequest) (*models.CategoryResponse, error)
|
||||
DeleteCategory(ctx context.Context, id uuid.UUID) error
|
||||
GetCategoryByID(ctx context.Context, id uuid.UUID) (*models.CategoryResponse, error)
|
||||
ListCategories(ctx context.Context, filters map[string]interface{}, page, limit int) ([]models.CategoryResponse, int, error)
|
||||
}
|
||||
|
||||
type CategoryRepository interface {
|
||||
Create(ctx context.Context, category *entities.Category) error
|
||||
GetByID(ctx context.Context, id uuid.UUID) (*entities.Category, error)
|
||||
GetWithProducts(ctx context.Context, id uuid.UUID) (*entities.Category, error)
|
||||
GetByOrganization(ctx context.Context, organizationID uuid.UUID) ([]*entities.Category, error)
|
||||
GetByBusinessType(ctx context.Context, businessType string) ([]*entities.Category, error)
|
||||
Update(ctx context.Context, category *entities.Category) error
|
||||
Delete(ctx context.Context, id uuid.UUID) error
|
||||
List(ctx context.Context, filters map[string]interface{}, limit, offset int) ([]*entities.Category, int64, error)
|
||||
Count(ctx context.Context, filters map[string]interface{}) (int64, error)
|
||||
GetByName(ctx context.Context, organizationID uuid.UUID, name string) (*entities.Category, error)
|
||||
ExistsByName(ctx context.Context, organizationID uuid.UUID, name string, excludeID *uuid.UUID) (bool, error)
|
||||
}
|
||||
|
||||
type CategoryProcessorImpl struct {
|
||||
categoryRepo CategoryRepository
|
||||
}
|
||||
|
||||
func NewCategoryProcessorImpl(categoryRepo CategoryRepository) *CategoryProcessorImpl {
|
||||
return &CategoryProcessorImpl{
|
||||
categoryRepo: categoryRepo,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *CategoryProcessorImpl) CreateCategory(ctx context.Context, req *models.CreateCategoryRequest) (*models.CategoryResponse, error) {
|
||||
// Check if category with same name exists for this organization
|
||||
exists, err := p.categoryRepo.ExistsByName(ctx, req.OrganizationID, req.Name, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to check category name uniqueness: %w", err)
|
||||
}
|
||||
if exists {
|
||||
return nil, fmt.Errorf("category with name '%s' already exists for this organization", req.Name)
|
||||
}
|
||||
|
||||
// Map request to entity
|
||||
categoryEntity := mappers.CreateCategoryRequestToEntity(req)
|
||||
|
||||
// Create category
|
||||
if err := p.categoryRepo.Create(ctx, categoryEntity); err != nil {
|
||||
return nil, fmt.Errorf("failed to create category: %w", err)
|
||||
}
|
||||
|
||||
// Map entity to response model
|
||||
response := mappers.CategoryEntityToResponse(categoryEntity)
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (p *CategoryProcessorImpl) UpdateCategory(ctx context.Context, id uuid.UUID, req *models.UpdateCategoryRequest) (*models.CategoryResponse, error) {
|
||||
// Get existing category
|
||||
existingCategory, err := p.categoryRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("category not found: %w", err)
|
||||
}
|
||||
|
||||
// Check name uniqueness if name is being updated
|
||||
if req.Name != nil && *req.Name != existingCategory.Name {
|
||||
exists, err := p.categoryRepo.ExistsByName(ctx, existingCategory.OrganizationID, *req.Name, &id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to check category name uniqueness: %w", err)
|
||||
}
|
||||
if exists {
|
||||
return nil, fmt.Errorf("category with name '%s' already exists for this organization", *req.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply updates to entity
|
||||
mappers.UpdateCategoryEntityFromRequest(existingCategory, req)
|
||||
|
||||
// Update category
|
||||
if err := p.categoryRepo.Update(ctx, existingCategory); err != nil {
|
||||
return nil, fmt.Errorf("failed to update category: %w", err)
|
||||
}
|
||||
|
||||
// Map entity to response model
|
||||
response := mappers.CategoryEntityToResponse(existingCategory)
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (p *CategoryProcessorImpl) DeleteCategory(ctx context.Context, id uuid.UUID) error {
|
||||
// Check if category exists
|
||||
_, err := p.categoryRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("category not found: %w", err)
|
||||
}
|
||||
|
||||
// Check if category has products
|
||||
categoryWithProducts, err := p.categoryRepo.GetWithProducts(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check category products: %w", err)
|
||||
}
|
||||
|
||||
if len(categoryWithProducts.Products) > 0 {
|
||||
return fmt.Errorf("cannot delete category: it has %d products associated with it", len(categoryWithProducts.Products))
|
||||
}
|
||||
|
||||
// Delete category
|
||||
if err := p.categoryRepo.Delete(ctx, id); err != nil {
|
||||
return fmt.Errorf("failed to delete category: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *CategoryProcessorImpl) GetCategoryByID(ctx context.Context, id uuid.UUID) (*models.CategoryResponse, error) {
|
||||
categoryEntity, err := p.categoryRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("category not found: %w", err)
|
||||
}
|
||||
|
||||
response := mappers.CategoryEntityToResponse(categoryEntity)
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (p *CategoryProcessorImpl) ListCategories(ctx context.Context, filters map[string]interface{}, page, limit int) ([]models.CategoryResponse, int, error) {
|
||||
offset := (page - 1) * limit
|
||||
|
||||
categoryEntities, total, err := p.categoryRepo.List(ctx, filters, limit, offset)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to list categories: %w", err)
|
||||
}
|
||||
|
||||
responses := make([]models.CategoryResponse, len(categoryEntities))
|
||||
for i, entity := range categoryEntities {
|
||||
response := mappers.CategoryEntityToResponse(entity)
|
||||
if response != nil {
|
||||
responses[i] = *response
|
||||
}
|
||||
}
|
||||
|
||||
return responses, int(total), nil
|
||||
}
|
||||
Reference in New Issue
Block a user