outgoing letter is read
This commit is contained in:
parent
d8942fa918
commit
e7455f107a
@ -110,6 +110,7 @@ type OutgoingLetterResponse struct {
|
||||
CreatedBy uuid.UUID `json:"created_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
IsRead bool `json:"is_read"`
|
||||
Recipients []OutgoingLetterRecipientResponse `json:"recipients,omitempty"`
|
||||
Attachments []OutgoingLetterAttachmentResponse `json:"attachments,omitempty"`
|
||||
Approvals []OutgoingLetterApprovalResponse `json:"approvals,omitempty"`
|
||||
@ -139,6 +140,7 @@ type ListOutgoingLettersRequest struct {
|
||||
SortBy string `form:"sort_by" json:"sort_by,omitempty"`
|
||||
SortOrder string `form:"sort_order" json:"sort_order,omitempty"`
|
||||
IsArchived *bool `form:"is_archived" json:"is_archived,omitempty"`
|
||||
IsRead *bool `form:"is_read,omitempty"`
|
||||
}
|
||||
|
||||
type ListOutgoingLettersResponse struct {
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"eslogad-be/internal/appcontext"
|
||||
"eslogad-be/internal/contract"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -101,6 +102,8 @@ func (h *LetterOutgoingHandler) ListOutgoingLetters(c *gin.Context) {
|
||||
req.Limit = 10
|
||||
}
|
||||
|
||||
fmt.Printf("[DEBUG] request: %v\n", req)
|
||||
|
||||
resp, err := h.svc.ListOutgoingLetters(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, &contract.ErrorResponse{Error: err.Error(), Code: http.StatusInternalServerError})
|
||||
|
||||
@ -51,6 +51,8 @@ type LetterOutgoingProcessor interface {
|
||||
GetBatchRecipients(ctx context.Context, letterIDs []uuid.UUID) (map[uuid.UUID][]entities.LetterOutgoingRecipient, 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)
|
||||
GetBatchOutgoingRecipientsByUser(ctx context.Context, letterIDs []uuid.UUID, userID uuid.UUID) (map[uuid.UUID]*entities.LetterOutgoingRecipient, error)
|
||||
|
||||
}
|
||||
|
||||
type LetterOutgoingProcessorImpl struct {
|
||||
@ -806,6 +808,13 @@ func (p *LetterOutgoingProcessorImpl) GetBatchRecipients(ctx context.Context, le
|
||||
return p.recipientRepo.ListByLetterIDs(ctx, letterIDs)
|
||||
}
|
||||
|
||||
func (p *LetterOutgoingProcessorImpl) GetBatchOutgoingRecipientsByUser(ctx context.Context, letterIDs []uuid.UUID, userID uuid.UUID) (map[uuid.UUID]*entities.LetterOutgoingRecipient, error) {
|
||||
if p.recipientRepo == nil || len(letterIDs) == 0 {
|
||||
return make(map[uuid.UUID]*entities.LetterOutgoingRecipient), nil
|
||||
}
|
||||
return p.recipientRepo.GetByLetterIDsAndUser(ctx, letterIDs, userID)
|
||||
}
|
||||
|
||||
// GetBatchPriorities fetches priorities by IDs in a single query
|
||||
func (p *LetterOutgoingProcessorImpl) GetBatchPriorities(ctx context.Context, priorityIDs []uuid.UUID) (map[uuid.UUID]*entities.Priority, error) {
|
||||
if p.priorityRepo == nil || len(priorityIDs) == 0 {
|
||||
|
||||
@ -2,6 +2,7 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"eslogad-be/internal/entities"
|
||||
@ -93,6 +94,7 @@ type ListOutgoingLettersFilter struct {
|
||||
SortBy *string
|
||||
SortOrder *string
|
||||
IsArchived *bool
|
||||
IsRead *bool
|
||||
}
|
||||
|
||||
func (r *LetterOutgoingRepository) List(ctx context.Context, filter ListOutgoingLettersFilter, limit, offset int) ([]entities.LetterOutgoing, int64, error) {
|
||||
@ -120,10 +122,25 @@ func (r *LetterOutgoingRepository) List(ctx context.Context, filter ListOutgoing
|
||||
}
|
||||
// Filter by UserID through recipients
|
||||
if filter.UserID != nil {
|
||||
query = query.Joins("LEFT JOIN letter_outgoing_recipients ON letter_outgoing_recipients.letter_id = letters_outgoing.id").
|
||||
Where("letter_outgoing_recipients.user_id = ?", *filter.UserID).
|
||||
Distinct()
|
||||
query = query.Joins("LEFT JOIN letter_outgoing_recipients ON letter_outgoing_recipients.letter_id = letters_outgoing.id")
|
||||
query = query.Where("letter_outgoing_recipients.user_id = ?", *filter.UserID)
|
||||
|
||||
fmt.Printf("[DEBUG] filter.UserID: %v\n", filter.UserID)
|
||||
fmt.Printf("[DEBUG] filter.isRead: %v\n", filter.IsRead)
|
||||
|
||||
// Tambahkan filter IsRead
|
||||
if filter.IsRead != nil {
|
||||
if *filter.IsRead {
|
||||
query = query.Where("letter_outgoing_recipients.read_at IS NOT NULL")
|
||||
} else {
|
||||
query = query.Where("letter_outgoing_recipients.read_at IS NULL")
|
||||
}
|
||||
}
|
||||
|
||||
query = query.Distinct()
|
||||
}
|
||||
|
||||
|
||||
if filter.ReceiverInstitutionID != nil {
|
||||
query = query.Where("receiver_institution_id = ?", *filter.ReceiverInstitutionID)
|
||||
}
|
||||
@ -485,6 +502,27 @@ func (r *LetterOutgoingDiscussionRepository) ListByLetter(ctx context.Context, l
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (r *LetterOutgoingRecipientRepository) GetByLetterIDsAndUser(ctx context.Context, letterIDs []uuid.UUID, userID uuid.UUID) (map[uuid.UUID]*entities.LetterOutgoingRecipient, error) {
|
||||
if len(letterIDs) == 0 {
|
||||
return make(map[uuid.UUID]*entities.LetterOutgoingRecipient), nil
|
||||
}
|
||||
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var recipients []entities.LetterOutgoingRecipient
|
||||
if err := db.WithContext(ctx).
|
||||
Where("letter_id IN ? AND user_id = ?", letterIDs, userID).
|
||||
Find(&recipients).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make(map[uuid.UUID]*entities.LetterOutgoingRecipient)
|
||||
for i := range recipients {
|
||||
result[recipients[i].LetterID] = &recipients[i]
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *LetterOutgoingDiscussionRepository) Update(ctx context.Context, e *entities.LetterOutgoingDiscussion) error {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
now := time.Now()
|
||||
|
||||
@ -212,6 +212,7 @@ func (s *LetterOutgoingServiceImpl) ListOutgoingLetters(ctx context.Context, req
|
||||
ReceiverInstitutionID: req.ReceiverInstitutionID,
|
||||
PriorityID: req.PriorityID,
|
||||
UserID: &userID,
|
||||
IsRead: req.IsRead,
|
||||
}
|
||||
|
||||
if departmentID != uuid.Nil {
|
||||
@ -250,6 +251,12 @@ func (s *LetterOutgoingServiceImpl) ListOutgoingLetters(ctx context.Context, req
|
||||
filter.IsArchived = req.IsArchived
|
||||
}
|
||||
|
||||
if filter.IsRead != nil {
|
||||
filter.IsRead = req.IsRead
|
||||
}
|
||||
|
||||
fmt.Printf("[DEBUG] filter: %v\n", filter)
|
||||
|
||||
// Get raw letters data
|
||||
letters, total, err := s.processor.ListOutgoingLetters(ctx, filter, req.Limit, offset)
|
||||
if err != nil {
|
||||
@ -293,6 +300,7 @@ func (s *LetterOutgoingServiceImpl) ListOutgoingLetters(ctx context.Context, req
|
||||
|
||||
result := batchResult{}
|
||||
errChan := make(chan error, 4)
|
||||
|
||||
|
||||
// Load attachments
|
||||
go func() {
|
||||
@ -346,7 +354,23 @@ func (s *LetterOutgoingServiceImpl) ListOutgoingLetters(ctx context.Context, req
|
||||
}
|
||||
}
|
||||
|
||||
items[i] = transformLetterToResponse(&letter)
|
||||
isRead := false
|
||||
recipientByUser := make(map[uuid.UUID]*entities.LetterOutgoingRecipient)
|
||||
recipientByUser, err = s.processor.GetBatchOutgoingRecipientsByUser(ctx, letterIDs, userID)
|
||||
if err != nil {
|
||||
// Handle error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Ambil isRead dari recipientByUser berdasarkan letter.ID
|
||||
if recipient, exists := recipientByUser[letter.ID]; exists && recipient != nil {
|
||||
isRead = recipient.ReadAt != nil
|
||||
}
|
||||
|
||||
|
||||
response := transformLetterToResponse(&letter)
|
||||
response.IsRead = isRead
|
||||
items[i] = response
|
||||
}
|
||||
|
||||
return &contract.ListOutgoingLettersResponse{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user