75 خطوط
3.0 KiB
PHP
75 خطوط
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Modules\Assignments\Application;
|
|
|
|
use App\Models\User;
|
|
use App\Modules\Assignments\Domain\Assignment;
|
|
use App\Modules\Identity\Domain\Enums\AccountStatus;
|
|
use App\Modules\Identity\Domain\Enums\UserRole;
|
|
use App\Modules\Teams\Domain\Team;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
final class AssignmentResolver
|
|
{
|
|
public function sync(Assignment $assignment): int
|
|
{
|
|
if ($assignment->status !== 'active') {
|
|
return 0;
|
|
}
|
|
|
|
$users = $this->resolve($assignment);
|
|
$rows = $users->mapWithKeys(fn (User $user): array => [(string) $user->getKey() => [
|
|
'status' => 'assigned', 'assigned_at' => now(), 'starts_at' => $assignment->starts_at,
|
|
'due_at' => $assignment->due_at, 'progress' => 0, 'created_at' => now(), 'updated_at' => now(),
|
|
]])->all();
|
|
$existing = $assignment->users()->pluck('users.id')->map(fn ($id) => (string) $id);
|
|
$assignment->users()->syncWithoutDetaching(collect($rows)->except($existing)->all());
|
|
|
|
return count($rows);
|
|
}
|
|
|
|
public function syncOrganization(string $organizationId): void
|
|
{
|
|
Assignment::query()->where('organization_id', $organizationId)->where('status', 'active')->each(fn (Assignment $assignment) => $this->sync($assignment));
|
|
}
|
|
|
|
/** @return Collection<int, User> */
|
|
private function resolve(Assignment $assignment): Collection
|
|
{
|
|
$query = User::query()->where('organization_id', $assignment->organization_id)->where('status', AccountStatus::Active);
|
|
|
|
if ($assignment->target_type === 'individual') {
|
|
return $query->whereKey($assignment->target_id)->get();
|
|
}
|
|
if ($assignment->target_type === 'team') {
|
|
$team = Team::query()->where('organization_id', $assignment->organization_id)->find($assignment->target_id);
|
|
|
|
return $team ? $query->whereIn('id', $team->members()->pluck('users.id'))->get() : collect();
|
|
}
|
|
if ($assignment->target_type === 'department') {
|
|
return $query->where('department', $assignment->target_value)->get();
|
|
}
|
|
if ($assignment->target_type === 'organization') {
|
|
return $query->whereIn('role', [UserRole::Learner, UserRole::Manager])->get();
|
|
}
|
|
if ($assignment->target_type === 'rule') {
|
|
$rule = json_decode((string) $assignment->target_value, true) ?: [];
|
|
if (($rule['field'] ?? null) === 'department') {
|
|
$query->where('department', $rule['value'] ?? '');
|
|
} elseif (($rule['field'] ?? null) === 'job_level') {
|
|
$query->where('job_level', $rule['value'] ?? '');
|
|
} elseif (($rule['field'] ?? null) === 'team') {
|
|
$memberIds = DB::table('team_memberships')->where('team_id', $rule['value'] ?? '')->pluck('user_id');
|
|
$query->whereIn('id', $memberIds);
|
|
} else {
|
|
return collect();
|
|
}
|
|
|
|
return $query->get();
|
|
}
|
|
|
|
return collect();
|
|
}
|
|
}
|