From 831e5ca5996e0a1d0f7d4f260fccd2fd1b32ea28 Mon Sep 17 00:00:00 2001 From: mohanmd Date: Sun, 14 Jun 2026 00:05:05 +0530 Subject: [PATCH] worker profile --- .../Api/EmployerWorkerController.php | 41 +++++++++++++ .../Controllers/Api/SponsorAuthController.php | 16 ++--- public/swagger.json | 60 ++++++++++++++++--- tests/Feature/EmployerWorkerFilterApiTest.php | 51 ++++++++++++++++ tests/Feature/SponsorAuthApiTest.php | 3 + 5 files changed, 155 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/Api/EmployerWorkerController.php b/app/Http/Controllers/Api/EmployerWorkerController.php index c8a8620..1f65a44 100644 --- a/app/Http/Controllers/Api/EmployerWorkerController.php +++ b/app/Http/Controllers/Api/EmployerWorkerController.php @@ -76,6 +76,7 @@ private function formatWorker(Worker $w) 'rating' => $rating, 'reviews_count' => $reviewsCount, 'preferred_location' => $w->preferred_location, + 'area' => $w->area, 'live_in_out' => $w->live_in_out, 'in_country' => (bool)$w->in_country, ]; @@ -199,6 +200,25 @@ public function getWorkers(Request $request) })); } + // Filter: area + if ($request->filled('area')) { + $areaParam = $request->area; + $areasArray = is_array($areaParam) ? $areaParam : array_filter(array_map('trim', explode(',', $areaParam))); + $areasArray = array_map('strtolower', $areasArray); + + $workersArray = array_values(array_filter($workersArray, function ($c) use ($areasArray) { + if (!isset($c['area'])) return false; + $wArea = strtolower($c['area']); + foreach ($areasArray as $a) { + if ($a === 'all') return true; + if (str_contains($wArea, $a)) { + return true; + } + } + return false; + })); + } + // Filter: job_type / preferred_job_type $jobTypeParam = $request->input('job_type') ?? $request->input('preferred_job_type'); if ($jobTypeParam) { @@ -388,6 +408,7 @@ public function getCandidates(Request $request) 'languages' => $langs, 'availability' => $w->availability ?? 'Immediate', 'preferred_location' => $w->preferred_location, + 'area' => $w->area, 'preferred_job_type' => $preferredJobType, 'live_in_out' => $w->live_in_out, 'in_country' => (bool)$w->in_country, @@ -429,6 +450,7 @@ public function getCandidates(Request $request) 'languages' => $langs, 'availability' => $w->availability ?? 'Immediate', 'preferred_location' => $w->preferred_location, + 'area' => $w->area, 'preferred_job_type' => $preferredJobType, 'live_in_out' => $w->live_in_out, 'in_country' => (bool)$w->in_country, @@ -527,6 +549,25 @@ public function getCandidates(Request $request) })); } + // Filter: area + if ($request->filled('area')) { + $areaParam = $request->area; + $areasArray = is_array($areaParam) ? $areaParam : array_filter(array_map('trim', explode(',', $areaParam))); + $areasArray = array_map('strtolower', $areasArray); + + $mergedCandidates = array_values(array_filter($mergedCandidates, function ($c) use ($areasArray) { + if (!isset($c['area'])) return false; + $wArea = strtolower($c['area']); + foreach ($areasArray as $a) { + if ($a === 'all') return true; + if (str_contains($wArea, $a)) { + return true; + } + } + return false; + })); + } + // Filter: job_type / preferred_job_type $jobTypeParam = $request->input('job_type') ?? $request->input('preferred_job_type'); if ($jobTypeParam) { diff --git a/app/Http/Controllers/Api/SponsorAuthController.php b/app/Http/Controllers/Api/SponsorAuthController.php index 2eecf04..5660945 100644 --- a/app/Http/Controllers/Api/SponsorAuthController.php +++ b/app/Http/Controllers/Api/SponsorAuthController.php @@ -27,14 +27,14 @@ public function register(Request $request) 'mobile' => 'required|string|max:50|unique:sponsors,mobile', 'password' => 'required|string|min:6', 'license_file' => 'required|file|mimes:jpeg,png,jpg,pdf|max:10240', - 'emirates_id_file' => 'nullable|file|mimes:jpeg,png,jpg,pdf|max:10240', - 'organization_name' => 'nullable|string|max:255', - 'email' => 'nullable|email|max:255|unique:sponsors,email', - 'nationality' => 'nullable|string|max:100', - 'city' => 'nullable|string|max:100', - 'address' => 'nullable|string|max:255', - 'country_code' => 'nullable|string|max:10', - 'license_expiry' => 'nullable|date_format:Y-m-d', + 'emirates_id_file' => 'required|file|mimes:jpeg,png,jpg,pdf|max:10240', + 'organization_name' => 'required|string|max:255', + 'email' => 'required|email|max:255|unique:sponsors,email', + 'nationality' => 'required|string|max:100', + 'city' => 'required|string|max:100', + 'address' => 'required|string|max:255', + 'country_code' => 'required|string|max:10', + 'license_expiry' => 'required|date_format:Y-m-d', ], [ 'mobile.unique' => 'This mobile number is already registered.', 'email.unique' => 'This email address is already registered.', diff --git a/public/swagger.json b/public/swagger.json index cd099a8..eaeb131 100644 --- a/public/swagger.json +++ b/public/swagger.json @@ -29,7 +29,20 @@ "multipart/form-data": { "schema": { "type": "object", - "required": ["full_name", "mobile", "password", "license_file"], + "required": [ + "full_name", + "mobile", + "password", + "license_file", + "emirates_id_file", + "organization_name", + "email", + "nationality", + "city", + "address", + "country_code", + "license_expiry" + ], "properties": { "full_name": { "type": "string", @@ -55,38 +68,44 @@ "emirates_id_file": { "type": "string", "format": "binary", - "description": "Emirates ID document file (jpg/png/pdf, max 10MB). (OPTIONAL)" + "description": "Emirates ID document file (jpg/png/pdf, max 10MB). (REQUIRED)" }, "organization_name": { "type": "string", "example": "Al-Rashidi Charitable Foundation", - "description": "Name of the sponsoring organization." + "description": "Name of the sponsoring organization. (REQUIRED)" }, "email": { "type": "string", "format": "email", "example": "info@alrashidi.ae", - "description": "Email address (optional — auto-generated if not provided)." + "description": "Email address (must be unique). (REQUIRED)" }, "nationality": { "type": "string", "example": "UAE", - "description": "Nationality of the sponsor." + "description": "Nationality of the sponsor. (REQUIRED)" }, "city": { "type": "string", "example": "Dubai", - "description": "City of residence." + "description": "City of residence. (REQUIRED)" }, "address": { "type": "string", "example": "Villa 12, Jumeirah 2", - "description": "Physical address." + "description": "Physical address. (REQUIRED)" }, "country_code": { "type": "string", "example": "+971", - "description": "Country dial code." + "description": "Country dial code. (REQUIRED)" + }, + "license_expiry": { + "type": "string", + "format": "date", + "example": "2028-06-12", + "description": "Expiry date of the license (YYYY-MM-DD). (REQUIRED)" } } } @@ -3316,6 +3335,15 @@ "type": "string" } }, + { + "name": "area", + "in": "query", + "required": false, + "description": "Filter by preferred area (comma-separated list, e.g. Marina,Al Barsha).", + "schema": { + "type": "string" + } + }, { "name": "job_type", "in": "query", @@ -4520,6 +4548,14 @@ "type": "string", "example": "+971509998888" }, + "language": { + "type": "string", + "example": "HI" + }, + "fcm_token": { + "type": "string", + "example": "fcm_token_example" + }, "nationality": { "type": "string", "example": "Egypt" @@ -4568,6 +4604,14 @@ "type": "string", "example": "Tourist Visa" }, + "passport_status": { + "type": "string", + "example": "Passport Verified" + }, + "emirates_id_status": { + "type": "string", + "example": "Passport Verified" + }, "preferred_job_type": { "type": "string", "example": "full-time" diff --git a/tests/Feature/EmployerWorkerFilterApiTest.php b/tests/Feature/EmployerWorkerFilterApiTest.php index 150a3d4..71391be 100644 --- a/tests/Feature/EmployerWorkerFilterApiTest.php +++ b/tests/Feature/EmployerWorkerFilterApiTest.php @@ -51,6 +51,7 @@ protected function setUp(): void 'verified' => true, 'status' => 'active', 'preferred_location' => 'Dubai', + 'area' => 'Al Barsha', 'preferred_job_type' => 'full-time', 'live_in_out' => 'live_in', 'in_country' => true, @@ -82,6 +83,7 @@ protected function setUp(): void 'verified' => true, 'status' => 'active', 'preferred_location' => 'Abu Dhabi', + 'area' => 'Khalifa City', 'preferred_job_type' => 'part-time', 'live_in_out' => 'live_out', 'in_country' => true, @@ -113,6 +115,7 @@ protected function setUp(): void 'verified' => true, 'status' => 'active', 'preferred_location' => 'Dubai', + 'area' => 'Marina', 'preferred_job_type' => 'full-time', 'live_in_out' => 'live_out', 'in_country' => false, @@ -348,4 +351,52 @@ public function test_get_workers_gender_filter() $workers2 = $response2->json('data.workers'); $this->assertCount(2, $workers2); } + + public function test_get_workers_area_filter() + { + $response = $this->withHeaders([ + 'Authorization' => 'Bearer ' . $this->token, + ])->getJson('/api/employers/workers?area=Marina'); + + $response->assertStatus(200); + $workers = $response->json('data.workers'); + $this->assertCount(1, $workers); + $this->assertEquals('Worker Kenya Out Country', $workers[0]['name']); + $this->assertEquals('Marina', $workers[0]['area']); + } + + public function test_get_candidates_area_filter() + { + $worker1 = Worker::where('nationality', 'India')->first(); + $worker2 = Worker::where('nationality', 'Philippines')->first(); + + JobOffer::create([ + 'employer_id' => $this->employer->id, + 'worker_id' => $worker1->id, + 'work_date' => now()->format('Y-m-d'), + 'location' => 'Dubai', + 'salary' => 1500, + 'notes' => 'Hired test', + 'status' => 'accepted', + ]); + + JobOffer::create([ + 'employer_id' => $this->employer->id, + 'worker_id' => $worker2->id, + 'work_date' => now()->format('Y-m-d'), + 'location' => 'Abu Dhabi', + 'salary' => 1500, + 'notes' => 'Hired test 2', + 'status' => 'accepted', + ]); + + $response = $this->withHeaders([ + 'Authorization' => 'Bearer ' . $this->token, + ])->getJson('/api/employers/candidates?area=Al Barsha'); + + $response->assertStatus(200); + $candidates = $response->json('data.candidates'); + $this->assertCount(1, $candidates); + $this->assertEquals('Worker India In Dubai', $candidates[0]['name']); + } } diff --git a/tests/Feature/SponsorAuthApiTest.php b/tests/Feature/SponsorAuthApiTest.php index cd70b87..30f791c 100644 --- a/tests/Feature/SponsorAuthApiTest.php +++ b/tests/Feature/SponsorAuthApiTest.php @@ -29,8 +29,11 @@ public function test_sponsor_can_register_with_license() 'license_file' => $licenseFile, 'emirates_id_file' => $emiratesIdFile, 'organization_name' => 'Charity Co', + 'email' => 'test.sponsor@example.com', 'nationality' => 'Emirati', 'city' => 'Abu Dhabi', + 'address' => 'Villa 45, Street 12', + 'country_code' => '+971', 'license_expiry' => '2028-06-12', ]);