Commit 94e1f426 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Use current membership value from pricing_configs for divorce fee calculation

Instead of using the stored member.membership_value (which may be outdated),
the divorce module now fetches the current active price from pricing_configs
based on the member's branch and qualification at the time of the request.

- Added DivorceFeeCalculator::getCurrentMembershipValue() method
- Updated boardApprove, show, and create to use current pricing
- Views now display "قيمة العضوية الحالية" with source indicator
- Payment breakdown shows which source was used for the calculation
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent e64c8865
......@@ -33,7 +33,14 @@ class DivorceController extends Controller
$spouses = $db->select("SELECT * FROM spouses WHERE member_id = ? AND is_archived = 0 AND status = 'active'", [(int) $memberId]);
if (empty($spouses)) return $this->redirect("/members/{$memberId}")->withError('لا يوجد زوج/زوجة مسجلة');
$qualifications = $db->select("SELECT id, name_ar FROM qualifications WHERE is_active = 1 ORDER BY sort_order");
return $this->view('Divorce.Views.create', ['member' => $member, 'spouses' => $spouses, 'qualifications' => $qualifications]);
$valueInfo = DivorceFeeCalculator::getCurrentMembershipValue($member);
return $this->view('Divorce.Views.create', [
'member' => $member,
'spouses' => $spouses,
'qualifications' => $qualifications,
'currentMembershipValue' => $valueInfo['value'],
'membershipValueSource' => $valueInfo['source'],
]);
}
public function store(Request $request, string $memberId): Response
......@@ -122,7 +129,10 @@ class DivorceController extends Controller
$feePercentage = (string) $feePercentage;
$member = $db->selectOne("SELECT * FROM members WHERE id = ?", [(int) $case['member_id']]);
$membershipValue = $member['membership_value'] ?? '0.00';
// Use current membership value from pricing_configs (not stored member value)
$valueInfo = DivorceFeeCalculator::getCurrentMembershipValue($member);
$membershipValue = $valueInfo['value'];
// Calculate fees: percentage * membership_value + form fee (570) + annual subscription
$percentageFee = bcdiv(bcmul($membershipValue, $feePercentage, 4), '100', 2);
......@@ -162,7 +172,7 @@ class DivorceController extends Controller
// Auto-send payment request to cashier
$breakdown = [
'قيمة العضوية: ' . money($membershipValue),
'قيمة العضوية الحالية: ' . money($membershipValue) . ($valueInfo['source'] === 'pricing_configs' ? ' (من جدول الأسعار)' : ''),
'النسبة المقررة: ' . $feePercentage . '%',
'رسوم الطلاق: ' . money($percentageFee),
'رسوم استمارة (570): ' . money($formFee),
......@@ -217,6 +227,7 @@ class DivorceController extends Controller
$db = App::getInstance()->db();
$case = $db->selectOne(
"SELECT dc.*, m.full_name_ar as member_name, m.membership_number, m.membership_value,
m.branch_id, m.qualification_id,
s.full_name_ar as spouse_name, s.spouse_order, s.join_date as spouse_join_date,
q.name_ar as qualification_name
FROM divorce_cases dc
......@@ -228,6 +239,11 @@ class DivorceController extends Controller
);
if (!$case) return $this->redirect('/divorce')->withError('الحالة غير موجودة');
// Get current membership value from pricing_configs
$valueInfo = DivorceFeeCalculator::getCurrentMembershipValue($case);
$currentMembershipValue = $valueInfo['value'];
$membershipValueSource = $valueInfo['source'];
$children = [];
$childFees = null;
$suggestedPercentage = null;
......@@ -237,7 +253,7 @@ class DivorceController extends Controller
if ($feeCalc['success'] ?? false) {
$suggestedPercentage = $feeCalc['suggested_percentage'] ?? null;
}
$childFees = DivorceFeeCalculator::calculateChildFees((int) $case['member_id'], $case['membership_value'] ?? '0');
$childFees = DivorceFeeCalculator::calculateChildFees((int) $case['member_id'], $currentMembershipValue);
$children = $childFees['children'] ?? [];
}
......@@ -246,6 +262,8 @@ class DivorceController extends Controller
'children' => $children,
'childFees' => $childFees,
'suggestedPercentage' => $suggestedPercentage,
'currentMembershipValue' => $currentMembershipValue,
'membershipValueSource' => $membershipValueSource,
]);
}
......
......@@ -110,6 +110,33 @@ final class DivorceFeeCalculator
return $data['percentage'] ?? '0.00';
}
/**
* Get the current membership value from pricing_configs (source of truth at time of request).
* Falls back to member's stored value if no active pricing config is found.
*/
public static function getCurrentMembershipValue(array $member): array
{
$db = App::getInstance()->db();
$today = date('Y-m-d');
$config = $db->selectOne(
"SELECT price FROM pricing_configs WHERE branch_id = ? AND qualification_id = ? AND membership_type = 'working' AND is_active = 1 AND effective_from <= ? AND (effective_to IS NULL OR effective_to >= ?) ORDER BY effective_from DESC LIMIT 1",
[(int) $member['branch_id'], (int) $member['qualification_id'], $today, $today]
);
if ($config && bccomp($config['price'], '0', 2) > 0) {
return [
'value' => $config['price'],
'source' => 'pricing_configs',
];
}
return [
'value' => $member['membership_value'] ?? '0.00',
'source' => 'member_record',
];
}
/**
* Validate eligibility and determine case type.
*/
......@@ -134,7 +161,10 @@ final class DivorceFeeCalculator
// Use SPOUSE's join_date for the 5-year calculation (not member's created_at)
$spouseJoinDate = $spouse['join_date'] ?? $spouse['created_at'];
$membershipValue = $member['membership_value'] ?? '0.00';
// Get current membership value from pricing_configs (not the stored member value)
$valueInfo = self::getCurrentMembershipValue($member);
$membershipValue = $valueInfo['value'];
// Check children on this membership
$childCount = (int) ($db->selectOne(
......@@ -174,6 +204,7 @@ final class DivorceFeeCalculator
'success' => true,
'case_type' => $caseType,
'membership_value' => $membershipValue,
'membership_value_source' => $valueInfo['source'],
'years_of_membership' => $yearsMembership,
'has_children' => $hasChildren,
'child_count' => $childCount,
......
......@@ -6,7 +6,7 @@
<div>
<strong>العضو:</strong> <?= e($member['full_name_ar']) ?>
&nbsp;|&nbsp; <strong>رقم العضوية:</strong> <?= e($member['membership_number'] ?? 'لم يُحدد') ?>
&nbsp;|&nbsp; <strong>قيمة العضوية:</strong> <span style="color:#0D7377;font-weight:700;"><?= money($member['membership_value'] ?? '0') ?></span>
&nbsp;|&nbsp; <strong>قيمة العضوية الحالية:</strong> <span style="color:#0D7377;font-weight:700;"><?= money($currentMembershipValue ?? $member['membership_value'] ?? '0') ?></span><?php if (($membershipValueSource ?? '') === 'pricing_configs'): ?> <span style="font-size:11px;color:#059669;">(من جدول الأسعار)</span><?php endif; ?>
</div>
<a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">← العودة للعضو</a>
</div>
......
......@@ -37,7 +37,7 @@ $statusLabel = $statusLabels[$case['status']] ?? $case['status'];
<?php if (!empty($case['divorce_certificate_path'])): ?>
<tr><td style="padding:6px 0;color:#6B7280;">قسيمة الطلاق</td><td style="padding:6px 0;"><a href="/<?= e($case['divorce_certificate_path']) ?>" target="_blank" style="color:#2563EB;">عرض المستند</a></td></tr>
<?php endif; ?>
<tr><td style="padding:6px 0;color:#6B7280;">قيمة العضوية</td><td style="padding:6px 0;font-weight:700;color:#0D7377;"><?= money($case['membership_value'] ?? '0') ?></td></tr>
<tr><td style="padding:6px 0;color:#6B7280;">قيمة العضوية الحالية</td><td style="padding:6px 0;font-weight:700;color:#0D7377;"><?= money($currentMembershipValue ?? $case['membership_value'] ?? '0') ?><?php if (($membershipValueSource ?? '') === 'pricing_configs'): ?> <span style="font-size:11px;color:#059669;font-weight:400;">(من جدول الأسعار الحالي)</span><?php endif; ?></td></tr>
<tr><td style="padding:6px 0;color:#6B7280;">نوع الحالة</td><td style="padding:6px 0;"><?= \App\Modules\Divorce\Models\DivorceCase::getCaseTypeLabel($case['divorce_case_type'] ?? '') ?></td></tr>
<tr><td style="padding:6px 0;color:#6B7280;">أبناء على العضوية</td><td style="padding:6px 0;"><?= $case['has_children_on_membership'] ? '<span style="color:#059669;font-weight:600;">نعم</span>' : 'لا' ?></td></tr>
<tr><td style="padding:6px 0;color:#6B7280;">الحالة</td><td style="padding:6px 0;font-weight:700;color:<?= $statusColor ?>;"><?= $statusLabel ?></td></tr>
......@@ -109,7 +109,7 @@ $statusLabel = $statusLabels[$case['status']] ?? $case['status'];
<div class="form-group">
<label class="form-label">النسبة من قيمة العضوية (%) <span style="color:#DC2626;">*</span></label>
<input type="number" name="fee_percentage" class="form-input" required min="0" max="100" step="0.01" style="font-size:18px;font-weight:700;" placeholder="مثال: 50" value="<?= e($suggestedPercentage ?? '') ?>">
<small style="color:#6B7280;">قيمة العضوية: <?= money($case['membership_value'] ?? '0') ?></small>
<small style="color:#6B7280;">قيمة العضوية الحالية: <?= money($currentMembershipValue ?? $case['membership_value'] ?? '0') ?></small>
</div>
<div class="form-group">
<label class="form-label">رقم قرار المجلس</label>
......@@ -197,8 +197,8 @@ $statusLabel = $statusLabels[$case['status']] ?? $case['status'];
<div style="padding:20px;">
<table style="width:100%;max-width:500px;font-size:14px;">
<tr>
<td style="padding:8px 0;color:#6B7280;">قيمة العضوية</td>
<td style="padding:8px 0;font-weight:600;direction:ltr;text-align:left;"><?= money($case['membership_value'] ?? '0') ?></td>
<td style="padding:8px 0;color:#6B7280;">قيمة العضوية وقت الاعتماد</td>
<td style="padding:8px 0;font-weight:600;direction:ltr;text-align:left;"><?= money($currentMembershipValue ?? $case['membership_value'] ?? '0') ?></td>
</tr>
<tr>
<td style="padding:8px 0;color:#6B7280;">النسبة المقررة من المجلس</td>
......@@ -305,7 +305,7 @@ document.addEventListener('DOMContentLoaded', function() {
$__db = \App\Core\App::getInstance()->db();
$__childRate = $__db->selectOne("SELECT base_amount FROM service_catalog WHERE service_code LIKE 'SVC_ANNUAL_CHILD%' AND is_active = 1 ORDER BY effective_from DESC LIMIT 1");
?>
var membershipValue = <?= json_encode((float) ($case['membership_value'] ?? 0)) ?>;
var membershipValue = <?= json_encode((float) ($currentMembershipValue ?? $case['membership_value'] ?? 0)) ?>;
var formFee = <?= json_encode((float) ($__formFeeData['amount'] ?? '570')) ?>;
var annualSub = <?= json_encode((float) ($__childRate['base_amount'] ?? '222') + (float) ($__devFeeData['amount'] ?? '35')) ?>;
......
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