Add Surat Keluar

This commit is contained in:
Aditya Siregar
2025-09-20 16:31:22 +07:00
parent 0399c87736
commit e4946d6e05
13 changed files with 1151 additions and 13 deletions
+73 -6
View File
@@ -53,31 +53,57 @@ type LetterOutgoingService interface {
}
type LetterOutgoingServiceImpl struct {
processor processor.LetterOutgoingProcessor
processor processor.LetterOutgoingProcessor
txManager *repository.TxManager
validationProcessor processor.LetterValidationProcessor
creationProcessor processor.LetterCreationProcessor
approvalProcessor processor.LetterApprovalProcessor
attachmentProcessor processor.LetterAttachmentProcessor
recipientProcessor processor.LetterOutgoingRecipientProcessor
activityProcessor processor.LetterActivityProcessor
}
func NewLetterOutgoingService(processor processor.LetterOutgoingProcessor) *LetterOutgoingServiceImpl {
func NewLetterOutgoingService(
processor processor.LetterOutgoingProcessor,
txManager *repository.TxManager,
validationProcessor processor.LetterValidationProcessor,
creationProcessor processor.LetterCreationProcessor,
approvalProcessor processor.LetterApprovalProcessor,
attachmentProcessor processor.LetterAttachmentProcessor,
recipientProcessor processor.LetterOutgoingRecipientProcessor,
activityProcessor processor.LetterActivityProcessor,
) *LetterOutgoingServiceImpl {
return &LetterOutgoingServiceImpl{
processor: processor,
processor: processor,
txManager: txManager,
validationProcessor: validationProcessor,
creationProcessor: creationProcessor,
approvalProcessor: approvalProcessor,
attachmentProcessor: attachmentProcessor,
recipientProcessor: recipientProcessor,
activityProcessor: activityProcessor,
}
}
func (s *LetterOutgoingServiceImpl) CreateOutgoingLetter(ctx context.Context, req *contract.CreateOutgoingLetterRequest) (*contract.OutgoingLetterResponse, error) {
departmentID := getDepartmentIDFromContext(ctx)
userID := getUserIDFromContext(ctx)
// Create letter entity
letter := &entities.LetterOutgoing{
Subject: req.Subject,
Description: req.Description,
PriorityID: req.PriorityID,
ReceiverInstitutionID: req.ReceiverInstitutionID,
IssueDate: req.IssueDate,
CreatedBy: req.UserID,
CreatedBy: userID,
}
if req.ReferenceNumber != nil {
letter.ReferenceNumber = req.ReferenceNumber
}
// Prepare attachments
var attachments []entities.LetterOutgoingAttachment
if len(req.Attachments) > 0 {
attachments = make([]entities.LetterOutgoingAttachment, len(req.Attachments))
@@ -86,16 +112,57 @@ func (s *LetterOutgoingServiceImpl) CreateOutgoingLetter(ctx context.Context, re
FileURL: a.FileURL,
FileName: a.FileName,
FileType: a.FileType,
UploadedBy: &req.UserID,
UploadedBy: &userID,
}
}
}
err := s.processor.CreateOutgoingLetter(ctx, letter, attachments, req.UserID, departmentID)
// Execute creation with transaction in service layer
err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
// Step 1: Validate letter
if err := s.validationProcessor.ValidateCreateOutgoingLetter(txCtx, letter); err != nil {
return err
}
// Step 2: Prepare letter for creation (assign approval flow, set initial status)
if err := s.creationProcessor.PrepareLetterForCreation(txCtx, letter, departmentID); err != nil {
return err
}
// Step 3: Generate letter number
if err := s.creationProcessor.GenerateLetterNumber(txCtx, letter); err != nil {
return err
}
// Step 4: Create the letter
if err := s.creationProcessor.CreateLetter(txCtx, letter); err != nil {
return err
}
// Step 5: Create approval steps if needed
if err := s.approvalProcessor.CreateApprovalSteps(txCtx, letter); err != nil {
return err
}
// Step 6: Create initial recipients (approval workflow users + department members)
if err := s.recipientProcessor.CreateInitialRecipients(txCtx, letter, departmentID); err != nil {
return err
}
// Step 7: Create attachments
if err := s.attachmentProcessor.CreateAttachments(txCtx, letter.ID, attachments); err != nil {
return err
}
// Step 8: Log the activity
return s.activityProcessor.LogActivity(txCtx, letter.ID, entities.LetterOutgoingActionCreated, userID, nil)
})
if err != nil {
return nil, err
}
// Get the created letter with all relationships
result, err := s.processor.GetOutgoingLetterByID(ctx, letter.ID)
if err != nil {
return nil, err