Commit a3fd26ba authored by Mahmoud Aglan's avatar Mahmoud Aglan

accounting bugs

parent 6d44324b
...@@ -4,6 +4,7 @@ declare(strict_types=1); ...@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Modules\Accounting\Controllers; namespace App\Modules\Accounting\Controllers;
use App\Core\Controller; use App\Core\Controller;
use App\Core\Request;
use App\Core\App; use App\Core\App;
use App\Core\Response; use App\Core\Response;
use App\Modules\Accounting\Models\BankAccount; use App\Modules\Accounting\Models\BankAccount;
...@@ -98,11 +99,11 @@ class BankAccountController extends Controller ...@@ -98,11 +99,11 @@ class BankAccountController extends Controller
return $this->redirect('/accounting/bank-accounts'); return $this->redirect('/accounting/bank-accounts');
} }
public function edit(int $id): Response public function edit(Request $request, string $id): Response
{ {
$this->authorize('accounting.bank_account.manage'); $this->authorize('accounting.bank_account.manage');
$account = BankAccount::findOrFail($id); $account = BankAccount::findOrFail((int) $id);
$glAccounts = Account::query() $glAccounts = Account::query()
->where('is_archived', '=', 0) ->where('is_archived', '=', 0)
...@@ -117,11 +118,11 @@ class BankAccountController extends Controller ...@@ -117,11 +118,11 @@ class BankAccountController extends Controller
]); ]);
} }
public function update(int $id): Response public function update(Request $request, string $id): Response
{ {
$this->authorize('accounting.bank_account.manage'); $this->authorize('accounting.bank_account.manage');
$account = BankAccount::findOrFail($id); $account = BankAccount::findOrFail((int) $id);
$data = $this->validate($_POST, [ $data = $this->validate($_POST, [
'account_name_ar' => 'required', 'account_name_ar' => 'required',
......
...@@ -4,6 +4,7 @@ declare(strict_types=1); ...@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Modules\Accounting\Controllers; namespace App\Modules\Accounting\Controllers;
use App\Core\Controller; use App\Core\Controller;
use App\Core\Request;
use App\Core\App; use App\Core\App;
use App\Core\Response; use App\Core\Response;
use App\Modules\Accounting\Models\BankReconciliation; use App\Modules\Accounting\Models\BankReconciliation;
...@@ -67,11 +68,11 @@ class BankReconciliationController extends Controller ...@@ -67,11 +68,11 @@ class BankReconciliationController extends Controller
return $this->redirect('/accounting/bank-reconciliation/create'); return $this->redirect('/accounting/bank-reconciliation/create');
} }
public function show(int $id): Response public function show(Request $request, string $id): Response
{ {
$this->authorize('accounting.bank_recon.view'); $this->authorize('accounting.bank_recon.view');
$recon = BankReconciliation::findOrFail($id); $recon = BankReconciliation::findOrFail((int) $id);
$items = $recon->items(); $items = $recon->items();
$bankAccount = BankAccount::find((int) $recon->bank_account_id); $bankAccount = BankAccount::find((int) $recon->bank_account_id);
...@@ -88,7 +89,7 @@ class BankReconciliationController extends Controller ...@@ -88,7 +89,7 @@ class BankReconciliationController extends Controller
]); ]);
} }
public function addItem(int $id): Response public function addItem(Request $request, string $id): Response
{ {
$this->authorize('accounting.bank_recon.manage'); $this->authorize('accounting.bank_recon.manage');
...@@ -98,7 +99,7 @@ class BankReconciliationController extends Controller ...@@ -98,7 +99,7 @@ class BankReconciliationController extends Controller
'amount' => 'required|numeric', 'amount' => 'required|numeric',
]); ]);
$result = BankReconciliationService::addItem($id, $_POST); $result = BankReconciliationService::addItem((int) $id, $_POST);
$session = App::getInstance()->session(); $session = App::getInstance()->session();
if ($result['success']) { if ($result['success']) {
...@@ -110,11 +111,11 @@ class BankReconciliationController extends Controller ...@@ -110,11 +111,11 @@ class BankReconciliationController extends Controller
return $this->redirect('/accounting/bank-reconciliation/' . $id); return $this->redirect('/accounting/bank-reconciliation/' . $id);
} }
public function complete(int $id): Response public function complete(Request $request, string $id): Response
{ {
$this->authorize('accounting.bank_recon.manage'); $this->authorize('accounting.bank_recon.manage');
$result = BankReconciliationService::complete($id); $result = BankReconciliationService::complete((int) $id);
$session = App::getInstance()->session(); $session = App::getInstance()->session();
if ($result['success']) { if ($result['success']) {
......
...@@ -4,6 +4,7 @@ declare(strict_types=1); ...@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Modules\Accounting\Controllers; namespace App\Modules\Accounting\Controllers;
use App\Core\Controller; use App\Core\Controller;
use App\Core\Request;
use App\Core\App; use App\Core\App;
use App\Core\Response; use App\Core\Response;
use App\Modules\Accounting\Models\Account; use App\Modules\Accounting\Models\Account;
...@@ -89,16 +90,16 @@ class ChartOfAccountsController extends Controller ...@@ -89,16 +90,16 @@ class ChartOfAccountsController extends Controller
return $this->redirect('/accounting/chart-of-accounts'); return $this->redirect('/accounting/chart-of-accounts');
} }
public function edit(int $id): Response public function edit(Request $request, string $id): Response
{ {
$this->authorize('accounting.coa.manage'); $this->authorize('accounting.coa.manage');
$account = Account::findOrFail($id); $account = Account::findOrFail((int) $id);
$parentAccounts = Account::query() $parentAccounts = Account::query()
->where('is_archived', '=', 0) ->where('is_archived', '=', 0)
->where('is_header', '=', 1) ->where('is_header', '=', 1)
->where('id', '!=', $id) ->where('id', '!=', (int) $id)
->orderBy('account_code', 'ASC') ->orderBy('account_code', 'ASC')
->get(); ->get();
...@@ -111,11 +112,11 @@ class ChartOfAccountsController extends Controller ...@@ -111,11 +112,11 @@ class ChartOfAccountsController extends Controller
]); ]);
} }
public function update(int $id): Response public function update(Request $request, string $id): Response
{ {
$this->authorize('accounting.coa.manage'); $this->authorize('accounting.coa.manage');
$account = Account::findOrFail($id); $account = Account::findOrFail((int) $id);
$data = $this->validate($_POST, [ $data = $this->validate($_POST, [
'name_ar' => 'required', 'name_ar' => 'required',
...@@ -128,7 +129,7 @@ class ChartOfAccountsController extends Controller ...@@ -128,7 +129,7 @@ class ChartOfAccountsController extends Controller
if ((int) $account->is_system === 1 && ($_POST['account_code'] ?? '') !== $account->account_code) { if ((int) $account->is_system === 1 && ($_POST['account_code'] ?? '') !== $account->account_code) {
$session = App::getInstance()->session(); $session = App::getInstance()->session();
$session->flash('_alerts', [['type' => 'error', 'message' => 'لا يمكن تعديل كود حساب نظامي']]); $session->flash('_alerts', [['type' => 'error', 'message' => 'لا يمكن تعديل كود حساب نظامي']]);
return $this->redirect('/accounting/chart-of-accounts/' . $id . '/edit'); return $this->redirect('/accounting/chart-of-accounts/' . (int) $id . '/edit');
} }
$account->update([ $account->update([
......
...@@ -4,6 +4,7 @@ declare(strict_types=1); ...@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Modules\Accounting\Controllers; namespace App\Modules\Accounting\Controllers;
use App\Core\Controller; use App\Core\Controller;
use App\Core\Request;
use App\Core\App; use App\Core\App;
use App\Core\Response; use App\Core\Response;
use App\Modules\Accounting\Models\CostCenter; use App\Modules\Accounting\Models\CostCenter;
...@@ -80,18 +81,18 @@ class CostCenterController extends Controller ...@@ -80,18 +81,18 @@ class CostCenterController extends Controller
return $this->redirect('/accounting/cost-centers'); return $this->redirect('/accounting/cost-centers');
} }
public function edit(int $id): Response public function edit(Request $request, string $id): Response
{ {
$this->authorize('accounting.cost_center.manage'); $this->authorize('accounting.cost_center.manage');
$center = CostCenter::findOrFail($id); $center = CostCenter::findOrFail((int) $id);
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$branches = $db->select("SELECT id, name_ar, name_en FROM branches WHERE is_active = 1 ORDER BY name_ar"); $branches = $db->select("SELECT id, name_ar, name_en FROM branches WHERE is_active = 1 ORDER BY name_ar");
$parents = CostCenter::query() $parents = CostCenter::query()
->where('is_archived', '=', 0) ->where('is_archived', '=', 0)
->where('id', '!=', $id) ->where('id', '!=', (int) $id)
->orderBy('code', 'ASC') ->orderBy('code', 'ASC')
->get(); ->get();
...@@ -102,11 +103,11 @@ class CostCenterController extends Controller ...@@ -102,11 +103,11 @@ class CostCenterController extends Controller
]); ]);
} }
public function update(int $id): Response public function update(Request $request, string $id): Response
{ {
$this->authorize('accounting.cost_center.manage'); $this->authorize('accounting.cost_center.manage');
$center = CostCenter::findOrFail($id); $center = CostCenter::findOrFail((int) $id);
$data = $this->validate($_POST, [ $data = $this->validate($_POST, [
'name_ar' => 'required', 'name_ar' => 'required',
......
...@@ -4,6 +4,7 @@ declare(strict_types=1); ...@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Modules\Accounting\Controllers; namespace App\Modules\Accounting\Controllers;
use App\Core\Controller; use App\Core\Controller;
use App\Core\Request;
use App\Core\App; use App\Core\App;
use App\Core\Response; use App\Core\Response;
use App\Modules\Accounting\Models\FiscalYear; use App\Modules\Accounting\Models\FiscalYear;
...@@ -92,12 +93,12 @@ class FiscalYearController extends Controller ...@@ -92,12 +93,12 @@ class FiscalYearController extends Controller
return $this->redirect('/accounting/fiscal-years'); return $this->redirect('/accounting/fiscal-years');
} }
public function show(int $id): Response public function show(Request $request, string $id): Response
{ {
$this->authorize('accounting.fiscal_year.view'); $this->authorize('accounting.fiscal_year.view');
$fy = FiscalYear::findOrFail($id); $fy = FiscalYear::findOrFail((int) $id);
$periods = PeriodClosingService::getPeriodSummary($id); $periods = PeriodClosingService::getPeriodSummary((int) $id);
return $this->view('Accounting/Views/fiscal_years/show', [ return $this->view('Accounting/Views/fiscal_years/show', [
'fiscal_year' => $fy->toArray(), 'fiscal_year' => $fy->toArray(),
...@@ -105,11 +106,11 @@ class FiscalYearController extends Controller ...@@ -105,11 +106,11 @@ class FiscalYearController extends Controller
]); ]);
} }
public function close(int $id): Response public function close(Request $request, string $id): Response
{ {
$this->authorize('accounting.fiscal_year.close'); $this->authorize('accounting.fiscal_year.close');
$result = PeriodClosingService::closeFiscalYear($id); $result = PeriodClosingService::closeFiscalYear((int) $id);
$session = App::getInstance()->session(); $session = App::getInstance()->session();
if ($result['success']) { if ($result['success']) {
...@@ -118,6 +119,6 @@ class FiscalYearController extends Controller ...@@ -118,6 +119,6 @@ class FiscalYearController extends Controller
$session->flash('_alerts', [['type' => 'error', 'message' => $result['error']]]); $session->flash('_alerts', [['type' => 'error', 'message' => $result['error']]]);
} }
return $this->redirect('/accounting/fiscal-years/' . $id); return $this->redirect('/accounting/fiscal-years/' . (int) $id);
} }
} }
...@@ -4,6 +4,7 @@ declare(strict_types=1); ...@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Modules\Accounting\Controllers; namespace App\Modules\Accounting\Controllers;
use App\Core\Controller; use App\Core\Controller;
use App\Core\Request;
use App\Core\App; use App\Core\App;
use App\Core\Response; use App\Core\Response;
use App\Modules\Accounting\Models\JournalEntry; use App\Modules\Accounting\Models\JournalEntry;
...@@ -116,12 +117,12 @@ class JournalEntryController extends Controller ...@@ -116,12 +117,12 @@ class JournalEntryController extends Controller
return $this->redirect('/accounting/journal-entries/create'); return $this->redirect('/accounting/journal-entries/create');
} }
public function show(int $id): Response public function show(Request $request, string $id): Response
{ {
$this->authorize('accounting.journal.view'); $this->authorize('accounting.journal.view');
$entry = JournalEntry::findOrFail($id); $entry = JournalEntry::findOrFail((int) $id);
$lines = JournalEntryLine::getByJournalEntry($id); $lines = JournalEntryLine::getByJournalEntry((int) $id);
// Get employee names // Get employee names
$db = App::getInstance()->db(); $db = App::getInstance()->db();
...@@ -142,11 +143,11 @@ class JournalEntryController extends Controller ...@@ -142,11 +143,11 @@ class JournalEntryController extends Controller
]); ]);
} }
public function post(int $id): Response public function post(Request $request, string $id): Response
{ {
$this->authorize('accounting.journal.post'); $this->authorize('accounting.journal.post');
$result = JournalService::postEntry($id); $result = JournalService::postEntry((int) $id);
$session = App::getInstance()->session(); $session = App::getInstance()->session();
if ($result['success']) { if ($result['success']) {
...@@ -155,16 +156,16 @@ class JournalEntryController extends Controller ...@@ -155,16 +156,16 @@ class JournalEntryController extends Controller
$session->flash('_alerts', [['type' => 'error', 'message' => $result['error']]]); $session->flash('_alerts', [['type' => 'error', 'message' => $result['error']]]);
} }
return $this->redirect('/accounting/journal-entries/' . $id); return $this->redirect('/accounting/journal-entries/' . (int) $id);
} }
public function reverse(int $id): Response public function reverse(Request $request, string $id): Response
{ {
$this->authorize('accounting.journal.reverse'); $this->authorize('accounting.journal.reverse');
$reason = $_POST['reason'] ?? 'عكس قيد'; $reason = $request->post('reason', 'عكس قيد');
$result = JournalService::reverseEntry($id, $reason); $result = JournalService::reverseEntry((int) $id, $reason);
$session = App::getInstance()->session(); $session = App::getInstance()->session();
if ($result['success']) { if ($result['success']) {
...@@ -173,7 +174,7 @@ class JournalEntryController extends Controller ...@@ -173,7 +174,7 @@ class JournalEntryController extends Controller
$session->flash('_alerts', [['type' => 'error', 'message' => $result['error']]]); $session->flash('_alerts', [['type' => 'error', 'message' => $result['error']]]);
} }
return $this->redirect('/accounting/journal-entries/' . $id); return $this->redirect('/accounting/journal-entries/' . (int) $id);
} }
public function searchAccounts(): Response public function searchAccounts(): Response
......
...@@ -180,11 +180,24 @@ final class PeriodClosingService ...@@ -180,11 +180,24 @@ final class PeriodClosingService
} }
// Check all monthly periods are closed // Check all monthly periods are closed
$openPeriods = $db->selectOne( $startDate = $fiscalYear->start_date;
"SELECT COUNT(*) as cnt FROM period_closings $endDate = $fiscalYear->end_date;
WHERE fiscal_year_id = ? AND status != 'closed' AND is_archived = 0", $start = new \DateTime($startDate);
[$fiscalYearId] $end = new \DateTime($endDate);
); $unclosedPeriods = [];
while ($start <= $end) {
$period = $start->format('Y-m');
if (!PeriodClosing::isPeriodClosed($fiscalYearId, $period)) {
$unclosedPeriods[] = $period;
}
$start->modify('first day of next month');
}
if (!empty($unclosedPeriods)) {
return [
'success' => false,
'error' => 'يوجد فترات غير مغلقة: ' . implode(', ', $unclosedPeriods) . ' — يجب إغلاقها أولاً',
];
}
// Get income statement for the entire year // Get income statement for the entire year
$incomeStatement = FinancialReportService::getIncomeStatement( $incomeStatement = FinancialReportService::getIncomeStatement(
...@@ -202,72 +215,72 @@ final class PeriodClosingService ...@@ -202,72 +215,72 @@ final class PeriodClosingService
return ['success' => false, 'error' => 'حساب الأرباح المحتجزة (3102) غير موجود']; return ['success' => false, 'error' => 'حساب الأرباح المحتجزة (3102) غير موجود'];
} }
$db->beginTransaction(); $lines = [];
try {
$lines = [];
// Close revenue accounts (debit revenue accounts to zero them out)
foreach ($incomeStatement['revenue'] as $rev) {
if (bccomp((string) $rev['balance'], '0.00', 2) !== 0) {
$lines[] = [
'account_id' => (int) $rev['id'],
'debit' => (string) $rev['balance'],
'credit' => '0.00',
'description_ar' => 'إقفال حساب إيرادات — ' . $rev['name_ar'],
];
}
}
// Close expense accounts (credit expense accounts to zero them out) // Close revenue accounts (debit revenue accounts to zero them out)
foreach ($incomeStatement['expenses'] as $exp) { foreach ($incomeStatement['revenue'] as $rev) {
if (bccomp((string) $exp['balance'], '0.00', 2) !== 0) { if (bccomp((string) $rev['balance'], '0.00', 2) !== 0) {
$lines[] = [ $lines[] = [
'account_id' => (int) $exp['id'], 'account_id' => (int) $rev['id'],
'debit' => '0.00', 'debit' => (string) $rev['balance'],
'credit' => (string) $exp['balance'], 'credit' => '0.00',
'description_ar' => 'إقفال حساب مصروفات — ' . $exp['name_ar'], 'description_ar' => 'إقفال حساب إيرادات — ' . $rev['name_ar'],
]; ];
}
} }
}
// Net income to retained earnings // Close expense accounts (credit expense accounts to zero them out)
if (bccomp($netIncome, '0.00', 2) > 0) { foreach ($incomeStatement['expenses'] as $exp) {
// Profit: Cr. Retained Earnings if (bccomp((string) $exp['balance'], '0.00', 2) !== 0) {
$lines[] = [ $lines[] = [
'account_id' => (int) $retainedEarnings['id'], 'account_id' => (int) $exp['id'],
'debit' => '0.00', 'debit' => '0.00',
'credit' => $netIncome, 'credit' => (string) $exp['balance'],
'description_ar' => 'صافي ربح السنة المالية — أرباح محتجزة', 'description_ar' => 'إقفال حساب مصروفات — ' . $exp['name_ar'],
];
} elseif (bccomp($netIncome, '0.00', 2) < 0) {
// Loss: Dr. Retained Earnings
$lines[] = [
'account_id' => (int) $retainedEarnings['id'],
'debit' => bcmul($netIncome, '-1', 2),
'credit' => '0.00',
'description_ar' => 'صافي خسارة السنة المالية — أرباح محتجزة',
]; ];
} }
}
if (empty($lines)) { // Net income to retained earnings
return ['success' => false, 'error' => 'لا توجد حسابات إيرادات أو مصروفات لإقفالها']; if (bccomp($netIncome, '0.00', 2) > 0) {
} // Profit: Cr. Retained Earnings
$lines[] = [
'account_id' => (int) $retainedEarnings['id'],
'debit' => '0.00',
'credit' => $netIncome,
'description_ar' => 'صافي ربح السنة المالية — أرباح محتجزة',
];
} elseif (bccomp($netIncome, '0.00', 2) < 0) {
// Loss: Dr. Retained Earnings
$lines[] = [
'account_id' => (int) $retainedEarnings['id'],
'debit' => bcmul($netIncome, '-1', 2),
'credit' => '0.00',
'description_ar' => 'صافي خسارة السنة المالية — أرباح محتجزة',
];
}
$closingResult = JournalService::createEntry([ if (empty($lines)) {
'entry_date' => $fiscalYear->end_date, return ['success' => false, 'error' => 'لا توجد حسابات إيرادات أو مصروفات لإقفالها'];
'description_ar' => 'قيد إقفال السنة المالية ' . $fiscalYear->name_ar, }
'description_en' => 'Year-end closing entry — ' . $fiscalYear->name_en,
'reference_type' => 'closing', // Step 1: Create closing journal entry (JournalService manages its own transaction)
'source_module' => 'accounting', $closingResult = JournalService::createEntry([
'is_auto_generated' => 1, 'entry_date' => $fiscalYear->end_date,
], $lines, true); 'description_ar' => 'قيد إقفال السنة المالية ' . $fiscalYear->name_ar,
'description_en' => 'Year-end closing entry — ' . $fiscalYear->name_en,
if (!$closingResult['success']) { 'reference_type' => 'closing',
$db->rollBack(); 'source_module' => 'accounting',
return $closingResult; 'is_auto_generated' => 1,
} ], $lines, true);
if (!$closingResult['success']) {
return $closingResult;
}
// Update fiscal year status // Step 2: Update fiscal year status and create year-end period record
$db->beginTransaction();
try {
$db->update('fiscal_years', [ $db->update('fiscal_years', [
'status' => 'closed', 'status' => 'closed',
'is_current' => 0, 'is_current' => 0,
...@@ -276,7 +289,6 @@ final class PeriodClosingService ...@@ -276,7 +289,6 @@ final class PeriodClosingService
'updated_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'),
], '`id` = ?', [$fiscalYearId]); ], '`id` = ?', [$fiscalYearId]);
// Create year-end period closing record
$endPeriod = substr($fiscalYear->end_date, 0, 7); $endPeriod = substr($fiscalYear->end_date, 0, 7);
$db->insert('period_closings', [ $db->insert('period_closings', [
'fiscal_year_id' => $fiscalYearId, 'fiscal_year_id' => $fiscalYearId,
...@@ -294,29 +306,29 @@ final class PeriodClosingService ...@@ -294,29 +306,29 @@ final class PeriodClosingService
]); ]);
$db->commit(); $db->commit();
EventBus::dispatch('accounting.fiscal_year.closed', [
'fiscal_year_id' => $fiscalYearId,
'net_income' => $netIncome,
'closing_entry' => $closingResult['journal_entry_id'],
]);
Logger::info("Fiscal year closed", [
'fiscal_year_id' => $fiscalYearId,
'net_income' => $netIncome,
]);
return [
'success' => true,
'net_income' => $netIncome,
'closing_entry_id' => $closingResult['journal_entry_id'],
'closing_entry_num' => $closingResult['entry_number'],
];
} catch (\Throwable $e) { } catch (\Throwable $e) {
$db->rollBack(); $db->rollBack();
Logger::error("Fiscal year closing failed: " . $e->getMessage()); Logger::error("Fiscal year status update failed (closing entry already posted): " . $e->getMessage());
return ['success' => false, 'error' => 'فشل إقفال السنة المالية: ' . $e->getMessage()]; return ['success' => false, 'error' => 'تم ترحيل قيد الإقفال لكن فشل تحديث حالة السنة المالية: ' . $e->getMessage()];
} }
EventBus::dispatch('accounting.fiscal_year.closed', [
'fiscal_year_id' => $fiscalYearId,
'net_income' => $netIncome,
'closing_entry' => $closingResult['journal_entry_id'],
]);
Logger::info("Fiscal year closed", [
'fiscal_year_id' => $fiscalYearId,
'net_income' => $netIncome,
]);
return [
'success' => true,
'net_income' => $netIncome,
'closing_entry_id' => $closingResult['journal_entry_id'],
'closing_entry_num' => $closingResult['entry_number'],
];
} }
/** /**
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</thead> </thead>
<tbody> <tbody>
<?php foreach ($outstanding as $ap): ?> <?php foreach ($outstanding as $ap): ?>
<?php $isOverdue = strtotime($ap['due_date']) < time(); ?> <?php $isOverdue = !empty($ap['due_date']) && strtotime($ap['due_date']) < time(); ?>
<tr> <tr>
<td><?= e($ap['supplier_name'] ?? '—') ?></td> <td><?= e($ap['supplier_name'] ?? '—') ?></td>
<td style="direction:ltr;text-align:right;"><?= e($ap['invoice_number']) ?></td> <td style="direction:ltr;text-align:right;"><?= e($ap['invoice_number']) ?></td>
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
'membership_fee' => 'عضوية', 'membership_fee' => 'عضوية',
default => $ar['document_type'] ?? '—', default => $ar['document_type'] ?? '—',
}; };
$isOverdue = strtotime($ar['due_date']) < time(); $isOverdue = !empty($ar['due_date']) && strtotime($ar['due_date']) < time();
?> ?>
<tr> <tr>
<td><?= e($ar['member_name'] ?? '—') ?></td> <td><?= e($ar['member_name'] ?? '—') ?></td>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<form method="GET" action="/accounting/reports/general-ledger" style="display:flex;gap:10px;flex-wrap:wrap;align-items:end;"> <form method="GET" action="/accounting/reports/general-ledger" style="display:flex;gap:10px;flex-wrap:wrap;align-items:end;">
<div style="flex:2;"> <div style="flex:2;">
<label class="form-label" style="font-size:12px;">الحساب</label> <label class="form-label" style="font-size:12px;">الحساب</label>
<input type="number" name="account_id" class="form-input" value="<?= $account_id ?>" placeholder="رقم الحساب (ID)"> <input type="number" name="account_id" class="form-input" value="<?= e($account_id) ?>" placeholder="رقم الحساب (ID)">
</div> </div>
<div> <div>
<label class="form-label" style="font-size:12px;">من تاريخ</label> <label class="form-label" style="font-size:12px;">من تاريخ</label>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<form method="GET" action="/accounting/reports/member-statement" style="display:flex;gap:10px;flex-wrap:wrap;align-items:end;"> <form method="GET" action="/accounting/reports/member-statement" style="display:flex;gap:10px;flex-wrap:wrap;align-items:end;">
<div> <div>
<label class="form-label" style="font-size:12px;">رقم العضو</label> <label class="form-label" style="font-size:12px;">رقم العضو</label>
<input type="number" name="member_id" class="form-input" value="<?= $member_id ?>" placeholder="ID العضو"> <input type="number" name="member_id" class="form-input" value="<?= e($member_id) ?>" placeholder="ID العضو">
</div> </div>
<div> <div>
<label class="form-label" style="font-size:12px;">من تاريخ</label> <label class="form-label" style="font-size:12px;">من تاريخ</label>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment