$context */ public function key(array $context, ?string $key, bool $required = false): ?string { $choices = $context['opportunity_choices'] ?? []; $key = $key ?: (count($choices) === 1 ? $choices[0]['opportunity']['key'] : null); abort_if($key && ! collect(StructuredData::collectionItems($choices))->contains('opportunity.key', $key), 422, 'Escolha uma oportunidade deste dossier.'); abort_if($required && count($choices) > 1 && ! $key, 422, 'Escolha a oportunidade em tratamento.'); return $key; } /** * @param array $context * @param array $payload * @return array */ public function facts(array $payload, array $context, ?string $key): array { $key = $this->key($context, $key); $path = $payload['investor_path'] ?? []; $defaults = ['land_needed' => 'unknown', 'external_funding' => 'unknown', 'viability' => 'unknown']; // A dossier-wide dispensation cannot decide a distinct opportunity's needs. if ($key && count($context['opportunity_choices'] ?? []) > 1) { return [...$defaults, ...($path['opportunity_facts'][$key] ?? [])]; } if ($key && isset($path['opportunity_facts'][$key])) { return [...$defaults, ...$path['opportunity_facts'][$key]]; } if (count($context['opportunity_choices'] ?? []) > 1) { return $defaults; } return [...$defaults, ...($path['facts'] ?? [])]; } /** * @param array $context * @return array */ public function context(array $context, ?string $key): array { $choices = $context['opportunity_choices'] ?? []; $key = $this->key($context, $key); if (! $choices) { return $context; } $choice = $key ? collect(StructuredData::collectionItems($choices))->firstWhere('opportunity.key', $key) : null; abort_if($key && ! $choice, 422, 'Escolha uma oportunidade deste dossier.'); $specific = ['project_summary', 'sector_id', 'sector', 'province_id', 'district_id', 'admin_post_id', 'locality_id', 'province', 'district', 'location', 'special_zone_id', 'investment_regime']; $context['fields'] = Arr::except($context['fields'], $specific); $context['provenance'] = Arr::except($context['provenance'] ?? [], $specific); $context['selection'] = Arr::except($context['selection'], ['opportunity', 'territory', 'park']); if (! $choice) { $context['opportunity_choices'] = []; $context['requirements_assessment']['requirements'] = []; return $context; } $context['selection']['opportunity'] = $choice['opportunity']; $context['fields'] = [...$context['fields'], ...Arr::only($choice['opportunity']['fields'], $specific)]; foreach (Arr::only($choice['opportunity']['fields'], $specific) as $field => $value) { $context['provenance'][$field] = Arr::only($choice['opportunity'], ['key', 'kind', 'id', 'title', 'version', 'sha256']); } unset($context['selection']['sector']); if (! empty($context['fields']['sector_id'])) { $context['selection']['sector'] = app(InvestorContext::class)->reference('sector:'.$context['fields']['sector_id']); } if ($choice['territory']) { $context['selection']['territory'] = $choice['territory']; $context['fields'] = [...Arr::except($context['fields'], array_keys(InvestmentGeography::FIELDS)), ...$choice['territory']['fields']]; foreach ($choice['territory']['fields'] as $field => $value) { $context['provenance'][$field] = Arr::only($choice['territory'], ['key', 'kind', 'id', 'title', 'version', 'sha256']); } } else { $context['fields'] = Arr::except($context['fields'], ['province_id', 'district_id', 'admin_post_id', 'locality_id', 'province', 'district', 'location']); } $park = $choice['park'] ?? null; if ($park) { $context['selection']['park'] = $park; } $context['fields']['special_zone_id'] = $park['id'] ?? ''; $context['fields']['investment_regime'] = $park['fields']['investment_regime'] ?? 'general'; $context['opportunity_choices'] = [$choice]; $context['requirements_assessment']['requirements'] = array_values(array_filter($context['requirements_assessment']['requirements'] ?? [], fn ($r) => $r['opportunity_key'] === $key)); $context['consumer_opportunity'] = $choice; $context['complements'] = array_values(array_filter($context['complements'] ?? [], fn ($c) => ($c['origin']['key'] ?? null) === $key || ($c['target']['key'] ?? null) === $key || in_array(substr($c['origin']['key'] ?? '', 10), array_column($choice['portfolio_origins'] ?? [], 'id'), true))); $context['dependency_hash'] = app(InvestorContext::class)->dependencyHash(['opportunity_choices' => [$choice], 'fields' => Arr::except($context['fields'], ['project_title', 'project_summary']), 'complements' => $context['complements']]); return $context; } /** * @param array $payload * @return array */ public function bind(User $actor, string $id, array $payload, bool $required = false): array { $case = app(VirtualDesk::class)->case($actor, $id, true); $context = app(InvestorContext::class)->state($case); $scoped = $this->context($context, $payload['context_opportunity'] ?? null); $choice = $scoped['consumer_opportunity'] ?? null; abort_if($required && count($context['opportunity_choices'] ?? []) > 1 && ! $choice, 422, 'Escolha a oportunidade em tratamento antes de submeter.'); if (! $choice) { return Arr::except($payload, ['context_opportunity', 'context_opportunity_snapshot']); } // Canonical server snapshot; client text cannot establish a different origin or territory. $payload['context_opportunity'] = $choice['opportunity']['key']; $payload['context_opportunity_snapshot'] = json_encode(['context_id' => $id, 'revision' => $context['revision'], 'choice' => $choice, 'requirements' => $scoped['requirements_assessment'] ?? null], JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE); return $payload; } }