dukcapil/internal/processor/recipient_processor.go
2025-09-08 15:21:17 +07:00

111 lines
3.6 KiB
Go

package processor
import (
"context"
"eslogad-be/internal/appcontext"
"time"
"eslogad-be/internal/entities"
"eslogad-be/internal/repository"
"github.com/google/uuid"
)
type RecipientProcessor interface {
CreateDefaultRecipients(ctx context.Context, letterID uuid.UUID) ([]entities.LetterIncomingRecipient, error)
CreateRecipients(ctx context.Context, letterID uuid.UUID, departmentIDs []uuid.UUID) ([]entities.LetterIncomingRecipient, error)
CreateSingleRecipient(ctx context.Context, recipient *entities.LetterIncomingRecipient) error
}
type RecipientProcessorImpl struct {
recipientRepo *repository.LetterIncomingRecipientRepository
settingRepo *repository.AppSettingRepository
departmentRepo *repository.DepartmentRepository
userDeptRepo *repository.UserDepartmentRepository
}
func NewRecipientProcessor(
recipientRepo *repository.LetterIncomingRecipientRepository,
settingRepo *repository.AppSettingRepository,
departmentRepo *repository.DepartmentRepository,
userDeptRepo *repository.UserDepartmentRepository,
) *RecipientProcessorImpl {
return &RecipientProcessorImpl{
recipientRepo: recipientRepo,
settingRepo: settingRepo,
departmentRepo: departmentRepo,
userDeptRepo: userDeptRepo,
}
}
func (p *RecipientProcessorImpl) CreateDefaultRecipients(ctx context.Context, letterID uuid.UUID) ([]entities.LetterIncomingRecipient, error) {
departmentIDs, err := p.settingRepo.GetDepartmentRecipients(ctx)
if err != nil {
return []entities.LetterIncomingRecipient{}, nil
}
if len(departmentIDs) == 0 {
return []entities.LetterIncomingRecipient{}, nil
}
return p.CreateRecipients(ctx, letterID, departmentIDs)
}
func (p *RecipientProcessorImpl) CreateRecipients(ctx context.Context, letterID uuid.UUID, departmentIDs []uuid.UUID) ([]entities.LetterIncomingRecipient, error) {
userCreatorDepartment := appcontext.FromGinContext(ctx).DepartmentID
departmentIDs = append(departmentIDs, userCreatorDepartment)
userMemberships, err := p.userDeptRepo.ListActiveByDepartmentIDs(ctx, departmentIDs)
if err != nil {
return nil, err
}
recipients := p.buildUniqueRecipients(letterID, userMemberships, userCreatorDepartment)
if err := p.recipientRepo.CreateBulk(ctx, recipients); err != nil {
return nil, err
}
return recipients, nil
}
func (p *RecipientProcessorImpl) buildUniqueRecipients(letterID uuid.UUID, userMemberships []repository.UserDepartmentRow, userCreatorDepartment uuid.UUID) []entities.LetterIncomingRecipient {
var recipients []entities.LetterIncomingRecipient
userMap := make(map[string]bool)
now := time.Now()
for _, membership := range userMemberships {
userIDStr := membership.UserID.String()
if !userMap[userIDStr] {
userID := membership.UserID
departmentID := membership.DepartmentID
if userCreatorDepartment == membership.DepartmentID {
recipients = append(recipients, entities.LetterIncomingRecipient{
LetterID: letterID,
RecipientUserID: &userID,
RecipientDepartmentID: &departmentID,
Status: entities.RecipientStatusCompleted,
ReadAt: &now,
CompletedAt: &now,
})
} else {
recipients = append(recipients, entities.LetterIncomingRecipient{
LetterID: letterID,
RecipientUserID: &userID,
RecipientDepartmentID: &departmentID,
Status: entities.RecipientStatusNew,
})
}
userMap[userIDStr] = true
}
}
return recipients
}
func (p *RecipientProcessorImpl) CreateSingleRecipient(ctx context.Context, recipient *entities.LetterIncomingRecipient) error {
return p.recipientRepo.Create(ctx, recipient)
}