113 lines
3.4 KiB
Go
113 lines
3.4 KiB
Go
package processor
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"eslogad-be/internal/entities"
|
|
"eslogad-be/internal/repository"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type LetterApprovalProcessor interface {
|
|
CreateApprovalSteps(ctx context.Context, letter *entities.LetterOutgoing) error
|
|
ProcessApprovalAction(ctx context.Context, letterID uuid.UUID, approval *entities.LetterOutgoingApproval, userID uuid.UUID, isApproval bool) error
|
|
UpdateApprovalStatus(ctx context.Context, approval *entities.LetterOutgoingApproval, status entities.ApprovalStatus, userID uuid.UUID) error
|
|
CheckAllApprovalsComplete(ctx context.Context, letterID uuid.UUID) (bool, error)
|
|
}
|
|
|
|
type LetterApprovalProcessorImpl struct {
|
|
approvalRepo *repository.LetterOutgoingApprovalRepository
|
|
approvalFlowRepo *repository.ApprovalFlowRepository
|
|
letterRepo *repository.LetterOutgoingRepository
|
|
}
|
|
|
|
func NewLetterApprovalProcessor(
|
|
approvalRepo *repository.LetterOutgoingApprovalRepository,
|
|
approvalFlowRepo *repository.ApprovalFlowRepository,
|
|
letterRepo *repository.LetterOutgoingRepository,
|
|
) *LetterApprovalProcessorImpl {
|
|
return &LetterApprovalProcessorImpl{
|
|
approvalRepo: approvalRepo,
|
|
approvalFlowRepo: approvalFlowRepo,
|
|
letterRepo: letterRepo,
|
|
}
|
|
}
|
|
|
|
func (p *LetterApprovalProcessorImpl) CreateApprovalSteps(ctx context.Context, letter *entities.LetterOutgoing) error {
|
|
if letter.ApprovalFlowID == nil {
|
|
return nil
|
|
}
|
|
|
|
flow, err := p.approvalFlowRepo.Get(ctx, *letter.ApprovalFlowID)
|
|
if err != nil || flow == nil || len(flow.Steps) == 0 {
|
|
return err
|
|
}
|
|
|
|
// Find the minimum step order (first step)
|
|
minStepOrder := flow.Steps[0].StepOrder
|
|
for _, step := range flow.Steps {
|
|
if step.StepOrder < minStepOrder {
|
|
minStepOrder = step.StepOrder
|
|
}
|
|
}
|
|
|
|
// Create approval records for each step
|
|
for _, step := range flow.Steps {
|
|
approval := entities.LetterOutgoingApproval{
|
|
LetterID: letter.ID,
|
|
StepID: step.ID,
|
|
StepOrder: step.StepOrder,
|
|
ParallelGroup: step.ParallelGroup,
|
|
IsRequired: step.Required,
|
|
ApproverID: step.ApproverUserID,
|
|
}
|
|
|
|
// Set initial status
|
|
if step.StepOrder == minStepOrder {
|
|
approval.Status = entities.ApprovalStatusPending
|
|
} else {
|
|
approval.Status = entities.ApprovalStatusNotStarted
|
|
}
|
|
|
|
if err := p.approvalRepo.Create(ctx, &approval); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p *LetterApprovalProcessorImpl) ProcessApprovalAction(ctx context.Context, letterID uuid.UUID, approval *entities.LetterOutgoingApproval, userID uuid.UUID, isApproval bool) error {
|
|
status := entities.ApprovalStatusApproved
|
|
if !isApproval {
|
|
status = entities.ApprovalStatusRejected
|
|
}
|
|
|
|
return p.UpdateApprovalStatus(ctx, approval, status, userID)
|
|
}
|
|
|
|
func (p *LetterApprovalProcessorImpl) UpdateApprovalStatus(ctx context.Context, approval *entities.LetterOutgoingApproval, status entities.ApprovalStatus, userID uuid.UUID) error {
|
|
approval.Status = status
|
|
approval.ApproverID = &userID
|
|
now := time.Now()
|
|
approval.ActedAt = &now
|
|
|
|
return p.approvalRepo.Update(ctx, approval)
|
|
}
|
|
|
|
func (p *LetterApprovalProcessorImpl) CheckAllApprovalsComplete(ctx context.Context, letterID uuid.UUID) (bool, error) {
|
|
approvals, err := p.approvalRepo.ListByLetter(ctx, letterID)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
for _, approval := range approvals {
|
|
if approval.IsRequired && approval.Status != entities.ApprovalStatusApproved {
|
|
return false, nil
|
|
}
|
|
}
|
|
|
|
return true, nil
|
|
} |