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" "github.com/Caknoooo/go-gin-clean-starter/pkg/constants" "github.com/Caknoooo/go-gin-clean-starter/pkg/utils" "github.com/google/uuid" "github.com/sirupsen/logrus" "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 log *logrus.Logger } func NewCategoryService(categoryRepo repository.CategoryRepository, db *gorm.DB, log *logrus.Logger) CategoryService { return &categoryService{ categoryRepo: categoryRepo, db: db, log: log, } } 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, FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE), } 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 } s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "create", "entity": "category", "entity_id": created.ID.String(), }).Info("Category created") return dto.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 dto.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, dto.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 category.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE) 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 } s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "update", "entity": "category", "entity_id": categoryId, }).Info("Category updated") return dto.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() } }() category, err := s.categoryRepo.GetById(ctx, tx, categoryId) if err != nil { tx.Rollback() return err } category.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE) if _, err := s.categoryRepo.Update(ctx, tx, category); err != nil { tx.Rollback() return err } if err := s.categoryRepo.Delete(ctx, tx, categoryId); err != nil { tx.Rollback() return err } tx.Commit() s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "delete", "entity": "category", "entity_id": categoryId, }).Info("Category deleted") return nil }