224 lines
6.2 KiB
Go
224 lines
6.2 KiB
Go
package company_category
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"tm/pkg/logger"
|
|
"tm/pkg/response"
|
|
)
|
|
|
|
// Service defines business logic for category operations
|
|
type Service interface {
|
|
// Core category operations
|
|
Create(ctx context.Context, form *CategoryForm) (*CategoryResponse, error)
|
|
Update(ctx context.Context, id string, form *CategoryForm) (*CategoryResponse, error)
|
|
GetByID(ctx context.Context, id string) (*CategoryResponse, error)
|
|
GetByIDs(ctx context.Context, ids []string) ([]*CategoryResponse, error)
|
|
Delete(ctx context.Context, id string) error
|
|
|
|
// Category listing and search
|
|
SearchCategories(ctx context.Context, form *SearchForm, pagination *response.Pagination) (*CategoryListResponse, error)
|
|
|
|
// Category management
|
|
TogglePublish(ctx context.Context, id string) (bool, error)
|
|
}
|
|
|
|
// categoryService implements the Service interface
|
|
type categoryService struct {
|
|
repository Repository
|
|
logger logger.Logger
|
|
}
|
|
|
|
// NewService creates a new category service
|
|
func NewService(repository Repository, logger logger.Logger) Service {
|
|
return &categoryService{
|
|
repository: repository,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// Create creates a new category
|
|
func (s *categoryService) Create(ctx context.Context, form *CategoryForm) (*CategoryResponse, error) {
|
|
// Check if category name already exists
|
|
existingCategory, _ := s.repository.GetByName(ctx, form.Name)
|
|
if existingCategory != nil {
|
|
return nil, errors.New("category with this name already exists")
|
|
}
|
|
|
|
// Create category
|
|
category := &Category{
|
|
Name: form.Name,
|
|
Description: form.Description,
|
|
Thumbnail: form.Thumbnail,
|
|
Published: false, // Default to unpublished
|
|
}
|
|
|
|
// Save to database
|
|
err := s.repository.Create(ctx, category)
|
|
if err != nil {
|
|
s.logger.Error("Failed to create category", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"name": form.Name,
|
|
})
|
|
return nil, err
|
|
}
|
|
|
|
s.logger.Info("Category created successfully", map[string]interface{}{
|
|
"category_id": category.ID,
|
|
"name": category.Name,
|
|
"published": category.Published,
|
|
})
|
|
|
|
return category.ToResponse(), nil
|
|
}
|
|
|
|
// GetByIDs retrieves categories by IDs
|
|
func (s *categoryService) GetByIDs(ctx context.Context, ids []string) ([]*CategoryResponse, error) {
|
|
categories, err := s.repository.GetByIDs(ctx, ids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var categoryResponses []*CategoryResponse
|
|
for _, category := range categories {
|
|
categoryResponses = append(categoryResponses, category.ToResponse())
|
|
}
|
|
|
|
return categoryResponses, nil
|
|
}
|
|
|
|
// GetByID retrieves a category by ID
|
|
func (s *categoryService) GetByID(ctx context.Context, id string) (*CategoryResponse, error) {
|
|
category, err := s.repository.GetByID(ctx, id)
|
|
if err != nil {
|
|
s.logger.Error("Failed to get category by ID", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"category_id": id,
|
|
})
|
|
return nil, err
|
|
}
|
|
|
|
s.logger.Info("Category retrieved successfully", map[string]interface{}{
|
|
"category_id": category.ID,
|
|
"name": category.Name,
|
|
})
|
|
|
|
return category.ToResponse(), nil
|
|
}
|
|
|
|
// Update updates a category
|
|
func (s *categoryService) Update(ctx context.Context, id string, form *CategoryForm) (*CategoryResponse, error) {
|
|
// Get existing category
|
|
category, err := s.repository.GetByID(ctx, id)
|
|
if err != nil {
|
|
s.logger.Error("Failed to get category for update", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"category_id": id,
|
|
})
|
|
return nil, errors.New("category not found")
|
|
}
|
|
|
|
// Check if name already exists (if changing name)
|
|
if form.Name != "" && form.Name != category.Name {
|
|
existingCategory, _ := s.repository.GetByName(ctx, form.Name)
|
|
if existingCategory != nil {
|
|
return nil, errors.New("category with this name already exists")
|
|
}
|
|
category.Name = form.Name
|
|
}
|
|
|
|
// Update fields if provided
|
|
if form.Description != nil {
|
|
category.Description = form.Description
|
|
}
|
|
|
|
if form.Thumbnail != nil {
|
|
category.Thumbnail = form.Thumbnail
|
|
}
|
|
|
|
// Update in database
|
|
err = s.repository.Update(ctx, category)
|
|
if err != nil {
|
|
s.logger.Error("Failed to update category", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"category_id": id,
|
|
})
|
|
return nil, errors.New("failed to update category")
|
|
}
|
|
|
|
s.logger.Info("Category updated successfully", map[string]interface{}{
|
|
"category_id": category.ID,
|
|
"name": category.Name,
|
|
})
|
|
|
|
return category.ToResponse(), nil
|
|
}
|
|
|
|
// Delete deletes a category
|
|
func (s *categoryService) Delete(ctx context.Context, id string) error {
|
|
// Delete category
|
|
err := s.repository.Delete(ctx, id)
|
|
if err != nil {
|
|
s.logger.Error("Failed to delete category", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"category_id": id,
|
|
})
|
|
return errors.New("failed to delete category")
|
|
}
|
|
|
|
s.logger.Info("Category deleted successfully", map[string]interface{}{
|
|
"category_id": id,
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// SearchCategories searches categories with filters
|
|
func (s *categoryService) SearchCategories(ctx context.Context, form *SearchForm, pagination *response.Pagination) (*CategoryListResponse, error) {
|
|
// Get categories using search
|
|
page, err := s.repository.Search(ctx, form, pagination)
|
|
if err != nil {
|
|
s.logger.Error("Failed to search categories", map[string]interface{}{
|
|
"error": err.Error(),
|
|
})
|
|
return nil, err
|
|
}
|
|
|
|
var categoryResponses []*CategoryResponse
|
|
for _, category := range page.Items {
|
|
categoryResponses = append(categoryResponses, category.ToResponse())
|
|
}
|
|
|
|
return &CategoryListResponse{
|
|
Categories: categoryResponses,
|
|
Meta: pagination.ListMeta(page.TotalCount, page.NextCursor, page.HasMore, page.PageOffset),
|
|
}, nil
|
|
}
|
|
|
|
// TogglePublish toggles category publish status
|
|
func (s *categoryService) TogglePublish(ctx context.Context, id string) (bool, error) {
|
|
// Get category to check if exists
|
|
_, err := s.repository.GetByID(ctx, id)
|
|
if err != nil {
|
|
return false, errors.New("category not found")
|
|
}
|
|
|
|
// Toggle publish status
|
|
published, err := s.repository.TogglePublish(ctx, id)
|
|
if err != nil {
|
|
s.logger.Error("Failed to toggle category publish status", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"category_id": id,
|
|
})
|
|
return false, errors.New("failed to toggle category publish status")
|
|
}
|
|
|
|
s.logger.Info("Category publish status updated successfully", map[string]interface{}{
|
|
"category_id": id,
|
|
"published": published,
|
|
})
|
|
|
|
return published, nil
|
|
}
|