Commit ab834992 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Block death registration when member has overdue subscriptions

Shows a modal popup on death/create page listing overdue years
and amounts. The user must go to subscriptions and settle
outstanding balances before registering a death case.
The death fee calculation itself remains unchanged.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 42f8a499
...@@ -158,13 +158,25 @@ class DeathController extends Controller ...@@ -158,13 +158,25 @@ class DeathController extends Controller
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$member = $db->selectOne("SELECT * FROM members WHERE id = ? AND is_archived = 0", [(int) $memberId]); $member = $db->selectOne("SELECT * FROM members WHERE id = ? AND is_archived = 0", [(int) $memberId]);
if (!$member) return $this->redirect('/members')->withError('العضو غير موجود'); if (!$member) return $this->redirect('/members')->withError('العضو غير موجود');
// Check for overdue/unpaid subscriptions
$overdueSubscriptions = $db->select(
"SELECT financial_year, COUNT(*) as cnt, SUM(total_amount - paid_amount) as total_due
FROM subscriptions
WHERE member_id = ? AND status IN ('pending', 'overdue') AND is_voided = 0
GROUP BY financial_year
ORDER BY financial_year ASC",
[(int) $memberId]
);
$totalOverdue = '0.00';
foreach ($overdueSubscriptions as $row) {
$totalOverdue = bcadd($totalOverdue, $row['total_due'] ?? '0', 2);
}
$spouses = $db->select("SELECT * FROM spouses WHERE member_id = ? AND is_archived = 0 AND status = 'active' ORDER BY spouse_order", [(int) $memberId]); $spouses = $db->select("SELECT * FROM spouses WHERE member_id = ? AND is_archived = 0 AND status = 'active' ORDER BY spouse_order", [(int) $memberId]);
$children = $db->select("SELECT * FROM children WHERE member_id = ? AND is_archived = 0 ORDER BY child_order", [(int) $memberId]); $children = $db->select("SELECT * FROM children WHERE member_id = ? AND is_archived = 0 ORDER BY child_order", [(int) $memberId]);
$temps = $db->select("SELECT * FROM temporary_members WHERE member_id = ? AND is_archived = 0 AND status = 'active' ORDER BY id", [(int) $memberId]); $temps = $db->select("SELECT * FROM temporary_members WHERE member_id = ? AND is_archived = 0 AND status = 'active' ORDER BY id", [(int) $memberId]);
$fees = self::getFees(); $fees = self::getFees();
// Preview: assume primary spouse becomes member, no secondaries yet
// Pass all spouses IDs to exclude (since user picks one as primary and others may be secondary)
// Worst case: show 1 member + children + temps (no extra spouses)
$familySub = self::calculateFamilyAnnualSub((int) $memberId, 0, array_column($spouses, 'id')); $familySub = self::calculateFamilyAnnualSub((int) $memberId, 0, array_column($spouses, 'id'));
return $this->view('Death.Views.create', [ return $this->view('Death.Views.create', [
...@@ -176,6 +188,8 @@ class DeathController extends Controller ...@@ -176,6 +188,8 @@ class DeathController extends Controller
'annual_sub' => $familySub['annual_sub_total'], 'annual_sub' => $familySub['annual_sub_total'],
'total_fee' => bcadd($fees['formFee'], $familySub['annual_sub_total'], 2), 'total_fee' => bcadd($fees['formFee'], $familySub['annual_sub_total'], 2),
'family_sub' => $familySub, 'family_sub' => $familySub,
'overdueSubscriptions' => $overdueSubscriptions,
'totalOverdue' => $totalOverdue,
]); ]);
} }
......
...@@ -10,6 +10,59 @@ ...@@ -10,6 +10,59 @@
<a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">← العودة للعضو</a> <a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">← العودة للعضو</a>
</div> </div>
<?php if (!empty($overdueSubscriptions) && bccomp($totalOverdue, '0', 2) > 0): ?>
<div id="overdue-modal" style="position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.6);">
<div style="background:white;border-radius:12px;max-width:500px;width:90%;box-shadow:0 25px 50px rgba(0,0,0,0.25);overflow:hidden;">
<div style="padding:20px 24px;border-bottom:1px solid #FCA5A5;background:#FEF2F2;">
<h3 style="margin:0;color:#DC2626;font-size:16px;display:flex;align-items:center;gap:8px;">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#DC2626" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
يوجد اشتراكات متأخرة غير مسددة
</h3>
</div>
<div style="padding:24px;">
<p style="margin:0 0 16px;color:#374151;font-size:14px;">
العضو <strong><?= e($member['full_name_ar']) ?></strong> عليه سنوات اشتراك غير مسددة.
يجب تسديد التجديدات المتأخرة أولاً قبل تسجيل حالة الوفاة.
</p>
<div style="background:#F9FAFB;border:1px solid #E5E7EB;border-radius:8px;padding:12px;margin-bottom:16px;">
<table style="width:100%;font-size:13px;border-collapse:collapse;">
<thead>
<tr style="border-bottom:1px solid #E5E7EB;">
<th style="text-align:right;padding:6px 8px;color:#6B7280;">السنة المالية</th>
<th style="text-align:right;padding:6px 8px;color:#6B7280;">عدد الاشتراكات</th>
<th style="text-align:left;padding:6px 8px;color:#6B7280;">المبلغ المستحق</th>
</tr>
</thead>
<tbody>
<?php foreach ($overdueSubscriptions as $row): ?>
<tr>
<td style="padding:6px 8px;font-weight:600;"><?= e($row['financial_year']) ?></td>
<td style="padding:6px 8px;"><?= (int) $row['cnt'] ?> اشتراك</td>
<td style="padding:6px 8px;text-align:left;color:#DC2626;font-weight:600;" dir="ltr"><?= number_format((float) $row['total_due'], 2) ?> ج.م</td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot>
<tr style="border-top:2px solid #E5E7EB;">
<td colspan="2" style="padding:8px;font-weight:700;">الإجمالي المستحق</td>
<td style="padding:8px;text-align:left;font-weight:700;color:#DC2626;font-size:15px;" dir="ltr"><?= number_format((float) $totalOverdue, 2) ?> ج.م</td>
</tr>
</tfoot>
</table>
</div>
<div style="display:flex;gap:12px;">
<a href="/members/<?= (int) $member['id'] ?>/subscriptions" class="btn btn-primary" style="flex:1;text-align:center;padding:12px;font-size:14px;">
سداد الاشتراكات المتأخرة
</a>
<a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline" style="flex:0;padding:12px 20px;font-size:14px;">
رجوع
</a>
</div>
</div>
</div>
</div>
<?php endif; ?>
<form method="POST" action="/death/store/<?= (int) $member['id'] ?>" enctype="multipart/form-data"> <form method="POST" action="/death/store/<?= (int) $member['id'] ?>" enctype="multipart/form-data">
<?= csrf_field() ?> <?= csrf_field() ?>
......
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