update unique letter number
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
type LetterOutgoingProcessor interface {
|
||||
CreateOutgoingLetter(ctx context.Context, letter *entities.LetterOutgoing, attachments []entities.LetterOutgoingAttachment, userID, departmentID uuid.UUID) error
|
||||
GetOutgoingLetterByID(ctx context.Context, id uuid.UUID) (*entities.LetterOutgoing, error)
|
||||
GetOutgoingLetterByReferenceNumber(ctx context.Context, referenceNumber *string) (*entities.LetterOutgoing, error)
|
||||
ListOutgoingLetters(ctx context.Context, filter repository.ListOutgoingLettersFilter, limit, offset int) ([]entities.LetterOutgoing, int64, error)
|
||||
SearchOutgoingLetters(ctx context.Context, filters map[string]interface{}, page, limit int, sortBy, sortOrder string) ([]entities.LetterOutgoing, int64, error)
|
||||
UpdateOutgoingLetter(ctx context.Context, letter *entities.LetterOutgoing, userID uuid.UUID) error
|
||||
@@ -110,6 +111,11 @@ func NewLetterOutgoingProcessor(
|
||||
}
|
||||
|
||||
func (p *LetterOutgoingProcessorImpl) CreateOutgoingLetter(ctx context.Context, letter *entities.LetterOutgoing, attachments []entities.LetterOutgoingAttachment, userID, departmentID uuid.UUID) error {
|
||||
existingOutgoing, err := p.letterRepo.GetByReferenceNumber(ctx, letter.ReferenceNumber)
|
||||
if err == nil && existingOutgoing != nil {
|
||||
return fmt.Errorf("surat dengan nomor %s sudah ada", *letter.ReferenceNumber)
|
||||
}
|
||||
|
||||
return p.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
|
||||
// Step 1: Assign approval flow from department if not provided
|
||||
if err := p.assignApprovalFlowFromDepartment(txCtx, letter, departmentID); err != nil {
|
||||
@@ -148,6 +154,10 @@ func (p *LetterOutgoingProcessorImpl) CreateOutgoingLetter(ctx context.Context,
|
||||
})
|
||||
}
|
||||
|
||||
func (p *LetterOutgoingProcessorImpl) GetOutgoingLetterByReferenceNumber(ctx context.Context, referenceNumber *string) (*entities.LetterOutgoing, error) {
|
||||
return p.letterRepo.GetByReferenceNumber(ctx, referenceNumber)
|
||||
}
|
||||
|
||||
func (p *LetterOutgoingProcessorImpl) assignApprovalFlowFromDepartment(ctx context.Context, letter *entities.LetterOutgoing, departmentID uuid.UUID) error {
|
||||
if letter.ApprovalFlowID != nil || departmentID == uuid.Nil {
|
||||
return nil
|
||||
@@ -598,17 +608,17 @@ func (p *LetterOutgoingProcessorImpl) isStepCompleted(stepApprovals []entities.L
|
||||
approvalsByParallelGroup := make(map[int][]entities.LetterOutgoingApproval)
|
||||
for _, approval := range stepApprovals {
|
||||
approvalsByParallelGroup[approval.ParallelGroup] = append(
|
||||
approvalsByParallelGroup[approval.ParallelGroup],
|
||||
approvalsByParallelGroup[approval.ParallelGroup],
|
||||
approval,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// Check each parallel group
|
||||
for _, groupApprovals := range approvalsByParallelGroup {
|
||||
// For each parallel group, check if it has at least one approved
|
||||
groupHasApproval := false
|
||||
hasRequiredPending := false
|
||||
|
||||
|
||||
for _, approval := range groupApprovals {
|
||||
if approval.Status == entities.ApprovalStatusApproved {
|
||||
groupHasApproval = true
|
||||
@@ -617,12 +627,12 @@ func (p *LetterOutgoingProcessorImpl) isStepCompleted(stepApprovals []entities.L
|
||||
hasRequiredPending = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If this group has required approvals that are still pending, step is not complete
|
||||
if hasRequiredPending {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// If this group has no approvals at all and contains required approvals, step is not complete
|
||||
if !groupHasApproval {
|
||||
for _, approval := range groupApprovals {
|
||||
@@ -632,7 +642,7 @@ func (p *LetterOutgoingProcessorImpl) isStepCompleted(stepApprovals []entities.L
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -778,7 +788,7 @@ func (p *LetterOutgoingProcessorImpl) activateNextParallelGroupForRevision(ctx c
|
||||
groups = append(groups, group)
|
||||
}
|
||||
sort.Ints(groups)
|
||||
|
||||
|
||||
var nextGroup int = -1
|
||||
for _, group := range groups {
|
||||
if group > currentGroup {
|
||||
@@ -786,22 +796,22 @@ func (p *LetterOutgoingProcessorImpl) activateNextParallelGroupForRevision(ctx c
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if nextGroup == -1 {
|
||||
return nil // No next group
|
||||
}
|
||||
|
||||
|
||||
nextGroupApprovals, exists := approvalsByGroup[nextGroup]
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// Get existing recipients to avoid duplicates
|
||||
existingUserIDs, err := p.getExistingRecipientUserIDs(ctx, letterID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Process each approval in the next group
|
||||
for _, nextApproval := range nextGroupApprovals {
|
||||
// Only process if it's the same revision
|
||||
@@ -810,14 +820,14 @@ func (p *LetterOutgoingProcessorImpl) activateNextParallelGroupForRevision(ctx c
|
||||
if err := p.activateApprovalIfNotStarted(ctx, &nextApproval); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Add approver as recipient if not already exists
|
||||
if err := p.addApproverAsRecipientIfNeeded(ctx, letterID, nextApproval.ApproverID, existingUserIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,11 @@ func NewLetterProcessor(letterRepo *repository.LetterIncomingRepository, attachR
|
||||
func (p *LetterProcessorImpl) CreateIncomingLetter(ctx context.Context, req *contract.CreateIncomingLetterRequest) (*contract.IncomingLetterResponse, error) {
|
||||
userID := appcontext.FromGinContext(ctx).UserID
|
||||
|
||||
existingIncoming, err := p.letterRepo.GetByReferenceNumber(ctx, req.ReferenceNumber)
|
||||
if err == nil && existingIncoming != nil {
|
||||
return nil, fmt.Errorf("surat dengan nomor %s sudah ada", *req.ReferenceNumber)
|
||||
}
|
||||
|
||||
letterType := entities.LetterIncomingTypeUtama
|
||||
if req.Type == "TEMBUSAN" {
|
||||
letterType = entities.LetterIncomingTypeTembusan
|
||||
|
||||
Reference in New Issue
Block a user