familyHub/api/bank_statement.php
Louis Whittington 6d10cb4726 Implement banking system features and enhancements
- Added banking mode with checking, savings, and charity accounts, including auto-split options for income.
- Introduced banking transaction management, including transfers and charity outflows.
- Updated family settings to allow configuration of banking features and interest rates.
- Enhanced data export functionality to include bank transactions.
- Improved user interface to display banking information and donation goals.
- Updated documentation to reflect new banking features and settings.
2026-03-31 11:03:53 -05:00

108 lines
3.4 KiB
PHP

<?php
require_once __DIR__ . '/../includes/api_bootstrap.php';
require_once __DIR__ . '/../includes/family_settings.php';
require_once __DIR__ . '/../includes/banking_helpers.php';
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
sendJson(['success' => false, 'error' => 'Method not allowed'], 405);
}
$people = migrateAllPeople(normalizePeopleList(readJsonFile('people.json')));
$actor = requireActivePerson($people);
$settings = loadFamilySettings();
if (!bankingEnabled($settings)) {
sendJson(['success' => false, 'error' => 'Banking mode is not enabled'], 400);
}
$month = trim((string) ($_GET['month'] ?? gmdate('Y-m')));
if (!preg_match('/^\d{4}-\d{2}$/', $month)) {
sendJson(['success' => false, 'error' => 'month must be YYYY-MM'], 400);
}
$format = trim((string) ($_GET['format'] ?? 'json'));
if (!in_array($format, ['json', 'csv'], true)) {
sendJson(['success' => false, 'error' => 'format must be json or csv'], 400);
}
$personId = trim((string) ($_GET['person_id'] ?? ''));
if ($personId === '') {
$personId = (string) ($actor['id'] ?? '');
}
$isHoh = (($actor['role'] ?? '') === ROLE_HEAD) && isHohVerified();
if (!$isHoh && $personId !== (string) ($actor['id'] ?? '')) {
sendJson(['success' => false, 'error' => 'Only verified Head of household can view statements for others'], 403);
}
$person = null;
foreach ($people as $p) {
if (($p['id'] ?? '') === $personId) {
$person = $p;
break;
}
}
if ($person === null) {
sendJson(['success' => false, 'error' => 'Person not found'], 404);
}
$rows = readJsonFile('bank_transactions.json');
if (!is_array($rows)) {
$rows = [];
}
$prefix = $month . '-';
$filtered = [];
foreach ($rows as $row) {
if (!is_array($row)) {
continue;
}
if ((string) ($row['person_id'] ?? '') !== $personId) {
continue;
}
$createdAt = (string) ($row['created_at'] ?? '');
$ymd = bankingYmd($createdAt);
if (strpos($ymd, $prefix) !== 0) {
continue;
}
$filtered[] = $row;
}
if ($format === 'csv') {
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="bank_statement_' . $personId . '_' . $month . '.csv"');
$out = fopen('php://output', 'w');
if ($out === false) {
exit;
}
fputcsv($out, ['id', 'created_at', 'type', 'amount', 'category', 'note', 'from_account', 'to_account', 'reversal_of_transaction_id']);
foreach ($filtered as $row) {
fputcsv($out, [
(string) ($row['id'] ?? ''),
(string) ($row['created_at'] ?? ''),
(string) ($row['type'] ?? ''),
(string) ($row['amount'] ?? ''),
(string) ($row['category'] ?? ''),
(string) ($row['note'] ?? ''),
(string) ($row['from_account'] ?? ''),
(string) ($row['to_account'] ?? ''),
(string) ($row['reversal_of_transaction_id'] ?? ''),
]);
}
fclose($out);
exit;
}
sendJson([
'success' => true,
'month' => $month,
'person' => [
'id' => (string) ($person['id'] ?? ''),
'name' => (string) ($person['name'] ?? ''),
],
'balances' => [
'checking' => (float) ($person['checking_balance'] ?? 0),
'savings' => (float) ($person['savings_balance'] ?? 0),
'charity_pending' => (float) ($person['charity_pending_balance'] ?? 0),
'charity_donated_total' => (float) ($person['charity_donated_total'] ?? 0),
],
'transactions' => $filtered,
]);