Commit cbf7de3f authored by Mahmoud Aglan's avatar Mahmoud Aglan

fixes Membership

parent 27dbd900
...@@ -29,7 +29,20 @@ class DeathController extends Controller ...@@ -29,7 +29,20 @@ class DeathController extends Controller
$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('العضو غير موجود');
$spouses = $db->select("SELECT * FROM spouses WHERE member_id = ? AND is_archived = 0 AND status = 'active'", [(int) $memberId]); $spouses = $db->select("SELECT * FROM spouses WHERE member_id = ? AND is_archived = 0 AND status = 'active'", [(int) $memberId]);
return $this->view('Death.Views.create', ['member' => $member, 'spouses' => $spouses]);
// Pre-calculate fees to show on form
$formFeeData = RuleEngine::get('FORM_TRANSFER_FEE');
$formFee = $formFeeData['amount'] ?? '570.00';
$annualSub = '527.00'; // 492 + 35 development
$totalFee = bcadd($formFee, $annualSub, 2);
return $this->view('Death.Views.create', [
'member' => $member,
'spouses' => $spouses,
'form_fee' => $formFee,
'annual_sub' => $annualSub,
'total_fee' => $totalFee,
]);
} }
public function store(Request $request, string $memberId): Response public function store(Request $request, string $memberId): Response
...@@ -43,6 +56,7 @@ class DeathController extends Controller ...@@ -43,6 +56,7 @@ class DeathController extends Controller
$certNumber = trim($request->post('death_certificate_number', '')); $certNumber = trim($request->post('death_certificate_number', ''));
$spouseId = $request->post('spouse_id') ? (int) $request->post('spouse_id') : null; $spouseId = $request->post('spouse_id') ? (int) $request->post('spouse_id') : null;
$notes = trim($request->post('notes', '')); $notes = trim($request->post('notes', ''));
$paymentMethod = trim($request->post('payment_method', 'cash'));
if (!$deceasedType || !$deathDate) { if (!$deceasedType || !$deathDate) {
return $this->redirect("/death/create/{$memberId}")->withError('بيانات الوفاة غير مكتملة'); return $this->redirect("/death/create/{$memberId}")->withError('بيانات الوفاة غير مكتملة');
...@@ -68,6 +82,36 @@ class DeathController extends Controller ...@@ -68,6 +82,36 @@ class DeathController extends Controller
EventBus::dispatch('death.recorded', ['case_id' => (int) $case->id, 'member_id' => (int) $memberId, 'type' => $deceasedType]); EventBus::dispatch('death.recorded', ['case_id' => (int) $case->id, 'member_id' => (int) $memberId, 'type' => $deceasedType]);
// Collect payment inline
if (bccomp($totalFee, '0', 2) > 0) {
$result = PaymentService::processPayment([
'member_id' => (int) $memberId,
'amount' => $totalFee,
'payment_type' => 'death_fee',
'payment_method' => $paymentMethod,
'related_entity_type' => 'death_cases',
'related_entity_id' => (int) $case->id,
'description' => 'رسوم وفاة (استمارة + اشتراك) — حالة #' . $case->id,
]);
if ($result['success']) {
$db->update('death_cases', [
'status' => 'fee_paid',
'updated_at' => date('Y-m-d H:i:s'),
], '`id` = ?', [(int) $case->id]);
EventBus::dispatch('death.fee_paid', ['case_id' => (int) $case->id, 'payment_id' => $result['payment_id']]);
return $this->redirect("/death/{$case->id}")->withSuccess(
'تم تسجيل حالة الوفاة وتحصيل الرسوم — ' . money($totalFee) . ' — إيصال: ' . $result['receipt_number']
);
}
return $this->redirect("/death/{$case->id}")->withError(
'تم تسجيل الحالة لكن فشل تحصيل الرسوم: ' . ($result['error'] ?? 'خطأ غير معروف')
);
}
return $this->redirect("/death/{$case->id}")->withSuccess('تم تسجيل حالة الوفاة'); return $this->redirect("/death/{$case->id}")->withSuccess('تم تسجيل حالة الوفاة');
} }
......
...@@ -25,7 +25,28 @@ ...@@ -25,7 +25,28 @@
<div class="form-group" style="grid-column:1/-1;"><label class="form-label">ملاحظات</label><textarea name="notes" class="form-textarea" rows="3"></textarea></div> <div class="form-group" style="grid-column:1/-1;"><label class="form-label">ملاحظات</label><textarea name="notes" class="form-textarea" rows="3"></textarea></div>
</div> </div>
</div> </div>
<button type="submit" class="btn btn-primary">تسجيل حالة الوفاة</button>
<!-- Fee & Payment -->
<div class="card" style="padding:20px;margin-bottom:20px;background:#FFF7ED;border:2px solid #F59E0B;">
<h4 style="margin:0 0 15px;color:#D97706;">رسوم الإجراء (استمارة + اشتراك سنوي)</h4>
<table style="font-size:14px;margin-bottom:15px;">
<tr><td style="padding:4px 20px 4px 0;color:#6B7280;">رسوم استمارة نقل</td><td style="font-weight:600;"><?= money($form_fee) ?></td></tr>
<tr><td style="padding:4px 20px 4px 0;color:#6B7280;">اشتراك سنوي (492 + 35 تنمية)</td><td style="font-weight:600;"><?= money($annual_sub) ?></td></tr>
<tr style="border-top:2px solid #D97706;"><td style="padding:8px 20px 4px 0;font-weight:700;">الإجمالي</td><td style="font-weight:700;font-size:18px;color:#DC2626;"><?= money($total_fee) ?></td></tr>
</table>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:15px;">
<div class="form-group">
<label class="form-label">طريقة الدفع <span style="color:#DC2626;">*</span></label>
<select name="payment_method" class="form-select" required>
<option value="cash">نقدي</option>
<option value="visa">فيزا</option>
<option value="bank_transfer">تحويل بنكي</option>
</select>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary" onclick="return confirm('سيتم تسجيل حالة الوفاة وتحصيل الرسوم. متأكد؟')">تسجيل الوفاة وتحصيل الرسوم</button>
<a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">إلغاء</a> <a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">إلغاء</a>
</form> </form>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
\ No newline at end of file
...@@ -43,6 +43,7 @@ class DivorceController extends Controller ...@@ -43,6 +43,7 @@ class DivorceController extends Controller
$spouseId = (int) $request->post('spouse_id', 0); $spouseId = (int) $request->post('spouse_id', 0);
$divorceDate = trim($request->post('divorce_date', '')); $divorceDate = trim($request->post('divorce_date', ''));
$notes = trim($request->post('notes', '')); $notes = trim($request->post('notes', ''));
$paymentMethod = trim($request->post('payment_method', 'cash'));
if (!$spouseId || !$divorceDate) { if (!$spouseId || !$divorceDate) {
return $this->redirect("/divorce/create/{$memberId}")->withError('بيانات الطلاق غير مكتملة'); return $this->redirect("/divorce/create/{$memberId}")->withError('بيانات الطلاق غير مكتملة');
...@@ -70,6 +71,39 @@ class DivorceController extends Controller ...@@ -70,6 +71,39 @@ class DivorceController extends Controller
EventBus::dispatch('divorce.submitted', ['case_id' => (int) $case->id, 'member_id' => (int) $memberId]); EventBus::dispatch('divorce.submitted', ['case_id' => (int) $case->id, 'member_id' => (int) $memberId]);
// Collect payment inline
$amount = $feeCalc['total_fee'] ?? '0.00';
if (bccomp((string) $amount, '0', 2) > 0) {
$result = PaymentService::processPayment([
'member_id' => (int) $memberId,
'amount' => $amount,
'payment_type' => 'divorce_fee',
'payment_method' => $paymentMethod,
'related_entity_type' => 'divorce_cases',
'related_entity_id' => (int) $case->id,
'description' => 'رسوم طلاق — حالة #' . $case->id,
]);
if ($result['success']) {
$db->update('divorce_cases', [
'status' => 'fee_paid',
'updated_at' => date('Y-m-d H:i:s'),
], '`id` = ?', [(int) $case->id]);
EventBus::dispatch('divorce.fee_paid', ['case_id' => (int) $case->id, 'payment_id' => $result['payment_id']]);
return $this->redirect("/divorce/{$case->id}")->withSuccess(
'تم تسجيل حالة الطلاق وتحصيل الرسوم — النوع: ' . DivorceCase::getCaseTypeLabel($feeCalc['case_type'])
. ' — الرسوم: ' . money($amount) . ' — إيصال: ' . $result['receipt_number']
);
}
// Payment failed — case created but not paid
return $this->redirect("/divorce/{$case->id}")->withError(
'تم تسجيل الحالة لكن فشل تحصيل الرسوم: ' . ($result['error'] ?? 'خطأ غير معروف')
);
}
return $this->redirect("/divorce/{$case->id}")->withSuccess('تم تسجيل حالة الطلاق — النوع: ' . DivorceCase::getCaseTypeLabel($feeCalc['case_type']) . ' — الرسوم: ' . money($feeCalc['total_fee'])); return $this->redirect("/divorce/{$case->id}")->withSuccess('تم تسجيل حالة الطلاق — النوع: ' . DivorceCase::getCaseTypeLabel($feeCalc['case_type']) . ' — الرسوم: ' . money($feeCalc['total_fee']));
} }
......
...@@ -22,7 +22,24 @@ ...@@ -22,7 +22,24 @@
</div> </div>
</div> </div>
</div> </div>
<button type="submit" class="btn btn-primary">تسجيل حالة الطلاق</button>
<!-- Fee & Payment -->
<div class="card" style="padding:20px;margin-bottom:20px;background:#FFF7ED;border:2px solid #F59E0B;">
<h4 style="margin:0 0 15px;color:#D97706;">رسوم الإجراء</h4>
<p style="font-size:13px;color:#6B7280;margin-bottom:15px;">سيتم احتساب الرسوم تلقائياً (رسوم استمارة + نسبة من قيمة العضوية حسب نوع الحالة).<br>قيمة العضوية: <strong style="color:#0D7377;"><?= money($member['membership_value'] ?? '0') ?></strong></p>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:15px;">
<div class="form-group">
<label class="form-label">طريقة الدفع <span style="color:#DC2626;">*</span></label>
<select name="payment_method" class="form-select" required>
<option value="cash">نقدي</option>
<option value="visa">فيزا</option>
<option value="bank_transfer">تحويل بنكي</option>
</select>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary" onclick="return confirm('سيتم تسجيل حالة الطلاق وتحصيل الرسوم. متأكد؟')">تسجيل الطلاق وتحصيل الرسوم</button>
<a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">إلغاء</a> <a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">إلغاء</a>
</form> </form>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
\ No newline at end of file
...@@ -58,6 +58,7 @@ class TransferController extends Controller ...@@ -58,6 +58,7 @@ class TransferController extends Controller
$childId = $request->post('child_id') ? (int) $request->post('child_id') : null; $childId = $request->post('child_id') ? (int) $request->post('child_id') : null;
$spouseId = $request->post('spouse_id') ? (int) $request->post('spouse_id') : null; $spouseId = $request->post('spouse_id') ? (int) $request->post('spouse_id') : null;
$notes = trim($request->post('notes', '')); $notes = trim($request->post('notes', ''));
$paymentMethod = trim($request->post('payment_method', 'cash'));
$validTypes = ['child_separation', 'child_mandatory_25', 'sports_conversion', 'cross_branch']; $validTypes = ['child_separation', 'child_mandatory_25', 'sports_conversion', 'cross_branch'];
if (!in_array($transferType, $validTypes)) { if (!in_array($transferType, $validTypes)) {
...@@ -106,6 +107,37 @@ class TransferController extends Controller ...@@ -106,6 +107,37 @@ class TransferController extends Controller
'type' => $transferType, 'type' => $transferType,
]); ]);
// Collect payment inline
$amount = $feeCalc['total_fee'] ?? '0.00';
if (bccomp((string) $amount, '0', 2) > 0) {
$result = PaymentService::processPayment([
'member_id' => (int) $memberId,
'amount' => $amount,
'payment_type' => 'separation_fee',
'payment_method' => $paymentMethod,
'related_entity_type' => 'transfer_requests',
'related_entity_id' => (int) $transferReq->id,
'description' => 'رسوم تحويل/فصل — طلب #' . $transferReq->id,
]);
if ($result['success']) {
$db->update('transfer_requests', [
'status' => 'fee_paid',
'updated_at' => date('Y-m-d H:i:s'),
], '`id` = ?', [(int) $transferReq->id]);
EventBus::dispatch('transfer.fee_paid', ['transfer_id' => (int) $transferReq->id, 'payment_id' => $result['payment_id']]);
return $this->redirect("/transfers/{$transferReq->id}")->withSuccess(
'تم تقديم طلب التحويل/الفصل وتحصيل الرسوم — الإجمالي: ' . money($amount) . ' — إيصال: ' . $result['receipt_number']
);
}
return $this->redirect("/transfers/{$transferReq->id}")->withError(
'تم تقديم الطلب لكن فشل تحصيل الرسوم: ' . ($result['error'] ?? 'خطأ غير معروف')
);
}
return $this->redirect("/transfers/{$transferReq->id}")->withSuccess('تم تقديم طلب التحويل/الفصل — الإجمالي: ' . money($feeCalc['total_fee'])); return $this->redirect("/transfers/{$transferReq->id}")->withSuccess('تم تقديم طلب التحويل/الفصل — الإجمالي: ' . money($feeCalc['total_fee']));
} }
......
...@@ -33,13 +33,62 @@ ...@@ -33,13 +33,62 @@
</div> </div>
</div> </div>
</div> </div>
<button type="submit" class="btn btn-primary">تقديم الطلب</button>
<!-- Fee & Payment -->
<div class="card" style="padding:20px;margin-bottom:20px;background:#FFF7ED;border:2px solid #F59E0B;">
<h4 style="margin:0 0 15px;color:#D97706;">رسوم الإجراء</h4>
<p style="font-size:13px;color:#6B7280;margin-bottom:15px;">سيتم احتساب رسوم الفصل/التحويل تلقائياً (نسبة من قيمة العضوية حسب سنوات الاكتساب + رسوم استمارة + اشتراك سنوي).</p>
<div id="fee-preview" style="display:none;margin-bottom:15px;padding:12px;background:#FEF3C7;border-radius:6px;">
<table style="font-size:14px;">
<tr><td style="padding:3px 15px 3px 0;color:#6B7280;">رسوم الفصل</td><td id="fp-separation" style="font-weight:600;"></td></tr>
<tr><td style="padding:3px 15px 3px 0;color:#6B7280;">رسوم الاستمارة</td><td id="fp-form" style="font-weight:600;"></td></tr>
<tr><td style="padding:3px 15px 3px 0;color:#6B7280;">اشتراك سنوي</td><td id="fp-annual" style="font-weight:600;"></td></tr>
<tr style="border-top:2px solid #D97706;"><td style="padding:6px 15px 3px 0;font-weight:700;">الإجمالي</td><td id="fp-total" style="font-weight:700;font-size:18px;color:#DC2626;"></td></tr>
</table>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:15px;">
<div class="form-group">
<label class="form-label">طريقة الدفع <span style="color:#DC2626;">*</span></label>
<select name="payment_method" class="form-select" required>
<option value="cash">نقدي</option>
<option value="visa">فيزا</option>
<option value="bank_transfer">تحويل بنكي</option>
</select>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary" onclick="return confirm('سيتم تقديم الطلب وتحصيل الرسوم. متأكد؟')">تقديم الطلب وتحصيل الرسوم</button>
<a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">إلغاء</a> <a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">إلغاء</a>
</form> </form>
<script> <script>
document.getElementById('transfer_type').addEventListener('change', function() { document.getElementById('transfer_type').addEventListener('change', function() {
var cs = document.getElementById('child-select'); var cs = document.getElementById('child-select');
cs.style.display = (this.value === 'child_separation' || this.value === 'child_mandatory_25') ? 'block' : 'none'; cs.style.display = (this.value === 'child_separation' || this.value === 'child_mandatory_25') ? 'block' : 'none';
// Fetch fee preview
if (this.value) {
var memberId = <?= (int) $member['id'] ?>;
var childId = document.querySelector('[name=child_id]').value || '';
fetch('/api/transfers/calculate-fee', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'X-CSRF-TOKEN': document.querySelector('[name=_csrf_token]').value},
body: 'member_id=' + memberId + '&child_id=' + childId
})
.then(function(r) { return r.json(); })
.then(function(d) {
if (d.success) {
document.getElementById('fp-separation').textContent = d.separation_fee;
document.getElementById('fp-form').textContent = d.form_fee;
document.getElementById('fp-annual').textContent = d.annual_subscription_fee;
document.getElementById('fp-total').textContent = d.total_fee;
document.getElementById('fee-preview').style.display = 'block';
}
})
.catch(function() {});
} else {
document.getElementById('fee-preview').style.display = 'none';
}
}); });
</script> </script>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
\ No newline at end of file
...@@ -59,6 +59,7 @@ class WaiverController extends Controller ...@@ -59,6 +59,7 @@ class WaiverController extends Controller
$waiverPctData = RuleEngine::get('WAIVER_FEE'); $waiverPctData = RuleEngine::get('WAIVER_FEE');
$waiverPct = $waiverPctData['percentage'] ?? '30.00'; $waiverPct = $waiverPctData['percentage'] ?? '30.00';
$waiverFee = bcdiv(bcmul($membershipValue, $waiverPct, 4), '100', 2); $waiverFee = bcdiv(bcmul($membershipValue, $waiverPct, 4), '100', 2);
$paymentMethod = trim($request->post('payment_method', 'cash'));
$spouseCount = (int) ($db->selectOne("SELECT COUNT(*) as cnt FROM spouses WHERE member_id = ? AND is_archived = 0", [(int) $memberId])['cnt'] ?? 0); $spouseCount = (int) ($db->selectOne("SELECT COUNT(*) as cnt FROM spouses WHERE member_id = ? AND is_archived = 0", [(int) $memberId])['cnt'] ?? 0);
$childCount = (int) ($db->selectOne("SELECT COUNT(*) as cnt FROM children WHERE member_id = ? AND is_archived = 0", [(int) $memberId])['cnt'] ?? 0); $childCount = (int) ($db->selectOne("SELECT COUNT(*) as cnt FROM children WHERE member_id = ? AND is_archived = 0", [(int) $memberId])['cnt'] ?? 0);
...@@ -78,6 +79,36 @@ class WaiverController extends Controller ...@@ -78,6 +79,36 @@ class WaiverController extends Controller
EventBus::dispatch('waiver.requested', ['waiver_id' => (int) $waiver->id, 'member_id' => (int) $memberId]); EventBus::dispatch('waiver.requested', ['waiver_id' => (int) $waiver->id, 'member_id' => (int) $memberId]);
// Collect payment inline
if (bccomp($waiverFee, '0', 2) > 0) {
$result = PaymentService::processPayment([
'member_id' => (int) $memberId,
'amount' => $waiverFee,
'payment_type' => 'waiver_fee',
'payment_method' => $paymentMethod,
'related_entity_type' => 'waiver_requests',
'related_entity_id' => (int) $waiver->id,
'description' => 'رسوم تنازل — طلب #' . $waiver->id,
]);
if ($result['success']) {
$db->update('waiver_requests', [
'status' => 'fee_paid',
'updated_at' => date('Y-m-d H:i:s'),
], '`id` = ?', [(int) $waiver->id]);
EventBus::dispatch('waiver.fee_paid', ['waiver_id' => (int) $waiver->id, 'payment_id' => $result['payment_id']]);
return $this->redirect("/waivers/{$waiver->id}")->withSuccess(
'تم تقديم طلب التنازل وتحصيل الرسوم — ' . money($waiverFee) . ' (' . $waiverPct . '%) — إيصال: ' . $result['receipt_number']
);
}
return $this->redirect("/waivers/{$waiver->id}")->withError(
'تم تقديم الطلب لكن فشل تحصيل الرسوم: ' . ($result['error'] ?? 'خطأ غير معروف')
);
}
return $this->redirect("/waivers/{$waiver->id}")->withSuccess('تم تقديم طلب التنازل — الرسوم: ' . money($waiverFee) . ' (' . $waiverPct . '%)'); return $this->redirect("/waivers/{$waiver->id}")->withSuccess('تم تقديم طلب التنازل — الرسوم: ' . money($waiverFee) . ' (' . $waiverPct . '%)');
} }
......
...@@ -19,7 +19,23 @@ ...@@ -19,7 +19,23 @@
<div class="card" style="padding:20px;margin-bottom:15px;"> <div class="card" style="padding:20px;margin-bottom:15px;">
<div class="form-group"><label class="form-label">ملاحظات</label><textarea name="notes" class="form-textarea" rows="3"></textarea></div> <div class="form-group"><label class="form-label">ملاحظات</label><textarea name="notes" class="form-textarea" rows="3"></textarea></div>
</div> </div>
<button type="submit" class="btn btn-primary" onclick="return confirm('هل تريد تقديم طلب التنازل؟')">تقديم طلب التنازل</button>
<!-- Fee & Payment -->
<div class="card" style="padding:20px;margin-bottom:20px;background:#FFF7ED;border:2px solid #F59E0B;">
<h4 style="margin:0 0 15px;color:#D97706;">تحصيل رسوم التنازل</h4>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:15px;">
<div class="form-group">
<label class="form-label">طريقة الدفع <span style="color:#DC2626;">*</span></label>
<select name="payment_method" class="form-select" required>
<option value="cash">نقدي</option>
<option value="visa">فيزا</option>
<option value="bank_transfer">تحويل بنكي</option>
</select>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary" onclick="return confirm('سيتم تقديم طلب التنازل وتحصيل الرسوم (<?= money($waiver_fee) ?>). متأكد؟')">تقديم الطلب وتحصيل الرسوم</button>
<a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">إلغاء</a> <a href="/members/<?= (int) $member['id'] ?>" class="btn btn-outline">إلغاء</a>
</form> </form>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
\ No newline at end of file
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