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

50 lines
3.6 KiB
PHP

<?php
namespace App\Services;
class PeopleEvidenceBrief
{
/**
* Inputs must be the already redacted show-page projections.
*
* @param array<string,mixed> $process
* @param array<int,array<string,mixed>> $candidates
* @param array<string,mixed> $clarifications
* @return array<string,mixed>
*/
public function build(array $process, array $candidates, array $clarifications, bool $financeVisible, bool $contractVisible): array
{
$claims = [];
$add = function (string $id, string $text, string $href, string $label, string $pointer, mixed $basis) use (&$claims): void {
$claims[] = ['id' => $id, 'text' => $text, 'source' => ['label' => $label, 'href' => $href, 'pointer' => $pointer],
'basis_sha256' => hash('sha256', json_encode($basis, JSON_THROW_ON_ERROR))];
};
$rules = $process['rules'];
$add('rules', count($rules['criteria']).' critérios preservados; mínimo de '.$rules['minimum_reviews'].' avaliações independentes por candidatura. Estes requisitos não comprovam que todas as avaliações já foram feitas.',
'#people-report-scope', 'Âmbito e critérios preservados', 'process.rules', $rules);
$frozen = $process['selection'] !== null && in_array($process['status'], ['selection_review', 'selected', 'contract_draft'], true);
$rows = $frozen ? $process['selection']['rows'] : $candidates;
$add('candidates', count($rows).' candidaturas constam da '.($frozen ? 'base de selecção preservada apresentada no relatório.' : 'matriz actual apresentada no relatório.').' A pontuação não constitui selecção automática.',
'#people-report-candidates', 'Candidaturas e avaliação', $frozen ? 'process.selection.rows' : 'candidates', $rows);
if ($process['selection'] !== null) {
$approved = in_array($process['status'], ['selected', 'contract_draft'], true);
$text = $approved ? 'Existe uma selecção aprovada e preservada; não equivale a contrato assinado ou admissão efectiva.' :
($process['status'] === 'selection_review' ? 'Existe uma proposta de selecção pendente de conferência independente.' : 'A proposta de selecção foi devolvida para nova análise; não está aprovada.');
$add('selection', $text,
'#people-report-selection', 'Fundamento da selecção', 'process.selection', [$process['status'], $process['selection']]);
}
if ($contractVisible && $process['contract'] !== null) {
$add('contract', 'Consta uma minuta contratual de preparação interna, sem confirmação de assinatura ou admissão efectiva.',
'#people-report-contract', 'Minuta contratual', 'process.contract', $process['contract']);
}
if ($clarifications['ready']) {
$pending = count(array_filter($clarifications['items'], fn ($item) => $item['status'] !== 'resolved'));
$add('clarifications', $pending.' esclarecimentos em acompanhamento constam deste painel. O acompanhamento posterior não reescreve as avaliações originais nem a base de uma selecção aprovada.',
'#people-clarifications', 'Esclarecimentos das avaliações', 'clarifications.items', $clarifications['items']);
}
$basis = ['method' => 'people_evidence_brief_v1', 'process_id' => $process['id'], 'process_version' => $process['version'], 'claims' => $claims];
return [...$basis, 'generated_at' => now()->toIso8601String(), 'basis_sha256' => hash('sha256', json_encode($basis, JSON_THROW_ON_ERROR)), 'finance_visible' => $financeVisible];
}
}