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"`
|
CreatedBy uuid.UUID `json:"created_by"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
IsRead bool `json:"is_read"`
|
||||||
Recipients []OutgoingLetterRecipientResponse `json:"recipients,omitempty"`
|
Recipients []OutgoingLetterRecipientResponse `json:"recipients,omitempty"`
|
||||||
Attachments []OutgoingLetterAttachmentResponse `json:"attachments,omitempty"`
|
Attachments []OutgoingLetterAttachmentResponse `json:"attachments,omitempty"`
|
||||||
Approvals []OutgoingLetterApprovalResponse `json:"approvals,omitempty"`
|
Approvals []OutgoingLetterApprovalResponse `json:"approvals,omitempty"`
|
||||||
@ -139,6 +140,7 @@ type ListOutgoingLettersRequest struct {
|
|||||||
SortBy string `form:"sort_by" json:"sort_by,omitempty"`
|
SortBy string `form:"sort_by" json:"sort_by,omitempty"`
|
||||||
SortOrder string `form:"sort_order" json:"sort_order,omitempty"`
|
SortOrder string `form:"sort_order" json:"sort_order,omitempty"`
|
||||||
IsArchived *bool `form:"is_archived" json:"is_archived,omitempty"`
|
IsArchived *bool `form:"is_archived" json:"is_archived,omitempty"`
|
||||||
|
IsRead *bool `form:"is_read,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListOutgoingLettersResponse struct {
|
type ListOutgoingLettersResponse struct {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"eslogad-be/internal/appcontext"
|
"eslogad-be/internal/appcontext"
|
||||||
"eslogad-be/internal/contract"
|
"eslogad-be/internal/contract"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@ -101,6 +102,8 @@ func (h *LetterOutgoingHandler) ListOutgoingLetters(c *gin.Context) {
|
|||||||
req.Limit = 10
|
req.Limit = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("[DEBUG] request: %v\n", req)
|
||||||
|
|
||||||
resp, err := h.svc.ListOutgoingLetters(c.Request.Context(), &req)
|
resp, err := h.svc.ListOutgoingLetters(c.Request.Context(), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, &contract.ErrorResponse{Error: err.Error(), Code: http.StatusInternalServerError})
|
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)
|
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)
|
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)
|
||||||
|
GetBatchOutgoingRecipientsByUser(ctx context.Context, letterIDs []uuid.UUID, userID uuid.UUID) (map[uuid.UUID]*entities.LetterOutgoingRecipient, error)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LetterOutgoingProcessorImpl struct {
|
type LetterOutgoingProcessorImpl struct {
|
||||||
@ -806,6 +808,13 @@ func (p *LetterOutgoingProcessorImpl) GetBatchRecipients(ctx context.Context, le
|
|||||||
return p.recipientRepo.ListByLetterIDs(ctx, letterIDs)
|
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
|
// 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) {
|
func (p *LetterOutgoingProcessorImpl) 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 {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package repository
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"eslogad-be/internal/entities"
|
"eslogad-be/internal/entities"
|
||||||
@ -93,6 +94,7 @@ type ListOutgoingLettersFilter struct {
|
|||||||
SortBy *string
|
SortBy *string
|
||||||
SortOrder *string
|
SortOrder *string
|
||||||
IsArchived *bool
|
IsArchived *bool
|
||||||
|
IsRead *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LetterOutgoingRepository) List(ctx context.Context, filter ListOutgoingLettersFilter, limit, offset int) ([]entities.LetterOutgoing, int64, error) {
|
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
|
// Filter by UserID through recipients
|
||||||
if filter.UserID != nil {
|
if filter.UserID != nil {
|
||||||
query = query.Joins("LEFT JOIN letter_outgoing_recipients ON letter_outgoing_recipients.letter_id = letters_outgoing.id").
|
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).
|
query = query.Where("letter_outgoing_recipients.user_id = ?", *filter.UserID)
|
||||||
Distinct()
|
|
||||||
|
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 {
|
if filter.ReceiverInstitutionID != nil {
|
||||||
query = query.Where("receiver_institution_id = ?", *filter.ReceiverInstitutionID)
|
query = query.Where("receiver_institution_id = ?", *filter.ReceiverInstitutionID)
|
||||||
}
|
}
|
||||||
@ -485,6 +502,27 @@ func (r *LetterOutgoingDiscussionRepository) ListByLetter(ctx context.Context, l
|
|||||||
return list, nil
|
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 {
|
func (r *LetterOutgoingDiscussionRepository) Update(ctx context.Context, e *entities.LetterOutgoingDiscussion) error {
|
||||||
db := DBFromContext(ctx, r.db)
|
db := DBFromContext(ctx, r.db)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|||||||
@ -212,6 +212,7 @@ func (s *LetterOutgoingServiceImpl) ListOutgoingLetters(ctx context.Context, req
|
|||||||
ReceiverInstitutionID: req.ReceiverInstitutionID,
|
ReceiverInstitutionID: req.ReceiverInstitutionID,
|
||||||
PriorityID: req.PriorityID,
|
PriorityID: req.PriorityID,
|
||||||
UserID: &userID,
|
UserID: &userID,
|
||||||
|
IsRead: req.IsRead,
|
||||||
}
|
}
|
||||||
|
|
||||||
if departmentID != uuid.Nil {
|
if departmentID != uuid.Nil {
|
||||||
@ -250,6 +251,12 @@ func (s *LetterOutgoingServiceImpl) ListOutgoingLetters(ctx context.Context, req
|
|||||||
filter.IsArchived = req.IsArchived
|
filter.IsArchived = req.IsArchived
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if filter.IsRead != nil {
|
||||||
|
filter.IsRead = req.IsRead
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("[DEBUG] filter: %v\n", filter)
|
||||||
|
|
||||||
// Get raw letters data
|
// Get raw letters data
|
||||||
letters, total, err := s.processor.ListOutgoingLetters(ctx, filter, req.Limit, offset)
|
letters, total, err := s.processor.ListOutgoingLetters(ctx, filter, req.Limit, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -294,6 +301,7 @@ func (s *LetterOutgoingServiceImpl) ListOutgoingLetters(ctx context.Context, req
|
|||||||
result := batchResult{}
|
result := batchResult{}
|
||||||
errChan := make(chan error, 4)
|
errChan := make(chan error, 4)
|
||||||
|
|
||||||
|
|
||||||
// Load attachments
|
// Load attachments
|
||||||
go func() {
|
go func() {
|
||||||
result.attachments, err = s.processor.GetBatchAttachments(ctx, letterIDs)
|
result.attachments, err = s.processor.GetBatchAttachments(ctx, letterIDs)
|
||||||
@ -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{
|
return &contract.ListOutgoingLettersResponse{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user