update api incoming letter
This commit is contained in:
parent
58128495a6
commit
92440953cb
@ -7,19 +7,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type SearchIncomingLettersRequest struct {
|
type SearchIncomingLettersRequest struct {
|
||||||
Query string `json:"query" form:"query"`
|
Query string `json:"query" form:"query"`
|
||||||
LetterNumber string `json:"letter_number" form:"letter_number"`
|
LetterNumber string `json:"letter_number" form:"letter_number"`
|
||||||
Subject string `json:"subject" form:"subject"`
|
Subject string `json:"subject" form:"subject"`
|
||||||
Status string `json:"status" form:"status"`
|
Status string `json:"status" form:"status"`
|
||||||
PriorityID *uuid.UUID `json:"priority_id" form:"priority_id"`
|
PriorityID *uuid.UUID `json:"priority_id" form:"priority_id"`
|
||||||
InstitutionID *uuid.UUID `json:"institution_id" form:"institution_id"`
|
InstitutionID *uuid.UUID `json:"institution_id" form:"institution_id"`
|
||||||
CreatedBy *uuid.UUID `json:"created_by" form:"created_by"`
|
CreatedBy *uuid.UUID `json:"created_by" form:"created_by"`
|
||||||
DateFrom *time.Time `json:"date_from" form:"date_from"`
|
DateFrom *time.Time `json:"date_from" form:"date_from"`
|
||||||
DateTo *time.Time `json:"date_to" form:"date_to"`
|
DateTo *time.Time `json:"date_to" form:"date_to"`
|
||||||
Page int `json:"page" form:"page"`
|
Page int `json:"page" form:"page"`
|
||||||
Limit int `json:"limit" form:"limit"`
|
Limit int `json:"limit" form:"limit"`
|
||||||
SortBy string `json:"sort_by" form:"sort_by"`
|
SortBy string `json:"sort_by" form:"sort_by"`
|
||||||
SortOrder string `json:"sort_order" form:"sort_order"`
|
SortOrder string `json:"sort_order" form:"sort_order"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchIncomingLettersResponse struct {
|
type SearchIncomingLettersResponse struct {
|
||||||
@ -77,6 +77,7 @@ type IncomingLetterResponse struct {
|
|||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
Attachments []IncomingLetterAttachmentResponse `json:"attachments"`
|
Attachments []IncomingLetterAttachmentResponse `json:"attachments"`
|
||||||
IsRead bool `json:"is_read"`
|
IsRead bool `json:"is_read"`
|
||||||
|
Dispositions []EnhancedDispositionResponse `json:"dispositions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateIncomingLetterRequest struct {
|
type UpdateIncomingLetterRequest struct {
|
||||||
|
|||||||
@ -101,6 +101,7 @@ func (p *LetterProcessorImpl) GetIncomingLetterByID(ctx context.Context, id uuid
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
atts, _ := p.attachRepo.ListByLetter(ctx, id)
|
atts, _ := p.attachRepo.ListByLetter(ctx, id)
|
||||||
|
dispo, _ := p.dispositionRepo.ListByLetter(ctx, id)
|
||||||
var pr *entities.Priority
|
var pr *entities.Priority
|
||||||
if entity.PriorityID != nil && p.priorityRepo != nil {
|
if entity.PriorityID != nil && p.priorityRepo != nil {
|
||||||
if got, err := p.priorityRepo.Get(ctx, *entity.PriorityID); err == nil {
|
if got, err := p.priorityRepo.Get(ctx, *entity.PriorityID); err == nil {
|
||||||
@ -119,10 +120,11 @@ func (p *LetterProcessorImpl) GetIncomingLetterByID(ctx context.Context, id uuid
|
|||||||
if p.recipientRepo != nil {
|
if p.recipientRepo != nil {
|
||||||
if recipient, err := p.recipientRepo.GetByLetterAndUser(ctx, id, userID); err == nil {
|
if recipient, err := p.recipientRepo.GetByLetterAndUser(ctx, id, userID); err == nil {
|
||||||
isRead = recipient.ReadAt != nil
|
isRead = recipient.ReadAt != nil
|
||||||
|
fmt.Printf("Recipient: %+v\n", recipient)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := transformer.LetterEntityToContract(entity, atts, pr, inst)
|
resp := transformer.LetterEntityToContract(entity, atts, dispo, pr, inst)
|
||||||
resp.IsRead = isRead
|
resp.IsRead = isRead
|
||||||
|
|
||||||
// Include created_by if the current user is the creator
|
// Include created_by if the current user is the creator
|
||||||
@ -209,6 +211,13 @@ func (p *LetterProcessorImpl) GetBatchAttachments(ctx context.Context, letterIDs
|
|||||||
return p.attachRepo.ListByLetterIDs(ctx, letterIDs)
|
return p.attachRepo.ListByLetterIDs(ctx, letterIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *LetterProcessorImpl) GetBatchDispositions(ctx context.Context, letterIDs []uuid.UUID) (map[uuid.UUID][]entities.LetterIncomingDisposition, error) {
|
||||||
|
if p.dispositionRepo == nil || len(letterIDs) == 0 {
|
||||||
|
return make(map[uuid.UUID][]entities.LetterIncomingDisposition), nil
|
||||||
|
}
|
||||||
|
return p.dispositionRepo.ListByLetterIDs(ctx, letterIDs)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *LetterProcessorImpl) GetBatchPriorities(ctx context.Context, priorityIDs []uuid.UUID) (map[uuid.UUID]*entities.Priority, error) {
|
func (p *LetterProcessorImpl) GetBatchPriorities(ctx context.Context, priorityIDs []uuid.UUID) (map[uuid.UUID]*entities.Priority, error) {
|
||||||
if p.priorityRepo == nil || len(priorityIDs) == 0 {
|
if p.priorityRepo == nil || len(priorityIDs) == 0 {
|
||||||
return make(map[uuid.UUID]*entities.Priority), nil
|
return make(map[uuid.UUID]*entities.Priority), nil
|
||||||
@ -290,6 +299,7 @@ func (p *LetterProcessorImpl) UpdateIncomingLetter(ctx context.Context, id uuid.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
atts, _ := p.attachRepo.ListByLetter(txCtx, id)
|
atts, _ := p.attachRepo.ListByLetter(txCtx, id)
|
||||||
|
dispo, _ := p.dispositionRepo.ListByLetter(txCtx, id)
|
||||||
var pr *entities.Priority
|
var pr *entities.Priority
|
||||||
if entity.PriorityID != nil && p.priorityRepo != nil {
|
if entity.PriorityID != nil && p.priorityRepo != nil {
|
||||||
if got, err := p.priorityRepo.Get(txCtx, *entity.PriorityID); err == nil {
|
if got, err := p.priorityRepo.Get(txCtx, *entity.PriorityID); err == nil {
|
||||||
@ -302,7 +312,7 @@ func (p *LetterProcessorImpl) UpdateIncomingLetter(ctx context.Context, id uuid.
|
|||||||
inst = got
|
inst = got
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out = transformer.LetterEntityToContract(entity, atts, pr, inst)
|
out = transformer.LetterEntityToContract(entity, atts, dispo, pr, inst)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -601,6 +611,7 @@ func (p *LetterProcessorImpl) SearchIncomingLetters(ctx context.Context, filters
|
|||||||
|
|
||||||
func (p *LetterProcessorImpl) buildLetterResponse(ctx context.Context, entity *entities.LetterIncoming) (*contract.IncomingLetterResponse, error) {
|
func (p *LetterProcessorImpl) buildLetterResponse(ctx context.Context, entity *entities.LetterIncoming) (*contract.IncomingLetterResponse, error) {
|
||||||
savedAttachments, _ := p.attachRepo.ListByLetter(ctx, entity.ID)
|
savedAttachments, _ := p.attachRepo.ListByLetter(ctx, entity.ID)
|
||||||
|
dispo, _ := p.dispositionRepo.ListByLetter(ctx, entity.ID)
|
||||||
|
|
||||||
var pr *entities.Priority
|
var pr *entities.Priority
|
||||||
if entity.PriorityID != nil && p.priorityRepo != nil {
|
if entity.PriorityID != nil && p.priorityRepo != nil {
|
||||||
@ -616,7 +627,7 @@ func (p *LetterProcessorImpl) buildLetterResponse(ctx context.Context, entity *e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return transformer.LetterEntityToContract(entity, savedAttachments, pr, inst), nil
|
return transformer.LetterEntityToContract(entity, savedAttachments, dispo, pr, inst), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *LetterProcessorImpl) BulkArchiveIncomingLetters(ctx context.Context, letterIDs []uuid.UUID) (int64, error) {
|
func (p *LetterProcessorImpl) BulkArchiveIncomingLetters(ctx context.Context, letterIDs []uuid.UUID) (int64, error) {
|
||||||
|
|||||||
@ -463,6 +463,33 @@ func (r *LetterIncomingDispositionRepository) ListByLetter(ctx context.Context,
|
|||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *LetterIncomingDispositionRepository) ListByLetterIDs(ctx context.Context, letterIDs []uuid.UUID) (map[uuid.UUID][]entities.LetterIncomingDisposition, error) {
|
||||||
|
if len(letterIDs) == 0 {
|
||||||
|
return make(map[uuid.UUID][]entities.LetterIncomingDisposition), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
db := DBFromContext(ctx, r.db)
|
||||||
|
var dispositions []entities.LetterIncomingDisposition
|
||||||
|
if err := db.WithContext(ctx).Where("letter_id IN ?", letterIDs).
|
||||||
|
Preload("Department").
|
||||||
|
Preload("Departments.Department").
|
||||||
|
Preload("ActionSelections.Action").
|
||||||
|
Preload("DispositionNotes.User").
|
||||||
|
Order("created_at ASC").
|
||||||
|
Find(&dispositions).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group by letter ID
|
||||||
|
result := make(map[uuid.UUID][]entities.LetterIncomingDisposition)
|
||||||
|
for i := range dispositions { // Gunakan index, bukan value
|
||||||
|
letterID := dispositions[i].LetterID
|
||||||
|
result[letterID] = append(result[letterID], dispositions[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *LetterIncomingDispositionRepository) GetByLetterIncomingID(ctx context.Context, letterIncomingID uuid.UUID) ([]entities.LetterIncomingDisposition, error) {
|
func (r *LetterIncomingDispositionRepository) GetByLetterIncomingID(ctx context.Context, letterIncomingID uuid.UUID) ([]entities.LetterIncomingDisposition, error) {
|
||||||
db := DBFromContext(ctx, r.db)
|
db := DBFromContext(ctx, r.db)
|
||||||
var list []entities.LetterIncomingDisposition
|
var list []entities.LetterIncomingDisposition
|
||||||
|
|||||||
@ -37,6 +37,7 @@ type LetterProcessor interface {
|
|||||||
|
|
||||||
// Batch loading methods
|
// Batch loading methods
|
||||||
GetBatchAttachments(ctx context.Context, letterIDs []uuid.UUID) (map[uuid.UUID][]entities.LetterIncomingAttachment, error)
|
GetBatchAttachments(ctx context.Context, letterIDs []uuid.UUID) (map[uuid.UUID][]entities.LetterIncomingAttachment, error)
|
||||||
|
GetBatchDispositions(ctx context.Context, letterIDs []uuid.UUID) (map[uuid.UUID][]entities.LetterIncomingDisposition, error)
|
||||||
GetBatchPriorities(ctx context.Context, priorityIDs []uuid.UUID) (map[uuid.UUID]*entities.Priority, error)
|
GetBatchPriorities(ctx context.Context, priorityIDs []uuid.UUID) (map[uuid.UUID]*entities.Priority, error)
|
||||||
GetBatchInstitutions(ctx context.Context, institutionIDs []uuid.UUID) (map[uuid.UUID]*entities.Institution, error)
|
GetBatchInstitutions(ctx context.Context, institutionIDs []uuid.UUID) (map[uuid.UUID]*entities.Institution, error)
|
||||||
GetBatchRecipientsByUser(ctx context.Context, letterIDs []uuid.UUID, userID uuid.UUID) (map[uuid.UUID]*entities.LetterIncomingRecipient, error)
|
GetBatchRecipientsByUser(ctx context.Context, letterIDs []uuid.UUID, userID uuid.UUID) (map[uuid.UUID]*entities.LetterIncomingRecipient, error)
|
||||||
@ -347,6 +348,7 @@ func (s *LetterServiceImpl) ListIncomingLetters(ctx context.Context, req *contra
|
|||||||
priorities map[uuid.UUID]*entities.Priority
|
priorities map[uuid.UUID]*entities.Priority
|
||||||
institutions map[uuid.UUID]*entities.Institution
|
institutions map[uuid.UUID]*entities.Institution
|
||||||
recipients map[uuid.UUID]*entities.LetterIncomingRecipient
|
recipients map[uuid.UUID]*entities.LetterIncomingRecipient
|
||||||
|
dispostions map[uuid.UUID][]entities.LetterIncomingDisposition
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,9 +360,10 @@ func (s *LetterServiceImpl) ListIncomingLetters(ctx context.Context, req *contra
|
|||||||
priorities: make(map[uuid.UUID]*entities.Priority),
|
priorities: make(map[uuid.UUID]*entities.Priority),
|
||||||
institutions: make(map[uuid.UUID]*entities.Institution),
|
institutions: make(map[uuid.UUID]*entities.Institution),
|
||||||
recipients: make(map[uuid.UUID]*entities.LetterIncomingRecipient),
|
recipients: make(map[uuid.UUID]*entities.LetterIncomingRecipient),
|
||||||
|
dispostions: make(map[uuid.UUID][]entities.LetterIncomingDisposition),
|
||||||
}
|
}
|
||||||
|
|
||||||
errChan := make(chan error, 4)
|
errChan := make(chan error, 5)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
var err error
|
var err error
|
||||||
@ -386,7 +389,13 @@ func (s *LetterServiceImpl) ListIncomingLetters(ctx context.Context, req *contra
|
|||||||
errChan <- err
|
errChan <- err
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for i := 0; i < 4; i++ {
|
go func() {
|
||||||
|
var err error
|
||||||
|
result.dispostions, err = s.processor.GetBatchDispositions(ctx, letterIDs)
|
||||||
|
errChan <- err
|
||||||
|
}()
|
||||||
|
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
if err := <-errChan; err != nil {
|
if err := <-errChan; err != nil {
|
||||||
// Batch load error, continue anyway
|
// Batch load error, continue anyway
|
||||||
}
|
}
|
||||||
@ -414,12 +423,17 @@ func (s *LetterServiceImpl) ListIncomingLetters(ctx context.Context, req *contra
|
|||||||
institution = batchData.institutions[*letter.SenderInstitutionID]
|
institution = batchData.institutions[*letter.SenderInstitutionID]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispositions := batchData.dispostions[letter.ID]
|
||||||
|
if dispositions == nil {
|
||||||
|
dispositions = []entities.LetterIncomingDisposition{}
|
||||||
|
}
|
||||||
|
|
||||||
isRead := false
|
isRead := false
|
||||||
if recipient, exists := batchData.recipients[letter.ID]; exists && recipient != nil {
|
if recipient, exists := batchData.recipients[letter.ID]; exists && recipient != nil {
|
||||||
isRead = recipient.ReadAt != nil
|
isRead = recipient.ReadAt != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := transformer.LetterEntityToContract(&letter, attachments, priority, institution)
|
resp := transformer.LetterEntityToContract(&letter, attachments, dispositions, priority, institution)
|
||||||
resp.IsRead = isRead
|
resp.IsRead = isRead
|
||||||
respList = append(respList, *resp)
|
respList = append(respList, *resp)
|
||||||
}
|
}
|
||||||
@ -697,7 +711,7 @@ func (s *LetterServiceImpl) CreateDispositions(ctx context.Context, req *contrac
|
|||||||
if len(recipients) > 0 {
|
if len(recipients) > 0 {
|
||||||
go s.sendDispositionNotifications(context.Background(), req.LetterID, recipients)
|
go s.sendDispositionNotifications(context.Background(), req.LetterID, recipients)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send notification to letter creator about new disposition
|
// Send notification to letter creator about new disposition
|
||||||
go s.sendDispositionCreatorNotification(context.Background(), req.LetterID, userID)
|
go s.sendDispositionCreatorNotification(context.Background(), req.LetterID, userID)
|
||||||
}
|
}
|
||||||
@ -711,7 +725,7 @@ func (s *LetterServiceImpl) GetEnhancedDispositionsByLetter(ctx context.Context,
|
|||||||
|
|
||||||
func (s *LetterServiceImpl) CreateDiscussion(ctx context.Context, letterID uuid.UUID, req *contract.CreateLetterDiscussionRequest) (*contract.LetterDiscussionResponse, error) {
|
func (s *LetterServiceImpl) CreateDiscussion(ctx context.Context, letterID uuid.UUID, req *contract.CreateLetterDiscussionRequest) (*contract.LetterDiscussionResponse, error) {
|
||||||
userID := appcontext.FromGinContext(ctx).UserID
|
userID := appcontext.FromGinContext(ctx).UserID
|
||||||
|
|
||||||
var result *contract.LetterDiscussionResponse
|
var result *contract.LetterDiscussionResponse
|
||||||
err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
|
err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
|
||||||
var err error
|
var err error
|
||||||
@ -719,34 +733,34 @@ func (s *LetterServiceImpl) CreateDiscussion(ctx context.Context, letterID uuid.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log activity for discussion creation
|
// Log activity for discussion creation
|
||||||
if s.activityLogger != nil && result != nil {
|
if s.activityLogger != nil && result != nil {
|
||||||
if err := s.activityLogger.LogLetterDispositionStatusUpdate(txCtx, letterID, userID, "discussion_created"); err != nil {
|
if err := s.activityLogger.LogLetterDispositionStatusUpdate(txCtx, letterID, userID, "discussion_created"); err != nil {
|
||||||
// Don't fail the transaction for logging errors
|
// Don't fail the transaction for logging errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send notifications to mentioned users asynchronously
|
// Send notifications to mentioned users asynchronously
|
||||||
if s.notificationProcessor != nil && req.Mentions != nil {
|
if s.notificationProcessor != nil && req.Mentions != nil {
|
||||||
go s.sendDiscussionMentionNotifications(context.Background(), letterID, userID, req.Mentions, req.Message)
|
go s.sendDiscussionMentionNotifications(context.Background(), letterID, userID, req.Mentions, req.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LetterServiceImpl) UpdateDiscussion(ctx context.Context, letterID uuid.UUID, discussionID uuid.UUID, req *contract.UpdateLetterDiscussionRequest) (*contract.LetterDiscussionResponse, error) {
|
func (s *LetterServiceImpl) UpdateDiscussion(ctx context.Context, letterID uuid.UUID, discussionID uuid.UUID, req *contract.UpdateLetterDiscussionRequest) (*contract.LetterDiscussionResponse, error) {
|
||||||
userID := appcontext.FromGinContext(ctx).UserID
|
userID := appcontext.FromGinContext(ctx).UserID
|
||||||
|
|
||||||
var result *contract.LetterDiscussionResponse
|
var result *contract.LetterDiscussionResponse
|
||||||
|
|
||||||
err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
|
err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
|
||||||
var err error
|
var err error
|
||||||
var oldMessage string
|
var oldMessage string
|
||||||
@ -754,7 +768,7 @@ func (s *LetterServiceImpl) UpdateDiscussion(ctx context.Context, letterID uuid.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log activity for discussion update (could use oldMessage for more detailed logging)
|
// Log activity for discussion update (could use oldMessage for more detailed logging)
|
||||||
if s.activityLogger != nil && result != nil {
|
if s.activityLogger != nil && result != nil {
|
||||||
// Create a simple activity log - oldMessage could be included in a more detailed log
|
// Create a simple activity log - oldMessage could be included in a more detailed log
|
||||||
@ -763,14 +777,14 @@ func (s *LetterServiceImpl) UpdateDiscussion(ctx context.Context, letterID uuid.
|
|||||||
// Don't fail the transaction for logging errors
|
// Don't fail the transaction for logging errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,14 +794,14 @@ func (s *LetterServiceImpl) GetDepartmentDispositionStatus(ctx context.Context,
|
|||||||
|
|
||||||
func (s *LetterServiceImpl) UpdateDispositionStatus(ctx context.Context, req *contract.UpdateDispositionStatusRequest) (*contract.DepartmentDispositionStatusResponse, error) {
|
func (s *LetterServiceImpl) UpdateDispositionStatus(ctx context.Context, req *contract.UpdateDispositionStatusRequest) (*contract.DepartmentDispositionStatusResponse, error) {
|
||||||
var result *contract.DepartmentDispositionStatusResponse
|
var result *contract.DepartmentDispositionStatusResponse
|
||||||
|
|
||||||
err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
|
err := s.txManager.WithTransaction(ctx, func(txCtx context.Context) error {
|
||||||
var err error
|
var err error
|
||||||
result, err = s.processor.UpdateDispositionStatus(txCtx, req)
|
result, err = s.processor.UpdateDispositionStatus(txCtx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log activity for disposition status update
|
// Log activity for disposition status update
|
||||||
if s.activityLogger != nil && result != nil {
|
if s.activityLogger != nil && result != nil {
|
||||||
userID := appcontext.FromGinContext(txCtx).UserID
|
userID := appcontext.FromGinContext(txCtx).UserID
|
||||||
@ -795,19 +809,19 @@ func (s *LetterServiceImpl) UpdateDispositionStatus(ctx context.Context, req *co
|
|||||||
// Don't fail the transaction for logging errors
|
// Don't fail the transaction for logging errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send notification to letter creator asynchronously
|
// Send notification to letter creator asynchronously
|
||||||
if s.notificationProcessor != nil && result != nil {
|
if s.notificationProcessor != nil && result != nil {
|
||||||
go s.sendDispositionStatusUpdateNotification(context.Background(), req.LetterIncomingID, req.Status)
|
go s.sendDispositionStatusUpdateNotification(context.Background(), req.LetterIncomingID, req.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -840,34 +854,34 @@ func (s *LetterServiceImpl) sendDiscussionMentionNotifications(ctx context.Conte
|
|||||||
if len(userIDs) == 0 {
|
if len(userIDs) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get letter details for notification
|
// Get letter details for notification
|
||||||
letter, err := s.processor.GetIncomingLetterByID(ctx, letterID)
|
letter, err := s.processor.GetIncomingLetterByID(ctx, letterID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get sender user name (you might need to implement this)
|
// Get sender user name (you might need to implement this)
|
||||||
appContext := appcontext.FromGinContext(ctx)
|
appContext := appcontext.FromGinContext(ctx)
|
||||||
senderName := appContext.UserName // or get from user service
|
senderName := appContext.UserName // or get from user service
|
||||||
|
|
||||||
// Send notification to each mentioned user
|
// Send notification to each mentioned user
|
||||||
for _, mentionedUserID := range userIDs {
|
for _, mentionedUserID := range userIDs {
|
||||||
// Don't send notification to the sender themselves
|
// Don't send notification to the sender themselves
|
||||||
if mentionedUserID == senderUserID {
|
if mentionedUserID == senderUserID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
subject := "Anda Disebutkan dalam Diskusi"
|
subject := "Anda Disebutkan dalam Diskusi"
|
||||||
notificationMessage := fmt.Sprintf("%s menyebutkan Anda dalam diskusi surat: %s", senderName, letter.Subject)
|
notificationMessage := fmt.Sprintf("%s menyebutkan Anda dalam diskusi surat: %s", senderName, letter.Subject)
|
||||||
|
|
||||||
err := s.notificationProcessor.SendIncomingLetterNotification(
|
err := s.notificationProcessor.SendIncomingLetterNotification(
|
||||||
ctx,
|
ctx,
|
||||||
letterID,
|
letterID,
|
||||||
mentionedUserID,
|
mentionedUserID,
|
||||||
subject,
|
subject,
|
||||||
notificationMessage)
|
notificationMessage)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Log error but continue with other notifications
|
// Log error but continue with other notifications
|
||||||
}
|
}
|
||||||
@ -876,7 +890,7 @@ func (s *LetterServiceImpl) sendDiscussionMentionNotifications(ctx context.Conte
|
|||||||
|
|
||||||
func (s *LetterServiceImpl) extractUserIDsFromMentions(mentions map[string]interface{}) []uuid.UUID {
|
func (s *LetterServiceImpl) extractUserIDsFromMentions(mentions map[string]interface{}) []uuid.UUID {
|
||||||
userIDs := make([]uuid.UUID, 0)
|
userIDs := make([]uuid.UUID, 0)
|
||||||
|
|
||||||
if userIDsInterface, exists := mentions["user_ids"]; exists {
|
if userIDsInterface, exists := mentions["user_ids"]; exists {
|
||||||
switch userIDsValue := userIDsInterface.(type) {
|
switch userIDsValue := userIDsInterface.(type) {
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
@ -895,7 +909,7 @@ func (s *LetterServiceImpl) extractUserIDsFromMentions(mentions map[string]inter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return userIDs
|
return userIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,8 +923,6 @@ func (s *LetterServiceImpl) sendDispositionCreatorNotification(ctx context.Conte
|
|||||||
fmt.Printf("[DEBUG] Starting sendDispositionCreatorNotification for letterID: %s\n", letterID.String())
|
fmt.Printf("[DEBUG] Starting sendDispositionCreatorNotification for letterID: %s\n", letterID.String())
|
||||||
fmt.Printf("[DEBUG] Successfully retrieved letter: %s\n", letter.Subject)
|
fmt.Printf("[DEBUG] Successfully retrieved letter: %s\n", letter.Subject)
|
||||||
fmt.Printf("[DEBUG] Successfully retrieved letter: %s\n", letter.CreatedBy)
|
fmt.Printf("[DEBUG] Successfully retrieved letter: %s\n", letter.CreatedBy)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
letterCreatorID := letter.CreatedBy
|
letterCreatorID := letter.CreatedBy
|
||||||
|
|
||||||
@ -924,7 +936,7 @@ func (s *LetterServiceImpl) sendDispositionCreatorNotification(ctx context.Conte
|
|||||||
dispositionCreatorName := appContext.UserName
|
dispositionCreatorName := appContext.UserName
|
||||||
|
|
||||||
subject := "Disposisi Baru pada Surat Anda"
|
subject := "Disposisi Baru pada Surat Anda"
|
||||||
message := fmt.Sprintf("Surat yang Anda buat telah didisposisikan %s: %s",
|
message := fmt.Sprintf("Surat yang Anda buat telah didisposisikan %s: %s",
|
||||||
dispositionCreatorName, letter.Subject)
|
dispositionCreatorName, letter.Subject)
|
||||||
|
|
||||||
err = s.notificationProcessor.SendIncomingLetterNotification(
|
err = s.notificationProcessor.SendIncomingLetterNotification(
|
||||||
@ -947,19 +959,19 @@ func (s *LetterServiceImpl) sendDispositionStatusUpdateNotification(ctx context.
|
|||||||
// Log error but don't fail
|
// Log error but don't fail
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current user context (the one updating the status)
|
// Get current user context (the one updating the status)
|
||||||
appContext := appcontext.FromGinContext(ctx)
|
appContext := appcontext.FromGinContext(ctx)
|
||||||
updaterUserID := appContext.UserID
|
updaterUserID := appContext.UserID
|
||||||
updaterName := appContext.UserName
|
updaterName := appContext.UserName
|
||||||
|
|
||||||
letterCreatorID := letter.CreatedBy
|
letterCreatorID := letter.CreatedBy
|
||||||
|
|
||||||
// Don't send notification if the updater is the same as letter creator
|
// Don't send notification if the updater is the same as letter creator
|
||||||
if letterCreatorID == updaterUserID {
|
if letterCreatorID == updaterUserID {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create status-specific notification message
|
// Create status-specific notification message
|
||||||
var statusMessage string
|
var statusMessage string
|
||||||
switch newStatus {
|
switch newStatus {
|
||||||
@ -974,20 +986,20 @@ func (s *LetterServiceImpl) sendDispositionStatusUpdateNotification(ctx context.
|
|||||||
default:
|
default:
|
||||||
statusMessage = fmt.Sprintf("diubah statusnya menjadi %s", newStatus)
|
statusMessage = fmt.Sprintf("diubah statusnya menjadi %s", newStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
subject := "Status Disposisi Surat Diperbarui"
|
subject := "Status Disposisi Surat Diperbarui"
|
||||||
message := fmt.Sprintf("Disposisi surat '%s' %s %s",
|
message := fmt.Sprintf("Disposisi surat '%s' %s %s",
|
||||||
letter.Subject, statusMessage, updaterName)
|
letter.Subject, statusMessage, updaterName)
|
||||||
|
|
||||||
err = s.notificationProcessor.SendIncomingLetterNotification(
|
err = s.notificationProcessor.SendIncomingLetterNotification(
|
||||||
ctx,
|
ctx,
|
||||||
letterID,
|
letterID,
|
||||||
letterCreatorID,
|
letterCreatorID,
|
||||||
subject,
|
subject,
|
||||||
message)
|
message)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Log error but don't fail the operation
|
// Log error but don't fail the operation
|
||||||
// You might want to add proper logging here
|
// You might want to add proper logging here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func LetterEntityToContract(e *entities.LetterIncoming, attachments []entities.LetterIncomingAttachment, refs ...interface{}) *contract.IncomingLetterResponse {
|
func LetterEntityToContract(e *entities.LetterIncoming, attachments []entities.LetterIncomingAttachment, dispositions []entities.LetterIncomingDisposition, refs ...interface{}) *contract.IncomingLetterResponse {
|
||||||
resp := &contract.IncomingLetterResponse{
|
resp := &contract.IncomingLetterResponse{
|
||||||
ID: e.ID,
|
ID: e.ID,
|
||||||
LetterNumber: e.LetterNumber,
|
LetterNumber: e.LetterNumber,
|
||||||
@ -24,6 +24,7 @@ func LetterEntityToContract(e *entities.LetterIncoming, attachments []entities.L
|
|||||||
CreatedAt: e.CreatedAt,
|
CreatedAt: e.CreatedAt,
|
||||||
UpdatedAt: e.UpdatedAt,
|
UpdatedAt: e.UpdatedAt,
|
||||||
Attachments: make([]contract.IncomingLetterAttachmentResponse, 0, len(attachments)),
|
Attachments: make([]contract.IncomingLetterAttachmentResponse, 0, len(attachments)),
|
||||||
|
Dispositions: make([]contract.EnhancedDispositionResponse, 0, len(dispositions)),
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional refs: allow passing already-fetched related objects
|
// optional refs: allow passing already-fetched related objects
|
||||||
@ -65,6 +66,23 @@ func LetterEntityToContract(e *entities.LetterIncoming, attachments []entities.L
|
|||||||
UploadedAt: a.UploadedAt,
|
UploadedAt: a.UploadedAt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, d := range dispositions {
|
||||||
|
resp.Dispositions = append(resp.Dispositions, contract.EnhancedDispositionResponse{
|
||||||
|
ID: d.ID,
|
||||||
|
LetterID: d.LetterID,
|
||||||
|
DepartmentID: d.DepartmentID,
|
||||||
|
Notes: d.Notes,
|
||||||
|
ReadAt: d.ReadAt,
|
||||||
|
CreatedBy: d.CreatedBy,
|
||||||
|
CreatedAt: d.CreatedAt,
|
||||||
|
UpdatedAt: d.UpdatedAt,
|
||||||
|
Departments: DispositionDepartmentsWithDetailsToContract(d.Departments),
|
||||||
|
Actions: DispositionActionSelectionsWithDetailsToContract(d.ActionSelections),
|
||||||
|
DispositionNotes: DispositionNotesWithDetailsToContract(d.DispositionNotes),
|
||||||
|
Department: DepartmentToContract(d.Department),
|
||||||
|
})
|
||||||
|
}
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user