dukcapil/internal/repository/letter_outgoing_repository.go
2025-08-29 16:10:05 +07:00

304 lines
10 KiB
Go

package repository
import (
"context"
"time"
"eslogad-be/internal/entities"
"github.com/google/uuid"
"gorm.io/gorm"
)
type LetterOutgoingRepository struct{ db *gorm.DB }
func NewLetterOutgoingRepository(db *gorm.DB) *LetterOutgoingRepository {
return &LetterOutgoingRepository{db: db}
}
func (r *LetterOutgoingRepository) Create(ctx context.Context, e *entities.LetterOutgoing) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(e).Error
}
func (r *LetterOutgoingRepository) Get(ctx context.Context, id uuid.UUID) (*entities.LetterOutgoing, error) {
db := DBFromContext(ctx, r.db)
var e entities.LetterOutgoing
if err := db.WithContext(ctx).
Preload("Priority").
Preload("ReceiverInstitution").
Preload("Creator").
Preload("ApprovalFlow").
Preload("Recipients").
Preload("Attachments").
Preload("Approvals.Step").
Preload("Approvals.Approver").
Where("id = ? AND deleted_at IS NULL", id).
First(&e).Error; err != nil {
return nil, err
}
return &e, nil
}
func (r *LetterOutgoingRepository) Update(ctx context.Context, e *entities.LetterOutgoing) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Model(&entities.LetterOutgoing{}).Where("id = ? AND deleted_at IS NULL", e.ID).Updates(e).Error
}
func (r *LetterOutgoingRepository) SoftDelete(ctx context.Context, id uuid.UUID) error {
db := DBFromContext(ctx, r.db)
now := time.Now()
return db.WithContext(ctx).Model(&entities.LetterOutgoing{}).Where("id = ? AND deleted_at IS NULL", id).Update("deleted_at", now).Error
}
func (r *LetterOutgoingRepository) GetWithRelations(ctx context.Context, id uuid.UUID, relations []string) (*entities.LetterOutgoing, error) {
db := DBFromContext(ctx, r.db)
query := db.WithContext(ctx).Where("id = ? AND deleted_at IS NULL", id)
// Preload all specified relations
for _, relation := range relations {
query = query.Preload(relation)
}
var e entities.LetterOutgoing
if err := query.First(&e).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, gorm.ErrRecordNotFound
}
return nil, err
}
return &e, nil
}
type ListOutgoingLettersFilter struct {
Status *string
Query *string
CreatedBy *uuid.UUID
ReceiverInstitutionID *uuid.UUID
FromDate *time.Time
ToDate *time.Time
}
func (r *LetterOutgoingRepository) List(ctx context.Context, filter ListOutgoingLettersFilter, limit, offset int) ([]entities.LetterOutgoing, int64, error) {
db := DBFromContext(ctx, r.db)
query := db.WithContext(ctx).Model(&entities.LetterOutgoing{}).Where("deleted_at IS NULL")
if filter.Status != nil {
query = query.Where("status = ?", *filter.Status)
}
if filter.Query != nil {
q := "%" + *filter.Query + "%"
query = query.Where("subject ILIKE ? OR reference_number ILIKE ? OR letter_number ILIKE ?", q, q, q)
}
if filter.CreatedBy != nil {
query = query.Where("created_by = ?", *filter.CreatedBy)
}
if filter.ReceiverInstitutionID != nil {
query = query.Where("receiver_institution_id = ?", *filter.ReceiverInstitutionID)
}
if filter.FromDate != nil {
query = query.Where("issue_date >= ?", *filter.FromDate)
}
if filter.ToDate != nil {
query = query.Where("issue_date <= ?", *filter.ToDate)
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
var list []entities.LetterOutgoing
if err := query.
Preload("Priority").
Preload("ReceiverInstitution").
Preload("Creator").
Preload("Recipients").
Preload("Attachments").
Preload("Approvals.Step").
Preload("Approvals.Approver").
Order("created_at DESC").
Limit(limit).
Offset(offset).
Find(&list).Error; err != nil {
return nil, 0, err
}
return list, 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
}
type LetterOutgoingAttachmentRepository struct{ db *gorm.DB }
func NewLetterOutgoingAttachmentRepository(db *gorm.DB) *LetterOutgoingAttachmentRepository {
return &LetterOutgoingAttachmentRepository{db: db}
}
func (r *LetterOutgoingAttachmentRepository) Create(ctx context.Context, e *entities.LetterOutgoingAttachment) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(e).Error
}
func (r *LetterOutgoingAttachmentRepository) CreateBulk(ctx context.Context, list []entities.LetterOutgoingAttachment) error {
db := DBFromContext(ctx, r.db)
if len(list) == 0 {
return nil
}
return db.WithContext(ctx).Create(&list).Error
}
func (r *LetterOutgoingAttachmentRepository) ListByLetter(ctx context.Context, letterID uuid.UUID) ([]entities.LetterOutgoingAttachment, error) {
db := DBFromContext(ctx, r.db)
var list []entities.LetterOutgoingAttachment
if err := db.WithContext(ctx).Where("letter_id = ?", letterID).Order("uploaded_at ASC").Find(&list).Error; err != nil {
return nil, err
}
return list, nil
}
func (r *LetterOutgoingAttachmentRepository) Delete(ctx context.Context, id uuid.UUID) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Where("id = ?", id).Delete(&entities.LetterOutgoingAttachment{}).Error
}
type LetterOutgoingRecipientRepository struct{ db *gorm.DB }
func NewLetterOutgoingRecipientRepository(db *gorm.DB) *LetterOutgoingRecipientRepository {
return &LetterOutgoingRecipientRepository{db: db}
}
func (r *LetterOutgoingRecipientRepository) Create(ctx context.Context, e *entities.LetterOutgoingRecipient) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(e).Error
}
func (r *LetterOutgoingRecipientRepository) CreateBulk(ctx context.Context, list []entities.LetterOutgoingRecipient) error {
db := DBFromContext(ctx, r.db)
if len(list) == 0 {
return nil
}
return db.WithContext(ctx).Create(&list).Error
}
func (r *LetterOutgoingRecipientRepository) ListByLetter(ctx context.Context, letterID uuid.UUID) ([]entities.LetterOutgoingRecipient, error) {
db := DBFromContext(ctx, r.db)
var list []entities.LetterOutgoingRecipient
if err := db.WithContext(ctx).
Preload("User").
Preload("Department").
Where("letter_id = ?", letterID).
Order("is_primary DESC, created_at ASC").
Find(&list).Error; err != nil {
return nil, err
}
return list, nil
}
func (r *LetterOutgoingRecipientRepository) Update(ctx context.Context, e *entities.LetterOutgoingRecipient) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Model(&entities.LetterOutgoingRecipient{}).Where("id = ?", e.ID).Updates(e).Error
}
func (r *LetterOutgoingRecipientRepository) Delete(ctx context.Context, id uuid.UUID) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Where("id = ?", id).Delete(&entities.LetterOutgoingRecipient{}).Error
}
func (r *LetterOutgoingRecipientRepository) DeleteByLetter(ctx context.Context, letterID uuid.UUID) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Where("letter_id = ?", letterID).Delete(&entities.LetterOutgoingRecipient{}).Error
}
type LetterOutgoingDiscussionRepository struct{ db *gorm.DB }
func NewLetterOutgoingDiscussionRepository(db *gorm.DB) *LetterOutgoingDiscussionRepository {
return &LetterOutgoingDiscussionRepository{db: db}
}
func (r *LetterOutgoingDiscussionRepository) Create(ctx context.Context, e *entities.LetterOutgoingDiscussion) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(e).Error
}
func (r *LetterOutgoingDiscussionRepository) Get(ctx context.Context, id uuid.UUID) (*entities.LetterOutgoingDiscussion, error) {
db := DBFromContext(ctx, r.db)
var e entities.LetterOutgoingDiscussion
if err := db.WithContext(ctx).
Preload("User").
Preload("Attachments").
Where("id = ?", id).
First(&e).Error; err != nil {
return nil, err
}
return &e, nil
}
func (r *LetterOutgoingDiscussionRepository) ListByLetter(ctx context.Context, letterID uuid.UUID) ([]entities.LetterOutgoingDiscussion, error) {
db := DBFromContext(ctx, r.db)
var list []entities.LetterOutgoingDiscussion
if err := db.WithContext(ctx).
Preload("User").
Preload("Attachments").
Preload("Replies.User").
Where("letter_id = ? AND parent_id IS NULL", letterID).
Order("created_at DESC").
Find(&list).Error; err != nil {
return nil, err
}
return list, nil
}
func (r *LetterOutgoingDiscussionRepository) Update(ctx context.Context, e *entities.LetterOutgoingDiscussion) error {
db := DBFromContext(ctx, r.db)
now := time.Now()
e.EditedAt = &now
return db.WithContext(ctx).Model(&entities.LetterOutgoingDiscussion{}).Where("id = ?", e.ID).Updates(e).Error
}
func (r *LetterOutgoingDiscussionRepository) Delete(ctx context.Context, id uuid.UUID) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Where("id = ?", id).Delete(&entities.LetterOutgoingDiscussion{}).Error
}
type LetterOutgoingDiscussionAttachmentRepository struct{ db *gorm.DB }
func NewLetterOutgoingDiscussionAttachmentRepository(db *gorm.DB) *LetterOutgoingDiscussionAttachmentRepository {
return &LetterOutgoingDiscussionAttachmentRepository{db: db}
}
func (r *LetterOutgoingDiscussionAttachmentRepository) CreateBulk(ctx context.Context, list []entities.LetterOutgoingDiscussionAttachment) error {
db := DBFromContext(ctx, r.db)
if len(list) == 0 {
return nil
}
return db.WithContext(ctx).Create(&list).Error
}
type LetterOutgoingActivityLogRepository struct{ db *gorm.DB }
func NewLetterOutgoingActivityLogRepository(db *gorm.DB) *LetterOutgoingActivityLogRepository {
return &LetterOutgoingActivityLogRepository{db: db}
}
func (r *LetterOutgoingActivityLogRepository) Create(ctx context.Context, e *entities.LetterOutgoingActivityLog) error {
db := DBFromContext(ctx, r.db)
return db.WithContext(ctx).Create(e).Error
}
func (r *LetterOutgoingActivityLogRepository) ListByLetter(ctx context.Context, letterID uuid.UUID) ([]entities.LetterOutgoingActivityLog, error) {
db := DBFromContext(ctx, r.db)
var list []entities.LetterOutgoingActivityLog
if err := db.WithContext(ctx).
Preload("ActorUser").
Preload("ActorDepartment").
Where("letter_id = ?", letterID).
Order("occurred_at DESC").
Find(&list).Error; err != nil {
return nil, err
}
return list, nil
}