mohan #12

Merged
mohanmd merged 4 commits from mohan into master 2026-06-23 13:43:57 +00:00
6 changed files with 224 additions and 130 deletions
Showing only changes of commit 25510d1b5e - Show all commits

View File

@ -309,6 +309,8 @@ public function getDashboard(Request $request)
$savedCandidates = \App\Models\Shortlist::where('employer_id', $employer->id)->count();
$totalWorkers = \App\Models\Worker::where('status', 'active')->count();
// Resolve plan
$sub = \Illuminate\Support\Facades\DB::table('subscriptions')
->where('user_id', $employer->id)
@ -375,6 +377,7 @@ public function getDashboard(Request $request)
'contacted_workers_count' => $contactedWorkersCount,
'total_hired_workers' => $totalHiredWorkers,
'saved_candidates' => $savedCandidates,
'total_workers' => $totalWorkers,
],
'current_plan' => $currentPlan,
'recent_announcements' => $recentAnnouncements,

View File

@ -44,6 +44,7 @@ private function formatWorker(Worker $w)
return [
'id' => $w->id,
'name' => $w->name,
'email' => $w->email,
'phone' => $w->phone,
'nationality' => $w->nationality,
'age' => $w->age,
@ -57,6 +58,8 @@ private function formatWorker(Worker $w)
'language' => $w->language,
'languages' => $langs,
'preferred_location' => $w->preferred_location,
'country' => $w->country,
'city' => $w->city,
'area' => $w->area,
'live_in_out' => $w->live_in_out,
'gender' => $w->gender,
@ -71,7 +74,6 @@ private function formatWorker(Worker $w)
'visa_expiry_date' => $w->visa_expiry_date,
'bio' => $w->bio,
'photo' => $photo,
'religion' => $w->religion,
'rating' => $rating,
'reviews_count' => $reviewsCount,
'skills' => $w->skills->map(function ($s) {
@ -88,6 +90,11 @@ private function formatWorker(Worker $w)
];
})->toArray(),
'documents' => $w->documents->map(function ($doc) {
$ocrData = $doc->ocr_data;
if ($doc->type === 'visa' && is_array($ocrData)) {
unset($ocrData['sponsor']);
unset($ocrData['valid_until']);
}
return [
'id' => $doc->id,
'worker_id' => $doc->worker_id,
@ -97,7 +104,7 @@ private function formatWorker(Worker $w)
'expiry_date' => $doc->expiry_date,
'ocr_accuracy' => $doc->ocr_accuracy,
'file_path' => $doc->file_path ? url($doc->file_path) : null,
'ocr_data' => $doc->ocr_data,
'ocr_data' => $ocrData,
'created_at' => $doc->created_at?->toISOString(),
'updated_at' => $doc->updated_at?->toISOString(),
];
@ -976,25 +983,74 @@ public function getWorkerDetail(Request $request, $id)
$workerProfile = [
'id' => $w->id,
'name' => $w->name,
'email' => $w->email,
'phone' => $w->phone,
'nationality' => $w->nationality,
'photo' => $photo,
'emirates_id_status' => $emiratesIdStatus,
'skills' => $mappedSkills,
'visa_status' => $visaStatus,
'experience' => $w->experience,
'experience_years' => 5,
'religion' => $w->religion,
'languages' => $langs,
'age' => $w->age,
'gender' => $w->gender,
'salary' => $w->salary,
'experience' => $w->experience,
'verified' => (bool)$w->verified,
'status' => $w->status,
'created_at' => $w->created_at?->toISOString(),
'updated_at' => $w->updated_at?->toISOString(),
'deleted_at' => $w->deleted_at?->toISOString(),
'language' => $w->language,
'languages' => $langs,
'preferred_location' => $w->preferred_location,
'country' => $w->country,
'city' => $w->city,
'area' => $w->area,
'live_in_out' => $w->live_in_out,
'gender' => $w->gender,
'in_country' => (bool)$w->in_country,
'visa_status' => $visaStatus,
'preferred_job_type' => $preferredJobType,
'fcm_token' => $w->fcm_token,
'passport_status' => $w->passport_status,
'emirates_id_status' => $emiratesIdStatus,
'document_expiry_days' => $w->document_expiry_days,
'document_expiry_status' => $w->document_expiry_status,
'visa_expiry_date' => $w->visa_expiry_date,
'bio' => $w->bio,
'photo' => $photo,
'rating' => $rating,
'reviews_count' => $reviewsCount,
'reviews' => $reviews,
'similar_workers' => $similarWorkers,
'conversation_id' => $conversation ? $conversation->id : null,
'skills' => $w->skills->map(function ($s) {
return [
'id' => $s->id,
'name' => $s->name,
'created_at' => $s->created_at?->toISOString(),
'updated_at' => $s->updated_at?->toISOString(),
'image_path' => $s->image_path,
'pivot' => [
'worker_id' => $s->pivot->worker_id,
'skill_id' => $s->pivot->skill_id,
]
];
})->toArray(),
'documents' => $w->documents->map(function ($doc) {
$ocrData = $doc->ocr_data;
if ($doc->type === 'visa' && is_array($ocrData)) {
unset($ocrData['sponsor']);
unset($ocrData['valid_until']);
}
return [
'id' => $doc->id,
'worker_id' => $doc->worker_id,
'type' => $doc->type,
'number' => $doc->number,
'issue_date' => $doc->issue_date,
'expiry_date' => $doc->expiry_date,
'ocr_accuracy' => $doc->ocr_accuracy,
'file_path' => $doc->file_path ? url($doc->file_path) : null,
'ocr_data' => $ocrData,
'created_at' => $doc->created_at?->toISOString(),
'updated_at' => $doc->updated_at?->toISOString(),
];
})->toArray(),
];
return response()->json([

View File

@ -370,7 +370,6 @@ public function show($id)
'skills' => $mappedSkills,
'visa_status' => $visaStatus,
'experience' => $w->experience,
'experience_years' => 5,
'salary' => (int) $w->salary,
'religion' => $w->religion,
'languages' => $langs,

View File

@ -4198,105 +4198,13 @@
"type": "object",
"properties": {
"worker": {
"allOf": [
{
"$ref": "#/components/schemas/Worker"
},
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "Jane Doe"
},
"nationality": {
"type": "string",
"example": "Filipino"
},
"photo": {
"type": "string",
"example": "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=200"
},
"emirates_id_status": {
"type": "string",
"example": "Passport Verified",
"description": "Deprecated - Use passport_status instead"
},
"passport_status": {
"type": "string",
"example": "Passport Verified"
},
"category": {
"type": "string",
"example": "Domestic Worker"
},
"skills": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"childcare",
"cooking"
]
},
"availability_status": {
"type": "string",
"example": "Active"
},
"visa_status": {
"type": "string",
"example": "Residence Visa"
},
"experience": {
"type": "string",
"example": "5 Years"
},
"experience_years": {
"type": "integer",
"example": 5
},
"salary": {
"type": "integer",
"example": 2500
},
"religion": {
"type": "string",
"example": "Christian"
},
"languages": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"English",
"Tagalog"
]
},
"age": {
"type": "integer",
"example": 28
},
"verified": {
"type": "boolean",
"example": true
},
"preferred_job_type": {
"type": "string",
"example": "live-in"
},
"bio": {
"type": "string",
"example": "Experienced and caring domestic worker specialing in childcare and housekeeping..."
},
"rating": {
"type": "number",
"example": 4.3
},
"reviews_count": {
"type": "integer",
"example": 6
},
"reviews": {
"type": "array",
"items": {
@ -4316,6 +4224,8 @@
}
}
}
]
}
}
}
}
@ -5738,10 +5648,6 @@
"type": "string",
"example": "4 Years"
},
"religion": {
"type": "string",
"example": "Muslim"
},
"bio": {
"type": "string",
"example": "Certified infant caregiver and housekeeper with excellent cooking skills."

View File

@ -241,4 +241,51 @@ public function test_employer_dashboard_returns_only_two_charity_drives()
$this->assertFalse($titles->contains('Charity Drive 1'));
$this->assertFalse($titles->contains('Pending Charity Drive'));
}
public function test_employer_dashboard_returns_total_workers_active()
{
// Delete any existing workers seeded or created to make count precise
\App\Models\Worker::query()->delete();
// Create 3 active workers
\App\Models\Worker::create([
'name' => 'Active 1', 'email' => 'a1@test.com', 'phone' => '+971501110001',
'password' => bcrypt('password'), 'status' => 'active', 'nationality' => 'Indian',
'preferred_location' => 'Dubai', 'age' => 25, 'salary' => 1500, 'experience' => '3 Years',
'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker',
]);
\App\Models\Worker::create([
'name' => 'Active 2', 'email' => 'a2@test.com', 'phone' => '+971501110002',
'password' => bcrypt('password'), 'status' => 'active', 'nationality' => 'Indian',
'preferred_location' => 'Dubai', 'age' => 26, 'salary' => 1500, 'experience' => '3 Years',
'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker',
]);
\App\Models\Worker::create([
'name' => 'Active 3', 'email' => 'a3@test.com', 'phone' => '+971501110003',
'password' => bcrypt('password'), 'status' => 'active', 'nationality' => 'Indian',
'preferred_location' => 'Dubai', 'age' => 27, 'salary' => 1500, 'experience' => '3 Years',
'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker',
]);
// Create 2 inactive/hidden workers
\App\Models\Worker::create([
'name' => 'Inactive 1', 'email' => 'i1@test.com', 'phone' => '+971502220001',
'password' => bcrypt('password'), 'status' => 'hidden', 'nationality' => 'Indian',
'preferred_location' => 'Dubai', 'age' => 28, 'salary' => 1500, 'experience' => '3 Years',
'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker',
]);
\App\Models\Worker::create([
'name' => 'Inactive 2', 'email' => 'i2@test.com', 'phone' => '+971502220002',
'password' => bcrypt('password'), 'status' => 'Hired', 'nationality' => 'Indian',
'preferred_location' => 'Dubai', 'age' => 29, 'salary' => 1500, 'experience' => '3 Years',
'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker',
]);
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
])->getJson('/api/employers/dashboard');
$response->assertStatus(200);
$this->assertEquals(3, $response->json('data.stats.total_workers'));
}
}

View File

@ -532,4 +532,87 @@ public function test_worker_list_api_has_full_details_and_pagination()
$this->assertEquals('passport', $matchingWorker['documents'][0]['type']);
$this->assertEquals('visa', $matchingWorker['documents'][1]['type']);
}
public function test_worker_detail_api_has_full_details_without_religion_and_cleaned_ocr_data()
{
$worker = Worker::create([
'name' => 'Detail Worker Test',
'email' => 'detail_test@example.com',
'phone' => '+971509999777',
'password' => bcrypt('password'),
'nationality' => 'Indian',
'verified' => true,
'status' => 'active',
'preferred_location' => 'Dubai Marina',
'live_in_out' => 'live_out',
'gender' => 'male',
'in_country' => true,
'visa_status' => 'Tourist Visa',
'preferred_job_type' => 'full-time',
'fcm_token' => 'fcm_token_example',
'age' => 36,
'salary' => 1500.00,
'experience' => '4 Years',
'language' => 'English, Arabic',
'availability' => 'Immediate',
'religion' => 'Christian',
'bio' => 'Experienced helper',
]);
$doc1 = WorkerDocument::create([
'worker_id' => $worker->id,
'type' => 'passport',
'number' => 'YB98239279327',
'issue_date' => '2017-07-05',
'expiry_date' => '2022-07-05',
'ocr_accuracy' => 99,
'ocr_data' => ['authority' => 'FMP LLC'],
]);
$doc2 = WorkerDocument::create([
'worker_id' => $worker->id,
'type' => 'visa',
'number' => '343434',
'issue_date' => '2022-02-16',
'expiry_date' => '2024-02-15',
'ocr_accuracy' => 99,
'ocr_data' => [
'sponsor' => 'some sponsor',
'sponsor_name' => 'some sponsor name',
'valid_until' => '2024-02-15',
'expiry_date' => '2024-02-15'
],
]);
$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $this->token,
])->getJson('/api/employers/workers/' . $worker->id);
$response->assertStatus(200);
$wData = $response->json('data.worker');
$this->assertNotNull($wData);
$this->assertEquals('+971509999777', $wData['phone']);
$this->assertEquals('detail_test@example.com', $wData['email']);
$this->assertEquals('1500.00', $wData['salary']);
$this->assertEquals('active', $wData['status']);
$this->assertEquals('English, Arabic', $wData['language']);
$this->assertEquals('fcm_token_example', $wData['fcm_token']);
$this->assertEquals('2024-02-15', $wData['visa_expiry_date']);
// Assert religion is removed
$this->assertArrayNotHasKey('religion', $wData);
// Check documents object array
$this->assertIsArray($wData['documents']);
$this->assertCount(2, $wData['documents']);
// Assert visa ocr_data is cleaned up
$visaDoc = collect($wData['documents'])->firstWhere('type', 'visa');
$this->assertNotNull($visaDoc);
$this->assertArrayNotHasKey('sponsor', $visaDoc['ocr_data']);
$this->assertArrayNotHasKey('valid_until', $visaDoc['ocr_data']);
$this->assertEquals('some sponsor name', $visaDoc['ocr_data']['sponsor_name']);
$this->assertEquals('2024-02-15', $visaDoc['ocr_data']['expiry_date']);
}
}