From 2483e2c933583ed490d6b8f42d79d6adf2e369e0 Mon Sep 17 00:00:00 2001 From: mohanmd Date: Thu, 9 Jul 2026 15:53:38 +0530 Subject: [PATCH] hire flow issue --- .../Employer/CandidateController.php | 5 +- database/seeders/DatabaseSeeder.php | 4 - database/seeders/EmployerProfileSeeder.php | 39 --- database/seeders/WorkerSeeder.php | 253 ------------------ resources/js/Pages/Employer/Workers/Show.jsx | 12 + tests/Feature/WorkerJobApiTest.php | 56 ++++ 6 files changed, 72 insertions(+), 297 deletions(-) delete mode 100644 database/seeders/EmployerProfileSeeder.php delete mode 100644 database/seeders/WorkerSeeder.php diff --git a/app/Http/Controllers/Employer/CandidateController.php b/app/Http/Controllers/Employer/CandidateController.php index a71efef..4af9ac6 100644 --- a/app/Http/Controllers/Employer/CandidateController.php +++ b/app/Http/Controllers/Employer/CandidateController.php @@ -362,7 +362,10 @@ public function updateStatus(Request $request, $id) return redirect()->route('employer.login'); } - if (!$this->checkJobAccess($user)) { + $statusLower = strtolower($request->status); + $isDirectHiringAction = in_array($statusLower, ['hired', 'hire_requested']); + + if (!$isDirectHiringAction && !$this->checkJobAccess($user)) { return redirect()->route('employer.subscription') ->with('error', 'Your current plan does not support the Job Apply module. Please upgrade to a Premium plan to access this feature.'); } diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index d9591e6..a99a731 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -32,10 +32,6 @@ public function run(): void SkillSeeder::class, AdminSeeder::class, NationalitySeeder::class, - WorkerSeeder::class, - EmployerProfileSeeder::class, - JobPostSeeder::class, - ConversationSeeder::class, ]); } } diff --git a/database/seeders/EmployerProfileSeeder.php b/database/seeders/EmployerProfileSeeder.php deleted file mode 100644 index f638b78..0000000 --- a/database/seeders/EmployerProfileSeeder.php +++ /dev/null @@ -1,39 +0,0 @@ -insertGetId([ - 'name' => 'Employer One', - 'email' => 'employer1@example.com', - 'password' => \Illuminate\Support\Facades\Hash::make('password'), - 'role' => 'employer', - 'created_at' => now(), - 'updated_at' => now(), - ]); - - // Create Employer Profile - \Illuminate\Support\Facades\DB::table('employer_profiles')->insert([ - 'user_id' => $userId, - 'company_name' => 'Al Mansoor Household', - 'phone' => '+971 50 123 4567', - 'verification_status' => 'approved', - 'emirates_id_front' => '[DELETED_FOR_PDPL_COMPLIANCE]', - 'emirates_id_back' => '[DELETED_FOR_PDPL_COMPLIANCE]', - 'emirates_id_number' => '784-1990-1234567-8', - 'emirates_id_expiry' => '2028-12-31', - 'created_at' => now(), - 'updated_at' => now(), - ]); - } -} diff --git a/database/seeders/WorkerSeeder.php b/database/seeders/WorkerSeeder.php deleted file mode 100644 index e3cf464..0000000 --- a/database/seeders/WorkerSeeder.php +++ /dev/null @@ -1,253 +0,0 @@ - 'John Doe', - 'email' => 'john.doe@example.com', - 'phone' => '+971 50 111 2222', - 'nationality' => 'Indian', - 'country' => 'United Arab Emirates', - 'city' => 'Dubai', - 'area' => 'Dubai Marina', - 'preferred_location' => 'Dubai Marina', - 'live_in_out' => 'Live-in (Stay with family)', - 'language' => 'English', - 'age' => 30, - 'gender' => 'Male', - 'salary' => 2500.00, - 'availability' => 'Immediate', - 'experience' => '5+ Years', - 'religion' => 'Christian', - 'bio' => '', - 'verified' => true, - 'status' => 'active', - ], - [ - 'name' => 'Ali Hassan', - 'email' => 'ali.hassan@example.com', - 'phone' => '+971 50 333 4444', - 'nationality' => 'Pakistani', - 'country' => 'United Arab Emirates', - 'city' => 'Dubai', - 'area' => 'Al Barsha', - 'preferred_location' => 'Al Barsha', - 'live_in_out' => 'Live-out (External housing)', - 'language' => 'English', - 'age' => 28, - 'gender' => 'Male', - 'salary' => 2000.00, - 'availability' => '1 Month Notice', - 'experience' => '3 Years', - 'religion' => 'Muslim', - 'bio' => 'Skilled mason with experience in block work and plastering.', - 'verified' => true, - 'status' => 'active', - ], - [ - 'name' => 'Maria Santos', - 'email' => 'maria.santos@example.com', - 'phone' => '+971 50 555 6666', - 'nationality' => 'Filipino', - 'country' => 'United Arab Emirates', - 'city' => 'Yas Island', - 'area' => 'Yas Island', - 'preferred_location' => 'Yas Island', - 'live_in_out' => 'Live-in (Stay with family)', - 'language' => 'Tagalog', - 'age' => 32, - 'gender' => 'Female', - 'salary' => 1800.00, - 'availability' => 'Immediate', - 'experience' => '5+ Years', - 'religion' => 'Christian', - 'bio' => 'Experienced nanny with 6 years working with expatriate families in Dubai. Certified in pediatric first aid.', - 'verified' => true, - 'status' => 'active', - ], - [ - 'name' => 'Lakshmi Sharma', - 'email' => 'lakshmi.sharma@example.com', - 'phone' => '+971 50 777 8888', - 'nationality' => 'Indian', - 'country' => 'United Arab Emirates', - 'city' => 'Abu Dhabi', - 'area' => 'Khalifa City', - 'preferred_location' => 'Khalifa City', - 'live_in_out' => 'Live-out (External housing)', - 'language' => 'Hindi', - 'age' => 38, - 'gender' => 'Female', - 'salary' => 1600.00, - 'availability' => '2 Weeks', - 'experience' => '3-5 Years', - 'religion' => 'Hindu', - 'bio' => 'Patient caregiver specializing in elderly assistance, mobility support, and vegetarian cooking.', - 'verified' => true, - 'status' => 'active', - ], - [ - 'name' => 'Siti Aminah', - 'email' => 'siti.aminah@example.com', - 'phone' => '+971 50 999 0000', - 'nationality' => 'Indonesian', - 'country' => 'United Arab Emirates', - 'city' => 'Sharjah', - 'area' => 'Al Nahda', - 'preferred_location' => 'Al Nahda', - 'live_in_out' => 'Live-in (Stay with family)', - 'language' => 'Arabic', - 'age' => 29, - 'gender' => 'Female', - 'salary' => 1400.00, - 'availability' => 'Immediate', - 'experience' => '3-5 Years', - 'religion' => 'Muslim', - 'bio' => 'Hardworking and meticulous housekeeper with excellent references from Abu Dhabi households.', - 'verified' => true, - 'status' => 'active', - ], - [ - 'name' => 'Grace Osei', - 'email' => 'grace.osei@example.com', - 'phone' => '+971 50 222 3333', - 'nationality' => 'Ghanaian', - 'country' => 'Saudi Arabia', - 'city' => 'Riyadh', - 'area' => 'Al Olaya', - 'preferred_location' => 'Al Olaya', - 'live_in_out' => 'Live-out (External housing)', - 'language' => 'English', - 'age' => 26, - 'gender' => 'Female', - 'salary' => 1500.00, - 'availability' => '1 Month', - 'experience' => '1-2 Years', - 'religion' => 'Christian', - 'bio' => 'Energetic and educated nanny. Fluent in English, great with toddlers and assisting with homework.', - 'verified' => false, - 'status' => 'active', - ], - [ - 'name' => 'Anoma Perera', - 'email' => 'anoma.perera@example.com', - 'phone' => '+971 50 444 5555', - 'nationality' => 'Sri Lankan', - 'country' => 'Saudi Arabia', - 'city' => 'Jeddah', - 'area' => 'Al Hamra', - 'preferred_location' => 'Al Hamra', - 'live_in_out' => 'Live-in (Stay with family)', - 'language' => 'English', - 'age' => 41, - 'gender' => 'Female', - 'salary' => 2200.00, - 'availability' => 'Immediate', - 'experience' => '5+ Years', - 'religion' => 'Buddhist', - 'bio' => 'Professional domestic cook skilled in Arabic, Continental, and Asian cuisine. Highly organized.', - 'verified' => true, - 'status' => 'active', - ], - [ - 'name' => 'Ramesh Thapa', - 'email' => 'ramesh.thapa@example.com', - 'phone' => '+971 50 666 7777', - 'nationality' => 'Nepalese', - 'country' => 'Saudi Arabia', - 'city' => 'Riyadh', - 'area' => 'Al Yasmin', - 'preferred_location' => 'Al Yasmin', - 'live_in_out' => 'Live-out (External housing)', - 'language' => 'English', - 'age' => 36, - 'gender' => 'Male', - 'salary' => 2500.00, - 'availability' => '2 Weeks', - 'experience' => '5+ Years', - 'religion' => 'Hindu', - 'bio' => 'Valid UAE driving license with clean record. Familiar with all Dubai and Sharjah school routes.', - 'verified' => true, - 'status' => 'active', - ], - ]; - - // Dynamic Skill Resolution - $skillIds = \Illuminate\Support\Facades\DB::table('skills')->pluck('id')->toArray(); - if (empty($skillIds)) { - foreach (['cooking', 'driving', 'childcare', 'cleaning', 'elderly care', 'gardening'] as $skillName) { - $skillIds[] = \Illuminate\Support\Facades\DB::table('skills')->insertGetId([ - 'name' => $skillName, - 'created_at' => now(), - 'updated_at' => now(), - ]); - } - } - - $sId1 = $skillIds[0] ?? 1; - $sId2 = $skillIds[1] ?? 2; - - foreach ($workers as $workerData) { - // Exclude email duplicates to avoid unique constraint violations - if (\Illuminate\Support\Facades\DB::table('workers')->where('email', $workerData['email'])->exists()) { - continue; - } - - $workerId = \Illuminate\Support\Facades\DB::table('workers')->insertGetId(array_merge($workerData, [ - 'created_at' => now(), - 'updated_at' => now(), - ])); - - // Seed Documents - \Illuminate\Support\Facades\DB::table('worker_documents')->insert([ - [ - 'worker_id' => $workerId, - 'type' => 'passport', - 'number' => 'P' . rand(100000, 999999), - 'issue_date' => '2020-01-01', - 'expiry_date' => '2030-01-01', - 'ocr_accuracy' => 95.5, - 'created_at' => now(), - 'updated_at' => now(), - ], - [ - 'worker_id' => $workerId, - 'type' => 'visa', - 'number' => 'V' . rand(100000, 999999), - 'issue_date' => '2022-01-01', - 'expiry_date' => '2025-01-01', - 'ocr_accuracy' => 98.0, - 'created_at' => now(), - 'updated_at' => now(), - ] - ]); - - // Seed Skills using resolved IDs - \Illuminate\Support\Facades\DB::table('worker_skills')->insert([ - [ - 'worker_id' => $workerId, - 'skill_id' => $sId1, - 'created_at' => now(), - 'updated_at' => now(), - ], - [ - 'worker_id' => $workerId, - 'skill_id' => $sId2, - 'created_at' => now(), - 'updated_at' => now(), - ] - ]); - } - } -} diff --git a/resources/js/Pages/Employer/Workers/Show.jsx b/resources/js/Pages/Employer/Workers/Show.jsx index 1abf6d7..68d575d 100644 --- a/resources/js/Pages/Employer/Workers/Show.jsx +++ b/resources/js/Pages/Employer/Workers/Show.jsx @@ -336,6 +336,18 @@ export default function Show({ worker }) { {t('start_direct_chat', 'Start Direct Chat')} + {/* Stage 4 Hire: Hire Worker Button */} + {availabilityStatus !== 'Pending Confirmation' && availabilityStatus !== 'Hired' && ( + + )} + {/* Stage 4 Hire: Pending Confirmation Indicator */} {availabilityStatus === 'Pending Confirmation' && (
diff --git a/tests/Feature/WorkerJobApiTest.php b/tests/Feature/WorkerJobApiTest.php index 809f0f3..9ab8521 100644 --- a/tests/Feature/WorkerJobApiTest.php +++ b/tests/Feature/WorkerJobApiTest.php @@ -1077,6 +1077,62 @@ public function test_direct_hiring_sends_correct_notifications_to_worker() unlink($credentialsPath); } } + + public function test_basic_plan_employer_can_directly_hire_without_subscription_redirect() + { + // 1. Change employer subscription to 'basic' + $this->employer->subscription()->delete(); + Subscription::create([ + 'user_id' => $this->employer->id, + 'plan_id' => 'basic', + 'amount_aed' => 0.00, + 'starts_at' => now(), + 'expires_at' => now()->addDays(30), + 'status' => 'active', + ]); + + // Create a job post (representing a placeholder or existing one) + $job = JobPost::create([ + 'employer_id' => $this->employer->id, + 'title' => 'General Helper Placeholder', + 'location' => 'Dubai', + 'salary' => 2000, + 'job_type' => 'Full Time', + 'start_date' => now()->addDays(5)->format('Y-m-d'), + 'description' => 'Placeholder', + 'status' => 'active', + ]); + + // Create a job application + $application = JobApplication::create([ + 'worker_id' => $this->worker->id, + 'job_id' => $job->id, + 'status' => 'applied' + ]); + + // 2. Try to update status to 'Shortlisted' - should redirect to subscription + $responseShortlist = $this->actingAs($this->employer) + ->withSession(['user' => $this->employer]) + ->post("/employer/candidates/{$application->id}/status", [ + 'status' => 'Shortlisted', + 'notes' => 'Try to shortlist' + ]); + $responseShortlist->assertRedirect(route('employer.subscription')); + + // 3. Try to update status to 'Hired' - should bypass redirect and succeed + $responseHire = $this->actingAs($this->employer) + ->withSession(['user' => $this->employer]) + ->post("/employer/candidates/{$application->id}/status", [ + 'status' => 'Hired', + 'notes' => 'Direct hiring worker' + ]); + $responseHire->assertSessionHasNoErrors(); + + $this->assertDatabaseHas('job_applications', [ + 'id' => $application->id, + 'status' => 'hire_requested', + ]); + } }