'Ideia', 'concept' => 'Conceito', 'prefeasibility' => 'Pré-viabilidade', 'feasibility' => 'Viabilidade', 'structured' => 'Estruturado', 'investment_ready' => 'Pronto para investimento', 'implementation' => 'Implementação', 'operational' => 'Operacional', ]; public const LEGACY_LABELS = [1 => 'Ideia identificada', 'Pré-estudo disponível', 'Estudo de viabilidade em curso', 'Projecto estruturado', 'Pronto para investimento', 'Em negociação ou implementação']; /** Public selection is explicit; historical numbers never stand for current stages. * @return array */ public static function searchOptions(): array { $options = []; foreach (self::STAGES as $code => $label) { $options[] = ['value' => 'stage:'.$code, 'label' => $label, 'group' => 'Etapas de preparação']; } foreach (self::LEGACY_LABELS as $level => $label) { $options[] = ['value' => 'historical:'.$level, 'label' => $label.' — registo histórico', 'group' => 'Classificações históricas']; } return $options; } /** * @param Builder $query */ public static function constrainSearch(Builder $query, string $selection): void { [$kind, $value] = explode(':', $selection, 2); if ($kind === 'stage') { $query->where('workflow_context->publication->maturity->catalogue_version', self::VERSION) ->where('workflow_context->publication->maturity->stage', $value); } else { $query->where(fn ($q) => $q->where('workflow_context->publication->maturity->catalogue_version', self::LEGACY) ->orWhere(fn ($old) => $old->whereNull('workflow_context->publication->maturity->catalogue_version')->whereNull('workflow_context->publication->maturity->stage'))) ->where('maturity_level', (int) $value); } } /** @param array $data * @return array */ public function normalize(array $data): array { if (! array_key_exists('maturity_level', $data) && ! array_key_exists('maturity_stage', $data)) { if (isset($data['maturity_catalogue_version'])) { throw ValidationException::withMessages(['maturity_catalogue_version' => 'Seleccione também a etapa; mudar só a versão não converte o valor histórico.']); } unset($data['maturity_catalogue_version']); return $data; } $level = isset($data['maturity_level']) ? (int) $data['maturity_level'] : null; $version = $data['maturity_catalogue_version'] ?? ((isset($data['maturity_stage']) || ($level ?? 0) > 6) ? self::VERSION : self::LEGACY); if ($version === self::LEGACY) { if (($level ?? 0) > 6 || isset($data['maturity_stage'])) { throw ValidationException::withMessages(['maturity_level' => 'O catálogo histórico tem seis níveis; seleccione explicitamente o catálogo de oito etapas.']); } return [...$data, 'maturity_catalogue_version' => self::LEGACY, 'maturity_stage' => null, 'maturity_label' => self::LEGACY_LABELS[$level ?? 0] ?? null]; } $codes = array_keys(self::STAGES); $stage = $data['maturity_stage'] ?? ($level !== null ? $codes[$level - 1] : null); if ($stage !== null && $level !== null && $codes[$level - 1] !== $stage) { throw ValidationException::withMessages(['maturity_stage' => 'O código da etapa e a posição no catálogo não correspondem.']); } return [...$data, 'maturity_catalogue_version' => self::VERSION, 'maturity_stage' => $stage, 'maturity_level' => $stage !== null ? array_search($stage, $codes, true) + 1 : null, 'maturity_label' => $stage !== null ? self::STAGES[$stage] : null]; } }