feat[BE]: add GetOverheadByProjectFlockKandang endpoint and update related services

This commit is contained in:
aguhh18
2026-01-13 13:20:06 +07:00
parent f7a392be52
commit 3c10866208
7 changed files with 190 additions and 32 deletions
@@ -2,6 +2,7 @@ package repository
import (
"context"
"fmt"
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
@@ -15,6 +16,7 @@ type ExpenseRealizationRepository interface {
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)
GetClosingOverhead(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.ExpenseRealization, error)
GetAllWithFilters(ctx context.Context, offset, limit int, filters *validation.ExpenseQuery) ([]entity.ExpenseRealization, int64, error)
}
@@ -55,6 +57,44 @@ func (r *ExpenseRealizationRepositoryImpl) GetByProjectFlockID(ctx context.Conte
return realizations, err
}
func (r *ExpenseRealizationRepositoryImpl) GetClosingOverhead(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.ExpenseRealization, error) {
var realizations []entity.ExpenseRealization
db := 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("expenses.realization_date IS NOT NULL")
// Build WHERE clause for project flock filtering
if projectFlockKandangID != nil {
// Per kandang: hanya ambil expense yang specific ke kandang tersebut
// SKIP expense level farm (yang punya multiple project flocks di JSON array)
// IMPORTANT: Untuk kandang_id, pastikan kandang tersebut belong to project_flock_kandang ini
db = db.Where(`(
expense_nonstocks.project_flock_kandang_id = ? OR
(expense_nonstocks.kandang_id = (SELECT kandang_id FROM project_flock_kandangs WHERE id = ?) AND
expense_nonstocks.project_flock_kandang_id IS NULL)
)`, *projectFlockKandangID, *projectFlockKandangID)
} else {
// All kandang: include expense kandang-specific DAN expense level farm
db = db.Where(`(
project_flock_kandangs.project_flock_id = ? OR
kandangs.id IN (SELECT kandang_id FROM project_flock_kandangs WHERE project_flock_id = ?) OR
(expenses.project_flock_id IS NOT NULL AND expenses.project_flock_id::jsonb @> ?::jsonb)
)`, projectFlockID, projectFlockID, fmt.Sprintf("[%d]", projectFlockID))
}
err := db.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