This commit is contained in:
Aditya Siregar
2025-08-19 16:11:32 +07:00
parent f41daa63da
commit 7d5f061a1b
6 changed files with 294 additions and 217 deletions
+201 -127
View File
@@ -18,36 +18,36 @@ type LetterOutgoingService interface {
ListOutgoingLetters(ctx context.Context, req *contract.ListOutgoingLettersRequest) (*contract.ListOutgoingLettersResponse, error)
UpdateOutgoingLetter(ctx context.Context, id uuid.UUID, req *contract.UpdateOutgoingLetterRequest) (*contract.OutgoingLetterResponse, error)
DeleteOutgoingLetter(ctx context.Context, id uuid.UUID) error
SubmitForApproval(ctx context.Context, letterID uuid.UUID) error
ApproveOutgoingLetter(ctx context.Context, letterID uuid.UUID, req *contract.ApproveLetterRequest) error
RejectOutgoingLetter(ctx context.Context, letterID uuid.UUID, req *contract.RejectLetterRequest) error
SendOutgoingLetter(ctx context.Context, letterID uuid.UUID) error
ArchiveOutgoingLetter(ctx context.Context, letterID uuid.UUID) error
AddRecipients(ctx context.Context, letterID uuid.UUID, req *contract.AddRecipientsRequest) error
UpdateRecipient(ctx context.Context, letterID uuid.UUID, recipientID uuid.UUID, req *contract.UpdateRecipientRequest) error
RemoveRecipient(ctx context.Context, letterID uuid.UUID, recipientID uuid.UUID) error
AddAttachments(ctx context.Context, letterID uuid.UUID, req *contract.AddAttachmentsRequest) error
RemoveAttachment(ctx context.Context, letterID uuid.UUID, attachmentID uuid.UUID) error
CreateDiscussion(ctx context.Context, letterID uuid.UUID, req *contract.CreateDiscussionRequest) (*contract.DiscussionResponse, error)
UpdateDiscussion(ctx context.Context, discussionID uuid.UUID, req *contract.UpdateDiscussionRequest) error
DeleteDiscussion(ctx context.Context, discussionID uuid.UUID) error
}
type LetterOutgoingServiceImpl struct {
db *gorm.DB
letterRepo *repository.LetterOutgoingRepository
attachmentRepo *repository.LetterOutgoingAttachmentRepository
recipientRepo *repository.LetterOutgoingRecipientRepository
discussionRepo *repository.LetterOutgoingDiscussionRepository
discussionAttachmentRepo *repository.LetterOutgoingDiscussionAttachmentRepository
activityLogRepo *repository.LetterOutgoingActivityLogRepository
approvalFlowRepo *repository.ApprovalFlowRepository
approvalRepo *repository.LetterOutgoingApprovalRepository
txManager *repository.TxManager
db *gorm.DB
letterRepo *repository.LetterOutgoingRepository
attachmentRepo *repository.LetterOutgoingAttachmentRepository
recipientRepo *repository.LetterOutgoingRecipientRepository
discussionRepo *repository.LetterOutgoingDiscussionRepository
discussionAttachmentRepo *repository.LetterOutgoingDiscussionAttachmentRepository
activityLogRepo *repository.LetterOutgoingActivityLogRepository
approvalFlowRepo *repository.ApprovalFlowRepository
approvalRepo *repository.LetterOutgoingApprovalRepository
txManager *repository.TxManager
}
func NewLetterOutgoingService(
@@ -77,8 +77,6 @@ func NewLetterOutgoingService(
}
func (s *LetterOutgoingServiceImpl) CreateOutgoingLetter(ctx context.Context, req *contract.CreateOutgoingLetterRequest) (*contract.OutgoingLetterResponse, error) {
userID := getUserIDFromContext(ctx)
letter := &entities.LetterOutgoing{
Subject: req.Subject,
Description: req.Description,
@@ -87,18 +85,18 @@ func (s *LetterOutgoingServiceImpl) CreateOutgoingLetter(ctx context.Context, re
IssueDate: req.IssueDate,
Status: entities.LetterOutgoingStatusDraft,
ApprovalFlowID: req.ApprovalFlowID,
CreatedBy: userID,
CreatedBy: req.UserID,
}
if req.ReferenceNumber != nil {
letter.ReferenceNumber = req.ReferenceNumber
}
err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.letterRepo.Create(txCtx, letter); err != nil {
return err
}
if len(req.Recipients) > 0 {
recipients := make([]entities.LetterOutgoingRecipient, len(req.Recipients))
for i, r := range req.Recipients {
@@ -115,7 +113,7 @@ func (s *LetterOutgoingServiceImpl) CreateOutgoingLetter(ctx context.Context, re
return err
}
}
if len(req.Attachments) > 0 {
attachments := make([]entities.LetterOutgoingAttachment, len(req.Attachments))
for i, a := range req.Attachments {
@@ -124,35 +122,35 @@ func (s *LetterOutgoingServiceImpl) CreateOutgoingLetter(ctx context.Context, re
FileURL: a.FileURL,
FileName: a.FileName,
FileType: a.FileType,
UploadedBy: &userID,
UploadedBy: &req.UserID,
}
}
if err := s.attachmentRepo.CreateBulk(txCtx, attachments); err != nil {
return err
}
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letter.ID,
ActionType: entities.LetterOutgoingActionCreated,
ActorUserID: &userID,
ActorUserID: &req.UserID,
}
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
result, err := s.letterRepo.Get(ctx, letter.ID)
if err != nil {
return nil, err
}
return transformLetterToResponse(result), nil
}
@@ -161,7 +159,7 @@ func (s *LetterOutgoingServiceImpl) GetOutgoingLetterByID(ctx context.Context, i
if err != nil {
return nil, err
}
return transformLetterToResponse(letter), nil
}
@@ -174,17 +172,17 @@ func (s *LetterOutgoingServiceImpl) ListOutgoingLetters(ctx context.Context, req
FromDate: req.FromDate,
ToDate: req.ToDate,
}
letters, total, err := s.letterRepo.List(ctx, filter, req.Limit, req.Offset)
if err != nil {
return nil, err
}
items := make([]*contract.OutgoingLetterResponse, len(letters))
for i, letter := range letters {
items[i] = transformLetterToResponse(&letter)
}
return &contract.ListOutgoingLettersResponse{
Items: items,
Total: total,
@@ -193,16 +191,16 @@ func (s *LetterOutgoingServiceImpl) ListOutgoingLetters(ctx context.Context, req
func (s *LetterOutgoingServiceImpl) UpdateOutgoingLetter(ctx context.Context, id uuid.UUID, req *contract.UpdateOutgoingLetterRequest) (*contract.OutgoingLetterResponse, error) {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, id)
if err != nil {
return nil, err
}
if letter.Status != entities.LetterOutgoingStatusDraft {
return nil, gorm.ErrInvalidData
}
if req.Subject != nil {
letter.Subject = *req.Subject
}
@@ -221,12 +219,12 @@ func (s *LetterOutgoingServiceImpl) UpdateOutgoingLetter(ctx context.Context, id
if req.ReferenceNumber != nil {
letter.ReferenceNumber = req.ReferenceNumber
}
err = s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.letterRepo.Update(txCtx, letter); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letter.ID,
ActionType: entities.LetterOutgoingActionUpdated,
@@ -235,39 +233,39 @@ func (s *LetterOutgoingServiceImpl) UpdateOutgoingLetter(ctx context.Context, id
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
result, err := s.letterRepo.Get(ctx, id)
if err != nil {
return nil, err
}
return transformLetterToResponse(result), nil
}
func (s *LetterOutgoingServiceImpl) DeleteOutgoingLetter(ctx context.Context, id uuid.UUID) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, id)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusDraft {
return gorm.ErrInvalidData
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.letterRepo.SoftDelete(txCtx, id); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letter.ID,
ActionType: entities.LetterOutgoingActionDeleted,
@@ -276,32 +274,32 @@ func (s *LetterOutgoingServiceImpl) DeleteOutgoingLetter(ctx context.Context, id
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
func (s *LetterOutgoingServiceImpl) SubmitForApproval(ctx context.Context, letterID uuid.UUID) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, letterID)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusDraft {
return gorm.ErrInvalidData
}
if letter.ApprovalFlowID == nil {
return gorm.ErrInvalidData
}
flow, err := s.approvalFlowRepo.Get(ctx, *letter.ApprovalFlowID)
if err != nil {
return err
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
approvals := make([]entities.LetterOutgoingApproval, len(flow.Steps))
for i, step := range flow.Steps {
@@ -311,15 +309,15 @@ func (s *LetterOutgoingServiceImpl) SubmitForApproval(ctx context.Context, lette
Status: entities.ApprovalStatusPending,
}
}
if err := s.approvalRepo.CreateBulk(txCtx, approvals); err != nil {
return err
}
if err := s.letterRepo.UpdateStatus(txCtx, letterID, entities.LetterOutgoingStatusPendingApproval); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionSubmittedApproval,
@@ -330,28 +328,28 @@ func (s *LetterOutgoingServiceImpl) SubmitForApproval(ctx context.Context, lette
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
func (s *LetterOutgoingServiceImpl) ApproveOutgoingLetter(ctx context.Context, letterID uuid.UUID, req *contract.ApproveLetterRequest) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, letterID)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusPendingApproval {
return gorm.ErrInvalidData
}
approvals, err := s.approvalRepo.ListByLetter(ctx, letterID)
if err != nil {
return err
}
var currentApproval *entities.LetterOutgoingApproval
for i := range approvals {
if approvals[i].Status == entities.ApprovalStatusPending {
@@ -363,22 +361,22 @@ func (s *LetterOutgoingServiceImpl) ApproveOutgoingLetter(ctx context.Context, l
}
}
}
if currentApproval == nil {
return gorm.ErrInvalidData
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
now := time.Now()
currentApproval.Status = entities.ApprovalStatusApproved
currentApproval.ApproverID = &userID
currentApproval.ActedAt = &now
currentApproval.Remarks = req.Remarks
if err := s.approvalRepo.Update(txCtx, currentApproval); err != nil {
return err
}
allApproved := true
for _, approval := range approvals {
if approval.ID != currentApproval.ID && approval.Status == entities.ApprovalStatusPending {
@@ -386,13 +384,13 @@ func (s *LetterOutgoingServiceImpl) ApproveOutgoingLetter(ctx context.Context, l
break
}
}
if allApproved {
if err := s.letterRepo.UpdateStatus(txCtx, letterID, entities.LetterOutgoingStatusApproved); err != nil {
return err
}
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionApproved,
@@ -402,28 +400,28 @@ func (s *LetterOutgoingServiceImpl) ApproveOutgoingLetter(ctx context.Context, l
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
func (s *LetterOutgoingServiceImpl) RejectOutgoingLetter(ctx context.Context, letterID uuid.UUID, req *contract.RejectLetterRequest) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, letterID)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusPendingApproval {
return gorm.ErrInvalidData
}
approvals, err := s.approvalRepo.ListByLetter(ctx, letterID)
if err != nil {
return err
}
var currentApproval *entities.LetterOutgoingApproval
for i := range approvals {
if approvals[i].Status == entities.ApprovalStatusPending {
@@ -435,26 +433,26 @@ func (s *LetterOutgoingServiceImpl) RejectOutgoingLetter(ctx context.Context, le
}
}
}
if currentApproval == nil {
return gorm.ErrInvalidData
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
now := time.Now()
currentApproval.Status = entities.ApprovalStatusRejected
currentApproval.ApproverID = &userID
currentApproval.ActedAt = &now
currentApproval.Remarks = &req.Reason
if err := s.approvalRepo.Update(txCtx, currentApproval); err != nil {
return err
}
if err := s.letterRepo.UpdateStatus(txCtx, letterID, entities.LetterOutgoingStatusDraft); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionRejected,
@@ -466,28 +464,28 @@ func (s *LetterOutgoingServiceImpl) RejectOutgoingLetter(ctx context.Context, le
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
func (s *LetterOutgoingServiceImpl) SendOutgoingLetter(ctx context.Context, letterID uuid.UUID) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, letterID)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusApproved {
return gorm.ErrInvalidData
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.letterRepo.UpdateStatus(txCtx, letterID, entities.LetterOutgoingStatusSent); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionSent,
@@ -498,28 +496,28 @@ func (s *LetterOutgoingServiceImpl) SendOutgoingLetter(ctx context.Context, lett
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
func (s *LetterOutgoingServiceImpl) ArchiveOutgoingLetter(ctx context.Context, letterID uuid.UUID) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, letterID)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusSent {
return gorm.ErrInvalidData
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.letterRepo.UpdateStatus(txCtx, letterID, entities.LetterOutgoingStatusArchived); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionArchived,
@@ -530,23 +528,23 @@ func (s *LetterOutgoingServiceImpl) ArchiveOutgoingLetter(ctx context.Context, l
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
func (s *LetterOutgoingServiceImpl) AddRecipients(ctx context.Context, letterID uuid.UUID, req *contract.AddRecipientsRequest) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, letterID)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusDraft {
return gorm.ErrInvalidData
}
recipients := make([]entities.LetterOutgoingRecipient, len(req.Recipients))
for i, r := range req.Recipients {
recipients[i] = entities.LetterOutgoingRecipient{
@@ -558,12 +556,12 @@ func (s *LetterOutgoingServiceImpl) AddRecipients(ctx context.Context, letterID
IsPrimary: r.IsPrimary,
}
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.recipientRepo.CreateBulk(txCtx, recipients); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionRecipientAdded,
@@ -572,7 +570,7 @@ func (s *LetterOutgoingServiceImpl) AddRecipients(ctx context.Context, letterID
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
@@ -582,11 +580,11 @@ func (s *LetterOutgoingServiceImpl) UpdateRecipient(ctx context.Context, letterI
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusDraft {
return gorm.ErrInvalidData
}
recipient := &entities.LetterOutgoingRecipient{
ID: recipientID,
RecipientName: req.Name,
@@ -595,27 +593,27 @@ func (s *LetterOutgoingServiceImpl) UpdateRecipient(ctx context.Context, letterI
RecipientInstitution: req.Institution,
IsPrimary: req.IsPrimary,
}
return s.recipientRepo.Update(ctx, recipient)
}
func (s *LetterOutgoingServiceImpl) RemoveRecipient(ctx context.Context, letterID uuid.UUID, recipientID uuid.UUID) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, letterID)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusDraft {
return gorm.ErrInvalidData
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.recipientRepo.Delete(txCtx, recipientID); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionRecipientRemoved,
@@ -625,23 +623,23 @@ func (s *LetterOutgoingServiceImpl) RemoveRecipient(ctx context.Context, letterI
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
func (s *LetterOutgoingServiceImpl) AddAttachments(ctx context.Context, letterID uuid.UUID, req *contract.AddAttachmentsRequest) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, letterID)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusDraft {
return gorm.ErrInvalidData
}
attachments := make([]entities.LetterOutgoingAttachment, len(req.Attachments))
for i, a := range req.Attachments {
attachments[i] = entities.LetterOutgoingAttachment{
@@ -652,12 +650,12 @@ func (s *LetterOutgoingServiceImpl) AddAttachments(ctx context.Context, letterID
UploadedBy: &userID,
}
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.attachmentRepo.CreateBulk(txCtx, attachments); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionAttachmentAdded,
@@ -666,28 +664,28 @@ func (s *LetterOutgoingServiceImpl) AddAttachments(ctx context.Context, letterID
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
func (s *LetterOutgoingServiceImpl) RemoveAttachment(ctx context.Context, letterID uuid.UUID, attachmentID uuid.UUID) error {
userID := getUserIDFromContext(ctx)
letter, err := s.letterRepo.Get(ctx, letterID)
if err != nil {
return err
}
if letter.Status != entities.LetterOutgoingStatusDraft {
return gorm.ErrInvalidData
}
return s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.attachmentRepo.Delete(txCtx, attachmentID); err != nil {
return err
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionAttachmentRemoved,
@@ -697,30 +695,30 @@ func (s *LetterOutgoingServiceImpl) RemoveAttachment(ctx context.Context, letter
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
}
func (s *LetterOutgoingServiceImpl) CreateDiscussion(ctx context.Context, letterID uuid.UUID, req *contract.CreateDiscussionRequest) (*contract.DiscussionResponse, error) {
userID := getUserIDFromContext(ctx)
discussion := &entities.LetterOutgoingDiscussion{
LetterID: letterID,
ParentID: req.ParentID,
UserID: userID,
Message: req.Message,
}
if req.Mentions != nil {
discussion.Mentions = req.Mentions
}
err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
if err := s.discussionRepo.Create(txCtx, discussion); err != nil {
return err
}
if len(req.Attachments) > 0 {
attachments := make([]entities.LetterOutgoingDiscussionAttachment, len(req.Attachments))
for i, a := range req.Attachments {
@@ -736,7 +734,7 @@ func (s *LetterOutgoingServiceImpl) CreateDiscussion(ctx context.Context, letter
return err
}
}
activityLog := &entities.LetterOutgoingActivityLog{
LetterID: letterID,
ActionType: entities.LetterOutgoingActionDiscussionAdded,
@@ -746,19 +744,19 @@ func (s *LetterOutgoingServiceImpl) CreateDiscussion(ctx context.Context, letter
if err := s.activityLogRepo.Create(txCtx, activityLog); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
result, err := s.discussionRepo.Get(ctx, discussion.ID)
if err != nil {
return nil, err
}
return transformDiscussionToResponse(result), nil
}
@@ -767,17 +765,17 @@ func (s *LetterOutgoingServiceImpl) UpdateDiscussion(ctx context.Context, discus
if err != nil {
return err
}
userID := getUserIDFromContext(ctx)
if discussion.UserID != userID {
return gorm.ErrInvalidData
}
discussion.Message = req.Message
if req.Mentions != nil {
discussion.Mentions = req.Mentions
}
return s.discussionRepo.Update(ctx, discussion)
}
@@ -786,12 +784,12 @@ func (s *LetterOutgoingServiceImpl) DeleteDiscussion(ctx context.Context, discus
if err != nil {
return err
}
userID := getUserIDFromContext(ctx)
if discussion.UserID != userID {
return gorm.ErrInvalidData
}
return s.discussionRepo.Delete(ctx, discussionID)
}
@@ -808,7 +806,7 @@ func ptr(s string) *string {
}
func transformLetterToResponse(letter *entities.LetterOutgoing) *contract.OutgoingLetterResponse {
return &contract.OutgoingLetterResponse{
resp := &contract.OutgoingLetterResponse{
ID: letter.ID,
LetterNumber: letter.LetterNumber,
ReferenceNumber: letter.ReferenceNumber,
@@ -823,6 +821,82 @@ func transformLetterToResponse(letter *entities.LetterOutgoing) *contract.Outgoi
CreatedAt: letter.CreatedAt,
UpdatedAt: letter.UpdatedAt,
}
if letter.Priority != nil {
resp.Priority = &contract.PriorityResponse{
ID: letter.Priority.ID.String(),
Name: letter.Priority.Name,
Level: letter.Priority.Level,
CreatedAt: letter.Priority.CreatedAt,
UpdatedAt: letter.Priority.UpdatedAt,
}
}
if letter.ReceiverInstitution != nil {
resp.ReceiverInstitution = &contract.InstitutionResponse{
ID: letter.ReceiverInstitution.ID.String(),
Name: letter.ReceiverInstitution.Name,
Type: string(letter.ReceiverInstitution.Type),
Address: letter.ReceiverInstitution.Address,
ContactPerson: letter.ReceiverInstitution.ContactPerson,
Phone: letter.ReceiverInstitution.Phone,
Email: letter.ReceiverInstitution.Email,
CreatedAt: letter.ReceiverInstitution.CreatedAt,
UpdatedAt: letter.ReceiverInstitution.UpdatedAt,
}
}
if len(letter.Recipients) > 0 {
resp.Recipients = make([]contract.OutgoingLetterRecipientResponse, len(letter.Recipients))
for i, recipient := range letter.Recipients {
resp.Recipients[i] = contract.OutgoingLetterRecipientResponse{
ID: recipient.ID,
Name: recipient.RecipientName,
Email: recipient.RecipientEmail,
Position: recipient.RecipientPosition,
Institution: recipient.RecipientInstitution,
IsPrimary: recipient.IsPrimary,
CreatedAt: recipient.CreatedAt,
}
}
}
if len(letter.Attachments) > 0 {
resp.Attachments = make([]contract.OutgoingLetterAttachmentResponse, len(letter.Attachments))
for i, attachment := range letter.Attachments {
resp.Attachments[i] = contract.OutgoingLetterAttachmentResponse{
ID: attachment.ID,
FileURL: attachment.FileURL,
FileName: attachment.FileName,
FileType: attachment.FileType,
UploadedAt: attachment.UploadedAt,
}
}
}
// Include Approvals if loaded
if len(letter.Approvals) > 0 {
resp.Approvals = make([]contract.OutgoingLetterApprovalResponse, len(letter.Approvals))
for i, approval := range letter.Approvals {
approvalResp := contract.OutgoingLetterApprovalResponse{
ID: approval.ID,
ApproverID: approval.ApproverID,
Status: string(approval.Status),
Remarks: approval.Remarks,
ActedAt: approval.ActedAt,
CreatedAt: approval.CreatedAt,
}
// Include step order if step is loaded
if approval.Step != nil {
approvalResp.StepOrder = approval.Step.StepOrder
}
resp.Approvals[i] = approvalResp
}
}
return resp
}
func transformDiscussionToResponse(discussion *entities.LetterOutgoingDiscussion) *contract.DiscussionResponse {
@@ -833,4 +907,4 @@ func transformDiscussionToResponse(discussion *entities.LetterOutgoingDiscussion
CreatedAt: discussion.CreatedAt,
UpdatedAt: discussion.UpdatedAt,
}
}
}