Files
prn2026/app/Services/Admin/OperationalAccountService.php
2026-06-03 08:51:22 +08:00

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];
}
}