'Banca', 'credit' => 'Crédito e microfinanças', 'investment' => 'Gestão de investimento', 'pensions' => 'Fundos de pensões', 'insurance' => 'Seguros e resseguros', 'intermediation' => 'Mediação de seguros', 'exchange' => 'Câmbio', 'payments' => 'Pagamentos e serviços interbancários', 'supervision' => 'Supervisão', 'other' => 'Outras instituições']; public const TYPES = ['commercial_bank' => 'Banco comercial', 'investment_bank' => 'Banco de investimento', 'bank' => 'Banco (tipo não especificado)', 'microbank' => 'Microbanco', 'cooperative' => 'Cooperativa de crédito', 'savings' => 'Organização de poupança e empréstimo', 'investment_manager' => 'Gestora de fundos de investimento', 'investment_company' => 'Sociedade de investimento', 'pension_manager' => 'Gestora de fundos de pensões', 'insurer' => 'Seguradora', 'reinsurer' => 'Resseguradora', 'microinsurer' => 'Micro-seguradora', 'broker' => 'Corretora de seguros', 'agent' => 'Agente de seguros', 'reinsurance_broker' => 'Corretor de resseguro', 'exchange_house' => 'Casa de câmbio', 'electronic_money' => 'Instituição de moeda electrónica', 'interbank' => 'Serviços interbancários', 'supervisor' => 'Supervisor', 'other' => 'Outro tipo documentado']; /** @param array $input * @return array */ public function normalize(array $input): array { return Validator::make($input, [ 'institution_categories' => 'array|max:10', 'institution_categories.*' => ['required', 'distinct', Rule::in(array_keys(self::CATEGORIES))], 'institution_types' => 'array|max:10', 'institution_types.*' => ['required', 'distinct', Rule::in(array_keys(self::TYPES))], 'institution_services' => 'array|max:12', 'institution_services.*' => ['required', 'distinct', Rule::in(array_keys(FundingInstitutionDetails::NEEDS))], 'institution_status' => 'nullable|in:reported,historical,merged,unknown', 'successor_key' => 'nullable|string|max:100', 'register_reference' => 'nullable|string|max:2000', 'aliases' => 'array|max:100', 'aliases.*' => 'required|string|max:500', 'source_rows' => 'array|max:250', 'source_rows.*' => 'required|array:id,section,text', 'source_rows.*.id' => 'required|string|max:100', 'source_rows.*.section' => 'required|string|max:250', 'source_rows.*.text' => 'required|string|max:8000', ])->validate(); } /** @param array $filters */ public function filter(Builder $query, array $filters): void { foreach (['category' => 'institution_categories', 'institution_type' => 'institution_types'] as $key => $field) { if (! empty($filters[$key])) { $query->whereRaw('v.payload->? @> ?::jsonb', [$field, json_encode([$filters[$key]], JSON_THROW_ON_ERROR)]); } } if (empty($filters['include_historical'])) { $query->whereRaw("COALESCE(v.payload->>'institution_status','reported') NOT IN ('historical','merged')"); } if (($filters['location_mode'] ?? 'coverage') !== 'physical') { return; } $query->whereRaw("v.payload->>'kind'='institution'"); if (empty($filters['territory'])) { return; } $unknown = ($filters['certainty'] ?? 'include_unknown') === 'include_unknown'; $path = array_column(app(InvestmentGeography::class)->path($filters['territory']), 'id'); $clauses = ["l->'territory_path' @> ?::jsonb"]; $bindings = [json_encode([['id' => $filters['territory']]], JSON_THROW_ON_ERROR)]; if ($unknown) { foreach ($path as $id) { $clauses[] = "l->>'territory_id' = ?"; $bindings[] = $id; } } $status = $unknown ? '' : " AND COALESCE(l->>'evidence_status','reported') NOT IN ('to_confirm','historical','conflict','unlocated')"; $query->where(function (Builder $q) use ($clauses, $bindings, $status, $unknown): void { $q->whereRaw("EXISTS (SELECT 1 FROM jsonb_array_elements(COALESCE(v.payload->'locations','[]'::jsonb)) l WHERE (".implode(' OR ', $clauses).')'.$status.')', $bindings); if ($unknown) { $q->orWhereRaw("NOT EXISTS (SELECT 1 FROM jsonb_array_elements(COALESCE(v.payload->'locations','[]'::jsonb)) l WHERE NULLIF(l->>'territory_id','') IS NOT NULL)"); } }); } /** @param array $payload */ public function permitsUnknownProduct(array $payload, ?string $need): bool { return ! $need || ! isset($payload['institution_services']) || in_array($need, $payload['institution_services'], true); } }