From 3db4ced0685e04f874ff325849c84ffa718c845e Mon Sep 17 00:00:00 2001 From: mohanmd Date: Wed, 24 Jun 2026 15:37:46 +0530 Subject: [PATCH] api changes --- .../Controllers/Api/WorkerAuthController.php | 65 +++++++++++++++- .../Api/WorkerProfileController.php | 72 ++++++++++++++++-- public/swagger.json | 74 ++++++++++++++++++- resources/js/Pages/Employer/Workers/Show.jsx | 64 ++++++++-------- 4 files changed, 230 insertions(+), 45 deletions(-) diff --git a/app/Http/Controllers/Api/WorkerAuthController.php b/app/Http/Controllers/Api/WorkerAuthController.php index 5b6aa49..17e79f1 100644 --- a/app/Http/Controllers/Api/WorkerAuthController.php +++ b/app/Http/Controllers/Api/WorkerAuthController.php @@ -497,9 +497,10 @@ public function register(Request $request) // Create visa document if provided if ($visaDataInput) { - $visaNum = $visaDataInput['entry_permit_no'] ?? $visaDataInput['file_number'] ?? $visaDataInput['id_number'] ?? ('V' . rand(1000000, 9999999)); - $expiryDate = $visaDataInput['valid_until'] ?? $visaDataInput['expiry_date'] ?? null; - $issueDate = $visaDataInput['issue_date'] ?? null; + $cleanedVisaOcr = $this->cleanVisaData($visaDataInput); + $visaNum = $cleanedVisaOcr['entry_permit_no'] ?: ('V' . rand(1000000, 9999999)); + $expiryDate = $cleanedVisaOcr['valid_until'] ?? null; + $issueDate = $cleanedVisaOcr['issue_date'] ?? null; $expiryDateFormatted = $expiryDate ? $this->normaliseDateForController($expiryDate) : now()->addYears(2)->toDateString(); $issueDateFormatted = $issueDate ? $this->normaliseDateForController($issueDate) : now()->subYears(2)->toDateString(); @@ -511,7 +512,7 @@ public function register(Request $request) 'expiry_date' => $expiryDateFormatted, 'ocr_accuracy' => isset($visaDataInput['ocr_accuracy']) ? (float)$visaDataInput['ocr_accuracy'] : 99.0, 'file_path' => null, - 'ocr_data' => $visaDataInput, + 'ocr_data' => $cleanedVisaOcr, ]); } @@ -1236,6 +1237,62 @@ private function normaliseDateForController(?string $raw): ?string } } + /** + * Standardize and clean Visa OCR data structure to exactly the 15 required fields. + */ + 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'] ?? 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; + + // 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 ?: '', + 'sponsor' => [ + 'name' => $sponsorNameFromObj ?: '', + 'address' => $sponsorAddress ?: '', + 'phone' => $sponsorPhone ?: '', + ] + ]; + } + // ------------------------------------------------------------------------- // Forgot / Reset Password (via Mobile Number) // ------------------------------------------------------------------------- diff --git a/app/Http/Controllers/Api/WorkerProfileController.php b/app/Http/Controllers/Api/WorkerProfileController.php index bb006b4..9161643 100644 --- a/app/Http/Controllers/Api/WorkerProfileController.php +++ b/app/Http/Controllers/Api/WorkerProfileController.php @@ -201,14 +201,15 @@ public function updateProfile(Request $request) $visaDataInput = $request->input('visa'); if ($visaDataInput) { $existingVisa = $worker->documents()->where('type', 'visa')->first(); - $expiryDate = $visaDataInput['expiry_date'] ?? null; - $issueDate = $visaDataInput['issue_date'] ?? null; + $cleanedVisaOcr = $this->cleanVisaData($visaDataInput); + $expiryDate = $cleanedVisaOcr['valid_until'] ?? null; + $issueDate = $cleanedVisaOcr['issue_date'] ?? null; $expiryDateFormatted = $expiryDate ? $this->normaliseDateForController($expiryDate) : null; $issueDateFormatted = $issueDate ? $this->normaliseDateForController($issueDate) : null; if ($existingVisa) { $updateFields = [ - 'ocr_data' => $visaDataInput, + 'ocr_data' => $cleanedVisaOcr, ]; if ($expiryDateFormatted) { $updateFields['expiry_date'] = $expiryDateFormatted; @@ -216,9 +217,12 @@ public function updateProfile(Request $request) if ($issueDateFormatted) { $updateFields['issue_date'] = $issueDateFormatted; } + if (!empty($cleanedVisaOcr['entry_permit_no'])) { + $updateFields['number'] = $cleanedVisaOcr['entry_permit_no']; + } $existingVisa->update($updateFields); } else { - $visaNum = $visaDataInput['file_number'] ?? $visaDataInput['id_number'] ?? ('V' . rand(1000000, 9999999)); + $visaNum = $cleanedVisaOcr['entry_permit_no'] ?: ('V' . rand(1000000, 9999999)); $expiryDateFormatted = $expiryDateFormatted ?: now()->addYears(2)->toDateString(); $issueDateFormatted = $issueDateFormatted ?: now()->subYears(2)->toDateString(); @@ -227,9 +231,9 @@ public function updateProfile(Request $request) 'number' => $visaNum, 'issue_date' => $issueDateFormatted, 'expiry_date' => $expiryDateFormatted, - 'ocr_accuracy' => 99.0, + 'ocr_accuracy' => isset($visaDataInput['ocr_accuracy']) ? (float)$visaDataInput['ocr_accuracy'] : 99.0, 'file_path' => null, - 'ocr_data' => $visaDataInput, + 'ocr_data' => $cleanedVisaOcr, ]); } } @@ -754,4 +758,60 @@ private function normaliseDateForController(?string $raw): ?string return $raw; } } + + /** + * Standardize and clean Visa OCR data structure to exactly the 15 required fields. + */ + 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'] ?? 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; + + // 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 ?: '', + 'sponsor' => [ + 'name' => $sponsorNameFromObj ?: '', + 'address' => $sponsorAddress ?: '', + 'phone' => $sponsorPhone ?: '', + ] + ]; + } } diff --git a/public/swagger.json b/public/swagger.json index 08a0094..172e042 100644 --- a/public/swagger.json +++ b/public/swagger.json @@ -2564,14 +2564,80 @@ }, "visa": { "type": "object", + "description": "Standardized UAE Visa metadata.", "properties": { - "file_number": { + "document_type": { "type": "string", - "example": "202/2022/2840234" + "example": "uae_visa" }, - "expiry_date": { + "country": { "type": "string", - "example": "2028-12-31" + "example": "United Arab Emirates" + }, + "visa_type": { + "type": "string", + "example": "ENTRY PERMIT" + }, + "entry_permit_no": { + "type": "string", + "example": "87654091 / 2016 / 210" + }, + "issue_date": { + "type": "string", + "example": "2016-11-18" + }, + "valid_until": { + "type": "string", + "example": "2017-01-18" + }, + "uid_no": { + "type": "string", + "example": "181825009" + }, + "full_name": { + "type": "string", + "example": "GILBERT DSOUZA W/O TIMOTHY" + }, + "nationality": { + "type": "string", + "example": "INDIAN" + }, + "place_of_birth": { + "type": "string", + "example": "MANGALORE" + }, + "date_of_birth": { + "type": "string", + "example": "1980-02-02" + }, + "passport_no": { + "type": "string", + "example": "U4690639" + }, + "profession": { + "type": "string", + "example": "BUSINESS PERSON" + }, + "sponsor_name": { + "type": "string", + "example": "Sponsor LLC" + }, + "sponsor": { + "type": "object", + "properties": { + "name": { + "type": "string", + "example": "Sponsor LLC" + }, + "address": { + "type": "string", + "example": "Dubai Marina, Dubai" + }, + "phone": { + "type": "string", + "example": "2977725" + } + } } } } diff --git a/resources/js/Pages/Employer/Workers/Show.jsx b/resources/js/Pages/Employer/Workers/Show.jsx index 69b3476..bd5ff46 100644 --- a/resources/js/Pages/Employer/Workers/Show.jsx +++ b/resources/js/Pages/Employer/Workers/Show.jsx @@ -676,51 +676,57 @@ export default function Show({ worker }) { )} -
- {visaDoc.ocr_data ? (() => { + {visaDoc.ocr_data ? (() => { const sponsorObj = visaDoc.ocr_data?.sponsor; const isSponsorObj = sponsorObj && typeof sponsorObj === 'object' && !Array.isArray(sponsorObj); const sponsorName = isSponsorObj - ? (sponsorObj.name || sponsorObj.sponsor_name || sponsorObj.full_name) - : (visaDoc.ocr_data?.sponsor_name || (typeof sponsorObj === 'string' ? sponsorObj : null)); - const sponsorMobile = isSponsorObj - ? (sponsorObj.mobile || sponsorObj.mobile_number || sponsorObj.phone) - : null; + ? (sponsorObj.name || sponsorObj.sponsor_name) + : (visaDoc.ocr_data?.sponsor_name || (typeof sponsorObj === 'string' ? sponsorObj : '')); + const sponsorPhone = isSponsorObj + ? (sponsorObj.phone || sponsorObj.mobile || sponsorObj.mobile_number) + : ''; + const sponsorAddress = isSponsorObj + ? (sponsorObj.address || '') + : ''; return (
+
+
{t('full_name', 'Full Name')}
+
{safeRender(visaDoc.ocr_data.full_name || worker.name)}
+
{t('entry_permit_no', 'Entry Permit No')}
-
{safeRender(visaDoc.ocr_data.entry_permit_no)}
+
{safeRender(visaDoc.ocr_data.entry_permit_no || visaDoc.number)}
{t('uid_no', 'UID No')}
{safeRender(visaDoc.ocr_data.uid_no)}
-
-
{t('id_number', 'ID Number')}
-
{safeRender(visaDoc.ocr_data.id_number || visaDoc.ocr_data.emirates_id_number)}
-
{t('visa_type', 'Visa Type')}
{safeRender(visaDoc.ocr_data.visa_type || 'ENTRY PERMIT')}
+
+
{t('passport_no', 'Passport No')}
+
{safeRender(visaDoc.ocr_data.passport_no || visaDoc.ocr_data.passport_number)}
+
{t('profession', 'Profession')}
{safeRender(visaDoc.ocr_data.profession || worker.visa_status)}
- {sponsorName && ( -
-
{t('sponsor_name', 'Sponsor Name')}
-
{safeRender(sponsorName)}
-
- )} - {sponsorMobile && ( -
-
{t('sponsor_mobile', 'Sponsor Mobile')}
-
{safeRender(sponsorMobile)}
-
- )} +
+
{t('sponsor_name', 'Sponsor Name')}
+
{safeRender(sponsorName || visaDoc.ocr_data.sponsor_name)}
+
+
+
{t('sponsor_phone', 'Sponsor Phone')}
+
{safeRender(sponsorPhone)}
+
+
+
{t('sponsor_address', 'Sponsor Address')}
+
{safeRender(sponsorAddress)}
+
{t('nationality', 'Nationality')}
{safeRender(visaDoc.ocr_data.nationality || worker.nationality)}
@@ -737,17 +743,13 @@ export default function Show({ worker }) {
{t('place_of_birth', 'Place of Birth')}
{safeRender(visaDoc.ocr_data.place_of_birth)}
-
-
{t('place_of_issue', 'Place of Issue')}
-
{safeRender(visaDoc.ocr_data.place_of_issue)}
-
{t('issue_date', 'Issue Date')}
{safeRender(visaDoc.ocr_data.issue_date || visaDoc.issue_date)}
-
{t('expiry_date', 'Expiry Date')}
-
{safeRender(visaDoc.ocr_data.expiry_date || visaDoc.expiry_date)}
+
{t('valid_until', 'Valid Until')}
+
{safeRender(visaDoc.ocr_data.valid_until || visaDoc.ocr_data.expiry_date || visaDoc.expiry_date)}
{t('document_type', 'Document Type')}
@@ -758,7 +760,7 @@ export default function Show({ worker }) {
{(visaDoc.ocr_accuracy || visaDoc.ocr_data?.ocr_accuracy || 99)}%
- ); + ); })() : (
-- 2.43.0