a342da193e
- Updated feedback repository and service methods to use a consistent naming convention, changing `NewTenderRepository` and similar methods to `NewRepository`. - Refactored feedback handler methods to improve clarity by renaming methods such as `ListFeedback` to `Search` and `GetFeedback` to `Get`. - Enhanced feedback response structures to include detailed company and tender information, improving the clarity of feedback data returned to API consumers. - Updated Swagger documentation to reflect changes in feedback response structures and endpoint paths, ensuring accurate representation of the API for consumers.
225 lines
6.3 KiB
Go
225 lines
6.3 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
|
|
categories, total, 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, errors.New("failed to search categories")
|
|
}
|
|
|
|
// Convert to responses
|
|
var categoryResponses []*CategoryResponse
|
|
for _, category := range categories {
|
|
categoryResponses = append(categoryResponses, category.ToResponse())
|
|
}
|
|
|
|
return &CategoryListResponse{
|
|
Categories: categoryResponses,
|
|
Meta: pagination.Response(total),
|
|
}, 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
|
|
}
|