package service import ( "context" "github.com/Caknoooo/go-gin-clean-starter/database/entities" "github.com/Caknoooo/go-gin-clean-starter/modules/category/dto" "github.com/Caknoooo/go-gin-clean-starter/modules/category/query" "github.com/Caknoooo/go-gin-clean-starter/modules/category/repository" pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto" "github.com/google/uuid" "gorm.io/gorm" ) type CategoryService interface { Create(ctx context.Context, req dto.CategoryCreateRequest) (dto.CategoryResponse, error) GetById(ctx context.Context, categoryId string) (dto.CategoryResponse, error) GetAll(ctx context.Context, filter query.CategoryFilter) ([]dto.CategoryResponse, int64, error) Update(ctx context.Context, req dto.CategoryUpdateRequest, categoryId string) (dto.CategoryResponse, error) Delete(ctx context.Context, categoryId string) error } type categoryService struct { db *gorm.DB categoryRepo repository.CategoryRepository } func NewCategoryService(categoryRepo repository.CategoryRepository, db *gorm.DB) CategoryService { return &categoryService{ categoryRepo: categoryRepo, db: db, } } func (s *categoryService) Create(ctx context.Context, req dto.CategoryCreateRequest) (dto.CategoryResponse, error) { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() category := entities.MCategoryEntity{ Name: req.Name, SearchKey: req.SearchKey, Description: req.Description, IsActive: req.IsActive, } clientUUID, err := uuid.Parse(req.ClientID) if err != nil { tx.Rollback() return dto.CategoryResponse{}, err } category.ClientID = clientUUID created, err := s.categoryRepo.Create(ctx, tx, category) if err != nil { tx.Rollback() return dto.CategoryResponse{}, err } tx.Commit() result, err := s.categoryRepo.GetById(ctx, s.db, created.ID.String()) if err != nil { return dto.CategoryResponse{}, err } return toCategoryResponse(result), nil } func (s *categoryService) GetById(ctx context.Context, categoryId string) (dto.CategoryResponse, error) { category, err := s.categoryRepo.GetById(ctx, nil, categoryId) if err != nil { return dto.CategoryResponse{}, err } return toCategoryResponse(category), nil } func (s *categoryService) GetAll(ctx context.Context, filter query.CategoryFilter) ([]dto.CategoryResponse, int64, error) { categories, total, err := s.categoryRepo.GetAll(ctx, filter) if err != nil { return nil, 0, err } var responses []dto.CategoryResponse for _, c := range categories { responses = append(responses, toCategoryResponse(c)) } if responses == nil { responses = make([]dto.CategoryResponse, 0) } return responses, total, nil } func (s *categoryService) Update(ctx context.Context, req dto.CategoryUpdateRequest, categoryId string) (dto.CategoryResponse, error) { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() category, err := s.categoryRepo.GetById(ctx, tx, categoryId) if err != nil { tx.Rollback() return dto.CategoryResponse{}, err } category.Name = req.Name category.SearchKey = req.SearchKey category.Description = req.Description category.IsActive = req.IsActive updated, err := s.categoryRepo.Update(ctx, tx, category) if err != nil { tx.Rollback() return dto.CategoryResponse{}, err } tx.Commit() result, err := s.categoryRepo.GetById(ctx, s.db, updated.ID.String()) if err != nil { return dto.CategoryResponse{}, err } return toCategoryResponse(result), nil } func (s *categoryService) Delete(ctx context.Context, categoryId string) error { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() if err := s.categoryRepo.Delete(ctx, tx, categoryId); err != nil { tx.Rollback() return err } tx.Commit() return nil } func toCategoryResponse(e entities.MCategoryEntity) dto.CategoryResponse { return dto.CategoryResponse{ ID: e.ID.String(), Name: e.Name, SearchKey: e.SearchKey, Description: e.Description, IsActive: e.IsActive, Client: pkgdto.ClientResponse{ ID: e.Client.ID.String(), Name: e.Client.Name, }, } }