add cashflow report

This commit is contained in:
Flatlogic Bot 2026-02-18 02:29:36 +00:00
parent 722390af9b
commit 17c3515c4a

222
index.php
View File

@ -2021,6 +2021,42 @@ switch ($page) {
$stmt->execute($params);
$data['expiry_items'] = $stmt->fetchAll();
break;
case 'cashflow_report':
$start_date = $_GET['start_date'] ?? date('Y-m-01');
$end_date = $_GET['end_date'] ?? date('Y-m-d');
// Fetch Cash & Bank Account IDs
$cash_accounts = db()->query("SELECT id FROM acc_accounts WHERE code IN (1100, 1200)")->fetchAll(PDO::FETCH_COLUMN);
$cash_ids_str = implode(',', $cash_accounts);
if (!empty($cash_ids_str)) {
// Opening Balance
$stmt = db()->prepare("SELECT SUM(debit - credit) FROM acc_ledger l JOIN acc_journal_entries je ON l.journal_entry_id = je.id WHERE l.account_id IN ($cash_ids_str) AND je.entry_date < ?");
$stmt->execute([$start_date]);
$data['opening_balance'] = $stmt->fetchColumn() ?: 0;
// Transactions in range
$stmt = db()->prepare("SELECT
je.entry_date,
je.description,
l.debit as inflow,
l.credit as outflow,
a.name_en as other_account,
a.type as other_type
FROM acc_ledger l
JOIN acc_journal_entries je ON l.journal_entry_id = je.id
LEFT JOIN acc_ledger l2 ON l2.journal_entry_id = je.id AND l2.id != l.id
LEFT JOIN acc_accounts a ON l2.account_id = a.id
WHERE l.account_id IN ($cash_ids_str)
AND je.entry_date BETWEEN ? AND ?
ORDER BY je.entry_date ASC, je.id ASC");
$stmt->execute([$start_date, $end_date]);
$data['cash_transactions'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
} else {
$data['opening_balance'] = 0;
$data['cash_transactions'] = [];
}
break;
case 'hr_departments':
$data['departments'] = db()->query("SELECT * FROM hr_departments ORDER BY id DESC")->fetchAll();
break;
@ -2097,7 +2133,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<style>
@media print {
.sidebar, .topbar, .d-print-none, .no-print { display: none !important; }
.main-content { margin-left: 0 !important; padding: 0 !important; }
.main-content { margin: 0 !important; padding: 0 !important; }
}
</style>
</head>
@ -2206,17 +2242,20 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
</div>
<!-- Reports Section -->
<div class="nav-section-title px-4 mt-3 mb-1 text-uppercase text-muted <?= !in_array($page, ['customer_statement', 'supplier_statement']) ? 'collapsed' : '' ?>" data-bs-toggle="collapse" data-bs-target="#reports-collapse">
<div class="nav-section-title px-4 mt-3 mb-1 text-uppercase text-muted <?= !in_array($page, ['customer_statement', 'supplier_statement', 'cashflow_report']) ? 'collapsed' : '' ?>" data-bs-toggle="collapse" data-bs-target="#reports-collapse">
<span data-en="Reports" data-ar="التقارير">Reports</span>
<i class="bi bi-chevron-down"></i>
</div>
<div class="collapse <?= in_array($page, ['customer_statement', 'supplier_statement']) ? 'show' : '' ?>" id="reports-collapse">
<div class="collapse <?= in_array($page, ['customer_statement', 'supplier_statement', 'cashflow_report']) ? 'show' : '' ?>" id="reports-collapse">
<a href="index.php?page=customer_statement" class="nav-link <?= isset($_GET['page']) && $_GET['page'] === 'customer_statement' ? 'active' : '' ?>">
<i class="bi bi-file-earmark-text"></i> <span data-en="Customer Statement" data-ar="كشف حساب عميل">Customer Statement</span>
</a>
<a href="index.php?page=supplier_statement" class="nav-link <?= isset($_GET['page']) && $_GET['page'] === 'supplier_statement' ? 'active' : '' ?>">
<i class="bi bi-file-earmark-medical"></i> <span data-en="Supplier Statement" data-ar="كشف حساب مورد">Supplier Statement</span>
</a>
<a href="index.php?page=cashflow_report" class="nav-link <?= isset($_GET['page']) && $_GET['page'] === 'cashflow_report' ? 'active' : '' ?>">
<i class="bi bi-cash-stack"></i> <span data-en="Cashflow Statement" data-ar="قائمة التدفقات النقدية">Cashflow Statement</span>
</a>
<a href="index.php?page=expiry_report" class="nav-link <?= isset($_GET['page']) && $_GET['page'] === 'expiry_report' ? 'active' : '' ?>">
<i class="bi bi-calendar-x"></i> <span data-en="Expiry Report" data-ar="تقرير الانتهاء">Expiry Report</span>
</a>
@ -2287,6 +2326,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
'hr_employees' => ['en' => 'HR Employees', 'ar' => 'موظفي الموارد البشرية'],
'hr_attendance' => ['en' => 'HR Attendance', 'ar' => 'حضور الموارد البشرية'],
'hr_payroll' => ['en' => 'HR Payroll', 'ar' => 'رواتب الموارد البشرية'],
'cashflow_report' => ['en' => 'Cashflow Statement', 'ar' => 'قائمة التدفقات النقدية'],
];
$currTitle = $titles[$page] ?? $titles['dashboard'];
?>
@ -3988,7 +4028,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<?php elseif ($page === 'customer_statement' || $page === 'supplier_statement'): ?>
<div class="card p-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<div class="d-flex justify-content-between align-items-center mb-4 d-print-none">
<h5 class="m-0" data-en="<?= $currTitle['en'] ?>" data-ar="<?= $currTitle['ar'] ?>"><?= $currTitle['en'] ?></h5>
<button class="btn btn-outline-secondary d-print-none" onclick="window.print()">
<i class="bi bi-printer"></i> <span data-en="Print" data-ar="طباعة">Print</span>
@ -4084,8 +4124,138 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<?php endif; ?>
</div>
<?php elseif ($page === 'payment_methods'): ?>
<?php elseif ($page === 'cashflow_report'): ?>
<div class="card p-4">
<div class="d-flex justify-content-between align-items-center mb-4 d-print-none">
<h5 class="m-0" data-en="Cashflow Statement" data-ar="قائمة التدفقات النقدية">Cashflow Statement</h5>
<button class="btn btn-outline-secondary d-print-none" onclick="window.print()">
<i class="bi bi-printer"></i> <span data-en="Print" data-ar="طباعة">Print</span>
</button>
</div>
<div class="bg-light p-3 rounded mb-4 d-print-none">
<form method="GET" class="row g-3 align-items-end">
<input type="hidden" name="page" value="<?= $page ?>">
<div class="col-md-5">
<label class="form-label small fw-bold" data-en="From Date" data-ar="من تاريخ">From Date</label>
<input type="date" name="start_date" class="form-control" value="<?= htmlspecialchars($_GET['start_date'] ?? date('Y-m-01')) ?>">
</div>
<div class="col-md-5">
<label class="form-label small fw-bold" data-en="To Date" data-ar="إلى تاريخ">To Date</label>
<input type="date" name="end_date" class="form-control" value="<?= htmlspecialchars($_GET['end_date'] ?? date('Y-m-d')) ?>">
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary w-100">
<i class="bi bi-search"></i> <span data-en="Generate" data-ar="توليد">Generate</span>
</button>
</div>
</form>
</div>
<div id="cashflow-print">
<div class="row mb-4">
<div class="col-6">
<h3 class="mb-0"><?= htmlspecialchars($data['settings']['company_name'] ?? 'Accounting System') ?></h3>
<p class="text-muted small"><?= nl2br(htmlspecialchars($data['settings']['company_address'] ?? '')) ?></p>
</div>
<div class="col-6 text-end">
<h2 class="text-uppercase text-muted" data-en="Cashflow Statement" data-ar="قائمة التدفقات النقدية">Cashflow Statement</h2>
<p class="text-muted small">Period: <?= htmlspecialchars($_GET['start_date'] ?? date('Y-m-01')) ?> to <?= htmlspecialchars($_GET['end_date'] ?? date('Y-m-d')) ?></p>
</div>
</div>
<table class="table table-bordered">
<thead class="bg-light">
<tr>
<th data-en="Description" data-ar="الوصف">Description</th>
<th data-en="Amount (OMR)" data-ar="المبلغ (ريال عماني)" class="text-end">Amount (OMR)</th>
</tr>
</thead>
<tbody>
<tr class="fw-bold table-light">
<td data-en="Opening Cash Balance" data-ar="رصيد النقدية الافتتاحي">Opening Cash Balance</td>
<td class="text-end"><?= number_format($data['opening_balance'], 3) ?></td>
</tr>
<tr>
<td colspan="2" class="fw-bold bg-light" data-en="Operating Activities" data-ar="الأنشطة التشغيلية">Operating Activities</td>
</tr>
<?php
$op_inflow = 0; $op_outflow = 0;
$inv_inflow = 0; $inv_outflow = 0;
$fin_inflow = 0; $fin_outflow = 0;
foreach ($data['cash_transactions'] as $t) {
$amt = (float)$t['inflow'] - (float)$t['outflow'];
// Very simple categorization based on account type
if ($t['other_type'] === 'revenue' || $t['other_type'] === 'expense' || in_array($t['other_account'], ['Accounts Receivable', 'Accounts Payable', 'VAT Input', 'VAT Payable'])) {
if ($amt > 0) $op_inflow += $amt; else $op_outflow += abs($amt);
} elseif ($t['other_type'] === 'asset' && !in_array($t['other_account'], ['Accounts Receivable', 'Inventory'])) {
// Fixed assets etc
if ($amt > 0) $inv_inflow += $amt; else $inv_outflow += abs($amt);
} elseif ($t['other_type'] === 'equity' || $t['other_type'] === 'liability') {
if ($amt > 0) $fin_inflow += $amt; else $fin_outflow += abs($amt);
} else {
// Default to operating if unsure
if ($amt > 0) $op_inflow += $amt; else $op_outflow += abs($amt);
}
}
?>
<tr>
<td class="ps-4" data-en="Cash Received from Customers & Others" data-ar="المقبوضات النقدية من العملاء وغيرهم">Cash Received from Customers & Others</td>
<td class="text-end text-success"><?= number_format($op_inflow, 3) ?></td>
</tr>
<tr>
<td class="ps-4" data-en="Cash Paid to Suppliers & Expenses" data-ar="المدفوعات النقدية للموردين والمصروفات">Cash Paid to Suppliers & Expenses</td>
<td class="text-end text-danger">(<?= number_format($op_outflow, 3) ?>)</td>
</tr>
<tr class="fw-bold">
<td data-en="Net Cash from Operating Activities" data-ar="صافي النقد من الأنشطة التشغيلية">Net Cash from Operating Activities</td>
<td class="text-end border-top"><?= number_format($op_inflow - $op_outflow, 3) ?></td>
</tr>
<tr>
<td colspan="2" class="fw-bold bg-light" data-en="Investing Activities" data-ar="الأنشطة الاستثمارية">Investing Activities</td>
</tr>
<tr>
<td class="ps-4" data-en="Net Cash from Investing Activities" data-ar="صافي النقد من الأنشطة الاستثمارية">Net Cash from Investing Activities</td>
<td class="text-end"><?= number_format($inv_inflow - $inv_outflow, 3) ?></td>
</tr>
<tr>
<td colspan="2" class="fw-bold bg-light" data-en="Financing Activities" data-ar="الأنشطة التمويلية">Financing Activities</td>
</tr>
<tr>
<td class="ps-4" data-en="Net Cash from Financing Activities" data-ar="صافي النقد من الأنشطة التمويلية">Net Cash from Financing Activities</td>
<td class="text-end"><?= number_format($fin_inflow - $fin_outflow, 3) ?></td>
</tr>
<tr class="fw-bold table-primary">
<?php $net_change = ($op_inflow - $op_outflow) + ($inv_inflow - $inv_outflow) + ($fin_inflow - $fin_outflow); ?>
<td data-en="Net Change in Cash" data-ar="صافي التغير في النقدية">Net Change in Cash</td>
<td class="text-end"><?= number_format($net_change, 3) ?></td>
</tr>
<tr class="fw-bold table-success">
<td data-en="Closing Cash Balance" data-ar="رصيد النقدية الختامي">Closing Cash Balance</td>
<td class="text-end"><?= number_format($data['opening_balance'] + $net_change, 3) ?></td>
</tr>
</tbody>
</table>
<div class="mt-4 d-none d-print-block">
<div class="row">
<div class="col-6">
<p>___________________<br>Prepared By</p>
</div>
<div class="col-6 text-end">
<p>___________________<br>Approved By</p>
</div>
</div>
</div>
</div>
</div>
<div class="card p-4 d-print-none">
<div class="d-flex justify-content-between align-items-center mb-4">
<h5 class="m-0" data-en="Payment Methods" data-ar="طرق الدفع">Payment Methods</h5>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addPaymentMethodModal">
@ -4250,7 +4420,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<?php elseif ($page === 'accounting'): ?>
<div class="card p-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<div class="d-flex justify-content-between align-items-center mb-4 d-print-none">
<h5 class="m-0"><i class="fas fa-calculator me-2"></i> <span data-en="Accounting Module" data-ar="وحدة المحاسبة">Accounting Module</span></h5>
<div class="d-flex gap-2">
<form method="POST" onsubmit="return confirm('This will re-calculate all automatic journal entries from scratch. Continue?')">
@ -4272,6 +4442,36 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
</div>
</div>
<div class="d-none d-print-block mb-4">
<div class="row">
<div class="col-6">
<h3 class="mb-0"><?= htmlspecialchars($data['settings']['company_name'] ?? 'Accounting System') ?></h3>
<p class="text-muted small"><?= nl2br(htmlspecialchars($data['settings']['company_address'] ?? '')) ?></p>
</div>
<div class="col-6 text-end">
<h2 class="text-uppercase text-muted"><?= isset($_GET['view']) ? ucwords(str_replace('_', ' ', $_GET['view'])) : 'Journal' ?></h2>
</div>
</div>
</div>
<form method="POST" onsubmit="return confirm('This will re-calculate all automatic journal entries from scratch. Continue?')">
<button type="submit" name="sync_accounting" class="btn btn-outline-warning">
<i class="bi bi-arrow-repeat"></i> <span data-en="Sync All" data-ar="مزامنة الكل">Sync All</span>
</button>
</form>
<button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#addManualJournalModal">
<i class="bi bi-plus-lg"></i> <span data-en="Manual Entry" data-ar="قيد يدوي">Manual Entry</span>
</button>
<div class="btn-group">
<a href="index.php?page=accounting" class="btn <?= !isset($_GET['view']) ? 'btn-primary' : 'btn-outline-primary' ?>" data-en="Journal" data-ar="اليومية">Journal</a>
<a href="index.php?page=accounting&view=coa" class="btn <?= isset($_GET['view']) && $_GET['view'] === 'coa' ? 'btn-primary' : 'btn-outline-primary' ?>" data-en="Accounts" data-ar="الحسابات">Accounts</a>
<a href="index.php?page=accounting&view=trial_balance" class="btn <?= isset($_GET['view']) && $_GET['view'] === 'trial_balance' ? 'btn-primary' : 'btn-outline-primary' ?>" data-en="Trial Balance" data-ar="ميزان المراجعة">Trial Balance</a>
<a href="index.php?page=accounting&view=profit_loss" class="btn <?= isset($_GET['view']) && $_GET['view'] === 'profit_loss' ? 'btn-primary' : 'btn-outline-primary' ?>" data-en="P&L" data-ar="الأرباح">P&L</a>
<a href="index.php?page=accounting&view=balance_sheet" class="btn <?= isset($_GET['view']) && $_GET['view'] === 'balance_sheet' ? 'btn-primary' : 'btn-outline-primary' ?>" data-en="Balance Sheet" data-ar="الميزانية">Balance Sheet</a>
<a href="index.php?page=accounting&view=vat_report" class="btn <?= isset($_GET['view']) && $_GET['view'] === 'vat_report' ? 'btn-primary' : 'btn-outline-primary' ?>" data-en="VAT Report" data-ar="تقرير الضريبة">VAT Report</a>
</div>
</div>
</div>
<?php if (!isset($_GET['view'])): ?>
<div class="table-responsive">
<table class="table table-hover align-middle">
@ -7554,8 +7754,8 @@ document.addEventListener('DOMContentLoaded', function() {
<style>
@media print {
.no-print, .sidebar, .topbar, .card, .btn, .modal-header, .modal-footer, .d-print-none, .table-responsive,
table:not(.table-formal), .bg-light:not(.invoice-info-card):not(.p-3), .modal-backdrop { display: none !important; }
.no-print, .sidebar, .topbar, .btn, .modal-header, .modal-footer, .d-print-none, .table-responsive,
table:not(.table-formal):not(.table-bordered), .bg-light:not(.invoice-info-card):not(.p-3):not(.card):not(.table-light), .modal-backdrop { display: none !important; }
body { background: white !important; margin: 0 !important; padding: 0 !important; }
.main-content { margin: 0 !important; padding: 0 !important; background: white !important; }
@ -7586,9 +7786,9 @@ document.addEventListener('DOMContentLoaded', function() {
.text-primary { color: #0d6efd !important; -webkit-print-color-adjust: exact; }
.badge { border: 1px solid #000; color: #000 !important; }
/* Ensure the modal is the only thing visible */
body > *:not(.main-content):not(.modal) { display: none !important; }
.main-content > *:not(.modal) { display: none !important; }
/* Ensure the modal is the only thing visible ONLY when a modal is open */
body.modal-open > *:not(.modal) { display: none !important; }
body.modal-open .main-content { display: none !important; }
}
.invoice-logo { max-height: 80px; width: auto; }
.invoice-header { border-bottom: 2px solid #333; padding-bottom: 20px; }