Files
compras/app/Services/PeopleOperationalInsights.php
T
nala c6373365bf
tests / ci (push) Canceled after 0s
commit9
2026-10-30 20:02:30 +02:00

42 lines
2.0 KiB
PHP

<?php
namespace App\Services;
use Carbon\CarbonImmutable;
class PeopleOperationalInsights
{
/**
* Derive facts only from the caller's already authorised, filtered workdesk.
* No candidate data, new database queries or inferred access rights.
*
* @param array<string,mixed> $workdesk
* @return array<string,mixed>
*/
public function build(array $workdesk): array
{
$today = CarbonImmutable::parse($workdesk['updated_at'])->setTimezone(config('app.timezone'))->startOfDay();
$overdue = [];
foreach ($workdesk['alerts'] as $alert) {
$days = (int) CarbonImmutable::parse($alert['due_on'], config('app.timezone'))->startOfDay()->diffInDays($today);
if ($days > 0) {
$overdue[] = ['id' => $alert['id'], 'process_id' => $alert['process_id'], 'reference' => $alert['reference'],
'label' => $alert['label'], 'due_on' => $alert['due_on'], 'days_overdue' => $days, 'href' => $alert['href']];
}
}
usort($overdue, fn ($a, $b) => ($b['days_overdue'] <=> $a['days_overdue']) ?: strcmp((string) $a['id'], (string) $b['id']));
$actions = [];
foreach ($workdesk['tasks'] as $task) {
$actions[$task['action']] = ($actions[$task['action']] ?? 0) + 1;
}
$withoutDeadline = count(array_filter($workdesk['tasks'], fn ($task) => $task['due_on'] === null));
return ['method' => 'operational_facts_v1', 'generated_at' => $workdesk['updated_at'],
'coverage' => ['processes' => $workdesk['counts']['processes'], 'tasks' => count($workdesk['tasks']), 'approvals' => count($workdesk['approvals'])],
'overdue' => ['items' => count($overdue), 'processes' => count(array_unique(array_column($overdue, 'process_id'))),
'maximum_days' => $overdue === [] ? null : $overdue[0]['days_overdue'], 'oldest' => array_slice($overdue, 0, 5)],
'task_actions' => $actions, 'tasks_without_deadline' => $withoutDeadline];
}
}