Commit 715fac64 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Add passport fallback for non-Egyptians with toggle and fix controller field mapping

- create.php: passport section (hidden by default) with passport number, manual DOB, manual gender
- create.php: checkbox toggle to switch between NID and passport modes
- create.php: JS hides NID card and shows passport section when toggled
- MemberController: store() reads date_of_birth_manual/gender_manual for passport path
- MemberController: nationality auto-set to أجنبي when using passport ID type
- MemberController: saveFillForm() now includes passport_number in allowed fields
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 82045b8e
...@@ -98,7 +98,8 @@ class MemberController extends Controller ...@@ -98,7 +98,8 @@ class MemberController extends Controller
$dup = $db->selectOne("SELECT id, full_name_ar FROM members WHERE national_id = ? AND is_archived = 0", [$nationalId]); $dup = $db->selectOne("SELECT id, full_name_ar FROM members WHERE national_id = ? AND is_archived = 0", [$nationalId]);
if ($dup) $errors[] = 'الرقم القومي مسجل بالفعل: ' . $dup['full_name_ar']; if ($dup) $errors[] = 'الرقم القومي مسجل بالفعل: ' . $dup['full_name_ar'];
} else { } else {
$dob = $request->post('date_of_birth', ''); $gender = $request->post('gender', ''); $dob = $request->post('date_of_birth_manual', '') ?: $request->post('date_of_birth', '');
$gender = $request->post('gender_manual', '') ?: $request->post('gender', '');
if (!$dob) $errors[] = 'تاريخ الميلاد مطلوب'; if (!$gender) $errors[] = 'النوع مطلوب'; if (!$dob) $errors[] = 'تاريخ الميلاد مطلوب'; if (!$gender) $errors[] = 'النوع مطلوب';
if ($dob) { $age = age_from_dob($dob); $ageYears = $age['years']; $ageMonths = $age['months']; } if ($dob) { $age = age_from_dob($dob); $ageYears = $age['years']; $ageMonths = $age['months']; }
$idType = 'passport'; $idType = 'passport';
...@@ -113,7 +114,8 @@ class MemberController extends Controller ...@@ -113,7 +114,8 @@ class MemberController extends Controller
$formNumber = MemberNumberGenerator::next(); $formNumber = MemberNumberGenerator::next();
if (!$formNumber) return $this->redirect('/members/create')->withError('يجب تحديد رقم بداية الاستمارات'); if (!$formNumber) return $this->redirect('/members/create')->withError('يجب تحديد رقم بداية الاستمارات');
$member = Member::create(['full_name_ar' => $fullNameAr, 'national_id' => $nationalId ?: null, 'passport_number' => $request->post('passport_number') ?: null, 'id_type' => $idType, 'date_of_birth' => $dob, 'age_years' => $ageYears, 'age_months' => $ageMonths, 'gender' => $gender, 'governorate_code' => $govCode, 'phone_mobile' => $phoneMobile, 'branch_id' => $branchId, 'nationality' => 'مصري', 'form_number' => (string) $formNumber, 'form_date' => date('Y-m-d'), 'status' => 'potential', 'membership_type' => 'working', 'member_category' => 'working_member']); $nationality = ($idType === 'passport') ? 'أجنبي' : 'مصري';
$member = Member::create(['full_name_ar' => $fullNameAr, 'national_id' => $nationalId ?: null, 'passport_number' => $request->post('passport_number') ?: null, 'id_type' => $idType, 'date_of_birth' => $dob, 'age_years' => $ageYears, 'age_months' => $ageMonths, 'gender' => $gender, 'governorate_code' => $govCode, 'phone_mobile' => $phoneMobile, 'branch_id' => $branchId, 'nationality' => $nationality, 'form_number' => (string) $formNumber, 'form_date' => date('Y-m-d'), 'status' => 'potential', 'membership_type' => 'working', 'member_category' => 'working_member']);
if (WorkflowEngine::hasDefinition('new_membership')) { if (WorkflowEngine::hasDefinition('new_membership')) {
try { try {
$wfInstance = WorkflowEngine::createInstance('new_membership', 'members', (int) $member->id); $wfInstance = WorkflowEngine::createInstance('new_membership', 'members', (int) $member->id);
...@@ -353,7 +355,7 @@ class MemberController extends Controller ...@@ -353,7 +355,7 @@ class MemberController extends Controller
if (!$formFeePaid) return $this->redirect('/members/' . $id)->withError('⚠ يجب دفع رسوم الاستمارة أولاً'); if (!$formFeePaid) return $this->redirect('/members/' . $id)->withError('⚠ يجب دفع رسوم الاستمارة أولاً');
$data = $request->all(); unset($data['_csrf_token']); $data = $request->all(); unset($data['_csrf_token']);
$fields = ['full_name_en','place_of_birth','nationality','religion','qualification_id','marital_status','id_issue_date','id_expiry_date','phone_home','phone_international','email','emergency_name','emergency_phone','residence_type','residence_address','landmark','floor','apartment','area','governorate','correspondence_address','employment_type','occupation','job_title','employment_date','business_address','office_phone','office_fax','business_activity','referral_source']; $fields = ['full_name_en','place_of_birth','nationality','religion','qualification_id','marital_status','passport_number','id_issue_date','id_expiry_date','phone_home','phone_international','email','emergency_name','emergency_phone','residence_type','residence_address','landmark','floor','apartment','area','governorate','correspondence_address','employment_type','occupation','job_title','employment_date','business_address','office_phone','office_fax','business_activity','referral_source'];
$update = []; $update = [];
foreach ($fields as $f) { if (array_key_exists($f, $data)) { $v = trim((string) ($data[$f] ?? '')); $update[$f] = $v === '' ? null : $v; } } foreach ($fields as $f) { if (array_key_exists($f, $data)) { $v = trim((string) ($data[$f] ?? '')); $update[$f] = $v === '' ? null : $v; } }
if (isset($update['qualification_id'])) $update['qualification_id'] = $update['qualification_id'] ? (int) $update['qualification_id'] : null; if (isset($update['qualification_id'])) $update['qualification_id'] = $update['qualification_id'] ? (int) $update['qualification_id'] : null;
......
...@@ -79,6 +79,32 @@ ...@@ -79,6 +79,32 @@
</div> </div>
</div> </div>
<!-- Passport fallback for non-Egyptians -->
<div class="card" style="margin-bottom:20px;border-right:4px solid #D97706;display:none;" id="passport-section">
<div style="padding:15px 20px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;color:#D97706;">بيانات جواز السفر / Passport (لغير المصريين)</h3>
<small style="color:#6B7280;">في حالة عدم وجود رقم قومي — أدخل بيانات جواز السفر يدوياً</small>
</div>
<div style="padding:20px;display:grid;grid-template-columns:1fr 1fr;gap:15px;">
<div class="form-group">
<label class="form-label">رقم جواز السفر / Passport No. <span style="color:#DC2626;">*</span></label>
<input type="text" name="passport_number" id="passport_number_field" value="<?= e(old('passport_number')) ?>" class="form-input" style="direction:ltr;text-align:left;font-size:16px;">
</div>
<div class="form-group">
<label class="form-label">تاريخ الميلاد / Date of Birth <span style="color:#DC2626;">*</span></label>
<input type="date" name="date_of_birth_manual" id="dob_manual" value="<?= e(old('date_of_birth')) ?>" class="form-input">
</div>
<div class="form-group">
<label class="form-label">النوع / Gender <span style="color:#DC2626;">*</span></label>
<select name="gender_manual" id="gender_manual" class="form-select">
<option value="">-- اختر --</option>
<option value="male" <?= old('gender') === 'male' ? 'selected' : '' ?>>ذكر / Male</option>
<option value="female" <?= old('gender') === 'female' ? 'selected' : '' ?>>أنثى / Female</option>
</select>
</div>
</div>
</div>
<!-- Basic Required Info --> <!-- Basic Required Info -->
<div class="card" style="margin-bottom:20px;"> <div class="card" style="margin-bottom:20px;">
<div style="padding:15px 20px;border-bottom:1px solid #E5E7EB;"> <div style="padding:15px 20px;border-bottom:1px solid #E5E7EB;">
...@@ -107,6 +133,14 @@ ...@@ -107,6 +133,14 @@
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
<!-- Toggle for non-Egyptian -->
<div class="form-group" style="grid-column:1/-1;">
<label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:#6B7280;">
<input type="checkbox" id="no-nid-toggle" style="width:16px;height:16px;">
غير مصري / ليس لديه رقم قومي — استخدام جواز السفر بدلاً
</label>
</div>
</div> </div>
</div> </div>
...@@ -134,6 +168,32 @@ document.addEventListener('DOMContentLoaded', function() { ...@@ -134,6 +168,32 @@ document.addEventListener('DOMContentLoaded', function() {
var feedback = document.getElementById('nid-feedback'); var feedback = document.getElementById('nid-feedback');
var resultsBox = document.getElementById('nid-results'); var resultsBox = document.getElementById('nid-results');
var noNidToggle = document.getElementById('no-nid-toggle');
var nidCard = nidInput.closest('.card');
var passportSection = document.getElementById('passport-section');
var passportField = document.getElementById('passport_number_field');
var dobManual = document.getElementById('dob_manual');
var genderManual = document.getElementById('gender_manual');
noNidToggle.addEventListener('change', function() {
if (this.checked) {
nidCard.style.display = 'none';
passportSection.style.display = 'block';
nidInput.value = '';
nidInput.removeAttribute('required');
dobInput.value = '';
genderHidden.value = '';
resultsBox.style.display = 'none';
feedback.innerHTML = '';
} else {
nidCard.style.display = 'block';
passportSection.style.display = 'none';
passportField.value = '';
dobManual.value = '';
genderManual.value = '';
}
});
nidInput.addEventListener('input', function() { nidInput.addEventListener('input', function() {
var val = this.value.replace(/\D/g, ''); var val = this.value.replace(/\D/g, '');
this.value = val; this.value = val;
......
...@@ -105,6 +105,10 @@ ...@@ -105,6 +105,10 @@
<option value="military" <?= ($member->id_type ?? '') === 'military' ? 'selected' : '' ?>>بطاقة عسكرية / Military ID</option> <option value="military" <?= ($member->id_type ?? '') === 'military' ? 'selected' : '' ?>>بطاقة عسكرية / Military ID</option>
</select> </select>
</div> </div>
<div class="form-group" id="passport-group" style="<?= ($member->id_type ?? 'national_id') === 'passport' || ($member->nationality ?? 'مصري') !== 'مصري' ? '' : 'display:none;' ?>">
<label class="form-label">رقم جواز السفر / Passport Number <span id="passport-required-star" style="color:#DC2626;<?= ($member->nationality ?? 'مصري') !== 'مصري' ? '' : 'display:none;' ?>">*</span></label>
<input type="text" name="passport_number" id="passport_number" value="<?= e($member->passport_number ?? '') ?>" class="form-input" style="direction:ltr;text-align:left;" placeholder="Passport number">
</div>
<div class="form-group"> <div class="form-group">
<label class="form-label">تاريخ إصدار المستند / ID Issue Date</label> <label class="form-label">تاريخ إصدار المستند / ID Issue Date</label>
<input type="date" name="id_issue_date" value="<?= e($member->id_issue_date ?? '') ?>" class="form-input"> <input type="date" name="id_issue_date" value="<?= e($member->id_issue_date ?? '') ?>" class="form-input">
...@@ -331,3 +335,28 @@ ...@@ -331,3 +335,28 @@
</form> </form>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
<?php $__template->section('scripts'); ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
var nationalitySelect = document.querySelector('select[name="nationality"]');
var passportGroup = document.getElementById('passport-group');
var passportInput = document.getElementById('passport_number');
var passportStar = document.getElementById('passport-required-star');
if (nationalitySelect && passportGroup) {
nationalitySelect.addEventListener('change', function() {
var isEgyptian = (this.value === 'مصري');
passportGroup.style.display = isEgyptian ? 'none' : '';
passportStar.style.display = isEgyptian ? 'none' : '';
if (isEgyptian) {
passportInput.removeAttribute('required');
passportInput.value = '';
} else {
passportInput.setAttribute('required', 'required');
}
});
}
});
</script>
<?php $__template->endSection(); ?>
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