package service import ( "context" "github.com/Caknoooo/go-gin-clean-starter/database/entities" "github.com/Caknoooo/go-gin-clean-starter/modules/mvendor/dto" "github.com/Caknoooo/go-gin-clean-starter/modules/mvendor/query" "github.com/Caknoooo/go-gin-clean-starter/modules/mvendor/repository" sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service" "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 VendorService interface { Create(ctx context.Context, req dto.VendorCreateRequest) (dto.VendorResponse, error) GetById(ctx context.Context, vendorId string) (dto.VendorResponse, error) GetAll(ctx context.Context, filter query.VendorFilter) ([]dto.VendorResponse, int64, error) Update(ctx context.Context, req dto.VendorUpdateRequest, vendorId string) (dto.VendorResponse, error) Delete(ctx context.Context, vendorId string) error } type vendorService struct { db *gorm.DB vendorRepo repository.VendorRepository sequenceService sequenceservice.SequenceService log *logrus.Logger } func NewVendorService(vendorRepo repository.VendorRepository, sequenceService sequenceservice.SequenceService, db *gorm.DB, log *logrus.Logger) VendorService { return &vendorService{ vendorRepo: vendorRepo, sequenceService: sequenceService, db: db, log: log, } } func (s *vendorService) Create(ctx context.Context, req dto.VendorCreateRequest) (dto.VendorResponse, error) { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() userID := utils.GetUserID(ctx) suffix := utils.GetInitials(req.Name) seqConfig := pkgdto.SequenceConfig{ EntityType: "vendor", Prefix: "VND", Period: "", } searchKey, err := s.sequenceService.GenerateNumberWithSuffix(ctx, req.ClientID, seqConfig, suffix) if err != nil { tx.Rollback() return dto.VendorResponse{}, err } vendor := entities.MVendorEntity{ SearchKey: searchKey, Name: req.Name, Address: req.Address, ContactPerson: req.ContactPerson, IsActive: req.IsActive, FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE), } clientUUID, err := uuid.Parse(req.ClientID) if err != nil { tx.Rollback() return dto.VendorResponse{}, err } vendor.ClientID = clientUUID created, err := s.vendorRepo.Create(ctx, tx, vendor) if err != nil { tx.Rollback() return dto.VendorResponse{}, err } s.log.WithFields(logrus.Fields{ "user_id": userID, "action": "create", "entity": "vendor", "entity_id": created.ID.String(), }).Info("Vendor created") tx.Commit() return dto.EntityToVendorResponse(created), nil } func (s *vendorService) GetById(ctx context.Context, vendorId string) (dto.VendorResponse, error) { vendor, err := s.vendorRepo.GetById(ctx, nil, vendorId) if err != nil { return dto.VendorResponse{}, err } return dto.EntityToVendorResponse(vendor), nil } func (s *vendorService) GetAll(ctx context.Context, filter query.VendorFilter) ([]dto.VendorResponse, int64, error) { vendors, total, err := s.vendorRepo.GetAll(ctx, filter) if err != nil { return nil, 0, err } responses := make([]dto.VendorResponse, len(vendors)) for i, v := range vendors { responses[i] = dto.EntityToVendorResponse(v) } return responses, total, nil } func (s *vendorService) Update(ctx context.Context, req dto.VendorUpdateRequest, vendorId string) (dto.VendorResponse, error) { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() userID := utils.GetUserID(ctx) vendor, err := s.vendorRepo.GetById(ctx, tx, vendorId) if err != nil { tx.Rollback() return dto.VendorResponse{}, err } if req.Name != "" { vendor.Name = req.Name } if req.Address != "" { vendor.Address = req.Address } if req.ContactPerson != "" { vendor.ContactPerson = req.ContactPerson } vendor.IsActive = req.IsActive if req.ClientID != "" { clientUUID, err := uuid.Parse(req.ClientID) if err != nil { tx.Rollback() return dto.VendorResponse{}, err } vendor.ClientID = clientUUID } vendor.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE) updated, err := s.vendorRepo.Update(ctx, tx, vendor) if err != nil { tx.Rollback() return dto.VendorResponse{}, err } s.log.WithFields(logrus.Fields{ "user_id": userID, "action": "update", "entity": "vendor", "entity_id": vendorId, }).Info("Vendor updated") tx.Commit() return dto.EntityToVendorResponse(updated), nil } func (s *vendorService) Delete(ctx context.Context, vendorId string) error { tx := s.db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() userID := utils.GetUserID(ctx) vendor, err := s.vendorRepo.GetById(ctx, tx, vendorId) if err != nil { tx.Rollback() return err } vendor.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE) _, err = s.vendorRepo.Update(ctx, tx, vendor) if err != nil { tx.Rollback() return err } if err := s.vendorRepo.Delete(ctx, tx, vendorId); err != nil { tx.Rollback() return err } s.log.WithFields(logrus.Fields{ "user_id": userID, "action": "delete", "entity": "vendor", "entity_id": vendorId, }).Info("Vendor deleted") tx.Commit() return nil }