add cashflow report
This commit is contained in:
parent
722390af9b
commit
17c3515c4a
222
index.php
222
index.php
@ -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; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user