90 lines
2.6 KiB
PHP
90 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Admin;
|
|
|
|
use App\Mail\OperationalAccountCreatedMail;
|
|
use App\Models\Application;
|
|
use App\Models\Position;
|
|
use App\Models\StaffAssignment;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Illuminate\Support\Str;
|
|
|
|
class OperationalAccountService
|
|
{
|
|
private const ROLES_NEEDING_ACCOUNT = ['PPM', 'KTM'];
|
|
|
|
public function provisionForApplication(Application $application, Position $position): void
|
|
{
|
|
if (! in_array($position->code, self::ROLES_NEEDING_ACCOUNT, true)) {
|
|
return;
|
|
}
|
|
|
|
if (! $application->email) {
|
|
return;
|
|
}
|
|
|
|
[$user, $tempPassword] = $this->findOrCreateUser($application->name, $application->email);
|
|
|
|
// Link user to application if not already linked
|
|
if ($application->user_id !== $user->id) {
|
|
$application->forceFill(['user_id' => $user->id])->save();
|
|
}
|
|
|
|
$user->assignRole($position->code);
|
|
|
|
if ($tempPassword !== null) {
|
|
Mail::to($user->email)->queue(
|
|
new OperationalAccountCreatedMail($user, $position->code, $tempPassword)
|
|
);
|
|
}
|
|
}
|
|
|
|
public function provisionForAssignment(StaffAssignment $assignment, Position $position): void
|
|
{
|
|
if (! in_array($position->code, self::ROLES_NEEDING_ACCOUNT, true)) {
|
|
return;
|
|
}
|
|
|
|
$application = $assignment->application;
|
|
|
|
if ($application) {
|
|
$this->provisionForApplication($application, $position);
|
|
|
|
// Re-link user_id on assignment after provisioning
|
|
$assignment->loadMissing('application');
|
|
if ($assignment->application?->user_id && $assignment->user_id !== $assignment->application->user_id) {
|
|
$assignment->forceFill(['user_id' => $assignment->application->user_id])->save();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Assignment without application (direct assignment) — skip provisioning
|
|
}
|
|
|
|
/**
|
|
* @return array{User, string|null} [$user, $tempPassword|null]
|
|
*/
|
|
private function findOrCreateUser(string $name, string $email): array
|
|
{
|
|
$existing = User::query()->where('email', $email)->first();
|
|
|
|
if ($existing) {
|
|
return [$existing, null];
|
|
}
|
|
|
|
$tempPassword = Str::random(10);
|
|
|
|
$user = User::query()->create([
|
|
'name' => $name,
|
|
'email' => $email,
|
|
'password' => Hash::make($tempPassword),
|
|
'email_verified_at' => now(),
|
|
]);
|
|
|
|
return [$user, $tempPassword];
|
|
}
|
|
}
|