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" pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto" "github.com/Caknoooo/go-gin-clean-starter/pkg/utils" "github.com/google/uuid" "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 } func NewVendorService(vendorRepo repository.VendorRepository, sequenceService sequenceservice.SequenceService, db *gorm.DB) VendorService { return &vendorService{ vendorRepo: vendorRepo, sequenceService: sequenceService, db: db, } } 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() } }() 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, } 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 } tx.Commit() return 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 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] = 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() } }() 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 } updated, err := s.vendorRepo.Update(ctx, tx, vendor) if err != nil { tx.Rollback() return dto.VendorResponse{}, err } tx.Commit() return 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() } }() if err := s.vendorRepo.Delete(ctx, tx, vendorId); err != nil { tx.Rollback() return err } tx.Commit() return nil } func entityToVendorResponse(e entities.MVendorEntity) dto.VendorResponse { return dto.VendorResponse{ ID: e.ID.String(), SearchKey: e.SearchKey, Name: e.Name, Address: e.Address, ContactPerson: e.ContactPerson, IsActive: e.IsActive, Client: pkgdto.IdNameResponse{ ID: e.ClientID.String(), Name: e.Client.Name, }, } }