99 lines
3.0 KiB
PHP
99 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Ppm;
|
|
|
|
use App\Models\Position;
|
|
use App\Models\PositionQuota;
|
|
use App\Models\PusatMengundi;
|
|
use App\Models\SaluranMengundi;
|
|
use App\Models\StaffAssignment;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class AssignmentVacancyService
|
|
{
|
|
public function hasPusatVacancy(PusatMengundi $pusatMengundi, string $roleCode): bool
|
|
{
|
|
$position = Position::query()->where('code', $roleCode)->first();
|
|
|
|
if ($position === null) {
|
|
return false;
|
|
}
|
|
|
|
$quota = PositionQuota::query()
|
|
->where('election_id', $pusatMengundi->election_id)
|
|
->where('pusat_mengundi_id', $pusatMengundi->id)
|
|
->whereNull('saluran_mengundi_id')
|
|
->where('position_id', $position->id)
|
|
->value('quota');
|
|
|
|
if ($quota === null) {
|
|
return false;
|
|
}
|
|
|
|
$used = StaffAssignment::query()
|
|
->where('election_id', $pusatMengundi->election_id)
|
|
->where('pusat_mengundi_id', $pusatMengundi->id)
|
|
->whereNull('saluran_mengundi_id')
|
|
->where('position_id', $position->id)
|
|
->where('status', 'active')
|
|
->count();
|
|
|
|
return $used < (int) $quota;
|
|
}
|
|
|
|
public function hasSaluranVacancy(PusatMengundi $pusatMengundi, int $saluranMengundiId, string $roleCode): bool
|
|
{
|
|
$position = Position::query()->where('code', $roleCode)->first();
|
|
|
|
if ($position === null) {
|
|
return false;
|
|
}
|
|
|
|
$saluran = SaluranMengundi::query()
|
|
->where('id', $saluranMengundiId)
|
|
->where('pusat_mengundi_id', $pusatMengundi->id)
|
|
->first();
|
|
|
|
if (! $saluran instanceof SaluranMengundi) {
|
|
return false;
|
|
}
|
|
|
|
$quota = PositionQuota::query()
|
|
->where('election_id', $pusatMengundi->election_id)
|
|
->where('pusat_mengundi_id', $pusatMengundi->id)
|
|
->where('saluran_mengundi_id', $saluran->id)
|
|
->where('position_id', $position->id)
|
|
->value('quota');
|
|
|
|
if ($quota === null) {
|
|
return false;
|
|
}
|
|
|
|
$used = StaffAssignment::query()
|
|
->where('election_id', $pusatMengundi->election_id)
|
|
->where('pusat_mengundi_id', $pusatMengundi->id)
|
|
->where('saluran_mengundi_id', $saluran->id)
|
|
->where('position_id', $position->id)
|
|
->where('status', 'active')
|
|
->count();
|
|
|
|
return $used < (int) $quota;
|
|
}
|
|
|
|
/**
|
|
* @return Collection<int, SaluranMengundi>
|
|
*/
|
|
public function availableSaluransForRole(PusatMengundi $pusatMengundi, string $roleCode): Collection
|
|
{
|
|
/** @var Collection<int, SaluranMengundi> $salurans */
|
|
$salurans = $pusatMengundi->saluranMengundis()
|
|
->orderBy('number')
|
|
->get()
|
|
->filter(fn (mixed $saluran): bool => $saluran instanceof SaluranMengundi
|
|
&& $this->hasSaluranVacancy($pusatMengundi, $saluran->id, $roleCode))
|
|
->values();
|
|
|
|
return $salurans;
|
|
}
|
|
}
|