400 lines
17 KiB
PHP
400 lines
17 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\User;
|
|
use App\Models\EmployerProfile;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
|
class EmployerProfileController extends Controller
|
|
{
|
|
/**
|
|
* Get the authenticated employer's profile details.
|
|
*
|
|
* @param \Illuminate\Http\Request $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function getProfile(Request $request)
|
|
{
|
|
/** @var User $employer */
|
|
$employer = $request->attributes->get('employer');
|
|
|
|
try {
|
|
$profile = $employer->employerProfile;
|
|
|
|
if (!$profile) {
|
|
$profile = EmployerProfile::create([
|
|
'user_id' => $employer->id,
|
|
'phone' => '+971 50 123 4567',
|
|
'address' => 'Dubai, UAE',
|
|
'verification_status' => 'approved',
|
|
]);
|
|
}
|
|
|
|
$employerProfile = [
|
|
'name' => $employer->name,
|
|
'email' => $employer->email,
|
|
'phone' => $profile->phone,
|
|
'address' => $profile->address,
|
|
'notifications' => (bool)($profile->notifications ?? true),
|
|
'verification_status' => $profile->verification_status ?? 'approved',
|
|
'emirates_id_number' => $profile->emirates_id_number,
|
|
'emirates_id_expiry' => $profile->emirates_id_expiry,
|
|
'id_number' => $profile->emirates_id_number,
|
|
'card_number' => $profile->emirates_id_card_number,
|
|
'full_name' => $profile->emirates_id_name,
|
|
'date_of_birth' => $profile->emirates_id_dob,
|
|
'nationality' => $profile->nationality,
|
|
'gender' => $profile->emirates_id_gender,
|
|
'issue_date' => $profile->emirates_id_issue_date,
|
|
'expiry_date' => $profile->emirates_id_expiry,
|
|
'occupation' => $profile->emirates_id_occupation,
|
|
'employer' => $profile->emirates_id_employer,
|
|
'issuing_place' => $profile->emirates_id_issue_place,
|
|
];
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => [
|
|
'profile' => $employerProfile
|
|
]
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
logger()->error('Mobile Employer Get Profile Failure: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'An error occurred while fetching the profile.',
|
|
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update the authenticated employer's profile details.
|
|
*
|
|
* @param \Illuminate\Http\Request $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function updateProfile(Request $request)
|
|
{
|
|
/** @var User $employer */
|
|
$employer = $request->attributes->get('employer');
|
|
|
|
$sponsor = \App\Models\Sponsor::where('email', $employer->email)->first();
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'name' => 'required|string|max:255',
|
|
'email' => [
|
|
'required',
|
|
'string',
|
|
'email',
|
|
'max:255',
|
|
'unique:users,email,' . $employer->id,
|
|
$sponsor ? 'unique:sponsors,email,' . $sponsor->id : 'unique:sponsors,email',
|
|
],
|
|
'phone' => [
|
|
'required',
|
|
'string',
|
|
'max:255',
|
|
'unique:employer_profiles,phone,' . ($employer->employerProfile ? $employer->employerProfile->id : 'NULL'),
|
|
$sponsor ? 'unique:sponsors,mobile,' . $sponsor->id : 'unique:sponsors,mobile',
|
|
],
|
|
'address' => 'required|string|max:255',
|
|
'notifications' => 'nullable|boolean',
|
|
'fcm_token' => 'nullable|string|max:255',
|
|
|
|
// Emirates ID optional fields
|
|
'id_number' => 'nullable|string|max:255',
|
|
'card_number' => 'nullable|string|max:255',
|
|
'full_name' => 'nullable|string|max:255',
|
|
'date_of_birth' => 'nullable|string|max:255',
|
|
'nationality' => 'nullable|string|max:255',
|
|
'gender' => 'nullable|string|max:255',
|
|
'issue_date' => 'nullable|string|max:255',
|
|
'expiry_date' => 'nullable|string|max:255',
|
|
'occupation' => 'nullable|string|max:255',
|
|
'employer' => 'nullable|string|max:255',
|
|
'issuing_place' => 'nullable|string|max:255',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Validation error.',
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
}
|
|
|
|
try {
|
|
// Validate Emirates ID immutability — once set, it cannot be changed
|
|
if ($request->filled('id_number')) {
|
|
$existingProfile = $employer->employerProfile;
|
|
if ($existingProfile && $existingProfile->emirates_id_number && $existingProfile->emirates_id_number !== $request->id_number) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Emirates ID mismatch. You cannot change your registered Emirates ID number.',
|
|
'errors' => [
|
|
'id_number' => ['Emirates ID mismatch.']
|
|
]
|
|
], 422);
|
|
}
|
|
}
|
|
|
|
// Find old email before update to locate the correct sponsor record
|
|
$oldEmail = $employer->getOriginal('email') ?? $employer->email;
|
|
|
|
// Update user table
|
|
$userData = [
|
|
'name' => $request->name,
|
|
'email' => $request->email,
|
|
];
|
|
if ($request->has('fcm_token')) {
|
|
$userData['fcm_token'] = $request->fcm_token;
|
|
}
|
|
$employer->update($userData);
|
|
|
|
// Sync with corresponding sponsor record if found
|
|
$matchingSponsor = \App\Models\Sponsor::where('email', $oldEmail)->first();
|
|
if ($matchingSponsor) {
|
|
$sponsorData = [
|
|
'full_name' => $request->name,
|
|
'email' => $request->email,
|
|
'mobile' => $request->phone,
|
|
'address' => $request->address,
|
|
];
|
|
|
|
if ($request->has('id_number')) {
|
|
$sponsorData['emirates_id'] = $request->id_number;
|
|
}
|
|
if ($request->has('card_number')) {
|
|
$sponsorData['emirates_id_card_number'] = $request->card_number;
|
|
}
|
|
if ($request->has('full_name')) {
|
|
$sponsorData['emirates_id_name'] = $request->full_name;
|
|
}
|
|
if ($request->has('date_of_birth')) {
|
|
$sponsorData['emirates_id_dob'] = $request->date_of_birth;
|
|
}
|
|
if ($request->has('nationality')) {
|
|
$sponsorData['nationality'] = $request->nationality;
|
|
}
|
|
if ($request->has('gender')) {
|
|
$sponsorData['emirates_id_gender'] = $request->gender;
|
|
}
|
|
if ($request->has('issue_date')) {
|
|
$sponsorData['emirates_id_issue_date'] = $request->issue_date;
|
|
}
|
|
if ($request->has('expiry_date')) {
|
|
$sponsorData['emirates_id_expiry'] = $request->expiry_date;
|
|
}
|
|
if ($request->has('occupation')) {
|
|
$sponsorData['emirates_id_occupation'] = $request->occupation;
|
|
}
|
|
if ($request->has('employer')) {
|
|
$sponsorData['emirates_id_employer'] = $request->employer;
|
|
}
|
|
if ($request->has('issuing_place')) {
|
|
$sponsorData['emirates_id_issue_place'] = $request->issuing_place;
|
|
}
|
|
|
|
$matchingSponsor->update($sponsorData);
|
|
}
|
|
|
|
// Update employer_profiles table
|
|
$profile = $employer->employerProfile;
|
|
if (!$profile) {
|
|
$profile = new EmployerProfile(['user_id' => $employer->id]);
|
|
}
|
|
$profile->address = $request->address;
|
|
$profile->phone = $request->phone;
|
|
$profile->notifications = $request->has('notifications') ? $request->notifications : ($profile->notifications ?? true);
|
|
|
|
if ($request->has('id_number')) {
|
|
$profile->emirates_id_number = $request->id_number;
|
|
}
|
|
if ($request->has('card_number')) {
|
|
$profile->emirates_id_card_number = $request->card_number;
|
|
}
|
|
if ($request->has('full_name')) {
|
|
$profile->emirates_id_name = $request->full_name;
|
|
}
|
|
if ($request->has('date_of_birth')) {
|
|
$profile->emirates_id_dob = $request->date_of_birth;
|
|
}
|
|
if ($request->has('nationality')) {
|
|
$profile->nationality = $request->nationality;
|
|
}
|
|
if ($request->has('gender')) {
|
|
$profile->emirates_id_gender = $request->gender;
|
|
}
|
|
if ($request->has('issue_date')) {
|
|
$profile->emirates_id_issue_date = $request->issue_date;
|
|
}
|
|
if ($request->has('expiry_date')) {
|
|
$profile->emirates_id_expiry = $request->expiry_date;
|
|
}
|
|
if ($request->has('occupation')) {
|
|
$profile->emirates_id_occupation = $request->occupation;
|
|
}
|
|
if ($request->has('employer')) {
|
|
$profile->emirates_id_employer = $request->employer;
|
|
}
|
|
if ($request->has('issuing_place')) {
|
|
$profile->emirates_id_issue_place = $request->issuing_place;
|
|
}
|
|
|
|
$profile->save();
|
|
|
|
$employerProfile = [
|
|
'name' => $employer->name,
|
|
'email' => $employer->email,
|
|
'phone' => $profile->phone,
|
|
'address' => $profile->address,
|
|
'notifications' => (bool)$profile->notifications,
|
|
'verification_status' => $profile->verification_status ?? 'approved',
|
|
'emirates_id_number' => $profile->emirates_id_number,
|
|
'emirates_id_expiry' => $profile->emirates_id_expiry,
|
|
'id_number' => $profile->emirates_id_number,
|
|
'card_number' => $profile->emirates_id_card_number,
|
|
'full_name' => $profile->emirates_id_name,
|
|
'date_of_birth' => $profile->emirates_id_dob,
|
|
'nationality' => $profile->nationality,
|
|
'gender' => $profile->emirates_id_gender,
|
|
'issue_date' => $profile->emirates_id_issue_date,
|
|
'expiry_date' => $profile->emirates_id_expiry,
|
|
'occupation' => $profile->emirates_id_occupation,
|
|
'employer' => $profile->emirates_id_employer,
|
|
'issuing_place' => $profile->emirates_id_issue_place,
|
|
];
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Profile updated successfully.',
|
|
'data' => [
|
|
'profile' => $employerProfile
|
|
]
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
logger()->error('Mobile Employer Update Profile Failure: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'An error occurred while updating the profile.',
|
|
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get dashboard analytics and summary for employer.
|
|
*/
|
|
public function getDashboard(Request $request)
|
|
{
|
|
/** @var User $employer */
|
|
$employer = $request->attributes->get('employer');
|
|
|
|
try {
|
|
$contactedWorkersCount = \App\Models\Conversation::where('employer_id', $employer->id)->count();
|
|
|
|
$totalHiredWorkers = \App\Models\JobOffer::where('employer_id', $employer->id)->where('status', 'accepted')->count() +
|
|
\App\Models\JobApplication::whereHas('jobPost', function($q) use ($employer) {
|
|
$q->where('employer_id', $employer->id);
|
|
})->where('status', 'hired')->count();
|
|
|
|
$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)
|
|
->where('status', 'active')
|
|
->latest('id')
|
|
->first();
|
|
|
|
$currentPlan = [
|
|
'plan_id' => $sub ? $sub->plan_id : 'premium',
|
|
'name' => $sub ? (ucfirst($sub->plan_id) . ' Pass') : 'Premium Employer Pass',
|
|
'status' => $sub ? $sub->status : 'active',
|
|
'starts_at' => $sub ? date('Y-m-d', strtotime($sub->starts_at)) : now()->subDays(6)->format('Y-m-d'),
|
|
'expires_at' => $sub ? date('Y-m-d', strtotime($sub->expires_at)) : now()->addDays(24)->format('Y-m-d'),
|
|
];
|
|
|
|
// Recent Announcements / Events
|
|
$dbAnnouncements = \App\Models\Announcement::where('status', 'approved')->latest()->limit(2)->get();
|
|
$recentAnnouncements = $dbAnnouncements->map(function ($ann) {
|
|
$body = $ann->body;
|
|
$eventDate = null;
|
|
$eventTime = null;
|
|
$locationDetails = null;
|
|
$locationPin = null;
|
|
$providedItems = null;
|
|
|
|
if (strpos($ann->body, '{"type":"Charity"') === 0) {
|
|
$decoded = json_decode($ann->body, true);
|
|
if ($decoded) {
|
|
$body = $decoded['content'] ?? $ann->body;
|
|
$eventDate = $decoded['event_date'] ?? null;
|
|
$eventTime = $decoded['event_time'] ?? null;
|
|
$locationDetails = $decoded['location_details'] ?? null;
|
|
$locationPin = $decoded['location_pin'] ?? null;
|
|
$providedItems = $decoded['provided_items'] ?? null;
|
|
}
|
|
} else {
|
|
$body = $ann->body;
|
|
$eventDate = $ann->created_at->addDays(2)->format('Y-m-d');
|
|
$eventTime = '9:00 AM - 3:00 PM';
|
|
$locationDetails = 'Al Quoz Community Center, Dubai';
|
|
$locationPin = 'https://maps.google.com';
|
|
$providedItems = 'Free Medical Checks & Food Supplies';
|
|
}
|
|
|
|
return [
|
|
'id' => $ann->id,
|
|
'title' => $ann->title,
|
|
'body' => $body,
|
|
'is_charity' => true,
|
|
'event_date' => $eventDate,
|
|
'event_time' => $eventTime,
|
|
'location_details' => $locationDetails,
|
|
'location_pin' => $locationPin,
|
|
'provided_items' => $providedItems,
|
|
'created_at' => $ann->created_at->toISOString(),
|
|
'time_ago' => $ann->created_at->diffForHumans(),
|
|
];
|
|
});
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => [
|
|
'stats' => [
|
|
'contacted_workers_count' => $contactedWorkersCount,
|
|
'total_hired_workers' => $totalHiredWorkers,
|
|
'saved_candidates' => $savedCandidates,
|
|
'total_workers' => $totalWorkers,
|
|
],
|
|
'current_plan' => $currentPlan,
|
|
'recent_announcements' => $recentAnnouncements,
|
|
'recent_events' => $recentAnnouncements, // alias for ease
|
|
]
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
logger()->error('Mobile Employer Get Dashboard Failure: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'An error occurred while fetching the dashboard statistics.',
|
|
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
}
|