wms-be/modules/sequence/service/sequence_service.go

122 lines
3.9 KiB
Go

package service
import (
"context"
"fmt"
"time"
"github.com/Caknoooo/go-gin-clean-starter/modules/sequence/repository"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
"gorm.io/gorm"
)
type SequenceService interface {
GenerateNumber(ctx context.Context, clientId string, config pkgdto.SequenceConfig) (string, error)
GenerateNumberWithPeriod(ctx context.Context, clientId string, config pkgdto.SequenceConfig, suffix string) (string, error)
GenerateNumberWithSuffix(ctx context.Context, clientId string, config pkgdto.SequenceConfig, suffix string) (string, error)
GetNextSequence(ctx context.Context, clientId string, config pkgdto.SequenceConfig) (int, error)
GenerateDocumentNumber(ctx context.Context, clientId string, docType string, config pkgdto.SequenceConfig) (string, error)
}
type sequenceService struct {
db *gorm.DB
sequenceRepo repository.SequenceRepository
}
func NewSequenceService(sequenceRepo repository.SequenceRepository, db *gorm.DB) SequenceService {
return &sequenceService{
sequenceRepo: sequenceRepo,
db: db,
}
}
// GenerateNumberWithSuffix implements SequenceService.
func (s *sequenceService) GenerateNumberWithSuffix(ctx context.Context, clientId string, config pkgdto.SequenceConfig, suffix string) (string, error) {
period := config.Period
seq, err := s.sequenceRepo.GetOrCreateSequence(ctx, s.db, clientId, config.EntityType, period)
if err != nil {
return "", err
}
seq.CurrentSeq++
if err := s.sequenceRepo.UpdateSequence(ctx, s.db, seq); err != nil {
return "", err
}
refNum := fmt.Sprintf("%s-%s-%04d", config.Prefix, suffix, seq.CurrentSeq)
return refNum, nil
}
func (s *sequenceService) GenerateNumber(ctx context.Context, clientId string, config pkgdto.SequenceConfig) (string, error) {
period := config.Period
if period == "" {
period = "-"
}
seq, err := s.sequenceRepo.GetOrCreateSequence(ctx, s.db, clientId, config.EntityType, period)
if err != nil {
return "", err
}
seq.CurrentSeq++
if err := s.sequenceRepo.UpdateSequence(ctx, s.db, seq); err != nil {
return "", err
}
refNum := fmt.Sprintf("%s-%04d", config.Prefix, seq.CurrentSeq)
return refNum, nil
}
func (s *sequenceService) GenerateNumberWithPeriod(ctx context.Context, clientId string, config pkgdto.SequenceConfig, suffix string) (string, error) {
if config.Period == "" {
config.Period = time.Now().Format("0601")
}
period := config.Period
seq, err := s.sequenceRepo.GetOrCreateSequence(ctx, s.db, clientId, config.EntityType, period)
if err != nil {
return "", err
}
seq.CurrentSeq++
if err := s.sequenceRepo.UpdateSequence(ctx, s.db, seq); err != nil {
return "", err
}
refNum := fmt.Sprintf("%s-%s-%s-%04d", config.Prefix, suffix, period, seq.CurrentSeq)
return refNum, nil
}
func (s *sequenceService) GetNextSequence(ctx context.Context, clientId string, config pkgdto.SequenceConfig) (int, error) {
period := config.Period
if period == "" {
period = "-"
}
seq, err := s.sequenceRepo.GetOrCreateSequence(ctx, s.db, clientId, config.EntityType, period)
if err != nil {
return 0, err
}
seq.CurrentSeq++
if err := s.sequenceRepo.UpdateSequence(ctx, s.db, seq); err != nil {
return 0, err
}
return seq.CurrentSeq, nil
}
func (s *sequenceService) GenerateDocumentNumber(ctx context.Context, clientId string, docType string, config pkgdto.SequenceConfig) (string, error) {
// Ambil nama client berdasarkan clientId
var client struct {
Name string
}
if err := s.db.Table("m_clients").Select("name").Where("id = ?", clientId).First(&client).Error; err != nil {
return "", fmt.Errorf("client not found")
}
if client.Name == "" {
return "", fmt.Errorf("client name is empty")
}
initials := utils.GetInitials(client.Name)
// Ambil sequence dari sequence service
seqNum, err := s.GetNextSequence(ctx, clientId, config)
if err != nil {
return "", err
}
docNum := fmt.Sprintf("%s-%s-%04d", docType, initials, seqNum)
return docNum, nil
}