Commit 28433036 authored by Mahmoud Aglan's avatar Mahmoud Aglan

feat(members): show subscription status, transfer details, and overdue amounts

1. Subscription badge: shows if active (paid), overdue, or awaiting renewal
2. Overdue table: lists all unpaid subscriptions with amounts needed to renew
3. Transfer origin card: shows who transferred, when, and actual amount paid
4. Financial summary: shows actual paid amount (not original membership_value) for transferred members
5. Payment history link for deceased member (accessible from transferee's page)
6. Redirect /members/{id} to archive page if member is archived
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent f8b4b352
...@@ -180,7 +180,8 @@ class MemberController extends Controller ...@@ -180,7 +180,8 @@ class MemberController extends Controller
{ {
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$member = Member::find((int) $id); $member = Member::find((int) $id);
if (!$member || $member->is_archived) return $this->redirect('/members')->withError('العضو غير موجود'); if (!$member) return $this->redirect('/members')->withError('العضو غير موجود');
if ($member->is_archived) return $this->redirect('/members/archive/' . (int) $id);
$branch = $db->selectOne("SELECT name_ar FROM branches WHERE id = ?", [(int) $member->branch_id]); $branch = $db->selectOne("SELECT name_ar FROM branches WHERE id = ?", [(int) $member->branch_id]);
$qualification = $member->qualification_id ? $db->selectOne("SELECT name_ar FROM qualifications WHERE id = ?", [(int) $member->qualification_id]) : null; $qualification = $member->qualification_id ? $db->selectOne("SELECT name_ar FROM qualifications WHERE id = ?", [(int) $member->qualification_id]) : null;
...@@ -286,11 +287,50 @@ class MemberController extends Controller ...@@ -286,11 +287,50 @@ class MemberController extends Controller
$deathTransfer = null; $deathTransfer = null;
if (!empty($member->transferred_from_death_id)) { if (!empty($member->transferred_from_death_id)) {
$deathTransfer = $db->selectOne( $deathTransfer = $db->selectOne(
"SELECT dc.id, dc.member_id as deceased_member_id, m.full_name_ar as deceased_member_name "SELECT dc.id, dc.member_id as deceased_member_id, m.full_name_ar as deceased_member_name,
dc.completed_at as transfer_date
FROM death_cases dc LEFT JOIN members m ON m.id = dc.member_id FROM death_cases dc LEFT JOIN members m ON m.id = dc.member_id
WHERE dc.id = ?", WHERE dc.id = ?",
[(int) $member->transferred_from_death_id] [(int) $member->transferred_from_death_id]
); );
if ($deathTransfer) {
$deathPayment = $db->selectOne(
"SELECT amount, payment_date FROM payments WHERE member_id = ? AND payment_type = 'death_transfer_fee' AND is_voided = 0 ORDER BY id DESC LIMIT 1",
[(int) $id]
);
$deathTransfer['paid_amount'] = $deathPayment['amount'] ?? null;
$deathTransfer['payment_date'] = $deathPayment['payment_date'] ?? null;
}
}
// Subscription status for current FY
$currentMonth = (int) date('n');
$currentYear = (int) date('Y');
$currentFY = $currentMonth >= 7 ? "$currentYear-" . ($currentYear + 1) : ($currentYear - 1) . "-$currentYear";
$subscriptionStatus = $db->selectOne(
"SELECT id, financial_year, status, total_amount, paid_amount, fine_amount
FROM subscriptions WHERE member_id = ? AND financial_year = ? LIMIT 1",
[(int) $id, $currentFY]
);
$overdueSubscriptions = $db->select(
"SELECT financial_year, total_amount, paid_amount, fine_amount, status
FROM subscriptions WHERE member_id = ? AND status IN ('pending','overdue')
ORDER BY financial_year ASC",
[(int) $id]
);
// Transfer fee payment (for separated children / waiver-acquired members)
$transferFeePayment = null;
if (!empty($member->transferred_from_waiver_id)) {
$transferFeePayment = $db->selectOne(
"SELECT amount, payment_date FROM payments WHERE member_id = ? AND payment_type = 'waiver_fee' AND is_voided = 0 ORDER BY id DESC LIMIT 1",
[(int) $id]
);
} elseif (!empty($member->transferred_from_divorce_id)) {
$transferFeePayment = $db->selectOne(
"SELECT amount, payment_date FROM payments WHERE member_id = ? AND payment_type IN ('separation_fee','transfer_fee','child_separation_fee') AND is_voided = 0 ORDER BY id DESC LIMIT 1",
[(int) $id]
);
} }
$instRateData = RuleEngine::get('INSTALLMENT_INTEREST_RATE'); $instRateData = RuleEngine::get('INSTALLMENT_INTEREST_RATE');
...@@ -322,6 +362,9 @@ class MemberController extends Controller ...@@ -322,6 +362,9 @@ class MemberController extends Controller
: null, : null,
'installInterestRate' => (float) ($instRateData['percentage'] ?? 22), 'installInterestRate' => (float) ($instRateData['percentage'] ?? 22),
'installMaxMonths' => (int) ($instMonthsData['months'] ?? 30), 'installMaxMonths' => (int) ($instMonthsData['months'] ?? 30),
'subscriptionStatus' => $subscriptionStatus,
'overdueSubscriptions' => $overdueSubscriptions,
'transferFeePayment' => $transferFeePayment,
]); ]);
} }
......
This diff is collapsed.
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