add sender and receiver
This commit is contained in:
@@ -188,6 +188,109 @@ func (r *LetterOutgoingRepository) List(ctx context.Context, filter ListOutgoing
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
func (r *LetterOutgoingRepository) Search(ctx context.Context, filters map[string]interface{}, limit, offset int, sortBy, sortOrder string) ([]entities.LetterOutgoing, int64, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
query := db.WithContext(ctx).Model(&entities.LetterOutgoing{}).Where("deleted_at IS NULL")
|
||||
|
||||
// Apply search filters
|
||||
if q, ok := filters["query"]; ok && q != "" {
|
||||
searchTerm := "%" + q.(string) + "%"
|
||||
query = query.Where("subject ILIKE ? OR reference_number ILIKE ? OR letter_number ILIKE ? OR description ILIKE ? OR receiver_name ILIKE ?", searchTerm, searchTerm, searchTerm, searchTerm, searchTerm)
|
||||
}
|
||||
|
||||
if letterNumber, ok := filters["letter_number"]; ok && letterNumber != "" {
|
||||
query = query.Where("letter_number ILIKE ?", "%"+letterNumber.(string)+"%")
|
||||
}
|
||||
|
||||
if subject, ok := filters["subject"]; ok && subject != "" {
|
||||
query = query.Where("subject ILIKE ?", "%"+subject.(string)+"%")
|
||||
}
|
||||
|
||||
if status, ok := filters["status"]; ok && status != "" {
|
||||
query = query.Where("status = ?", status)
|
||||
}
|
||||
|
||||
if priorityID, ok := filters["priority_id"]; ok {
|
||||
query = query.Where("priority_id = ?", priorityID)
|
||||
}
|
||||
|
||||
if institutionID, ok := filters["receiver_institution_id"]; ok {
|
||||
query = query.Where("receiver_institution_id = ?", institutionID)
|
||||
}
|
||||
|
||||
if createdBy, ok := filters["created_by"]; ok {
|
||||
query = query.Where("created_by = ?", createdBy)
|
||||
}
|
||||
|
||||
if dateFrom, ok := filters["date_from"]; ok {
|
||||
query = query.Where("issue_date >= ?", dateFrom)
|
||||
}
|
||||
|
||||
if dateTo, ok := filters["date_to"]; ok {
|
||||
query = query.Where("issue_date <= ?", dateTo)
|
||||
}
|
||||
|
||||
// Apply user context filters if present
|
||||
if userContext, ok := filters["user_context"]; ok {
|
||||
if ctx, ok := userContext.(map[string]interface{}); ok {
|
||||
if userID, ok := ctx["user_id"]; ok {
|
||||
// User can see: letters created by them OR letters where they are recipients
|
||||
subQuery := db.Model(&entities.LetterOutgoingRecipient{}).Select("letter_id").Where("user_id = ?", userID)
|
||||
query = query.Where("created_by = ? OR id IN (?)", userID, subQuery)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Count total results
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Apply sorting
|
||||
if sortBy == "" {
|
||||
sortBy = "created_at"
|
||||
}
|
||||
if sortOrder == "" {
|
||||
sortOrder = "desc"
|
||||
}
|
||||
|
||||
validSortFields := map[string]bool{
|
||||
"letter_number": true,
|
||||
"subject": true,
|
||||
"issue_date": true,
|
||||
"status": true,
|
||||
"created_at": true,
|
||||
"updated_at": true,
|
||||
}
|
||||
|
||||
if !validSortFields[sortBy] {
|
||||
sortBy = "created_at"
|
||||
}
|
||||
|
||||
if sortOrder != "asc" && sortOrder != "desc" {
|
||||
sortOrder = "desc"
|
||||
}
|
||||
|
||||
orderBy := sortBy + " " + sortOrder
|
||||
|
||||
// Execute query with preloads
|
||||
var letters []entities.LetterOutgoing
|
||||
if err := query.
|
||||
Preload("Priority").
|
||||
Preload("ReceiverInstitution").
|
||||
Preload("Creator").
|
||||
Preload("Creator.Profile").
|
||||
Order(orderBy).
|
||||
Limit(limit).
|
||||
Offset(offset).
|
||||
Find(&letters).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return letters, total, nil
|
||||
}
|
||||
|
||||
func (r *LetterOutgoingRepository) UpdateStatus(ctx context.Context, id uuid.UUID, status entities.LetterOutgoingStatus) error {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
return db.WithContext(ctx).Model(&entities.LetterOutgoing{}).Where("id = ? AND deleted_at IS NULL", id).Update("status", status).Error
|
||||
|
||||
@@ -210,6 +210,139 @@ func (r *LetterIncomingRepository) List(ctx context.Context, filter ListIncoming
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
func (r *LetterIncomingRepository) Search(ctx context.Context, filters map[string]interface{}, limit, offset int, sortBy, sortOrder string) ([]entities.LetterIncoming, int64, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
query := db.WithContext(ctx).Model(&entities.LetterIncoming{}).Where("deleted_at IS NULL")
|
||||
|
||||
joinedRecipients := false
|
||||
needsGroupBy := false
|
||||
|
||||
// Apply search filters
|
||||
if q, ok := filters["query"]; ok && q != "" {
|
||||
searchTerm := "%" + q.(string) + "%"
|
||||
query = query.Where("subject ILIKE ? OR reference_number ILIKE ? OR letter_number ILIKE ? OR description ILIKE ? OR sender_name ILIKE ?", searchTerm, searchTerm, searchTerm, searchTerm, searchTerm)
|
||||
}
|
||||
|
||||
if letterNumber, ok := filters["letter_number"]; ok && letterNumber != "" {
|
||||
query = query.Where("letter_number ILIKE ?", "%"+letterNumber.(string)+"%")
|
||||
}
|
||||
|
||||
if subject, ok := filters["subject"]; ok && subject != "" {
|
||||
query = query.Where("subject ILIKE ?", "%"+subject.(string)+"%")
|
||||
}
|
||||
|
||||
if status, ok := filters["status"]; ok && status != "" {
|
||||
query = query.Where("status = ?", status)
|
||||
}
|
||||
|
||||
if priorityID, ok := filters["priority_id"]; ok {
|
||||
query = query.Where("priority_id = ?", priorityID)
|
||||
}
|
||||
|
||||
if institutionID, ok := filters["sender_institution_id"]; ok {
|
||||
query = query.Where("sender_institution_id = ?", institutionID)
|
||||
}
|
||||
|
||||
if createdBy, ok := filters["created_by"]; ok {
|
||||
query = query.Where("created_by = ?", createdBy)
|
||||
}
|
||||
|
||||
if dateFrom, ok := filters["date_from"]; ok {
|
||||
query = query.Where("received_date >= ?", dateFrom)
|
||||
}
|
||||
|
||||
if dateTo, ok := filters["date_to"]; ok {
|
||||
query = query.Where("received_date <= ?", dateTo)
|
||||
}
|
||||
|
||||
// Apply user context filters if present
|
||||
if userContext, ok := filters["user_context"]; ok {
|
||||
if ctx, ok := userContext.(map[string]interface{}); ok {
|
||||
if userID, ok := ctx["user_id"]; ok {
|
||||
// User can see letters where they are recipients
|
||||
query = query.Joins("JOIN letter_incoming_recipients ON letter_incoming_recipients.letter_id = letters_incoming.id").
|
||||
Where("letter_incoming_recipients.recipient_user_id = ?", userID)
|
||||
joinedRecipients = true
|
||||
needsGroupBy = true
|
||||
}
|
||||
if departmentID, ok := ctx["department_id"]; ok {
|
||||
// Also include letters for user's department
|
||||
if !joinedRecipients {
|
||||
query = query.Joins("JOIN letter_incoming_recipients ON letter_incoming_recipients.letter_id = letters_incoming.id")
|
||||
joinedRecipients = true
|
||||
needsGroupBy = true
|
||||
}
|
||||
query = query.Where("letter_incoming_recipients.recipient_department_id = ?", departmentID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Count total results
|
||||
var total int64
|
||||
if needsGroupBy {
|
||||
// For grouped queries, count distinct letter IDs
|
||||
if err := db.WithContext(ctx).Model(&entities.LetterIncoming{}).
|
||||
Joins("JOIN letter_incoming_recipients ON letter_incoming_recipients.letter_id = letters_incoming.id").
|
||||
Where("letters_incoming.deleted_at IS NULL").
|
||||
Distinct("letters_incoming.id").
|
||||
Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
} else {
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
}
|
||||
|
||||
// Apply sorting
|
||||
if sortBy == "" {
|
||||
sortBy = "created_at"
|
||||
}
|
||||
if sortOrder == "" {
|
||||
sortOrder = "desc"
|
||||
}
|
||||
|
||||
validSortFields := map[string]bool{
|
||||
"letter_number": true,
|
||||
"subject": true,
|
||||
"received_date": true,
|
||||
"status": true,
|
||||
"created_at": true,
|
||||
"updated_at": true,
|
||||
}
|
||||
|
||||
if !validSortFields[sortBy] {
|
||||
sortBy = "created_at"
|
||||
}
|
||||
|
||||
if sortOrder != "asc" && sortOrder != "desc" {
|
||||
sortOrder = "desc"
|
||||
}
|
||||
|
||||
orderBy := "letters_incoming." + sortBy + " " + sortOrder
|
||||
|
||||
// Apply grouping if necessary
|
||||
if needsGroupBy {
|
||||
query = query.Group("letters_incoming.id, letters_incoming.letter_number, letters_incoming.reference_number, " +
|
||||
"letters_incoming.subject, letters_incoming.description, letters_incoming.priority_id, " +
|
||||
"letters_incoming.sender_institution_id, letters_incoming.received_date, letters_incoming.due_date, " +
|
||||
"letters_incoming.status, letters_incoming.created_by, letters_incoming.created_at, " +
|
||||
"letters_incoming.updated_at, letters_incoming.deleted_at")
|
||||
}
|
||||
|
||||
// Execute query
|
||||
var letters []entities.LetterIncoming
|
||||
if err := query.
|
||||
Order(orderBy).
|
||||
Limit(limit).
|
||||
Offset(offset).
|
||||
Find(&letters).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return letters, total, nil
|
||||
}
|
||||
|
||||
type LetterIncomingAttachmentRepository struct{ db *gorm.DB }
|
||||
|
||||
func NewLetterIncomingAttachmentRepository(db *gorm.DB) *LetterIncomingAttachmentRepository {
|
||||
|
||||
Reference in New Issue
Block a user