38471-vm/pages/accounting_view.php
2026-05-03 02:08:14 +00:00

420 lines
24 KiB
PHP

<div class="card p-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?')">
<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="Chart of Accounts" data-ar="شجرة الحسابات">Chart of 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>
<button class="btn btn-outline-secondary" onclick="window.print()">
<i class="bi bi-printer"></i> <span data-en="Print" data-ar="طباعة">Print</span>
</button>
</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']) ? ($_GET['view'] === 'coa' ? 'Chart of Accounts' : ucwords(str_replace('_', ' ', $_GET['view']))) : 'Journal' ?></h2>
</div>
</div>
</div>
<?php if (!isset($_GET['view'])): ?>
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead>
<tr>
<th data-en="Date" data-ar="التاريخ">Date</th>
<th data-en="Description" data-ar="الوصف">Description</th>
<th data-en="Reference" data-ar="المرجع">Reference</th>
<th data-en="Amount" data-ar="المبلغ">Amount</th>
<th data-en="Action" data-ar="الإجراء">Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($data['journal_entries'] as $entry): ?>
<tr>
<td><?= $entry['entry_date'] ?></td>
<td><?= htmlspecialchars($entry['description']) ?></td>
<td><span class="badge bg-secondary"><?= htmlspecialchars($entry['reference']) ?></span></td>
<td><?= number_format((float)$entry['total_debit'], 3) ?></td>
<td>
<button class="btn btn-sm btn-outline-info" onclick="viewJournalEntry(<?= $entry['id'] ?>)">
<i class="bi bi-eye"></i> <span data-en="View" data-ar="عرض">View</span>
</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?= renderPagination($data['current_page'] ?? 1, $data['total_pages'] ?? 1) ?>
<?php elseif ($_GET['view'] === 'coa'): ?>
<div class="row g-3 mb-4">
<div class="col-md-4">
<div class="card border-0 bg-light h-100">
<div class="card-body">
<div class="text-muted text-uppercase small mb-2">Total Accounts</div>
<div class="display-6 fw-bold mb-1"><?= number_format((int)($data['coa_summary']['total'] ?? 0)) ?></div>
<div class="small text-muted">All parent and child accounts in your chart.</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-0 bg-light h-100">
<div class="card-body">
<div class="text-muted text-uppercase small mb-2">Main Parents</div>
<div class="display-6 fw-bold mb-1"><?= number_format((int)($data['coa_summary']['parents'] ?? 0)) ?></div>
<div class="small text-muted">Top-level groups like Assets, Liabilities, Revenue, and Expenses.</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-0 bg-light h-100">
<div class="card-body">
<div class="text-muted text-uppercase small mb-2">Child Accounts</div>
<div class="display-6 fw-bold mb-1"><?= number_format((int)($data['coa_summary']['children'] ?? 0)) ?></div>
<div class="small text-muted">Operational accounts you can post transactions into.</div>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-3">
<div>
<h6 class="mb-1" data-en="Chart of Accounts" data-ar="شجرة الحسابات">Chart of Accounts</h6>
<p class="text-muted small mb-0">Use this page to seed the main parent accounts, then add custom child accounts under the right parent.</p>
</div>
<div class="d-flex gap-2">
<form method="POST" onsubmit="return confirm('Seed the default main accounts and repair parent links?')">
<button type="submit" name="seed_default_accounts" class="btn btn-outline-secondary btn-sm">
<i class="bi bi-diagram-3"></i> <span data-en="Seed Main Accounts" data-ar="زرع الحسابات الرئيسية">Seed Main Accounts</span>
</button>
</form>
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addAccountModal">
<i class="bi bi-plus-lg"></i> <span data-en="Add Account" data-ar="إضافة حساب">Add Account</span>
</button>
</div>
</div>
<?php if (empty($data['coa'])): ?>
<div class="alert alert-warning border-0 shadow-sm">
<i class="bi bi-exclamation-triangle me-1"></i>
No accounts exist yet. Click <strong>Seed Main Accounts</strong> to create the default chart of accounts.
</div>
<?php endif; ?>
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead class="table-light">
<tr>
<th data-en="Code" data-ar="الكود">Code</th>
<th data-en="Name" data-ar="الاسم">Name</th>
<th data-en="Type" data-ar="النوع">Type</th>
<th data-en="Level" data-ar="المستوى">Level</th>
<th data-en="Parent" data-ar="الحساب الأب">Parent</th>
<th data-en="Balance" data-ar="الرصيد" class="text-end">Balance</th>
</tr>
</thead>
<tbody>
<?php foreach ($data['coa'] as $acc): ?>
<tr>
<td class="fw-bold"><?= htmlspecialchars($acc['code']) ?></td>
<td>
<?= htmlspecialchars($acc['name_en']) ?><br>
<small class="text-muted"><?= htmlspecialchars($acc['name_ar']) ?></small>
</td>
<td><span class="badge bg-light text-dark border text-uppercase"><?= htmlspecialchars($acc['type']) ?></span></td>
<td>
<?php if (empty($acc['parent_id'])): ?>
<span class="badge bg-light text-primary border">Main</span>
<?php else: ?>
<span class="badge bg-light text-secondary border">Child</span>
<?php endif; ?>
</td>
<td><?= htmlspecialchars($acc['parent_name'] ?? '— Main Account —') ?></td>
<td class="text-end fw-bold"><?= number_format((float)getAccountBalance($acc['code']), 3) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php elseif ($_GET['view'] === 'vat_report'): ?>
<div class="row">
<div class="col-md-6 mx-auto">
<div class="bg-light p-3 rounded mb-4 d-print-none">
<form method="GET" class="row g-2">
<input type="hidden" name="page" value="accounting">
<input type="hidden" name="view" value="vat_report">
<div class="col">
<input type="date" name="start_date" class="form-control" value="<?= $data['start_date'] ?>">
</div>
<div class="col">
<input type="date" name="end_date" class="form-control" value="<?= $data['end_date'] ?>">
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary" data-en="Filter" data-ar="تصفية">Filter</button>
</div>
</form>
</div>
<div class="card shadow-sm border-0">
<div class="card-body">
<h4 class="text-center mb-4 d-print-none">VAT Summary Report</h4>
<table class="table">
<tr>
<th data-en="VAT Input (Purchases)" data-ar="ضريبة المدخلات (المشتريات)">VAT Input (Purchases)</th>
<td class="text-end text-success fw-bold"><?= number_format($data['vat_report']['input_vat'], 2) ?></td>
</tr>
<tr>
<th data-en="VAT Output (Sales)" data-ar="ضريبة المخرجات (المبيعات)">VAT Output (Sales)</th>
<td class="text-end text-danger fw-bold"><?= number_format($data['vat_report']['output_vat'], 2) ?></td>
</tr>
<tr class="table-dark h5">
<th data-en="Net VAT Payable / (Refundable)" data-ar="صافي الضريبة المستحقة / (المستردة)">Net VAT Payable / (Refundable)</th>
<td class="text-end"><?= number_format($data['vat_report']['net_vat'], 2) ?></td>
</tr>
</table>
<div class="alert alert-info small mt-3">
<i class="bi bi-info-circle me-1"></i>
This report calculates the difference between VAT collected on sales and VAT paid on purchases for the selected period.
</div>
</div>
</div>
</div>
</div>
<?php elseif ($_GET['view'] === 'trial_balance'): ?>
<div class="table-responsive">
<table class="table table-bordered">
<thead class="table-light">
<tr>
<th data-en="Code" data-ar="الكود">Code</th>
<th data-en="Account Name" data-ar="اسم الحساب">Account Name</th>
<th class="text-end" data-en="Debit" data-ar="مدين">Debit</th>
<th class="text-end" data-en="Credit" data-ar="دائن">Credit</th>
</tr>
</thead>
<tbody>
<?php
$total_d = 0; $total_c = 0;
foreach ($data['trial_balance'] as $row):
$total_d += (float)$row['total_debit'];
$total_c += (float)$row['total_credit'];
?>
<tr>
<td><?= $row['code'] ?></td>
<td><?= htmlspecialchars($row['name_en']) ?></td>
<td class="text-end"><?= number_format((float)$row['total_debit'], 3) ?></td>
<td class="text-end"><?= number_format((float)$row['total_credit'], 3) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot class="table-light fw-bold">
<tr>
<td colspan="2" class="text-end" data-en="Total" data-ar="الإجمالي">Total</td>
<td class="text-end"><?= number_format($total_d, 3) ?></td>
<td class="text-end"><?= number_format($total_c, 3) ?></td>
</tr>
</tfoot>
</table>
</div>
<?php elseif ($_GET['view'] === 'profit_loss'): ?>
<div class="row">
<div class="col-md-8 mx-auto">
<div class="card bg-light">
<div class="card-body">
<h4 class="text-center mb-4 d-print-none" data-en="Profit & Loss Statement" data-ar="قائمة الأرباح والخسائر">Profit & Loss Statement</h4>
<table class="table">
<tr class="table-primary"><th colspan="2" data-en="Revenue" data-ar="الإيرادات">Revenue</th></tr>
<?php
$total_rev = 0;
foreach ($data['revenue_accounts'] as $acc):
$bal = getAccountBalance($acc['code']);
if ($bal == 0) continue;
$total_rev += $bal;
?>
<tr>
<td><?= htmlspecialchars($acc['name_en']) ?></td>
<td class="text-end"><?= number_format($bal, 3) ?></td>
</tr>
<?php endforeach; ?>
<tr class="fw-bold">
<td data-en="Total Revenue" data-ar="إجمالي الإيرادات">Total Revenue</td>
<td class="text-end border-top"><?= number_format($total_rev, 3) ?></td>
</tr>
<tr class="table-warning"><th colspan="2" class="pt-4" data-en="Expenses" data-ar="المصروفات">Expenses</th></tr>
<?php
$total_exp = 0;
foreach ($data['expense_accounts'] as $acc):
$bal = getAccountBalance($acc['code']);
if ($bal == 0) continue;
$total_exp += $bal;
?>
<tr>
<td><?= htmlspecialchars($acc['name_en']) ?></td>
<td class="text-end"><?= number_format($bal, 3) ?></td>
</tr>
<?php endforeach; ?>
<tr class="fw-bold">
<td data-en="Total Expenses" data-ar="إجمالي المصروفات">Total Expenses</td>
<td class="text-end border-top"><?= number_format($total_exp, 3) ?></td>
</tr>
<tr class="table-success h4">
<td data-en="Net Profit / Loss" data-ar="صافي الربح / الخسارة">Net Profit / Loss</td>
<td class="text-end"><?= number_format($total_rev - $total_exp, 3) ?></td>
</tr>
</table>
</div>
</div>
</div>
</div>
<?php elseif ($_GET['view'] === 'balance_sheet'): ?>
<div class="row">
<div class="col-md-10 mx-auto">
<div class="card bg-light">
<div class="card-body">
<h4 class="text-center mb-4 d-print-none" data-en="Balance Sheet" data-ar="الميزانية العمومية">Balance Sheet</h4>
<div class="row">
<div class="col-md-6 border-end">
<h5 class="text-primary border-bottom pb-2" data-en="Assets" data-ar="الأصول">Assets</h5>
<table class="table table-sm">
<?php
$total_assets = 0;
foreach ($data['asset_accounts'] as $acc):
$bal = getAccountBalance($acc['code']);
if ($bal == 0) continue;
$total_assets += $bal;
?>
<tr>
<td><?= htmlspecialchars($acc['name_en']) ?></td>
<td class="text-end"><?= number_format($bal, 3) ?></td>
</tr>
<?php endforeach; ?>
<tr class="fw-bold h5">
<td data-en="Total Assets" data-ar="إجمالي الأصول">Total Assets</td>
<td class="text-end border-top"><?= number_format($total_assets, 3) ?></td>
</tr>
</table>
</div>
<div class="col-md-6">
<h5 class="text-danger border-bottom pb-2" data-en="Liabilities & Equity" data-ar="الالتزامات وحقوق الملكية">Liabilities & Equity</h5>
<table class="table table-sm">
<tr class="bg-light"><td colspan="2" class="small fw-bold text-muted">Liabilities</td></tr>
<?php
$total_liab = 0;
foreach ($data['liability_accounts'] as $acc):
$bal = getAccountBalance($acc['code']);
if ($bal == 0) continue;
$total_liab += $bal;
?>
<tr>
<td><?= htmlspecialchars($acc['name_en']) ?></td>
<td class="text-end"><?= number_format($bal, 3) ?></td>
</tr>
<?php endforeach; ?>
<tr class="bg-light"><td colspan="2" class="small fw-bold text-muted pt-3">Equity</td></tr>
<?php
$total_equity = 0;
foreach ($data['equity_accounts'] as $acc):
$bal = getAccountBalance($acc['code']);
if ($bal == 0) continue;
$total_equity += $bal;
?>
<tr>
<td><?= htmlspecialchars($acc['name_en']) ?></td>
<td class="text-end"><?= number_format($bal, 3) ?></td>
</tr>
<?php endforeach; ?>
<?php
// Current Year Earnings (Revenue - Expenses)
$rev = 0; foreach(db()->query("SELECT code FROM acc_accounts WHERE type='revenue' AND parent_id IS NOT NULL")->fetchAll() as $a) $rev += getAccountBalance($a['code']);
$exp = 0; foreach(db()->query("SELECT code FROM acc_accounts WHERE type='expense' AND parent_id IS NOT NULL")->fetchAll() as $a) $exp += getAccountBalance($a['code']);
$earnings = $rev - $exp;
$total_equity += $earnings;
?>
<tr>
<td data-en="Retained Earnings (Current)" data-ar="الأرباح المحتجزة (الحالية)">Retained Earnings (Current)</td>
<td class="text-end"><?= number_format($earnings, 3) ?></td>
</tr>
<tr class="fw-bold h5 pt-3">
<td data-en="Total Liab. & Equity" data-ar="إجمالي الالتزامات وحقوق الملكية">Total Liab. & Equity</td>
<td class="text-end border-top"><?= number_format($total_liab + $total_equity, 3) ?></td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
</div>
<!-- Journal Entry Details Modal -->
<div class="modal fade" id="journalModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" data-en="Journal Entry Details" data-ar="تفاصيل قيد اليومية">Journal Entry Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<table class="table table-bordered">
<thead>
<tr>
<th data-en="Account" data-ar="الحساب">Account</th>
<th class="text-end" data-en="Debit" data-ar="مدين">Debit</th>
<th class="text-end" data-en="Credit" data-ar="دائن">Credit</th>
</tr>
</thead>
<tbody id="journalDetailsBody"></tbody>
</table>
</div>
</div>
</div>
</div>
<script>
function viewJournalEntry(id) {
fetch('index.php?page=accounting&action=get_entry_details&id=' + id)
.then(r => r.json())
.then(data => {
let html = '';
data.forEach(row => {
html += `<tr>
<td>${row.code} - ${row.name_en}</td>
<td class="text-end">${parseFloat(row.debit).toFixed(3)}</td>
<td class="text-end">${parseFloat(row.credit).toFixed(3)}</td>
</tr>`;
});
document.getElementById('journalDetailsBody').innerHTML = html;
new bootstrap.Modal(document.getElementById('journalModal')).show();
});
}
</script>