add new ststs feature
This commit is contained in:
@@ -11,6 +11,7 @@ use App\Models\ReimbursementModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Libraries\FinancialStatus;
|
||||
use App\Libraries\InvoiceLedgerService;
|
||||
use App\Services\FinancialCategorySummaryService;
|
||||
|
||||
require_once APPPATH . 'ThirdParty/fpdf/fpdf.php';
|
||||
use FPDF;
|
||||
@@ -340,10 +341,16 @@ public function financialReport()
|
||||
unset($invoiceRow);
|
||||
|
||||
// === Expenses ===
|
||||
$expenses = $expenseModel
|
||||
$expenseRows = $expenseModel
|
||||
->select('category, SUM(amount) AS total_amount')
|
||||
->groupBy('category')
|
||||
->findAll();
|
||||
$categorySummary = FinancialCategorySummaryService::summarize($expenseRows);
|
||||
$expenses = [];
|
||||
foreach ($categorySummary['expenseCategories'] as $category => $amount) {
|
||||
$expenses[] = ['category' => $category, 'total_amount' => $amount];
|
||||
}
|
||||
$donationToSchool = $categorySummary['donationIncome'];
|
||||
|
||||
// === Reimbursements ===
|
||||
$reimbursements = $reimbursementModel
|
||||
@@ -370,6 +377,7 @@ public function financialReport()
|
||||
'paymentTotals' => $paymentTotals,
|
||||
'refunds' => $refunds,
|
||||
'expenses' => $expenses,
|
||||
'donationToSchool' => $donationToSchool,
|
||||
'reimbursements' => $reimbursements,
|
||||
'discounts' => $discounts,
|
||||
'eventFeesTotal' => $eventFeesTotal,
|
||||
@@ -385,6 +393,7 @@ public function financialReport()
|
||||
'paymentTotals' => $paymentTotals, // summary totals + grand total
|
||||
'refunds' => $refunds,
|
||||
'expenses' => $expenses,
|
||||
'donationToSchool' => $donationToSchool,
|
||||
'reimbursements' => $reimbursements,
|
||||
'discounts' => $discounts,
|
||||
'eventFeesTotal' => $eventFeesTotal,
|
||||
@@ -457,7 +466,7 @@ public function financialReport()
|
||||
['Total Refunds', (float)($data['totalRefunds'] ?? 0)],
|
||||
['Total Expenses', (float)($data['totalExpenses'] ?? 0)],
|
||||
['Total Reimbursements', (float)($data['totalReimbursements'] ?? 0)],
|
||||
['Donation to School (included in expenses)', (float)($data['donationToSchool'] ?? 0)],
|
||||
['Donation Income to School', (float)($data['donationToSchool'] ?? 0)],
|
||||
['Net Charges After Discounts/Refunds', (float)($data['netAmount'] ?? 0)],
|
||||
['Amount Collected (Paid)', (float)($data['amountCollected'] ?? 0)],
|
||||
['Overpayment Credits', (float)($data['totalOverpaid'] ?? 0)],
|
||||
@@ -534,7 +543,7 @@ public function financialReport()
|
||||
['Total Refunds' => (float)($summary['totalRefunds'] ?? 0)],
|
||||
['Total Expenses' => (float)($summary['totalExpenses'] ?? 0)],
|
||||
['Total Reimbursements' => (float)($summary['totalReimbursements'] ?? 0)],
|
||||
['Donation to School (included in expenses)' => (float)($summary['donationToSchool'] ?? 0)],
|
||||
['Donation Income to School' => (float)($summary['donationToSchool'] ?? 0)],
|
||||
['Net Charges After Discounts/Refunds' => (float)($summary['netAmount'] ?? 0)],
|
||||
['Amount Collected (Paid)' => (float)($summary['amountCollected'] ?? 0)],
|
||||
['Overpayment Credits' => (float)($summary['totalOverpaid'] ?? 0)],
|
||||
@@ -572,8 +581,8 @@ public function financialReport()
|
||||
'Parents With Outstanding Balance Details' => $sections['unpaidParents'] ?? [],
|
||||
'Expense Details' => $sections['expenses'] ?? [],
|
||||
'Reimbursement Details' => $sections['reimbursements'] ?? [],
|
||||
'Donation Expense Details' => $sections['donationExpenses'] ?? [],
|
||||
'Donation Reimbursement Details' => $sections['donationReimbursements'] ?? [],
|
||||
'Donation Income Details' => $sections['donationExpenses'] ?? [],
|
||||
'Special Recipient Reimbursement Details' => $sections['donationReimbursements'] ?? [],
|
||||
'Reimbursement Batch Fallback Details' => $sections['reimbursementBatchFallbacks'] ?? [],
|
||||
'Overpayment Credit Details' => $summary['overpaymentDetails'] ?? [],
|
||||
];
|
||||
@@ -883,6 +892,9 @@ public function financialReport()
|
||||
$donationExpenses = array_values(array_filter($expenses, static function ($row) {
|
||||
return strtolower(trim((string)($row['Category'] ?? ''))) === 'donation';
|
||||
}));
|
||||
$expenses = array_values(array_filter($expenses, static function ($row) {
|
||||
return strtolower(trim((string)($row['Category'] ?? ''))) !== 'donation';
|
||||
}));
|
||||
|
||||
$donationReimbursements = [];
|
||||
if (!empty($specialRecipientIds)) {
|
||||
@@ -1319,7 +1331,13 @@ public function financialReport()
|
||||
if (!empty($dateTo)) {
|
||||
$expBuilder->where('DATE(created_at) <=', $dateTo);
|
||||
}
|
||||
$expenses = $expBuilder->groupBy('category')->findAll();
|
||||
$expenseRows = $expBuilder->groupBy('category')->findAll();
|
||||
$categorySummary = FinancialCategorySummaryService::summarize($expenseRows);
|
||||
$expenses = [];
|
||||
foreach ($categorySummary['expenseCategories'] as $category => $amount) {
|
||||
$expenses[] = ['category' => $category, 'total_amount' => $amount];
|
||||
}
|
||||
$donationIncome = $categorySummary['donationIncome'];
|
||||
|
||||
// Reimbursements summary with filters
|
||||
$reimbBuilder = $reimbursementModel
|
||||
@@ -1412,6 +1430,10 @@ public function financialReport()
|
||||
'',
|
||||
]);
|
||||
|
||||
// Donation income is incoming money, not an expense.
|
||||
fputcsv($out, []);
|
||||
fputcsv($out, ['Donation Income to School', $donationIncome]);
|
||||
|
||||
// Expenses section
|
||||
fputcsv($out, []); // blank line
|
||||
fputcsv($out, ['Expenses Summary']);
|
||||
@@ -1469,7 +1491,7 @@ public function financialReport()
|
||||
'Total Refunds' => $data['totalRefunds'],
|
||||
'Total Expenses' => $data['totalExpenses'],
|
||||
'Total Reimbursements' => $data['totalReimbursements'],
|
||||
'Donation to School (Masjid/Donation reimbursements)' => $data['donationToSchool'] ?? 0,
|
||||
'Donation Income to School' => $data['donationToSchool'] ?? 0,
|
||||
'Net Amount (Earned Income)' => $data['netAmount'],
|
||||
'Amount Collected (Paid)' => $data['amountCollected'],
|
||||
'Amount Unpaid (Outstanding)' => $data['totalUnpaid'],
|
||||
@@ -1673,16 +1695,25 @@ public function financialReport()
|
||||
|
||||
$totalCharges += $extraChargesUnapplied;
|
||||
|
||||
// === Expenses ===
|
||||
$expenseBuilder = $expenseModel->where('school_year', $schoolYear);
|
||||
// Donation rows live in the legacy expenses table but represent incoming
|
||||
// funds. Classify them separately so they never inflate school expenses.
|
||||
$expenseCategoryBuilder = $db->table('expenses')
|
||||
->select('category, COALESCE(SUM(amount), 0) AS amount', false)
|
||||
->where('school_year', $schoolYear)
|
||||
->groupBy('category')
|
||||
->orderBy('amount', 'DESC');
|
||||
if (!empty($invoiceDateFrom)) {
|
||||
$expenseBuilder->where('DATE(created_at) >=', $invoiceDateFrom);
|
||||
$expenseCategoryBuilder->where('DATE(created_at) >=', $invoiceDateFrom);
|
||||
}
|
||||
if (!empty($invoiceDateTo)) {
|
||||
$expenseBuilder->where('DATE(created_at) <=', $invoiceDateTo);
|
||||
$expenseCategoryBuilder->where('DATE(created_at) <=', $invoiceDateTo);
|
||||
}
|
||||
$expenseResult = $expenseBuilder->selectSum('amount')->get()->getRowArray();
|
||||
$totalExpenses = isset($expenseResult['amount']) ? (float) $expenseResult['amount'] : 0.00;
|
||||
$categorySummary = FinancialCategorySummaryService::summarize(
|
||||
$expenseCategoryBuilder->get()->getResultArray()
|
||||
);
|
||||
$totalExpenses = $categorySummary['totalExpenses'];
|
||||
$donationToSchool = $categorySummary['donationIncome'];
|
||||
$expenseCategories = $categorySummary['expenseCategories'];
|
||||
|
||||
// === Reimbursements ===
|
||||
// Reimbursements: include rows missing school_year by falling back to expense.school_year
|
||||
@@ -1754,62 +1785,6 @@ public function financialReport()
|
||||
$fallbackAmount = isset($batchFallbackRow['amount']) ? (float) $batchFallbackRow['amount'] : 0.00;
|
||||
$totalReimbursements += $fallbackAmount;
|
||||
|
||||
// Donations line: donations captured as expenses (category=Donation) plus legacy Masjid/Donation reimbursements.
|
||||
$donationExpense = 0.0;
|
||||
$donationExpenseBuilder = (new ExpenseModel())
|
||||
->where('school_year', $schoolYear)
|
||||
->where('category', 'Donation');
|
||||
if (!empty($invoiceDateFrom)) {
|
||||
$donationExpenseBuilder->where('DATE(created_at) >=', $invoiceDateFrom);
|
||||
}
|
||||
if (!empty($invoiceDateTo)) {
|
||||
$donationExpenseBuilder->where('DATE(created_at) <=', $invoiceDateTo);
|
||||
}
|
||||
$donationExpenseRow = $donationExpenseBuilder->selectSum('amount')->get()->getRowArray();
|
||||
$donationExpense = isset($donationExpenseRow['amount']) ? (float) $donationExpenseRow['amount'] : 0.00;
|
||||
|
||||
$donationReimb = 0.0;
|
||||
$specialRecipientIds = array_map('intval', array_keys(ReimbursementController::SPECIAL_RECIPIENTS));
|
||||
if (!empty($specialRecipientIds)) {
|
||||
$donationBuilder = $db->table('reimbursements r')
|
||||
->select('SUM(r.amount) AS amount')
|
||||
->join('expenses e', 'e.id = r.expense_id', 'left')
|
||||
->whereIn('r.reimbursed_to', $specialRecipientIds);
|
||||
if (!empty($schoolYear)) {
|
||||
$donationBuilder
|
||||
->groupStart()
|
||||
->groupStart()
|
||||
->where('r.school_year', $schoolYear)
|
||||
->orWhere(
|
||||
"REPLACE(REPLACE(REPLACE(REPLACE(r.school_year, ' ', ''), '-', ''), '/', ''), '\\\\', '')",
|
||||
$normalizedYear
|
||||
)
|
||||
->groupEnd()
|
||||
->orGroupStart()
|
||||
->where('r.school_year IS NULL', null, false)
|
||||
->groupStart()
|
||||
->where('e.school_year', $schoolYear)
|
||||
->orWhere(
|
||||
"REPLACE(REPLACE(REPLACE(REPLACE(e.school_year, ' ', ''), '-', ''), '/', ''), '\\\\', '')",
|
||||
$normalizedYear
|
||||
)
|
||||
->groupEnd()
|
||||
->groupEnd()
|
||||
->groupEnd();
|
||||
}
|
||||
if (!empty($invoiceDateFrom)) {
|
||||
$donationBuilder->where('DATE(COALESCE(r.created_at, e.created_at)) >=', $invoiceDateFrom);
|
||||
}
|
||||
if (!empty($invoiceDateTo)) {
|
||||
$donationBuilder->where('DATE(COALESCE(r.created_at, e.created_at)) <=', $invoiceDateTo);
|
||||
}
|
||||
$donationRow = $donationBuilder->get()->getRowArray();
|
||||
$donationReimb = isset($donationRow['amount']) ? (float) $donationRow['amount'] : 0.00;
|
||||
}
|
||||
|
||||
$donationToSchool = $donationExpense + $donationReimb;
|
||||
$totalReimbursements = max(0.0, $totalReimbursements - $donationReimb);
|
||||
|
||||
// === Net, Outstanding & Overpayments ===
|
||||
$overpaymentDetails = [];
|
||||
$totalUnpaid = 0.0;
|
||||
@@ -1884,6 +1859,7 @@ public function financialReport()
|
||||
'totalDiscounts' => $totalDiscounts,
|
||||
'totalRefunds' => $totalRefunds,
|
||||
'totalExpenses' => $totalExpenses,
|
||||
'expenseCategories' => $expenseCategories,
|
||||
'totalReimbursements' => $totalReimbursements,
|
||||
'donationToSchool' => $donationToSchool,
|
||||
'totalPaid' => $totalPaid,
|
||||
|
||||
Reference in New Issue
Block a user