mohan #12
@ -309,6 +309,8 @@ public function getDashboard(Request $request)
|
|||||||
|
|
||||||
$savedCandidates = \App\Models\Shortlist::where('employer_id', $employer->id)->count();
|
$savedCandidates = \App\Models\Shortlist::where('employer_id', $employer->id)->count();
|
||||||
|
|
||||||
|
$totalWorkers = \App\Models\Worker::where('status', 'active')->count();
|
||||||
|
|
||||||
// Resolve plan
|
// Resolve plan
|
||||||
$sub = \Illuminate\Support\Facades\DB::table('subscriptions')
|
$sub = \Illuminate\Support\Facades\DB::table('subscriptions')
|
||||||
->where('user_id', $employer->id)
|
->where('user_id', $employer->id)
|
||||||
@ -375,6 +377,7 @@ public function getDashboard(Request $request)
|
|||||||
'contacted_workers_count' => $contactedWorkersCount,
|
'contacted_workers_count' => $contactedWorkersCount,
|
||||||
'total_hired_workers' => $totalHiredWorkers,
|
'total_hired_workers' => $totalHiredWorkers,
|
||||||
'saved_candidates' => $savedCandidates,
|
'saved_candidates' => $savedCandidates,
|
||||||
|
'total_workers' => $totalWorkers,
|
||||||
],
|
],
|
||||||
'current_plan' => $currentPlan,
|
'current_plan' => $currentPlan,
|
||||||
'recent_announcements' => $recentAnnouncements,
|
'recent_announcements' => $recentAnnouncements,
|
||||||
|
|||||||
@ -44,6 +44,7 @@ private function formatWorker(Worker $w)
|
|||||||
return [
|
return [
|
||||||
'id' => $w->id,
|
'id' => $w->id,
|
||||||
'name' => $w->name,
|
'name' => $w->name,
|
||||||
|
'email' => $w->email,
|
||||||
'phone' => $w->phone,
|
'phone' => $w->phone,
|
||||||
'nationality' => $w->nationality,
|
'nationality' => $w->nationality,
|
||||||
'age' => $w->age,
|
'age' => $w->age,
|
||||||
@ -57,6 +58,8 @@ private function formatWorker(Worker $w)
|
|||||||
'language' => $w->language,
|
'language' => $w->language,
|
||||||
'languages' => $langs,
|
'languages' => $langs,
|
||||||
'preferred_location' => $w->preferred_location,
|
'preferred_location' => $w->preferred_location,
|
||||||
|
'country' => $w->country,
|
||||||
|
'city' => $w->city,
|
||||||
'area' => $w->area,
|
'area' => $w->area,
|
||||||
'live_in_out' => $w->live_in_out,
|
'live_in_out' => $w->live_in_out,
|
||||||
'gender' => $w->gender,
|
'gender' => $w->gender,
|
||||||
@ -71,7 +74,6 @@ private function formatWorker(Worker $w)
|
|||||||
'visa_expiry_date' => $w->visa_expiry_date,
|
'visa_expiry_date' => $w->visa_expiry_date,
|
||||||
'bio' => $w->bio,
|
'bio' => $w->bio,
|
||||||
'photo' => $photo,
|
'photo' => $photo,
|
||||||
'religion' => $w->religion,
|
|
||||||
'rating' => $rating,
|
'rating' => $rating,
|
||||||
'reviews_count' => $reviewsCount,
|
'reviews_count' => $reviewsCount,
|
||||||
'skills' => $w->skills->map(function ($s) {
|
'skills' => $w->skills->map(function ($s) {
|
||||||
@ -88,6 +90,11 @@ private function formatWorker(Worker $w)
|
|||||||
];
|
];
|
||||||
})->toArray(),
|
})->toArray(),
|
||||||
'documents' => $w->documents->map(function ($doc) {
|
'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 [
|
return [
|
||||||
'id' => $doc->id,
|
'id' => $doc->id,
|
||||||
'worker_id' => $doc->worker_id,
|
'worker_id' => $doc->worker_id,
|
||||||
@ -97,7 +104,7 @@ private function formatWorker(Worker $w)
|
|||||||
'expiry_date' => $doc->expiry_date,
|
'expiry_date' => $doc->expiry_date,
|
||||||
'ocr_accuracy' => $doc->ocr_accuracy,
|
'ocr_accuracy' => $doc->ocr_accuracy,
|
||||||
'file_path' => $doc->file_path ? url($doc->file_path) : null,
|
'file_path' => $doc->file_path ? url($doc->file_path) : null,
|
||||||
'ocr_data' => $doc->ocr_data,
|
'ocr_data' => $ocrData,
|
||||||
'created_at' => $doc->created_at?->toISOString(),
|
'created_at' => $doc->created_at?->toISOString(),
|
||||||
'updated_at' => $doc->updated_at?->toISOString(),
|
'updated_at' => $doc->updated_at?->toISOString(),
|
||||||
];
|
];
|
||||||
@ -976,25 +983,74 @@ public function getWorkerDetail(Request $request, $id)
|
|||||||
$workerProfile = [
|
$workerProfile = [
|
||||||
'id' => $w->id,
|
'id' => $w->id,
|
||||||
'name' => $w->name,
|
'name' => $w->name,
|
||||||
|
'email' => $w->email,
|
||||||
|
'phone' => $w->phone,
|
||||||
'nationality' => $w->nationality,
|
'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,
|
'age' => $w->age,
|
||||||
'gender' => $w->gender,
|
'salary' => $w->salary,
|
||||||
|
'experience' => $w->experience,
|
||||||
'verified' => (bool)$w->verified,
|
'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,
|
'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,
|
'bio' => $w->bio,
|
||||||
|
'photo' => $photo,
|
||||||
'rating' => $rating,
|
'rating' => $rating,
|
||||||
'reviews_count' => $reviewsCount,
|
'reviews_count' => $reviewsCount,
|
||||||
'reviews' => $reviews,
|
'reviews' => $reviews,
|
||||||
'similar_workers' => $similarWorkers,
|
'similar_workers' => $similarWorkers,
|
||||||
'conversation_id' => $conversation ? $conversation->id : null,
|
'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([
|
return response()->json([
|
||||||
|
|||||||
@ -370,7 +370,6 @@ public function show($id)
|
|||||||
'skills' => $mappedSkills,
|
'skills' => $mappedSkills,
|
||||||
'visa_status' => $visaStatus,
|
'visa_status' => $visaStatus,
|
||||||
'experience' => $w->experience,
|
'experience' => $w->experience,
|
||||||
'experience_years' => 5,
|
|
||||||
'salary' => (int) $w->salary,
|
'salary' => (int) $w->salary,
|
||||||
'religion' => $w->religion,
|
'religion' => $w->religion,
|
||||||
'languages' => $langs,
|
'languages' => $langs,
|
||||||
|
|||||||
@ -4198,105 +4198,13 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"worker": {
|
"worker": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/Worker"
|
||||||
|
},
|
||||||
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"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": {
|
"reviews": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@ -4316,6 +4224,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5738,10 +5648,6 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "4 Years"
|
"example": "4 Years"
|
||||||
},
|
},
|
||||||
"religion": {
|
|
||||||
"type": "string",
|
|
||||||
"example": "Muslim"
|
|
||||||
},
|
|
||||||
"bio": {
|
"bio": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "Certified infant caregiver and housekeeper with excellent cooking skills."
|
"example": "Certified infant caregiver and housekeeper with excellent cooking skills."
|
||||||
|
|||||||
@ -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('Charity Drive 1'));
|
||||||
$this->assertFalse($titles->contains('Pending Charity Drive'));
|
$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'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -532,4 +532,87 @@ public function test_worker_list_api_has_full_details_and_pagination()
|
|||||||
$this->assertEquals('passport', $matchingWorker['documents'][0]['type']);
|
$this->assertEquals('passport', $matchingWorker['documents'][0]['type']);
|
||||||
$this->assertEquals('visa', $matchingWorker['documents'][1]['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']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user