package repository import ( "context" "gitlab.com/mbugroup/lti-api.git/internal/common/repository" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/repports/validations" "gitlab.com/mbugroup/lti-api.git/internal/utils" "gorm.io/gorm" ) type ExpenseRealizationRepository interface { repository.BaseRepository[entity.ExpenseRealization] IdExists(ctx context.Context, id uint64) (bool, error) GetByExpenseNonstockID(ctx context.Context, expenseNonstockID uint64) (*entity.ExpenseRealization, error) GetByProjectFlockID(ctx context.Context, projectFlockID uint) ([]entity.ExpenseRealization, error) GetAllWithFilters(ctx context.Context, offset, limit int, filters *validation.ExpenseQuery) ([]entity.ExpenseRealization, int64, error) } type ExpenseRealizationRepositoryImpl struct { *repository.BaseRepositoryImpl[entity.ExpenseRealization] } func NewExpenseRealizationRepository(db *gorm.DB) ExpenseRealizationRepository { return &ExpenseRealizationRepositoryImpl{ BaseRepositoryImpl: repository.NewBaseRepository[entity.ExpenseRealization](db), } } func (r *ExpenseRealizationRepositoryImpl) IdExists(ctx context.Context, id uint64) (bool, error) { return repository.Exists[entity.ExpenseRealization](ctx, r.DB(), uint(id)) } func (r *ExpenseRealizationRepositoryImpl) GetByExpenseNonstockID(ctx context.Context, expenseNonstockID uint64) (*entity.ExpenseRealization, error) { var realization entity.ExpenseRealization err := r.DB().WithContext(ctx).Where("expense_nonstock_id = ?", expenseNonstockID).First(&realization).Error return &realization, err } func (r *ExpenseRealizationRepositoryImpl) GetByProjectFlockID(ctx context.Context, projectFlockID uint) ([]entity.ExpenseRealization, error) { var realizations []entity.ExpenseRealization err := r.DB().WithContext(ctx). Preload("ExpenseNonstock"). Preload("ExpenseNonstock.Nonstock"). Preload("ExpenseNonstock.Nonstock.Uom"). Preload("ExpenseNonstock.Nonstock.Flags"). Preload("ExpenseNonstock.Expense"). Joins("JOIN expense_nonstocks ON expense_nonstocks.id = expense_realizations.expense_nonstock_id"). Joins("JOIN expenses ON expenses.id = expense_nonstocks.expense_id"). Joins("LEFT JOIN project_flock_kandangs ON project_flock_kandangs.id = expense_nonstocks.project_flock_kandang_id"). Joins("LEFT JOIN kandangs ON kandangs.id = expense_nonstocks.kandang_id"). Where("project_flock_kandangs.project_flock_id = ? OR kandangs.id IN (SELECT kandang_id FROM project_flock_kandangs WHERE project_flock_id = ?)", projectFlockID, projectFlockID). Find(&realizations).Error return realizations, err } func (r *ExpenseRealizationRepositoryImpl) GetAllWithFilters(ctx context.Context, offset, limit int, filters *validation.ExpenseQuery) ([]entity.ExpenseRealization, int64, error) { var realizations []entity.ExpenseRealization var total int64 db := r.DB().WithContext(ctx). Model(&entity.ExpenseRealization{}). Preload("ExpenseNonstock", func(db *gorm.DB) *gorm.DB { return db. Preload("Expense"). Preload("Expense.Supplier"). Preload("Kandang"). Preload("Kandang.Location"). Preload("Nonstock"). Preload("Nonstock.Flags") }). Joins("JOIN expense_nonstocks ON expense_nonstocks.id = expense_realizations.expense_nonstock_id"). Joins("JOIN expenses ON expenses.id = expense_nonstocks.expense_id"). Joins("LEFT JOIN suppliers ON suppliers.id = expenses.supplier_id") if filters.Search != "" { db = db.Where("expenses.category LIKE ? OR expenses.reference_number LIKE ? OR expenses.po_number LIKE ? OR expenses.notes LIKE ? OR suppliers.name LIKE ?", "%"+filters.Search+"%", "%"+filters.Search+"%", "%"+filters.Search+"%", "%"+filters.Search+"%", "%"+filters.Search+"%") } if filters.Category != "" { db = db.Where("expenses.category = ?", filters.Category) } if filters.SupplierId > 0 { db = db.Where("expenses.supplier_id = ?", filters.SupplierId) } if filters.KandangId > 0 { db = db.Where("expense_nonstocks.kandang_id = ?", filters.KandangId) } if filters.ProjectFlockKandangId > 0 { db = db.Where("expense_nonstocks.project_flock_kandang_id = ?", filters.ProjectFlockKandangId) } if filters.NonstockId > 0 { db = db.Where("expense_nonstocks.nonstock_id = ?", filters.NonstockId) } locationID := filters.LocationId areaID := filters.AreaId if locationID > 0 || areaID > 0 { db = db.Joins("JOIN kandangs ON kandangs.id = expense_nonstocks.kandang_id") if locationID > 0 { db = db.Where("kandangs.location_id = ?", uint(locationID)) } if areaID > 0 { db = db.Joins("JOIN locations ON locations.id = kandangs.location_id"). Where("locations.area_id = ?", uint(areaID)) } } if filters.RealizationDate != "" { if realizationDate, err := utils.ParseDateString(filters.RealizationDate); err == nil { db = db.Where("DATE(expenses.realization_date) = ?", realizationDate) } } if err := db.Count(&total).Error; err != nil { return nil, 0, err } if err := db. Offset(offset). Limit(limit). Order("expense_realizations.created_at DESC"). Find(&realizations).Error; err != nil { return nil, 0, err } return realizations, total, nil }