package service import ( "context" "time" "gorm.io/gorm" ) const farmDepreciationSnapshotTable = "farm_depreciation_snapshots" func NormalizeDateOnlyUTC(value time.Time) time.Time { if value.IsZero() { return value } v := value.UTC() return time.Date(v.Year(), v.Month(), v.Day(), 0, 0, 0, 0, time.UTC) } func MinNonZeroDateOnlyUTC(values ...time.Time) time.Time { var out time.Time for _, value := range values { if value.IsZero() { continue } normalized := NormalizeDateOnlyUTC(value) if out.IsZero() || normalized.Before(out) { out = normalized } } return out } func InvalidateFarmDepreciationSnapshotsFromDate(ctx context.Context, db *gorm.DB, farmIDs []uint, fromDate time.Time) error { if db == nil { return nil } if fromDate.IsZero() { return nil } fromDate = NormalizeDateOnlyUTC(fromDate) query := db.WithContext(ctx). Table(farmDepreciationSnapshotTable). Where("period_date >= ?", fromDate) if len(farmIDs) > 0 { query = query.Where("project_flock_id IN ?", farmIDs) } return query.Delete(nil).Error } func ResolveProjectFlockIDsByProjectFlockKandangIDs(ctx context.Context, db *gorm.DB, pfkIDs []uint) ([]uint, error) { if db == nil || len(pfkIDs) == 0 { return []uint{}, nil } var projectFlockIDs []uint if err := db.WithContext(ctx). Table("project_flock_kandangs"). Distinct("project_flock_id"). Where("id IN ?", pfkIDs). Pluck("project_flock_id", &projectFlockIDs).Error; err != nil { return nil, err } return projectFlockIDs, nil } func ResolveProjectFlockIDsByExpenseID(ctx context.Context, db *gorm.DB, expenseID uint) ([]uint, error) { if db == nil || expenseID == 0 { return []uint{}, nil } query := ` WITH direct_farms AS ( SELECT DISTINCT pfk.project_flock_id FROM expense_nonstocks ens JOIN project_flock_kandangs pfk ON pfk.id = ens.project_flock_kandang_id WHERE ens.expense_id = @expense_id ), json_farms AS ( SELECT DISTINCT (jsonb_array_elements_text(e.project_flock_id::jsonb))::bigint AS project_flock_id FROM expenses e WHERE e.id = @expense_id AND e.project_flock_id IS NOT NULL ) SELECT DISTINCT project_flock_id FROM ( SELECT project_flock_id FROM direct_farms UNION ALL SELECT project_flock_id FROM json_farms ) x ` var ids []uint if err := db.WithContext(ctx).Raw(query, map[string]any{ "expense_id": expenseID, }).Scan(&ids).Error; err != nil { return nil, err } return ids, nil }