50 lines
3.6 KiB
PHP
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];
|
|
}
|
|
}
|