Commit 30048dc4 authored by Fares's avatar Fares

fix(foreign): enable dependents and standard payment flow for foreign members

Foreign members can now add spouse/children (allowsDependents=true), and
the $10k fee routes through the cashier queue instead of inline processing,
matching the standard activation path used by other membership types.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 0ab98b7e
...@@ -10,7 +10,6 @@ use App\Core\App; ...@@ -10,7 +10,6 @@ use App\Core\App;
use App\Core\EventBus; use App\Core\EventBus;
use App\Modules\Foreign\Models\ForeignMemberDetail; use App\Modules\Foreign\Models\ForeignMemberDetail;
use App\Modules\Rules\Services\RuleEngine; use App\Modules\Rules\Services\RuleEngine;
use App\Modules\Payments\Services\PaymentService;
class ForeignController extends Controller class ForeignController extends Controller
{ {
...@@ -113,31 +112,16 @@ class ForeignController extends Controller ...@@ -113,31 +112,16 @@ class ForeignController extends Controller
'notes' => $data['notes'] ?? null, 'notes' => $data['notes'] ?? null,
]); ]);
// membership_type already set at creation — no update needed // Update member passport number for reference
$db->update('members', [
// Process payment through central PaymentService (use EGP amount if available, otherwise USD) 'passport_number' => trim($data['passport_number']),
$chargeAmount = $feeEgp ?? $feeUsd; 'updated_at' => date('Y-m-d H:i:s'),
$chargeCurrency = $feeEgp ? 'EGP' : 'USD'; ], '`id` = ?', [(int) $memberId]);
if (bccomp((string) $chargeAmount, '0.00', 2) > 0) {
$payResult = PaymentService::processPayment([
'member_id' => (int) $memberId,
'amount' => (string) $chargeAmount,
'payment_type' => 'membership_fee',
'payment_method' => $data['payment_method'] ?? 'cash',
'currency' => $chargeCurrency,
'related_entity_type' => 'foreign_member_details',
'related_entity_id' => (int) $foreign->id,
'description' => 'رسوم عضوية أجنبية — ' . number_format((float) $feeUsd, 2) . ' USD',
]);
if (!$payResult['success']) {
return $this->redirect("/members/{$memberId}")
->withError('تم تسجيل العضوية الأجنبية لكن فشل تسجيل الدفع: ' . ($payResult['error'] ?? ''));
}
}
EventBus::dispatch('foreign.registered', ['member_id' => (int) $memberId, 'foreign_id' => (int) $foreign->id]); EventBus::dispatch('foreign.registered', ['member_id' => (int) $memberId, 'foreign_id' => (int) $foreign->id]);
return $this->redirect("/members/{$memberId}")->withSuccess('تم تسجيل العضوية الأجنبية — الرسوم: ' . number_format((float) $feeUsd, 2) . ' USD'); return $this->redirect("/members/{$memberId}")->withSuccess(
'تم تسجيل بيانات العضوية الأجنبية — الرسوم: ' . number_format((float) $feeUsd, 2) . ' USD — استكمل الإجراءات من صفحة العضو'
);
} }
} }
\ No newline at end of file
...@@ -78,7 +78,7 @@ final class MembershipRulesService ...@@ -78,7 +78,7 @@ final class MembershipRulesService
'seasonal' => ['name_ar' => 'عضو موسمي', 'min_age' => 0, 'allows_dependents' => false, 'requires_qualification' => false], 'seasonal' => ['name_ar' => 'عضو موسمي', 'min_age' => 0, 'allows_dependents' => false, 'requires_qualification' => false],
'sports' => ['name_ar' => 'عضو رياضي', 'min_age' => 0, 'allows_dependents' => false, 'requires_qualification' => false], 'sports' => ['name_ar' => 'عضو رياضي', 'min_age' => 0, 'allows_dependents' => false, 'requires_qualification' => false],
'honorary' => ['name_ar' => 'عضو شرفي', 'min_age' => 0, 'allows_dependents' => false, 'requires_qualification' => false], 'honorary' => ['name_ar' => 'عضو شرفي', 'min_age' => 0, 'allows_dependents' => false, 'requires_qualification' => false],
'foreign' => ['name_ar' => 'عضو أجنبي', 'min_age' => 21, 'allows_dependents' => false, 'requires_qualification' => false], 'foreign' => ['name_ar' => 'عضو أجنبي', 'min_age' => 21, 'allows_dependents' => true, 'requires_qualification' => false],
]; ];
} }
......
...@@ -83,14 +83,14 @@ $canEdit = can('member.edit') && (!$isLocked || ($isSuperAdmin ?? false)); ...@@ -83,14 +83,14 @@ $canEdit = can('member.edit') && (!$isLocked || ($isSuperAdmin ?? false));
<div class="card" style="margin-bottom:20px;padding:25px;background:#F0FDF4;border:2px solid #059669;"> <div class="card" style="margin-bottom:20px;padding:25px;background:#F0FDF4;border:2px solid #059669;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;"> <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;">
<div> <div>
<h3 style="color:#059669;margin:0 0 8px;">✅ تم دفع رسوم الاستمارة — الآن قم بملء البيانات<?= ($member->membership_type ?? 'working') === 'working' ? ' وإضافة الأسرة' : '' ?></h3> <h3 style="color:#059669;margin:0 0 8px;">✅ تم دفع رسوم الاستمارة — الآن قم بملء البيانات<?= in_array($member->membership_type ?? 'working', ['working', 'foreign']) ? ' وإضافة الأسرة' : '' ?></h3>
<p style="color:#6B7280;margin:0;font-size:14px;">استمارة رقم <strong><?= e($member->form_number) ?></strong><?= ($member->membership_type ?? 'working') === 'working' ? ' — يمكنك إضافة أفراد الأسرة الآن بدون رسوم إضافية' : '' ?></p> <p style="color:#6B7280;margin:0;font-size:14px;">استمارة رقم <strong><?= e($member->form_number) ?></strong><?= in_array($member->membership_type ?? 'working', ['working', 'foreign']) ? ' — يمكنك إضافة أفراد الأسرة الآن بدون رسوم إضافية' : '' ?></p>
</div> </div>
<?php if (can('member.fill_form')): ?> <?php if (can('member.fill_form')): ?>
<a href="/members/<?= (int) $member->id ?>/fill-form" class="btn btn-primary" style="padding:15px 30px;font-size:18px;">📝 ملء الاستمارة</a> <a href="/members/<?= (int) $member->id ?>/fill-form" class="btn btn-primary" style="padding:15px 30px;font-size:18px;">📝 ملء الاستمارة</a>
<?php endif; ?> <?php endif; ?>
</div> </div>
<?php if (($member->membership_type ?? 'working') === 'working'): ?> <?php if (in_array($member->membership_type ?? 'working', ['working', 'foreign'])): ?>
<div style="display:flex;gap:8px;flex-wrap:wrap;padding-top:12px;border-top:1px solid #A7F3D0;"> <div style="display:flex;gap:8px;flex-wrap:wrap;padding-top:12px;border-top:1px solid #A7F3D0;">
<a href="/members/<?= (int) $member->id ?>/spouses/create" class="btn btn-sm btn-outline">💍 إضافة زوج/ة</a> <a href="/members/<?= (int) $member->id ?>/spouses/create" class="btn btn-sm btn-outline">💍 إضافة زوج/ة</a>
<a href="/members/<?= (int) $member->id ?>/children/create" class="btn btn-sm btn-outline">👶 إضافة ابن/ة</a> <a href="/members/<?= (int) $member->id ?>/children/create" class="btn btn-sm btn-outline">👶 إضافة ابن/ة</a>
...@@ -242,8 +242,8 @@ $canEdit = can('member.edit') && (!$isLocked || ($isSuperAdmin ?? false)); ...@@ -242,8 +242,8 @@ $canEdit = can('member.edit') && (!$isLocked || ($isSuperAdmin ?? false));
</table> </table>
</div> </div>
<!-- Add Family Before Paying (working type only) --> <!-- Add Family Before Paying -->
<?php if (($member->membership_type ?? 'working') === 'working'): ?> <?php if (in_array($member->membership_type ?? 'working', ['working', 'foreign'])): ?>
<div style="padding:0 20px 15px;display:flex;gap:10px;flex-wrap:wrap;border-top:1px solid #E5E7EB;padding-top:15px;"> <div style="padding:0 20px 15px;display:flex;gap:10px;flex-wrap:wrap;border-top:1px solid #E5E7EB;padding-top:15px;">
<span style="color:#6B7280;font-size:13px;padding:8px 0;">أضف أفراد الأسرة (بدون رسوم استمارة إضافية):</span> <span style="color:#6B7280;font-size:13px;padding:8px 0;">أضف أفراد الأسرة (بدون رسوم استمارة إضافية):</span>
<a href="/members/<?= (int) $member->id ?>/spouses/create" class="btn btn-sm btn-outline">💍 إضافة زوج/ة</a> <a href="/members/<?= (int) $member->id ?>/spouses/create" class="btn btn-sm btn-outline">💍 إضافة زوج/ة</a>
...@@ -848,9 +848,9 @@ $hasIncomplete = !empty(array_filter($missingSteps, fn($s) => !$s['done'])); ...@@ -848,9 +848,9 @@ $hasIncomplete = !empty(array_filter($missingSteps, fn($s) => !$s['done']));
</div> </div>
<!-- ═══════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════ -->
<!-- FAMILY TREE — unified display of all dependants (working members only) --> <!-- FAMILY TREE — unified display of all dependants -->
<!-- ═══════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════ -->
<?php if (($member->membership_type ?? 'working') === 'working'): ?> <?php if (in_array($member->membership_type ?? 'working', ['working', 'foreign'])): ?>
<?php <?php
$totalDependants = count($spouses) + count($children) + count($temporaries ?? []); $totalDependants = count($spouses) + count($children) + count($temporaries ?? []);
$categoryLabels = [ $categoryLabels = [
......
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