Compare commits

..

3 Commits

Author SHA1 Message Date
93b3018a0a Merge pull request 'mohan' (#17) from mohan into master
Reviewed-on: #17
2026-06-24 11:05:30 +00:00
fab61468d2 api changes 2026-06-24 16:35:09 +05:30
291591f3a9 api changes 2026-06-24 15:42:59 +05:30
6 changed files with 252 additions and 139 deletions

View File

@ -1246,7 +1246,7 @@ private function cleanVisaData(array $visaDataInput): array
$rawEntryPermitNo = $visaDataInput['entry_permit_no'] ?? $visaDataInput['file_number'] ?? $visaDataInput['id_number'] ?? $visaDataInput['number'] ?? null;
$rawIssueDate = $visaDataInput['issue_date'] ?? null;
$rawValidUntil = $visaDataInput['valid_until'] ?? $visaDataInput['expiry_date'] ?? null;
$rawUidNo = $visaDataInput['uid_no'] ?? null;
$rawUidNo = $visaDataInput['uid_no'] ?? $visaDataInput['id_number'] ?? null;
$rawFullName = $visaDataInput['full_name'] ?? $visaDataInput['name'] ?? null;
$rawNationality = $visaDataInput['nationality'] ?? null;
$rawPlaceOfBirth = $visaDataInput['place_of_birth'] ?? null;

View File

@ -768,7 +768,7 @@ private function cleanVisaData(array $visaDataInput): array
$rawEntryPermitNo = $visaDataInput['entry_permit_no'] ?? $visaDataInput['file_number'] ?? $visaDataInput['id_number'] ?? $visaDataInput['number'] ?? null;
$rawIssueDate = $visaDataInput['issue_date'] ?? null;
$rawValidUntil = $visaDataInput['valid_until'] ?? $visaDataInput['expiry_date'] ?? null;
$rawUidNo = $visaDataInput['uid_no'] ?? null;
$rawUidNo = $visaDataInput['uid_no'] ?? $visaDataInput['id_number'] ?? null;
$rawFullName = $visaDataInput['full_name'] ?? $visaDataInput['name'] ?? null;
$rawNationality = $visaDataInput['nationality'] ?? null;
$rawPlaceOfBirth = $visaDataInput['place_of_birth'] ?? null;

View File

@ -0,0 +1,89 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$visaDocuments = \DB::table('worker_documents')->where('type', 'visa')->get();
foreach ($visaDocuments as $doc) {
$ocrData = json_decode($doc->ocr_data, true);
if (is_array($ocrData)) {
$cleaned = $this->cleanVisaData($ocrData);
\DB::table('worker_documents')->where('id', $doc->id)->update([
'ocr_data' => json_encode($cleaned)
]);
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Cleaning up or reverting structure is not strictly necessary or possible
// since we map legacy fields to modern ones.
}
private function cleanVisaData(array $visaDataInput): array
{
$rawVisaType = $visaDataInput['visa_type'] ?? null;
$rawEntryPermitNo = $visaDataInput['entry_permit_no'] ?? $visaDataInput['file_number'] ?? $visaDataInput['id_number'] ?? $visaDataInput['number'] ?? null;
$rawIssueDate = $visaDataInput['issue_date'] ?? null;
$rawValidUntil = $visaDataInput['valid_until'] ?? $visaDataInput['expiry_date'] ?? null;
$rawUidNo = $visaDataInput['uid_no'] ?? $visaDataInput['id_number'] ?? null;
$rawFullName = $visaDataInput['full_name'] ?? $visaDataInput['name'] ?? null;
$rawNationality = $visaDataInput['nationality'] ?? null;
$rawPlaceOfBirth = $visaDataInput['place_of_birth'] ?? null;
$rawDateOfBirth = $visaDataInput['date_of_birth'] ?? $visaDataInput['dob'] ?? null;
$rawPassportNo = $visaDataInput['passport_no'] ?? $visaDataInput['passport_number'] ?? null;
$rawProfession = $visaDataInput['profession'] ?? null;
$rawSponsorName = $visaDataInput['sponsor_name'] ?? null;
$rawOcrAccuracy = $visaDataInput['ocr_accuracy'] ?? null;
// Clean sponsor
$sponsorData = $visaDataInput['sponsor'] ?? [];
if (is_string($sponsorData)) {
$sponsorNameFromObj = $sponsorData;
$sponsorAddress = '';
$sponsorPhone = '';
} else {
$sponsorNameFromObj = $sponsorData['name'] ?? $sponsorData['sponsor_name'] ?? $sponsorData['full_name'] ?? '';
$sponsorAddress = $sponsorData['address'] ?? '';
$sponsorPhone = $sponsorData['phone'] ?? $sponsorData['mobile'] ?? $sponsorData['mobile_number'] ?? $sponsorData['phone_number'] ?? '';
}
if (empty($rawSponsorName)) {
$rawSponsorName = $sponsorNameFromObj;
}
return [
'document_type' => 'uae_visa',
'country' => 'United Arab Emirates',
'visa_type' => $rawVisaType ?: 'ENTRY PERMIT',
'entry_permit_no' => $rawEntryPermitNo ?: '',
'issue_date' => $rawIssueDate ?: '',
'valid_until' => $rawValidUntil ?: '',
'uid_no' => $rawUidNo ?: '',
'full_name' => $rawFullName ?: '',
'nationality' => $rawNationality ?: '',
'place_of_birth' => $rawPlaceOfBirth ?: '',
'date_of_birth' => $rawDateOfBirth ?: '',
'passport_no' => $rawPassportNo ?: '',
'profession' => $rawProfession ?: '',
'sponsor_name' => $rawSponsorName ?: '',
'ocr_accuracy' => $rawOcrAccuracy !== null ? (int)$rawOcrAccuracy : 99,
'sponsor' => [
'name' => $sponsorNameFromObj ?: '',
'address' => $sponsorAddress ?: '',
'phone' => $sponsorPhone ?: '',
]
];
}
};

View File

@ -1102,92 +1102,85 @@
},
"visa": {
"type": "object",
"description": "Optional JSON object containing extracted visa details.",
"description": "Standardized UAE Visa metadata.",
"properties": {
"accompanied_by": {
"type": "string"
"document_type": {
"type": "string",
"example": "uae_visa"
},
"country": {
"type": "string",
"example": "United Arab Emirates"
},
"date_of_birth": {
"visa_type": {
"type": "string",
"example": "25-JUN-1999"
},
"document_type": {
"type": "string",
"example": "uae_visa"
"example": "ENTRY PERMIT"
},
"entry_permit_no": {
"type": "string",
"example": "77003098 / 2019 / 204"
},
"expiry_date": {
"type": "string",
"example": "2024-02-15"
},
"file_number": {
"type": "string"
},
"full_name": {
"type": "string",
"example": "Mr.MUHAMMAD NADEEM RASHEED"
},
"id_number": {
"type": "string"
},
"issue_date": {
"type": "string",
"example": "2022-02-16"
},
"name": {
"type": "string"
},
"nationality": {
"valid_until": {
"type": "string",
"example": "PAKISTAN"
},
"ocr_accuracy": {
"type": "number",
"format": "float",
"example": 99
},
"passport_no": {
"type": "string",
"example": "EN9458281"
},
"passport_number": {
"type": "string"
},
"place_of_birth": {
"type": "string",
"example": "SIALKOT PAK"
},
"place_of_issue": {
"type": "string"
},
"profession": {
"type": "string",
"example": "SALES REPRESENTATIVE"
},
"sponsor": {
"type": "string"
},
"sponsor_name": {
"type": "string"
"example": "2024-02-15"
},
"uid_no": {
"type": "string",
"example": "207404887"
},
"valid_until": {
"full_name": {
"type": "string",
"example": "04-MAR-2019"
"example": "Mr.MUHAMMAD NADEEM RASHEED"
},
"visa_type": {
"nationality": {
"type": "string",
"example": "ENTRY PERMIT"
"example": "PAKISTAN"
},
"place_of_birth": {
"type": "string",
"example": "SIALKOT PAK"
},
"date_of_birth": {
"type": "string",
"example": "25-JUN-1999"
},
"passport_no": {
"type": "string",
"example": "EN9458281"
},
"profession": {
"type": "string",
"example": "SALES REPRESENTATIVE"
},
"sponsor_name": {
"type": "string",
"example": "Sponsor Name"
},
"ocr_accuracy": {
"type": "number",
"format": "float",
"example": 97.4
},
"sponsor": {
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "Sponsor Name"
},
"address": {
"type": "string",
"example": "Dubai Marina, Dubai"
},
"phone": {
"type": "string",
"example": "2977725"
}
}
}
}
}
@ -6648,10 +6641,38 @@
"type": "string",
"example": "uploads/licenses/1234567890_emirates_id.pdf"
},
"license_expiry": {
"type": "string",
"nullable": true,
"example": "2026-05-03"
},
"validity": {
"type": "string",
"example": "Valid"
},
"joined_at": {
"type": "string",
"format": "date-time"
},
"fcm_token": {
"type": "string",
"example": "fcm_token_example"
},
"license": {
"type": "object",
"properties": {
"license_number": {
"type": "string",
"example": "828302"
},
"organization_name": {
"type": "string",
"example": "MSJ INTERNATIONAL TECHNICAL SERVICES L.L.C"
},
"expiry_date": {
"type": "string",
"example": "2026-05-03"
},
"document_type": {
"type": "string",
"example": "dubai_commercial_license"
@ -6688,10 +6709,6 @@
"type": "string",
"example": "06/03/2019"
},
"expiry_date": {
"type": "string",
"example": "05/03/2026"
},
"main_license_no": {
"type": "string",
"example": "828302"
@ -6727,6 +6744,8 @@
}
}
}
}
}
},
"emirates_id": {
"type": "object",

View File

@ -676,6 +676,7 @@ export default function Show({ worker }) {
)}
</div>
<div className="p-6">
{visaDoc.ocr_data ? (() => {
const sponsorObj = visaDoc.ocr_data?.sponsor;
const isSponsorObj = sponsorObj && typeof sponsorObj === 'object' && !Array.isArray(sponsorObj);

View File

@ -531,9 +531,13 @@ public function test_register_passport_and_visa_with_direct_json_payload()
$visaDoc = \App\Models\WorkerDocument::where('worker_id', $workerId)->where('type', 'visa')->first();
$this->assertNotNull($visaDoc->ocr_data);
$this->assertEquals('784198839607839', $visaDoc->ocr_data['id_number']);
$this->assertEquals('784198839607839', $visaDoc->ocr_data['uid_no']);
$this->assertEquals('CLEANER', $visaDoc->ocr_data['profession']);
$this->assertEquals('Sponsor Name', $visaDoc->ocr_data['sponsor']);
$this->assertEquals([
'name' => 'Sponsor Name',
'address' => '',
'phone' => '',
], $visaDoc->ocr_data['sponsor']);
}
/**
@ -630,7 +634,7 @@ public function test_register_visa_with_full_ocr_fields()
$this->assertEquals('uae_visa', $visaDoc->ocr_data['document_type']);
$this->assertEquals('ENTRY PERMIT', $visaDoc->ocr_data['visa_type']);
$this->assertEquals('Mr.MUHAMMAD NADEEM RASHEED', $visaDoc->ocr_data['full_name']);
$this->assertEquals(97.4, $visaDoc->ocr_data['ocr_accuracy']);
$this->assertEquals(97.4, $visaDoc->ocr_accuracy);
}
/**