package service import ( "context" "github.com/Caknoooo/go-gin-clean-starter/database/entities" "github.com/Caknoooo/go-gin-clean-starter/modules/zona/dto" "github.com/Caknoooo/go-gin-clean-starter/modules/zona/query" "github.com/Caknoooo/go-gin-clean-starter/modules/zona/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 ZonaService interface { Create(ctx context.Context, req dto.ZonaCreateRequest) (dto.ZonaResponse, error) GetById(ctx context.Context, zonaId string) (dto.ZonaResponse, error) GetAll(ctx context.Context, filter query.ZonaFilter) ([]dto.ZonaResponse, int64, error) Update(ctx context.Context, req dto.ZonaUpdateRequest, zonaId string) (dto.ZonaResponse, error) Delete(ctx context.Context, zonaId string) error } type zonaService struct { db *gorm.DB zonaRepo repository.ZonaRepository log *logrus.Logger } func (s *zonaService) Create(ctx context.Context, req dto.ZonaCreateRequest) (dto.ZonaResponse, error) { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() warehouseUUID, err := uuid.Parse(req.WarehouseID) if err != nil { tx.Rollback() return dto.ZonaResponse{}, err } clientUUID, err := uuid.Parse(req.ClientID) if err != nil { tx.Rollback() return dto.ZonaResponse{}, err } zona := entities.MZonaEntity{ Code: req.Code, Name: req.Name, Type: req.Type, Temperature: req.Temperature, Hazardous: req.Hazardous, WarehouseID: warehouseUUID, ClientID: clientUUID, FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE), } created, err := s.zonaRepo.Create(ctx, tx, zona) if err != nil { tx.Rollback() return dto.ZonaResponse{}, err } tx.Commit() result, err := s.zonaRepo.GetById(ctx, nil, created.ID.String()) if err != nil { return dto.ZonaResponse{}, err } s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "create", "entity": "zona", "entity_id": created.ID.String(), }).Info("Zona created") return dto.ToZonaResponse(result), nil } func (s *zonaService) GetById(ctx context.Context, zonaId string) (dto.ZonaResponse, error) { zona, err := s.zonaRepo.GetById(ctx, nil, zonaId) if err != nil { return dto.ZonaResponse{}, err } return dto.ToZonaResponse(zona), nil } func (s *zonaService) GetAll(ctx context.Context, filter query.ZonaFilter) ([]dto.ZonaResponse, int64, error) { zonas, total, err := s.zonaRepo.GetAll(ctx, filter) if err != nil { return nil, 0, err } var responses []dto.ZonaResponse for _, e := range zonas { responses = append(responses, dto.ToZonaResponse(e)) } if responses == nil { responses = make([]dto.ZonaResponse, 0) } return responses, total, nil } func (s *zonaService) Update(ctx context.Context, req dto.ZonaUpdateRequest, zonaId string) (dto.ZonaResponse, error) { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() zona, err := s.zonaRepo.GetById(ctx, tx, zonaId) if err != nil { tx.Rollback() return dto.ZonaResponse{}, err } before := zona if req.Code != "" { zona.Code = req.Code } if req.Name != "" { zona.Name = req.Name } if req.Type != "" { zona.Type = req.Type } zona.Temperature = req.Temperature zona.Hazardous = req.Hazardous zona.IsActive = req.IsActive zona.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE) updated, err := s.zonaRepo.Update(ctx, tx, zona) if err != nil { tx.Rollback() return dto.ZonaResponse{}, err } tx.Commit() result, err := s.zonaRepo.GetById(ctx, nil, updated.ID.String()) if err != nil { return dto.ZonaResponse{}, err } changes := utils.GetChangedFields(before, result) s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "update", "entity": "zona", "entity_id": zonaId, "changes": changes, }).Info("Zona updated") return dto.ToZonaResponse(result), nil } func (s *zonaService) Delete(ctx context.Context, zonaId string) error { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() zona, err := s.zonaRepo.GetById(ctx, tx, zonaId) if err != nil { tx.Rollback() return err } zona.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE) if _, err := s.zonaRepo.Update(ctx, tx, zona); err != nil { tx.Rollback() return err } if err := s.zonaRepo.Delete(ctx, tx, zonaId); err != nil { tx.Rollback() return err } tx.Commit() s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "delete", "entity": "zona", "entity_id": zonaId, }).Info("Zona deleted") return nil } func NewZonaService(zonaRepo repository.ZonaRepository, db *gorm.DB, log *logrus.Logger) ZonaService { return &zonaService{ zonaRepo: zonaRepo, db: db, log: log, } }