101 lines
2.7 KiB
PHP
101 lines
2.7 KiB
PHP
<?php
|
|
header('Content-Type: application/json');
|
|
require_once __DIR__ . '../../../db/config.php';
|
|
|
|
//
|
|
// ## Income Statement Report (Profit & Loss)
|
|
//
|
|
// Purpose: Show financial performance (Revenue - Expenses) over a period.
|
|
//
|
|
// ---
|
|
//
|
|
// **Rule (Absolute):** Reads ONLY from `accounts` and `journal_lines` for posted entries.
|
|
// Filters for accounts of type 'revenue' and 'expense'.
|
|
//
|
|
|
|
$pdo = db();
|
|
|
|
// Optional date range filtering
|
|
$start_date = $_GET['start_date'] ?? null;
|
|
$end_date = $_GET['end_date'] ?? date('Y-m-d');
|
|
|
|
try {
|
|
$sql = <<<SQL
|
|
SELECT
|
|
a.account_code,
|
|
a.account_name,
|
|
a.account_type,
|
|
a.normal_balance,
|
|
SUM(CASE
|
|
WHEN a.normal_balance = 'debit' THEN jl.debit_amount - jl.credit_amount
|
|
ELSE jl.credit_amount - jl.debit_amount
|
|
END) as balance
|
|
FROM
|
|
accounts a
|
|
JOIN
|
|
journal_lines jl ON a.account_code = jl.account_code
|
|
JOIN
|
|
journal_entries je ON jl.journal_entry_id = je.id
|
|
WHERE
|
|
je.status = 'posted'
|
|
AND a.account_type IN ('revenue', 'expense')
|
|
SQL;
|
|
|
|
$params = [];
|
|
if ($start_date) {
|
|
$sql .= " AND je.entry_date >= :start_date";
|
|
$params[':start_date'] = $start_date;
|
|
}
|
|
if ($end_date) {
|
|
$sql .= " AND je.entry_date <= :end_date";
|
|
$params[':end_date'] = $end_date;
|
|
}
|
|
|
|
$sql .= " GROUP BY a.account_code, a.account_name, a.account_type, a.normal_balance ORDER BY a.account_type, a.account_code";
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
$report_lines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Structure the report and calculate totals
|
|
$revenue_total = 0;
|
|
$expense_total = 0;
|
|
$revenues = [];
|
|
$expenses = [];
|
|
|
|
foreach ($report_lines as $line) {
|
|
if ($line['account_type'] == 'revenue') {
|
|
$revenues[] = $line;
|
|
$revenue_total += $line['balance'];
|
|
} else {
|
|
$expenses[] = $line;
|
|
$expense_total += $line['balance'];
|
|
}
|
|
}
|
|
|
|
$net_income = $revenue_total - $expense_total;
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'report_name' => 'Income Statement',
|
|
'generated_at' => date('c'),
|
|
'filters' => ['start_date' => $start_date, 'end_date' => $end_date],
|
|
'data' => [
|
|
'revenues' => $revenues,
|
|
'expenses' => $expenses
|
|
],
|
|
'summary' => [
|
|
'total_revenue' => $revenue_total,
|
|
'total_expense' => $expense_total,
|
|
'net_income' => $net_income
|
|
]
|
|
]);
|
|
|
|
} catch (PDOException $e) {
|
|
http_response_code(500);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'error' => 'Database error: ' . $e->getMessage()
|
|
]);
|
|
}
|