package service import ( "context" "github.com/Caknoooo/go-gin-clean-starter/database/entities" sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service" dtodomain "github.com/Caknoooo/go-gin-clean-starter/modules/uom/dto" "github.com/Caknoooo/go-gin-clean-starter/modules/uom/query" "github.com/Caknoooo/go-gin-clean-starter/modules/uom/repository" "github.com/Caknoooo/go-gin-clean-starter/pkg/constants" pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto" "github.com/Caknoooo/go-gin-clean-starter/pkg/utils" "github.com/google/uuid" "github.com/sirupsen/logrus" "gorm.io/gorm" ) type UomService interface { Create(ctx context.Context, req dtodomain.UomCreateRequest) (dtodomain.UomResponse, error) GetById(ctx context.Context, uomId string) (dtodomain.UomResponse, error) GetAll(ctx context.Context, filter query.UomFilter) ([]dtodomain.UomResponse, int64, error) Update(ctx context.Context, req dtodomain.UomUpdateRequest, uomId string) (dtodomain.UomResponse, error) Delete(ctx context.Context, uomId string) error } type uomService struct { db *gorm.DB uomRepo repository.UomRepository sequenceService sequenceservice.SequenceService log *logrus.Logger } func NewUomService(uomRepo repository.UomRepository, sequenceService sequenceservice.SequenceService, db *gorm.DB, log *logrus.Logger) UomService { return &uomService{ uomRepo: uomRepo, sequenceService: sequenceService, db: db, log: log, } } func (s *uomService) Create(ctx context.Context, req dtodomain.UomCreateRequest) (dtodomain.UomResponse, error) { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() seqConfig := pkgdto.SequenceConfig{ EntityType: "UOM", Prefix: "UOM", Period: "", } code, err := s.sequenceService.GenerateNumber(ctx, req.ClientID, seqConfig) if err != nil { tx.Rollback() return dtodomain.UomResponse{}, err } uom := entities.MUomEntity{ Name: req.Name, Description: req.Description, Symbol: req.Symbol, Code: code, StdPrecision: req.StdPrecision, IsActive: req.IsActive, FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE), } clientUUID, err := uuid.Parse(req.ClientID) if err != nil { tx.Rollback() return dtodomain.UomResponse{}, err } uom.ClientID = clientUUID created, err := s.uomRepo.Create(ctx, tx, uom) if err != nil { tx.Rollback() return dtodomain.UomResponse{}, err } tx.Commit() result, err := s.uomRepo.GetById(ctx, nil, created.ID.String()) if err != nil { return dtodomain.UomResponse{}, err } return dtodomain.ToUomResponse(result), nil } func (s *uomService) GetById(ctx context.Context, uomId string) (dtodomain.UomResponse, error) { uom, err := s.uomRepo.GetById(ctx, nil, uomId) if err != nil { return dtodomain.UomResponse{}, err } return dtodomain.ToUomResponse(uom), nil } func (s *uomService) GetAll(ctx context.Context, filter query.UomFilter) ([]dtodomain.UomResponse, int64, error) { uoms, total, err := s.uomRepo.GetAll(ctx, filter) if err != nil { return nil, 0, err } var responses []dtodomain.UomResponse for _, u := range uoms { responses = append(responses, dtodomain.ToUomResponse(u)) } if responses == nil { responses = make([]dtodomain.UomResponse, 0) } return responses, total, nil } func (s *uomService) Update(ctx context.Context, req dtodomain.UomUpdateRequest, uomId string) (dtodomain.UomResponse, error) { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() uom, err := s.uomRepo.GetById(ctx, tx, uomId) if err != nil { tx.Rollback() return dtodomain.UomResponse{}, err } before := uom uom.Name = req.Name uom.Description = req.Description uom.Symbol = req.Symbol uom.Code = req.Code uom.StdPrecision = req.StdPrecision uom.IsActive = req.IsActive if req.ClientID != "" { clientUUID, err := uuid.Parse(req.ClientID) if err != nil { tx.Rollback() return dtodomain.UomResponse{}, err } uom.ClientID = clientUUID uom.Client = entities.M_Client{} } else { uom.Client = entities.M_Client{} } uom.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE) updated, err := s.uomRepo.Update(ctx, tx, uom) if err != nil { tx.Rollback() return dtodomain.UomResponse{}, err } tx.Commit() result, err := s.uomRepo.GetById(ctx, nil, updated.ID.String()) changes := utils.GetChangedFields(before, result) s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "update", "entity": "uom", "entity_id": uomId, "changes": changes, // berisi field yang berubah saja }).Info("UOM updated") if err != nil { return dtodomain.UomResponse{}, err } return dtodomain.ToUomResponse(result), nil } func (s *uomService) Delete(ctx context.Context, uomId string) error { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() uom, err := s.uomRepo.GetById(ctx, tx, uomId) if err != nil { tx.Rollback() return err } // Isi audit trail DeletedBy uom.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE) // Update audit trail sebelum delete if _, err := s.uomRepo.Update(ctx, tx, uom); err != nil { tx.Rollback() return err } if err := s.uomRepo.Delete(ctx, tx, uomId); err != nil { tx.Rollback() return err } tx.Commit() s.log.WithFields(logrus.Fields{ "user_id": utils.GetUserID(ctx), "action": "delete", "entity": "uom", "entity_id": uomId, }).Info("UOM deleted") return nil }