employer page issue count #9

Merged
mohanmd merged 1 commits from mohan into master 2026-06-15 12:28:48 +00:00
5 changed files with 102 additions and 8 deletions

View File

@ -67,6 +67,7 @@ public function index(Request $request)
return Inertia::render('Admin/Employers/Index', [ return Inertia::render('Admin/Employers/Index', [
'employers' => $employers, 'employers' => $employers,
'sponsors' => $employers,
'filters' => $request->only(['search', 'status', 'location', 'sort_field', 'sort_order']) 'filters' => $request->only(['search', 'status', 'location', 'sort_field', 'sort_order'])
]); ]);
} }

View File

@ -298,7 +298,7 @@ public function setupProfile(Request $request)
public function register(Request $request) public function register(Request $request)
{ {
$validator = Validator::make($request->all(), [ $validator = Validator::make($request->all(), [
'name' => 'required|string|max:255', 'name' => 'nullable|string|max:255',
'phone' => 'required|string|max:50|unique:workers,phone', 'phone' => 'required|string|max:50|unique:workers,phone',
'salary' => 'required|numeric|min:0', 'salary' => 'required|numeric|min:0',
'password' => 'required|string|min:6', 'password' => 'required|string|min:6',
@ -352,6 +352,10 @@ public function register(Request $request)
'issue_date' => now()->subYears(2)->toDateString(), 'issue_date' => now()->subYears(2)->toDateString(),
]; ];
$extractedAge = null;
$extractedName = null;
$extractedNationality = null;
if ($request->hasFile('passport_file')) { if ($request->hasFile('passport_file')) {
$file = $request->file('passport_file'); $file = $request->file('passport_file');
$ocrRes = \App\Services\OcrDocumentService::extractData($file); $ocrRes = \App\Services\OcrDocumentService::extractData($file);
@ -364,7 +368,49 @@ public function register(Request $request)
if (!empty($ocrRes['expiry_date'])) { if (!empty($ocrRes['expiry_date'])) {
$passportData['issue_date'] = date('Y-m-d', strtotime($ocrRes['expiry_date'] . ' - 5 years')); $passportData['issue_date'] = date('Y-m-d', strtotime($ocrRes['expiry_date'] . ' - 5 years'));
} }
if (!empty($ocrRes['date_of_birth'])) {
try {
$dob = new \DateTime($ocrRes['date_of_birth']);
$now = new \DateTime();
$extractedAge = $now->diff($dob)->y;
} catch (\Exception $dateEx) {
logger()->error('Error calculating age from OCR DOB: ' . $dateEx->getMessage());
} }
}
if (!empty($ocrRes['name'])) {
$extractedName = $ocrRes['name'];
}
if (!empty($ocrRes['nationality'])) {
$iso3ToDemonym = [
'ARE' => 'Emirati',
'IND' => 'Indian',
'PAK' => 'Pakistani',
'PHL' => 'Filipino',
'IDN' => 'Indonesian',
'GHA' => 'Ghanaian',
'LKA' => 'Sri Lankan',
'NPL' => 'Nepalese',
'KEN' => 'Kenyan',
'UGA' => 'Ugandan',
'ETH' => 'Ethiopian',
'BGD' => 'Bangladeshi',
];
$codeUpper = strtoupper($ocrRes['nationality']);
$extractedNationality = $iso3ToDemonym[$codeUpper] ?? $ocrRes['nationality'];
}
}
$workerName = $request->name ?? $extractedName;
if (empty($workerName)) {
return response()->json([
'success' => false,
'message' => 'Validation error.',
'errors' => ['name' => ['The name field is required or could not be extracted from the passport.']]
], 422);
}
$workerNationality = $request->nationality ?? $extractedNationality ?? 'Not Specified';
$workerAge = $request->age ?? $extractedAge ?? 25;
$visaData = [ $visaData = [
'number' => 'V' . rand(100000, 999999), 'number' => 'V' . rand(100000, 999999),
@ -394,18 +440,18 @@ public function register(Request $request)
$inCountry = filter_var($request->input('in_country', true), FILTER_VALIDATE_BOOLEAN); $inCountry = filter_var($request->input('in_country', true), FILTER_VALIDATE_BOOLEAN);
$apiToken = Str::random(80); $apiToken = Str::random(80);
$result = DB::transaction(function () use ($request, $email, $skillsArray, $passportPath, $visaPath, $apiToken, $inCountry, $passportData, $visaData) { $result = DB::transaction(function () use ($request, $email, $skillsArray, $passportPath, $visaPath, $apiToken, $inCountry, $passportData, $visaData, $workerName, $workerNationality, $workerAge) {
$worker = Worker::create([ $worker = Worker::create([
'name' => $request->name, 'name' => $workerName,
'email' => $email, 'email' => $email,
'phone' => $request->phone, 'phone' => $request->phone,
'language' => $request->language ?? 'HI', 'language' => $request->language ?? 'HI',
'password' => Hash::make($request->password), 'password' => Hash::make($request->password),
'nationality' => $request->nationality ?? 'Not Specified', 'nationality' => $workerNationality,
'gender' => $request->gender, 'gender' => $request->gender,
'live_in_out' => $request->live_in_out, 'live_in_out' => $request->live_in_out,
'preferred_location' => $request->preferred_location, 'preferred_location' => $request->preferred_location,
'age' => $request->age ?? 25, 'age' => $workerAge,
'salary' => $request->salary, 'salary' => $request->salary,
'availability' => 'Immediate', 'availability' => 'Immediate',
'experience' => $request->experience ?? 'Not Specified', 'experience' => $request->experience ?? 'Not Specified',

View File

@ -29,15 +29,19 @@ public static function extractData(UploadedFile $file): array
try { try {
// Send file directly from temp upload directory to the OCR API // Send file directly from temp upload directory to the OCR API
$apiUrl = config('services.ocr.api_url', 'http://192.168.0.220:5000/passport'); $apiUrl = config('services.ocr.api_url', 'http://192.168.0.220:5000/passport');
$contents = $file->getContent();
if ($contents === '' || $contents === false || empty($contents)) {
$contents = ' ';
}
$response = Http::attach( $response = Http::attach(
'file', 'file',
file_get_contents($file->getRealPath()), $contents,
$file->getClientOriginalName() $file->getClientOriginalName()
)->post($apiUrl); )->post($apiUrl);
if ($response->successful()) { if ($response->successful()) {
$json = $response->json(); $json = $response->json();
if (!empty($json['success'])) { if (!empty($json['success']) || isset($json['data'])) {
$extracted['success'] = true; $extracted['success'] = true;
$data = $json['data'] ?? []; $data = $json['data'] ?? [];

View File

@ -50,7 +50,8 @@ import {
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
export default function EmployersIndex({ employers, filters = {} }) { export default function EmployersIndex({ employers: initialEmployers, sponsors, filters = {} }) {
const employers = initialEmployers || sponsors || { data: [], total: 0 };
const [searchTerm, setSearchTerm] = useState(filters.search || ''); const [searchTerm, setSearchTerm] = useState(filters.search || '');
const [statusFilter, setStatusFilter] = useState(filters.status || 'All'); const [statusFilter, setStatusFilter] = useState(filters.status || 'All');
const [locationFilter, setLocationFilter] = useState(filters.location || 'All'); const [locationFilter, setLocationFilter] = useState(filters.location || 'All');

View File

@ -406,6 +406,48 @@ public function test_register_with_new_api_fields()
]); ]);
} }
/**
* Test worker registration utilizing OCR extracted fields.
*/
public function test_register_with_ocr_extraction()
{
$apiUrl = config('services.ocr.api_url', 'http://192.168.0.220:5000/passport');
\Illuminate\Support\Facades\Http::fake([
'*' => \Illuminate\Support\Facades\Http::response([
'success' => true,
'data' => [
'date_of_birth' => '1990-11-07',
'date_of_expiry' => '2030-09-06',
'given_names' => 'MATAR ALI KHARBASH',
'surname' => 'ALSAEDI',
'nationality' => 'ARE',
'passport_number' => 'SQ0000151',
]
], 200)
]);
$fakePassport = UploadedFile::fake()->create('passport.pdf', 500, 'application/pdf');
$response = $this->postJson('/api/workers/register', [
'phone' => '+971509999999',
'salary' => 2500,
'password' => 'secret123',
'passport_file' => $fakePassport,
'language' => 'HI',
]);
$response->assertStatus(201);
$expectedAge = now()->diff(new \DateTime('1990-11-07'))->y;
$this->assertDatabaseHas('workers', [
'name' => 'MATAR ALI KHARBASH ALSAEDI',
'phone' => '+971509999999',
'nationality' => 'Emirati',
'age' => $expectedAge,
]);
}
/** /**
* Test updating profile with new API fields. * Test updating profile with new API fields.
*/ */