57 lines
2.7 KiB
PHP
57 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Requisition;
|
|
use Carbon\CarbonImmutable;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
class ProcurementOperationalInsights
|
|
{
|
|
/**
|
|
* The caller supplies the report's authorised, filtered records query with
|
|
* quotations_count and order_number projections, inside its read snapshot.
|
|
*
|
|
* @param Builder<Requisition> $query
|
|
* @return array<string,mixed>
|
|
*/
|
|
public function build(Builder $query, CarbonImmutable $instant): array
|
|
{
|
|
$today = $instant->setTimezone(config('app.timezone'))->startOfDay();
|
|
$total = $pending = $missingSubmission = $neededPast = $approved = $withoutQuotes = $withoutOrder = 0;
|
|
$oldest = [];
|
|
foreach ((clone $query)->reorder()->lazyById(200) as $record) {
|
|
$total++;
|
|
if (in_array($record->status, ['draft', 'pending'], true) && $record->needed_by !== null && $record->needed_by->toDateString() < $today->toDateString()) {
|
|
$neededPast++;
|
|
}
|
|
if ($record->status === 'pending') {
|
|
$pending++;
|
|
if ($record->submitted_at === null) {
|
|
$missingSubmission++;
|
|
} else {
|
|
$age = (int) $record->submitted_at->toImmutable()->setTimezone(config('app.timezone'))->startOfDay()->diffInDays($today);
|
|
if ($age >= 0) {
|
|
$oldest[] = ['id' => $record->id, 'number' => $record->number, 'submitted_at' => $record->submitted_at->toIso8601String(),
|
|
'days_since_submission' => $age, 'href' => '/requisicoes/'.$record->id.'/processo'];
|
|
usort($oldest, fn ($a, $b) => ($b['days_since_submission'] <=> $a['days_since_submission']) ?: ($a['id'] <=> $b['id']));
|
|
$oldest = array_slice($oldest, 0, 5);
|
|
} else {
|
|
$missingSubmission++;
|
|
}
|
|
}
|
|
}
|
|
if ($record->status === 'approved') {
|
|
$approved++;
|
|
$withoutQuotes += (int) $record->getAttribute('quotations_count') === 0 ? 1 : 0;
|
|
$withoutOrder += $record->getAttribute('order_number') === null ? 1 : 0;
|
|
}
|
|
}
|
|
|
|
return ['method' => 'procurement_facts_v1', 'generated_at' => $instant->toIso8601String(), 'processes' => $total,
|
|
'pending' => ['count' => $pending, 'unknown_submission_age' => $missingSubmission, 'oldest' => $oldest],
|
|
'unapproved_past_needed_date' => $neededPast,
|
|
'approved' => ['count' => $approved, 'without_registered_quotes' => $withoutQuotes, 'without_visible_order' => $withoutOrder]];
|
|
}
|
|
}
|