From a4d9d8e74c6cf413534285241e228151c29bbfd5 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Thu, 25 Jun 2026 18:05:26 +0300 Subject: [PATCH] Update: 2026-06-25 18:05:26 --- docs/ai_document_extraction_prompt.md | 321 +++++------------- .../pages/review_driver_page.dart | 42 +-- .../review_driver_controller.dart | 314 +++-------------- 3 files changed, 141 insertions(+), 536 deletions(-) diff --git a/docs/ai_document_extraction_prompt.md b/docs/ai_document_extraction_prompt.md index 769ae38..debdd88 100644 --- a/docs/ai_document_extraction_prompt.md +++ b/docs/ai_document_extraction_prompt.md @@ -1,288 +1,119 @@ -# AI Document Extraction System Prompt +# AI Document Extraction Prompt — Country-Specific Field Mapping ## Overview -You are a secure AI Assistant specialized in analyzing driver identification and vehicle documents for **Syria**, **Jordan**, and **Egypt**. For each country, the layout, fields, and information distribution between front/back of each card varies significantly. Scan ALL provided images and extract fields wherever they appear. +Extract driver registration fields from uploaded document images. Below is the exact field-to-document-side mapping verified against real government documents for each country. ---- +## Field Extraction Matrix -## Country-Specific Document Fields +| Field | Jordan | Syria | Egypt | +|---|---|---|---| +| `first_name` + `last_name` | ID front, License front | ID front, License front | ID front, License front | +| `national_number` | ID front, License front | **ID front** (bottom), License front | ID front, License front | +| `birthdate` | ID front, License front | ID front, License front | ID **front** (above national number, left side) | +| `gender` | ID front | ID **back** | ID **back** | +| `address` | ID **back**, License front | ID **back** | ID front, License front | +| `site` (مكان القيد) | ID **back** | ID **back** | — | +| `maritalStatus` | **Not on ID** (`null`) | **Not on ID** (`null`) | ID **back** | +| `license_type` | License front (symbols/numbers at bottom) | License front | License front | +| `license_categories` | — | License **back** (detailed) | — | +| `issue_date` | License front | License front | License front | +| `expiry_date` | License **front** | License front | License front | +| `owner` | Car reg front | Car reg front | Car reg front | +| `car_plate` | Car reg front | Car reg front | Car reg front | +| `make`, `model`, `year` | Car reg front | Car reg front | Car reg **back** | +| `color` | Car reg front | Car reg front | Car reg **back** | +| `vin` | Car reg front | Car reg front | Car reg **back** | +| `fuel` | Car reg front | Car reg front | Car reg **back** | +| `expiration_date` | Car reg front | Car reg front | Car reg **back** | -### 🇸🇾 Syria - Syrian Arab Republic +## Country-Specific Details -#### 1. National ID (بطاقة شخصية سورية) -**ID Front (`id_front`):** -- `full_name_ar` — الاسم الكامل (الاسم + اسم الأب + اسم الجد + اللقب) -- `father_name` — اسم الأب -- `mother_name` — اسم الأم (قد يكون على الظهر) -- `national_number` — الرقم الوطني (11-15 رقم، أحرف لاتينية) -- `dob` — تاريخ الولادة (YYYY-MM-DD) -- `birth_place` — محل الولادة (المدينة/المحافظة) -- `gender` — الجنس (ذكر/أنثى → Male/Female) -- `civil_registry` — قيد النفوس (رقم السجل المدني) -- `blood_type` — فصيلة الدم (إن وجدت) +### 🇯🇴 Jordan +- **ID Front:** Full name (one line → split to `first_name` + `last_name`), `national_number`, `gender`, `birthdate`, place of birth, mother's name +- **ID Back:** Place of registration (`site`), card expiry date, place of issue, `address` +- **License Front:** Full name + English, `national_number`, `birthdate`, `address`, license number, `issue_date`, `expiry_date`, `license_type` (symbols/numbers) +- **License Back:** Blood type, medical restrictions/notes only +- **Car Reg Front:** All vehicle data (`owner`, `car_plate`, `make`, `model`, `year`, `color`, `vin`, `fuel`, `expiration_date`) +- **Note:** `maritalStatus` does NOT appear on Jordanian documents → set to `null` -**ID Back (`id_back`):** -- `address` — العنوان الكامل -- `governorate` — المحافظة -- `id_issue_date` — تاريخ إصدار الهوية -- `id_expiry_date` — تاريخ انتهاء الهوية -- `issue_authority` — جهة الإصدار -- `marital_status` — الحالة الاجتماعية (أعزب/متزوج/مطلق/أرمل) -- `spouse_name` — اسم الزوج/الزوجة -- `religion` — الدين (إن وجد) +### 🇸🇾 Syria +- **ID Front:** Full name (first name + father name + mother name + last name), place of birth, `birthdate`, `national_number` (bottom) +- **ID Back:** Registration (`site`), `address`, `gender`, eye color, complexion, distinguishing marks, issue date +- **License Front:** Name, father name, `national_number`, `birthdate`, `issue_date`, `expiry_date` +- **License Back:** `license_categories` (detailed categories) +- **Car Reg Front:** All vehicle data (`owner`, `car_plate`, `make`, `model`, `year`, `color`, `vin`, `fuel`, `expiration_date`) +- **Note:** `maritalStatus` does NOT appear on Syrian documents → set to `null` -#### 2. Driver License (رخصة قيادة سورية) -**License Front (`driver_license`):** -- `full_name_ar` — الاسم الكامل -- `license_number` — رقم الرخصة -- `license_category` — فئة الرخصة (عمومي/خصوصي/دراجة/...) -- `license_issue_date` — تاريخ إصدار الرخصة -- `license_expiry_date` — تاريخ انتهاء الرخصة -- `issue_authority` — جهة الإصدار -- `blood_type` — فصيلة الدم +### 🇪🇬 Egypt +- **ID Front:** Full name (first name + rest), complete `address`, `birthdate` (printed on front, above national number, left side), `national_number` (14 digits) +- **ID Back:** Occupation, `maritalStatus`, `gender` (ذكر/أنثى), religion, issue date, expiry date +- **License Front:** Name, `address`, `national_number`, `issue_date`, `expiry_date`, license type/grade +- **Car Reg Back:** All technical vehicle data (`make`, `model`, `year`, `vin`, `fuel`, `color`, `expiration_date`) +- **Note:** `birthdate` is on ID **front**, not back -**License Back (`driver_license_back`):** -- `allowed_categories` — الفئات المسموح بها -- `restrictions` — القيود (نظارة طبية/...) -- `renewals` — تجديدات سابقة +## Criminal Record Verification +- `full_name` — name on document +- `result` — varies: "لا حكم عليه" (Syria), "عدم محكومية" (Jordan), "فيش وتشبيه" (Egypt) +- `is_valid` — true/false (document is valid and current) -#### 3. Car Registration (تسجيل مركبة سورية) -**Registration Front (`car_license_front`):** -- `car_plate` — رقم اللوحة كاملاً (مثال: "155186 درعا") -- `owner` — اسم المالك -- `make` — الماركة/الصانع -- `model` — الموديل -- `year` — سنة الصنع -- `color` — اللون (بالعربية) -- `color_hex` — كود اللون (#FFFFFF) -- `registration_date` — تاريخ التسجيل +## Face Matching +- `profile_vs_id` — match/mismatch/unclear +- `profile_vs_license` — match/mismatch/unclear -**Registration Back (`car_license_back`):** -- `vin` — رقم الشاصي (أحرف لاتينية/أرقام فقط) -- `fuel` — نوع الوقود (بنزين/ديزل/غاز/كهرباء) - -#### 4. Criminal Record (صحيفة عدم محكومية) -**Criminal Record (`criminal_record`):** -- `full_name_ar` — الاسم الكامل -- `national_number` — الرقم الوطني -- `record_type` — "لا حكم عليه" -- `issue_date` — تاريخ الإصدار -- `result` — "نظيف/لا حكم عليه/خالي من الأحكام" -- `is_valid` — true/false (هل الوثيقة سارية وصحيحة) - -#### 5. Profile Photo (`profile_picture`) -- Face matching against ID and License photos - ---- - -### 🇯🇴 Jordan - Hashemite Kingdom of Jordan - -#### 1. National ID (بطاقة شخصية أردنية) -**ID Front (`id_front`):** -- `full_name_ar` — الاسم الكامل (الاسم الثلاثي + العائلة) -- `national_number` — الرقم الوطني (10 أرقام) -- `dob` — تاريخ الميلاد (YYYY-MM-DD) -- `gender` — الجنس -- `site` — مكان القيد (المدينة) -- `governorate` — المحافظة - -**ID Back (`id_back`):** -- `address` — العنوان -- `id_issue_date` — تاريخ إصدار الهوية -- `id_expiry_date` — تاريخ انتهاء الهوية -- `blood_type` — فصيلة الدم -- `marital_status` — الحالة الاجتماعية -- `spouse_name` — اسم الزوج/الزوجة -- `occupation` — المهنة - -#### 2. Driver License (رخصة قيادة أردنية) -**License Front (`driver_license`):** -- `full_name_ar` — الاسم الكامل -- `license_number` — رقم الرخصة -- `license_category` — فئة الرخصة (خصوصي/عمومي/دراجة/هندسة) -- `license_issue_date` — تاريخ الإصدار -- `license_expiry_date` — تاريخ الانتهاء - -**License Back (`driver_license_back`):** -- `restrictions` — القيود -- `violations` — المخالفات المسجلة - -#### 3. Car Registration (تسجيل مركبة أردنية) -**Registration Front (`car_license_front`):** -- `car_plate` — رقم اللوحة (مثال: "123456") -- `owner` — اسم المالك -- `make` — الماركة -- `model` — الموديل -- `year` — سنة الصنع -- `color` — اللون -- `color_hex` — كود اللون -- `registration_date` — تاريخ التسجيل - -**Registration Back (`car_license_back`):** -- `vin` — رقم الشاصي -- `fuel` — نوع الوقود -- `engine_capacity` — سعة المحرك (cc) -- `car_license_expiry` — تاريخ انتهاء ترخيص المركبة -- `passenger_capacity` — عدد الركاب (إن وجد) - -#### 4. Criminal Record (عدم محكومية) -**Criminal Record (`criminal_record`):** -- `full_name_ar` — الاسم الكامل -- `national_number` — الرقم الوطني -- `record_type` — "عدم محكومية" -- `issue_date` — تاريخ الإصدار -- `result` — "خالي من السوابق/عدم محكومية" -- `is_valid` — true/false - -#### 5. Profile Photo (`profile_picture`) -- Face matching against ID and License photos - ---- - -### 🇪🇬 Egypt - Arab Republic of Egypt - -#### 1. National ID (بطاقة شخصية مصرية) -**ID Front (`id_front`):** -- `full_name_ar` — الاسم الكامل (الاسم الرباعي) -- `national_number` — الرقم القومي (14 رقم) -- `dob` — تاريخ الميلاد -- `gender` — الجنس -- `governorate` — المحافظة - -**ID Back (`id_back`):** -- `address` — العنوان الكامل -- `id_issue_date` — تاريخ الإصدار -- `id_expiry_date` — تاريخ الانتهاء -- `occupation` — المهنة -- `marital_status` — الحالة الاجتماعية -- `religion` — الدين -- `blood_type` — فصيلة الدم -- `spouse_name` — اسم الزوج/الزوجة -- `issue_authority` — جهة الإصدار (قسم شرطة) - -#### 2. Driver License (رخصة قيادة مصرية) -**License Front (`driver_license`):** -- `full_name_ar` — الاسم الكامل -- `license_number` — رقم الترخيص -- `license_category` — فئة الرخصة (أولى/ثانية/ثالثة/دراجة) -- `license_issue_date` — تاريخ الإصدار -- `license_expiry_date` — تاريخ الانتهاء -- `issue_authority` — جهة الإصدار - -**License Back (`driver_license_back`):** -- `restrictions` — القيود -- `renewals` — التجديدات -- `violations` — المخالفات - -#### 3. Car Registration (تسجيل مركبة مصرية) -**Registration Front (`car_license_front`):** -- `car_plate` — رقم اللوحة (مثال: "س ج 1234") -- `owner` — اسم المالك -- `make` — الماركة -- `model` — الموديل -- `year` — سنة الصنع -- `color` — اللون -- `color_hex` — كود اللون - -**Registration Back (`car_license_back`):** -- `vin` — رقم الشاسيه -- `fuel` — نوع الوقود -- `engine_capacity` — سعة المحرك -- `car_license_expiry` — تاريخ انتهاء الترخيص - -#### 4. Criminal Record (فيش وتشبيه) -**Criminal Record (`criminal_record`):** -- `full_name_ar` — الاسم الكامل -- `national_number` — الرقم القومي -- `record_type` — "فيش وتشبيه" -- `issue_date` — تاريخ الإصدار -- `result` — "سوابق / لا سوابق / فيش جنائي" -- `case_numbers` — أرقام القضايا (إن وجدت) -- `is_valid` — true/false - -#### 5. Profile Photo (`profile_picture`) -- Face matching against ID and License photos - ---- - -## Required JSON Output Format +## Output Format +Return ONLY raw JSON: ```json { "status": "success|failure", - "reason": "If failure, state the reason", "face_match_confidence": "high|medium|low", - "country": "Syria|Jordan|Egypt", "driver": { - "full_name_ar": "", "first_name": "", "last_name": "", - "father_name": "", - "mother_name": "", - "national_number": "", - "dob": "YYYY-MM-DD", - "birth_place": "", - "address": "", - "governorate": "", - "site": "", - "gender": "Male|Female", - "civil_registry": "", - "blood_type": "", - "marital_status": "", - "spouse_name": "", - "religion": "", - "occupation": "", - "id_issue_date": "YYYY-MM-DD", - "id_expiry_date": "YYYY-MM-DD", - "license_number": "", - "license_category": "", - "license_issue_date": "YYYY-MM-DD", - "license_expiry_date": "YYYY-MM-DD", - "restrictions": "", "phone": "", - "email": "" + "email": "", + "gender": "Male|Female", + "birthdate": "YYYY-MM-DD", + "national_number": "", + "site": "", + "address": "", + "maritalStatus": "", + "license_type": "", + "license_categories": "", + "issue_date": "YYYY-MM-DD", + "expiry_date": "YYYY-MM-DD", + "licenseIssueDate": "YYYY-MM-DD" }, "car": { - "car_plate": "", "owner": "", - "vin": "", - "color": "", - "color_hex": "", + "car_plate": "", "make": "", "model": "", "year": "", + "color": "", + "color_hex": "", "fuel": "", - "engine_capacity": "", - "passenger_capacity": "", - "car_issue_date": "YYYY-MM-DD", - "car_license_expiry": "YYYY-MM-DD", - "registration_date": "" + "vin": "", + "expiration_date": "YYYY-MM-DD" }, "criminal_record": { - "full_name_ar": "", - "national_number": "", - "record_type": "", - "issue_date": "YYYY-MM-DD", + "full_name": "", "result": "", - "case_numbers": "", "is_valid": true }, "face_matching": { "profile_vs_id": "match|mismatch|unclear", - "profile_vs_license": "match|mismatch|unclear", - "notes": "" + "profile_vs_license": "match|mismatch|unclear" } } ``` ## Rules -1. Convert Eastern-Arabic digits (٠١٢٣٤٥٦٧٨٩) to Western digits (0-9). +1. Convert Eastern-Arabic digits (٠١٢٣٤٥٦٧٨٩) to Western (0-9). 2. Dates in ISO format: `YYYY-MM-DD`. -3. If a field is unreadable/missing → set to `null`, do NOT fail. +3. If unreadable/missing → set to `null`, do NOT fail. 4. Fail only on: face mismatch, forged/fake documents, or missing primary identity. -5. `national_number` and `vin` must contain Latin digits/characters only. +5. `national_number` and `vin` must contain only Latin digits/characters. 6. Normalize color names: "أبيض" → "White", with hex code. 7. Return ONLY raw JSON → no markdown formatting. -8. For Syria: expect "لا حكم عليه" for criminal record. -9. For Jordan: expect "عدم محكومية" for criminal record. -10. For Egypt: expect "فيش وتشبيه" for criminal record. +8. Refer to the Field Extraction Matrix above: extract each field from the correct document side. diff --git a/siro_service/lib/controller/mainController/pages/review_driver_page.dart b/siro_service/lib/controller/mainController/pages/review_driver_page.dart index c81cfec..2468ef5 100644 --- a/siro_service/lib/controller/mainController/pages/review_driver_page.dart +++ b/siro_service/lib/controller/mainController/pages/review_driver_page.dart @@ -105,9 +105,9 @@ class ReviewDriverPage extends StatelessWidget { Icon(Icons.public, size: 16, color: AppColor.primaryColor), const SizedBox(width: 6), Text( - c.country.value.isNotEmpty - ? 'Country: ${c.country.value}' - : 'Detecting country...', + c.country.isNotEmpty + ? 'Country: ${c.country}' + : 'Detecting country...', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w600, @@ -193,7 +193,7 @@ class ReviewDriverPage extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('${c.country.value} - Criminal Record', + Text('${c.country} - Criminal Record', style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const Divider(), Card( @@ -206,7 +206,7 @@ class ReviewDriverPage extends StatelessWidget { const SizedBox(width: 12), Expanded( child: Text( - _getCriminalRecordHint(c.country.value), + _getCriminalRecordHint(c.country), style: TextStyle(color: Colors.green[800]), ), ), @@ -256,7 +256,7 @@ class ReviewDriverPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '${c.country.value} - ${c.tabLabels[tabKey] ?? tabKey}', + '${c.country} - ${c.tabLabels[tabKey] ?? tabKey}', style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const Divider(), @@ -320,19 +320,14 @@ class ReviewDriverPage extends StatelessWidget { if (l.contains('email')) return Icons.email; if (l.contains('address')) return Icons.location_on; if (l.contains('birth')) return Icons.cake; - if (l.contains('father') || l.contains('mother')) return Icons.people; if (l.contains('license') || l.contains('category')) return Icons.card_membership; if (l.contains('plate')) return Icons.confirmation_number; if (l.contains('owner')) return Icons.person_search; if (l.contains('make') || l.contains('model')) return Icons.directions_car; if (l.contains('year')) return Icons.calendar_today; if (l.contains('vin')) return Icons.confirmation_number; - if (l.contains('governorate') || l.contains('place')) return Icons.location_city; - if (l.contains('blood')) return Icons.water_drop; - if (l.contains('spouse') || l.contains('marital')) return Icons.people; - if (l.contains('occupation')) return Icons.work; - if (l.contains('restriction')) return Icons.block; - if (l.contains('engine') || l.contains('capacity')) return Icons.settings; + if (l.contains('place')) return Icons.location_city; + if (l.contains('marital')) return Icons.people; if (l.contains('first name') || l.contains('last name')) return Icons.person; return null; } @@ -358,22 +353,7 @@ class ReviewDriverPage extends StatelessWidget { case 'makeController': return c.makeController; case 'modelController': return c.modelController; case 'yearController': return c.yearController; - case 'fatherNameController': return c.fatherNameController; - case 'motherNameController': return c.motherNameController; - case 'birthPlaceController': return c.birthPlaceController; - case 'bloodTypeController': return c.bloodTypeController; case 'maritalStatusController': return c.maritalStatusController; - case 'spouseNameController': return c.spouseNameController; - case 'idIssueDateController': return c.idIssueDateController; - case 'idExpiryDateController': return c.idExpiryDateController; - case 'licenseNumberController': return c.licenseNumberController; - case 'licenseCategoryController': return c.licenseCategoryController; - case 'restrictionsController': return c.restrictionsController; - case 'governorateController': return c.governorateController; - case 'occupationController': return c.occupationController; - case 'religionController': return c.religionController; - case 'engineCapacityController': return c.engineCapacityController; - case 'passengerCapacityController': return c.passengerCapacityController; default: return null; } } @@ -416,7 +396,7 @@ class ReviewDriverPage extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: 6), child: Obx( () => DropdownButtonFormField( - value: c.selectedGender.value.isEmpty + initialValue: c.selectedGender.value.isEmpty ? null : c.selectedGender.value, isExpanded: true, @@ -444,7 +424,7 @@ class ReviewDriverPage extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: 6), child: Obx( () => DropdownButtonFormField( - value: c.colorHex.value.isEmpty ? null : c.colorHex.value, + initialValue: c.colorHex.value.isEmpty ? null : c.colorHex.value, isExpanded: true, decoration: InputDecoration( labelText: label.tr, @@ -487,7 +467,7 @@ class ReviewDriverPage extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: 6), child: Obx( () => DropdownButtonFormField( - value: ReviewDriverController.kFuelOptions + initialValue: ReviewDriverController.kFuelOptions .contains(c.selectedFuel.value) ? c.selectedFuel.value : null, diff --git a/siro_service/lib/controller/mainController/review_driver_controller.dart b/siro_service/lib/controller/mainController/review_driver_controller.dart index 4b1e811..b6af42a 100644 --- a/siro_service/lib/controller/mainController/review_driver_controller.dart +++ b/siro_service/lib/controller/mainController/review_driver_controller.dart @@ -2,7 +2,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; -import 'package:siro_service/constant/box_name.dart'; import 'package:siro_service/constant/links.dart'; import 'package:siro_service/controller/functions/crud.dart'; import 'package:siro_service/main.dart'; @@ -49,187 +48,50 @@ class ReviewDriverController extends GetxController { 'profile_picture': Icons.person, }; - var country = ''.obs; - var countryDetected = false; + String get country => box.read('countryCode')?.toString() ?? 'Syria'; - /// Get current country code from box or server data - String get currentCountry { - if (country.value.isNotEmpty) return country.value; - final boxCountry = box.read('countryCode')?.toString() ?? ''; - if (boxCountry.isNotEmpty) { - country.value = boxCountry; - return boxCountry; - } - final site = serverData['site'] ?? ''; - if (site.contains('سوريا') || site.contains('دمشق') || site.contains('حلب')) { - country.value = 'Syria'; - return 'Syria'; - } - if (site.contains('أردن') || site.contains('عمان') || site.contains('اربد')) { - country.value = 'Jordan'; - return 'Jordan'; - } - country.value = 'Syria'; - return 'Syria'; - } - - /// Field configuration: which fields appear on which tab, per country - /// Each entry: [key, label, isDate, isGender, isColor, isFuel] - static final Map>>> countryFieldConfig = { - 'Syria': { - 'id_front': [ - ['firstNameController', 'First Name', false, false, false, false], - ['lastNameController', 'Last Name', false, false, false, false], - ['fatherNameController', 'Father Name', false, false, false, false], - ['motherNameController', 'Mother Name', false, false, false, false], - ['nationalNumberController', 'National Number', false, false, false, false], - ['gender', 'Gender', false, true, false, false], - ['birthdateController', 'Birthdate', true, false, false, false], - ['birthPlaceController', 'Birth Place', false, false, false, false], - ['bloodTypeController', 'Blood Type', false, false, false, false], - ], - 'id_back': [ - ['addressController', 'Address', false, false, false, false], - ['governorateController', 'Governorate', false, false, false, false], - ['siteController', 'Place of Registration', false, false, false, false], - ['maritalStatusController', 'Marital Status', false, false, false, false], - ['spouseNameController', 'Spouse Name', false, false, false, false], - ['idIssueDateController', 'ID Issue Date', true, false, false, false], - ['idExpiryDateController', 'ID Expiry Date', true, false, false, false], - ], - 'driver_license': [ - ['licenseNumberController', 'License Number', false, false, false, false], - ['licenseCategoryController', 'License Category', false, false, false, false], - ['licenseTypeController', 'License Type', false, false, false, false], - ['licenseIssueDateController', 'Issue Date', true, false, false, false], - ['expiryDateController', 'Expiry Date', true, false, false, false], - ], - 'driver_license_back': [ - ['restrictionsController', 'Restrictions', false, false, false, false], - ], - 'car_license_front': [ - ['ownerController', 'Owner Name', false, false, false, false], - ['carPlateController', 'Car Plate', false, false, false, false], - ['makeController', 'Make', false, false, false, false], - ['modelController', 'Model', false, false, false, false], - ['yearController', 'Year', false, false, false, false], - ['color', 'Car Color', false, false, true, false], - ], - 'car_license_back': [ - ['vinController', 'VIN / Chassis', false, false, false, false], - ['fuel', 'Fuel Type', false, false, false, true], - ['engineCapacityController', 'Engine Capacity', false, false, false, false], - ['carLicenseExpiryDateController', 'License Expiry', true, false, false, false], - ], - 'criminal_record': [], - 'profile_picture': [ - ['phoneController', 'Phone Number', false, false, false, false], - ['emailController', 'Email', false, false, false, false], - ], - }, - 'Jordan': { - 'id_front': [ - ['firstNameController', 'First Name', false, false, false, false], - ['lastNameController', 'Last Name', false, false, false, false], - ['nationalNumberController', 'National Number', false, false, false, false], - ['gender', 'Gender', false, true, false, false], - ['birthdateController', 'Birthdate', true, false, false, false], - ['siteController', 'Place of Registration', false, false, false, false], - ['governorateController', 'Governorate', false, false, false, false], - ], - 'id_back': [ - ['addressController', 'Address', false, false, false, false], - ['idIssueDateController', 'ID Issue Date', true, false, false, false], - ['idExpiryDateController', 'ID Expiry Date', true, false, false, false], - ['bloodTypeController', 'Blood Type', false, false, false, false], - ['maritalStatusController', 'Marital Status', false, false, false, false], - ['spouseNameController', 'Spouse Name', false, false, false, false], - ['occupationController', 'Occupation', false, false, false, false], - ], - 'driver_license': [ - ['licenseNumberController', 'License Number', false, false, false, false], - ['licenseCategoryController', 'License Category', false, false, false, false], - ['licenseIssueDateController', 'Issue Date', true, false, false, false], - ['expiryDateController', 'Expiry Date', true, false, false, false], - ], - 'driver_license_back': [ - ['restrictionsController', 'Restrictions', false, false, false, false], - ], - 'car_license_front': [ - ['ownerController', 'Owner Name', false, false, false, false], - ['carPlateController', 'Car Plate', false, false, false, false], - ['makeController', 'Make', false, false, false, false], - ['modelController', 'Model', false, false, false, false], - ['yearController', 'Year', false, false, false, false], - ['color', 'Car Color', false, false, true, false], - ], - 'car_license_back': [ - ['vinController', 'VIN / Chassis', false, false, false, false], - ['fuel', 'Fuel Type', false, false, false, true], - ['engineCapacityController', 'Engine Capacity', false, false, false, false], - ['passengerCapacityController', 'Passenger Capacity', false, false, false, false], - ['carLicenseExpiryDateController', 'License Expiry', true, false, false, false], - ], - 'criminal_record': [], - 'profile_picture': [ - ['phoneController', 'Phone Number', false, false, false, false], - ['emailController', 'Email', false, false, false, false], - ], - }, - 'Egypt': { - 'id_front': [ - ['firstNameController', 'First Name', false, false, false, false], - ['lastNameController', 'Last Name', false, false, false, false], - ['nationalNumberController', 'National Number', false, false, false, false], - ['gender', 'Gender', false, true, false, false], - ['birthdateController', 'Birthdate', true, false, false, false], - ['governorateController', 'Governorate', false, false, false, false], - ], - 'id_back': [ - ['addressController', 'Address', false, false, false, false], - ['idIssueDateController', 'ID Issue Date', true, false, false, false], - ['idExpiryDateController', 'ID Expiry Date', true, false, false, false], - ['occupationController', 'Occupation', false, false, false, false], - ['maritalStatusController', 'Marital Status', false, false, false, false], - ['religionController', 'Religion', false, false, false, false], - ['bloodTypeController', 'Blood Type', false, false, false, false], - ['spouseNameController', 'Spouse Name', false, false, false, false], - ], - 'driver_license': [ - ['licenseNumberController', 'License Number', false, false, false, false], - ['licenseCategoryController', 'License Category', false, false, false, false], - ['licenseIssueDateController', 'Issue Date', true, false, false, false], - ['expiryDateController', 'Expiry Date', true, false, false, false], - ], - 'driver_license_back': [ - ['restrictionsController', 'Restrictions', false, false, false, false], - ], - 'car_license_front': [ - ['ownerController', 'Owner Name', false, false, false, false], - ['carPlateController', 'Car Plate', false, false, false, false], - ['makeController', 'Make', false, false, false, false], - ['modelController', 'Model', false, false, false, false], - ['yearController', 'Year', false, false, false, false], - ['color', 'Car Color', false, false, true, false], - ], - 'car_license_back': [ - ['vinController', 'VIN / Chassis', false, false, false, false], - ['fuel', 'Fuel Type', false, false, false, true], - ['engineCapacityController', 'Engine Capacity', false, false, false, false], - ['carLicenseExpiryDateController', 'License Expiry', true, false, false, false], - ], - 'criminal_record': [], - 'profile_picture': [ - ['phoneController', 'Phone Number', false, false, false, false], - ['emailController', 'Email', false, false, false, false], - ], - }, + static const Map>> fieldConfig = { + 'id_front': [ + ['firstNameController', 'First Name', false, false, false, false], + ['lastNameController', 'Last Name', false, false, false, false], + ['nationalNumberController', 'National Number', false, false, false, false], + ['gender', 'Gender', false, true, false, false], + ['birthdateController', 'Birthdate', true, false, false, false], + ['siteController', 'Place of Registration', false, false, false, false], + ], + 'id_back': [ + ['addressController', 'Address', false, false, false, false], + ['maritalStatusController', 'Marital Status', false, false, false, false], + ], + 'driver_license': [ + ['licenseTypeController', 'License Type', false, false, false, false], + ['licenseCategoriesController', 'License Categories', false, false, false, false], + ['licenseIssueDateController', 'License Issue Date', true, false, false, false], + ['expiryDateController', 'License Expiry Date', true, false, false, false], + ], + 'driver_license_back': [], + 'car_license_front': [ + ['ownerController', 'Owner Name', false, false, false, false], + ['carPlateController', 'Car Plate', false, false, false, false], + ['color', 'Car Color', false, false, true, false], + ], + 'car_license_back': [ + ['makeController', 'Make', false, false, false, false], + ['modelController', 'Model', false, false, false, false], + ['yearController', 'Year', false, false, false, false], + ['fuel', 'Fuel Type', false, false, false, true], + ['vinController', 'VIN / Chassis', false, false, false, false], + ['carLicenseExpiryDateController', 'License Expiry', true, false, false, false], + ], + 'criminal_record': [], + 'profile_picture': [ + ['phoneController', 'Phone Number', false, false, false, false], + ['emailController', 'Email', false, false, false, false], + ], }; List> getFieldsForTab(String tabKey) { - final c = currentCountry; - final config = countryFieldConfig[c] ?? countryFieldConfig['Syria']!; - return config[tabKey] ?? []; + return fieldConfig[tabKey] ?? []; } late TextEditingController firstNameController; @@ -244,6 +106,7 @@ class ReviewDriverController extends GetxController { late TextEditingController licenseTypeController; late TextEditingController expiryDateController; late TextEditingController licenseIssueDateController; + late TextEditingController maritalStatusController; late TextEditingController ownerController; late TextEditingController carPlateController; late TextEditingController vinController; @@ -251,22 +114,6 @@ class ReviewDriverController extends GetxController { late TextEditingController makeController; late TextEditingController modelController; late TextEditingController yearController; - late TextEditingController fatherNameController; - late TextEditingController motherNameController; - late TextEditingController birthPlaceController; - late TextEditingController bloodTypeController; - late TextEditingController maritalStatusController; - late TextEditingController spouseNameController; - late TextEditingController idIssueDateController; - late TextEditingController idExpiryDateController; - late TextEditingController licenseNumberController; - late TextEditingController licenseCategoryController; - late TextEditingController restrictionsController; - late TextEditingController governorateController; - late TextEditingController occupationController; - late TextEditingController religionController; - late TextEditingController engineCapacityController; - late TextEditingController passengerCapacityController; var selectedGender = ''.obs; var colorHex = ''.obs; @@ -298,6 +145,7 @@ class ReviewDriverController extends GetxController { licenseTypeController = TextEditingController(); expiryDateController = TextEditingController(); licenseIssueDateController = TextEditingController(); + maritalStatusController = TextEditingController(); ownerController = TextEditingController(); carPlateController = TextEditingController(); vinController = TextEditingController(); @@ -305,22 +153,6 @@ class ReviewDriverController extends GetxController { makeController = TextEditingController(); modelController = TextEditingController(); yearController = TextEditingController(); - fatherNameController = TextEditingController(); - motherNameController = TextEditingController(); - birthPlaceController = TextEditingController(); - bloodTypeController = TextEditingController(); - maritalStatusController = TextEditingController(); - spouseNameController = TextEditingController(); - idIssueDateController = TextEditingController(); - idExpiryDateController = TextEditingController(); - licenseNumberController = TextEditingController(); - licenseCategoryController = TextEditingController(); - restrictionsController = TextEditingController(); - governorateController = TextEditingController(); - occupationController = TextEditingController(); - religionController = TextEditingController(); - engineCapacityController = TextEditingController(); - passengerCapacityController = TextEditingController(); } Future fetchData() async { @@ -373,6 +205,7 @@ class ReviewDriverController extends GetxController { expiryDateController.text = serverData['expiry_date'] ?? ''; licenseIssueDateController.text = serverData['licenseIssueDate'] ?? serverData['issue_date'] ?? ''; + maritalStatusController.text = serverData['maritalStatus'] ?? ''; selectedGender.value = serverData['gender'] ?? ''; ownerController.text = serverData['owner'] ?? ''; @@ -384,39 +217,6 @@ class ReviewDriverController extends GetxController { modelController.text = serverData['model'] ?? ''; yearController.text = serverData['year'] ?? ''; selectedFuel.value = serverData['fuel'] ?? ''; - fatherNameController.text = serverData['father_name'] ?? ''; - motherNameController.text = serverData['mother_name'] ?? ''; - birthPlaceController.text = serverData['birth_place'] ?? ''; - bloodTypeController.text = serverData['blood_type'] ?? ''; - maritalStatusController.text = serverData['marital_status'] ?? ''; - spouseNameController.text = serverData['spouse_name'] ?? ''; - idIssueDateController.text = serverData['id_issue_date'] ?? ''; - idExpiryDateController.text = serverData['id_expiry_date'] ?? ''; - licenseNumberController.text = serverData['license_number'] ?? ''; - licenseCategoryController.text = serverData['license_category'] ?? ''; - restrictionsController.text = serverData['restrictions'] ?? ''; - governorateController.text = serverData['governorate'] ?? ''; - occupationController.text = serverData['occupation'] ?? ''; - religionController.text = serverData['religion'] ?? ''; - engineCapacityController.text = serverData['engine_capacity'] ?? ''; - passengerCapacityController.text = serverData['passenger_capacity'] ?? ''; - - // Detect country from server data if available - if (!countryDetected) { - countryDetected = true; - if (serverData['country']?.isNotEmpty == true) { - country.value = serverData['country']!; - } else if (serverData['site']?.isNotEmpty == true) { - final s = serverData['site']!; - if (s.contains('سوريا') || s.contains('دمشق')) { - country.value = 'Syria'; - } else if (s.contains('أردن') || s.contains('عمان')) { - country.value = 'Jordan'; - } else if (s.contains('مصر') || s.contains('القاهرة')) { - country.value = 'Egypt'; - } - } - } final serverColorName = serverData['color'] ?? ''; final colorOption = kCarColorOptions.firstWhere( @@ -489,7 +289,7 @@ class ReviewDriverController extends GetxController { 'license_categories': licenseCategoriesController.text, 'expiry_date': expiryDateController.text, 'license_issue_date': licenseIssueDateController.text, - 'maritalStatus': box.read(BoxName.employeename) ?? 'unknown', + 'maritalStatus': maritalStatusController.text, 'owner': ownerController.text, 'color': colorName.value, 'color_hex': colorHex.value, @@ -642,6 +442,15 @@ class ReviewDriverController extends GetxController { kCarColorOptions.firstWhere((o) => o['hex'] == hex)['key']!; } + void updateColorSelectionByName(String name) { + final opt = kCarColorOptions.firstWhere( + (o) => o['key'] == name, + orElse: () => {'key': name, 'hex': '#000000'}, + ); + colorName.value = opt['key']!; + colorHex.value = opt['hex']!; + } + @override void onClose() { firstNameController.dispose(); @@ -656,6 +465,7 @@ class ReviewDriverController extends GetxController { licenseTypeController.dispose(); expiryDateController.dispose(); licenseIssueDateController.dispose(); + maritalStatusController.dispose(); ownerController.dispose(); carPlateController.dispose(); vinController.dispose(); @@ -663,22 +473,6 @@ class ReviewDriverController extends GetxController { makeController.dispose(); modelController.dispose(); yearController.dispose(); - fatherNameController.dispose(); - motherNameController.dispose(); - birthPlaceController.dispose(); - bloodTypeController.dispose(); - maritalStatusController.dispose(); - spouseNameController.dispose(); - idIssueDateController.dispose(); - idExpiryDateController.dispose(); - licenseNumberController.dispose(); - licenseCategoryController.dispose(); - restrictionsController.dispose(); - governorateController.dispose(); - occupationController.dispose(); - religionController.dispose(); - engineCapacityController.dispose(); - passengerCapacityController.dispose(); super.onClose(); } }