File manager - Edit - /var/www/html/portalHomolog/database/seeders/ProjetosProgramasMigrationInteractiveSeeder.php
Back
<?php namespace Database\Seeders; use Illuminate\Database\Seeder; use App\Models\ProjetosProgramas\{Tipo, Classificacao, Etapa, Prazo, Fonte, Eixo, Area, Ods, ProjetoPrograma}; use App\Models\Structure; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; use Carbon\Carbon; /** * Seeder interativa para migração de Projetos e Programas com mapeamento de órgãos. * * Esta seeder: * - NÃO cria novos órgãos * - Usa mapeamento do config/legacy_orgaos_mapping.php * - Tenta encontrar órgãos existentes por sigla/nome * - Pergunta interativamente qual secretaria atribuir quando não encontrar * - Salva novos mapeamentos no config para reutilização * * Execute: php artisan db:seed --class=ProjetosProgramasMigrationInteractiveSeeder */ class ProjetosProgramasMigrationInteractiveSeeder extends Seeder { private array $orgaoMap = []; private array $stats = [ 'total' => 0, 'migrated' => 0, 'skipped' => 0, 'errors' => 0, ]; private array $novosMapeamentos = []; public function run(): void { $this->command->info('==========================================='); $this->command->info('Migração Interativa de Projetos e Programas'); $this->command->info('==========================================='); $this->command->info('Esta seeder NÃO criará novos órgãos.'); $this->command->info('Você será perguntado sobre órgãos não mapeados.'); $this->command->info(''); // Etapa 1: Criar dados básicos (tipos, classificações, etapas, etc.) $this->seedDadosBasicos(); // Etapa 2: Mapear órgãos do CSV legado (interativo) $this->mapOrgaosInterativo(); // Etapa 3: Limpar dados existentes (opcional) if ($this->command->confirm('Deseja limpar projetos existentes antes da migração?', false)) { $this->cleanExistingData(); } // Etapa 4: Migrar projetos do CSV legado $this->migrateProjects(); // Etapa 5: Salvar novos mapeamentos $this->salvarNovosMapeamentos(); // Etapa 6: Mostrar estatísticas $this->showStatistics(); } /** * Etapa 1: Cria os dados básicos do módulo */ private function seedDadosBasicos(): void { $this->command->info(''); $this->command->info('Criando dados básicos do módulo...'); // Tipos foreach (['Projeto', 'Programa', 'Projeto Estruturante', 'Ação/Iniciativa/Atividade'] as $v) { Tipo::firstOrCreate(['nome' => $v]); } // Classificações foreach (['Estratégico/Prioritário', 'Estruturante', 'Modernização/Inovação', 'Setoriais'] as $v) { Classificacao::firstOrCreate(['nome' => $v]); } // Etapas foreach (['Iniciação', 'Planejamento', 'Processo Licitatório', 'Execução', 'Monitoramento e Controle', 'Encerramento'] as $v) { Etapa::firstOrCreate(['nome' => $v]); } // Prazos foreach (['100 dias', '1 ano', '4 anos'] as $v) { Prazo::firstOrCreate(['nome' => $v]); } // Fontes foreach ([ 'Recurso Próprio', 'Convênio', 'Parceria Público Privada', 'Emenda Parlamentar', 'Fundo', 'Transferência Voluntária', 'Banco de Projetos', 'Outro' ] as $v) { Fonte::firstOrCreate(['nome' => $v]); } // Eixos e Áreas $eixos = [ 1 => 'Gestão pública eficiente', 2 => 'Angra, cidade com desenvolvimento e oportunidade', 3 => 'Angra, cidade acolhedora e saudável', 4 => 'Angra, cidade moderna e do conhecimento', 5 => 'Angra, cidade sustentável', 6 => 'Angra, cidade pacífica e segura', ]; $areas = [ 1 => ['Gestão pública', 'Infraestrutura e parcerias de investimento'], 2 => ['Desenvolvimento econômico e geração de emprego', 'Cultura', 'Turismo e eventos'], 3 => ['Saúde', 'Esporte e lazer', 'Desenvolvimento social e promoção da cidadania', 'Juventude e terceira idade'], 4 => ['Educação', 'Modernização e inovação'], 5 => ['Planejamento urbano, habitação e defesa civil', 'Mobilidade urbana e acessibilidade', 'Meio ambiente', 'Saneamento básico e ambiental'], 6 => ['Segurança pública'], ]; $mapEixos = []; foreach ($eixos as $code => $nome) { $eixo = Eixo::firstOrCreate(['nome' => $nome]); $mapEixos[$code] = $eixo->id; } foreach ($areas as $eixoCode => $lista) { foreach ($lista as $nomeArea) { Area::firstOrCreate([ 'eixo_id' => $mapEixos[$eixoCode], 'nome' => $nomeArea ]); } } // ODS (1 a 17) foreach (range(1, 17) as $i) { Ods::firstOrCreate(['codigo' => str_pad($i, 2, '0', STR_PAD_LEFT)]); } $this->command->info('✓ Dados básicos criados com sucesso'); } /** * Etapa 2: Mapeia órgãos do CSV legado de forma interativa */ private function mapOrgaosInterativo(): void { $this->command->info(''); $this->command->info('Mapeando órgãos do CSV legado...'); $csvPath = base_path('Orgaos.csv'); if (!file_exists($csvPath)) { $this->command->warn("Arquivo de órgãos não encontrado: {$csvPath}"); $this->command->warn("Continuando sem mapeamento de órgãos..."); return; } // Carregar mapeamento existente do config $configMapping = config('legacy_orgaos_mapping.orgao_mapping', []); $handle = fopen($csvPath, 'r'); if (!$handle) { $this->command->error("Não foi possível abrir o arquivo: {$csvPath}"); return; } // Read header $header = fgetcsv($handle); if (!$header) { $this->command->error("Arquivo CSV vazio ou inválido"); fclose($handle); return; } // Remove BOM if present $header[0] = preg_replace('/^\x{FEFF}/u', '', $header[0]); $mapeados = 0; $naoEncontrados = 0; $total = 0; while (($row = fgetcsv($handle)) !== false) { if (count($row) < count($header)) { continue; } $data = array_combine($header, $row); $idOrg = trim($data['id_org'] ?? ''); $sigla = trim($data['org_sigla'] ?? ''); $nome = trim($data['org_nome'] ?? ''); if (empty($idOrg) || empty($sigla) || empty($nome)) { continue; } $total++; // Verificar se já existe mapeamento no config if (isset($configMapping[$idOrg])) { $structureId = $configMapping[$idOrg]; $structure = Structure::find($structureId); if ($structure) { $this->orgaoMap[$idOrg] = $structureId; $mapeados++; continue; } else { $this->command->warn("⚠ Mapeamento do config aponta para structure inexistente: {$idOrg} -> {$structureId}"); } } // Tentar encontrar por sigla $structure = Structure::where('abbreviation', $sigla)->first(); // Se não encontrou por sigla, tentar por nome (busca parcial) if (!$structure) { $structure = Structure::where('name', 'like', "%{$nome}%") ->orWhere('name', 'like', "%{$sigla}%") ->first(); } // Se ainda não encontrou, perguntar ao usuário if (!$structure) { $structureId = $this->perguntarOrgao($idOrg, $sigla, $nome); if ($structureId) { $this->orgaoMap[$idOrg] = $structureId; $this->novosMapeamentos[$idOrg] = $structureId; $mapeados++; } else { $naoEncontrados++; $this->command->warn(" ⚠ Órgão não mapeado: {$sigla} - {$nome} (ID legado: {$idOrg})"); } } else { $this->orgaoMap[$idOrg] = $structure->id; $mapeados++; } } fclose($handle); // Store mapping in cache cache()->put('legacy_orgao_map', $this->orgaoMap, now()->addHours(24)); $this->command->info(''); $this->command->info("✓ Mapeamento de órgãos concluído!"); $this->command->info(" Total processados: {$total}"); $this->command->info(" Mapeados: {$mapeados}"); $this->command->info(" Não encontrados: {$naoEncontrados}"); if (!empty($this->novosMapeamentos)) { $this->command->info(" Novos mapeamentos: " . count($this->novosMapeamentos)); } } /** * Pergunta ao usuário qual structure atribuir a um órgão legado */ private function perguntarOrgao(string $idOrg, string $sigla, string $nome): ?string { $this->command->info(''); $this->command->warn("═══════════════════════════════════════════════════════"); $this->command->warn("ÓRGÃO NÃO ENCONTRADO NO SISTEMA"); $this->command->warn("═══════════════════════════════════════════════════════"); $this->command->info("ID Legado: {$idOrg}"); $this->command->info("Sigla: {$sigla}"); $this->command->info("Nome: {$nome}"); $this->command->info(''); // Buscar structures disponíveis $structures = Structure::where('status', 'ATIVADO') ->orderBy('name', 'asc') ->get(); if ($structures->isEmpty()) { $this->command->error("Nenhuma structure ativa encontrada no sistema!"); return null; } // Mostrar opções $this->command->info("Structures disponíveis:"); $options = []; $index = 1; foreach ($structures as $structure) { $display = "{$structure->name}"; if ($structure->abbreviation) { $display .= " ({$structure->abbreviation})"; } $display .= " [{$structure->type}]"; $options[$index] = $structure->id; $this->command->info(" [{$index}] {$display}"); $index++; } $this->command->info(''); $this->command->info(" [0] Pular este órgão (usar PMAR como padrão)"); $this->command->info(" [s] Buscar por sigla/nome"); $resposta = $this->command->ask("Qual structure deseja atribuir a '{$sigla} - {$nome}'?"); // Buscar por sigla/nome if (strtolower($resposta) === 's') { $termo = $this->command->ask("Digite a sigla ou nome para buscar:"); $encontradas = Structure::where('status', 'ATIVADO') ->where(function ($query) use ($termo) { $query->where('abbreviation', 'like', "%{$termo}%") ->orWhere('name', 'like', "%{$termo}%"); }) ->orderBy('name', 'asc') ->get(); if ($encontradas->isEmpty()) { $this->command->warn("Nenhuma structure encontrada com o termo '{$termo}'"); return $this->perguntarOrgao($idOrg, $sigla, $nome); // Recursivo } $this->command->info(''); $this->command->info("Structures encontradas:"); $options = []; $index = 1; foreach ($encontradas as $structure) { $display = "{$structure->name}"; if ($structure->abbreviation) { $display .= " ({$structure->abbreviation})"; } $display .= " [{$structure->type}]"; $options[$index] = $structure->id; $this->command->info(" [{$index}] {$display}"); $index++; } $this->command->info(''); $resposta = $this->command->ask("Escolha uma opção:"); } // Pular (usar PMAR) if ($resposta === '0' || empty($resposta)) { $pmarId = Structure::where('abbreviation', 'PMAR')->value('id'); if (!$pmarId) { $pmarId = config('legacy_orgaos_mapping.default_orgao_id'); } if ($pmarId) { $this->command->info(" → Usando PMAR como padrão"); return $pmarId; } return null; } // Selecionar por índice $escolha = (int) $resposta; if (isset($options[$escolha])) { $structureId = $options[$escolha]; $structure = Structure::find($structureId); if ($structure) { $this->command->info(" → Mapeado para: {$structure->name}"); return $structureId; } } $this->command->error("Opção inválida!"); return $this->perguntarOrgao($idOrg, $sigla, $nome); // Recursivo } /** * Limpa dados existentes de projetos */ private function cleanExistingData(): void { $this->command->info(''); $this->command->info('Limpando dados de teste existentes...'); DB::beginTransaction(); try { DB::table('project_program_ods')->delete(); DB::table('project_program_orgaos')->delete(); DB::table('project_program_attachments')->delete(); $projectCount = DB::table('projects_programs')->count(); DB::table('projects_programs')->delete(); DB::commit(); $this->command->info("✓ Removidos {$projectCount} projetos"); $this->command->info("✓ Relacionamentos limpos"); } catch (\Exception $e) { DB::rollBack(); $this->command->error("Erro ao limpar dados: " . $e->getMessage()); throw $e; } } /** * Etapa 4: Migra projetos do CSV legado */ private function migrateProjects(): void { $this->command->info(''); $this->command->info('Migrando projetos do CSV...'); $csvPath = base_path('Projetos.csv'); if (!file_exists($csvPath)) { $this->command->warn("Arquivo de projetos não encontrado: {$csvPath}"); return; } $handle = fopen($csvPath, 'r'); if (!$handle) { $this->command->error("Não foi possível abrir o arquivo: {$csvPath}"); return; } $header = fgetcsv($handle); if (!$header) { $this->command->error("Arquivo CSV vazio ou inválido"); fclose($handle); return; } $header[0] = preg_replace('/^\x{FEFF}/u', '', $header[0]); $lineNumber = 1; $progressBar = $this->command->getOutput()->createProgressBar(); $progressBar->start(); while (($row = fgetcsv($handle)) !== false) { $lineNumber++; $this->stats['total']++; if (count($row) < count($header)) { $this->stats['skipped']++; $progressBar->advance(); continue; } $data = array_combine($header, $row); try { $this->migrateProject($data); $this->stats['migrated']++; } catch (\Exception $e) { $this->stats['errors']++; $this->command->error("\nErro na linha {$lineNumber}: " . $e->getMessage()); } $progressBar->advance(); } $progressBar->finish(); $this->command->info(''); fclose($handle); } /** * Migra um projeto individual */ private function migrateProject(array $data): void { DB::beginTransaction(); try { // Map gestor (órgão) $gestorId = null; if (!empty($data['pro_dimen_orgao'])) { $gestorId = $this->orgaoMap[$data['pro_dimen_orgao']] ?? null; } // Se não encontrou gestor, usar PMAR if (!$gestorId) { $pmarId = Structure::where('abbreviation', 'PMAR')->value('id'); if (!$pmarId) { $pmarId = config('legacy_orgaos_mapping.default_orgao_id'); } $gestorId = $pmarId; } // Parse dates $dataInicio = $this->parseDate($data['pro_crono_inicio']); if (!$dataInicio) { $dataInicio = '2022-01-01'; } $dataTermino = $this->parseDate($data['pro_crono_fim']); // Build observacoes $observacoes = $this->cleanText($data['pro_dados_obs'] ?? ''); $extraInfo = []; if (!empty($data['pro_dados_status_outro'])) { $extraInfo[] = "Status: " . $data['pro_dados_status_outro']; } if (!empty($data['pro_dados_dificuldades_outro'])) { $extraInfo[] = "Dificuldades: " . $data['pro_dados_dificuldades_outro']; } if (!empty($extraInfo)) { $observacoes = trim(($observacoes ? $observacoes . "\n\n" : '') . implode("\n", $extraInfo)); } // Build relacao_ppa $relacaoPpa = $this->cleanText($data['pro_dimen_acao'] ?? ''); if (!empty($data['pro_inves_horizonte'])) { $relacaoPpa = trim(($relacaoPpa ? $relacaoPpa . "\n" : '') . "Horizonte: " . $data['pro_inves_horizonte']); } if (!empty($data['pro_inves_relacao'])) { $relacaoPpa = trim(($relacaoPpa ? $relacaoPpa . "\n" : '') . "Relação: " . $data['pro_inves_relacao']); } // Create project $project = ProjetoPrograma::create([ 'denominacao' => $this->cleanText($data['pro_dimen_denominacao']) ?? 'Sem denominação', 'num_processo_adm' => $this->cleanText($data['pro_dimen_numprocessoadm']), 'gestor_structure_id' => $gestorId, 'tipo_id' => $this->mapTipo($data['pro_dimen_tipo']), 'programa_ppa' => $this->cleanText($data['pro_dimen_programa']), 'endereco' => $this->cleanText($data['pro_dimen_endereco']), 'bairro' => $this->cleanText($data['pro_dimen_bairro']), 'data_inicio' => $dataInicio, 'data_termino' => $dataTermino, 'prazo_id' => $this->mapPrazo($data['pro_crono_prazo_entrega']), 'codigo' => $this->cleanText($data['pro_dimen_codigo']), 'acompanhamento_governo' => $this->parseBoolean($data['pro_dimen_acompanhamento'] ?? 0), 'classificacao_id' => $this->mapClassificacao($data['pro_dimen_classificacao']), 'etapa_id' => $this->mapEtapa($data['pro_dimen_etapa']), 'relacao_ppa' => $relacaoPpa, 'eixo_id' => $this->mapEixo($data['pro_eixo'] ?? ''), 'area_id' => $this->mapArea($data['pro_area'] ?? ''), 'contato_nome' => $this->cleanText($data['pro_contato_nome']), 'contato_matricula' => $this->cleanText($data['pro_contato_matricula']), 'contato_ramal' => $this->cleanText($data['pro_contato_ramal']), 'contato_telefone' => $this->cleanText($data['pro_contato_telefone']), 'contato_email' => $this->cleanText($data['pro_contato_email']), 'descricao_objeto' => $this->cleanText($data['pro_dados_objeto']), 'justificativa' => $this->cleanText($data['pro_dados_justificativa']), 'descricao_responsabilidades' => $this->cleanText($data['pro_dados_responsabilidades']), 'status_id' => $this->mapStatus($data['pro_dados_status']), 'dificuldade_id' => $this->mapDificuldade($data['pro_dados_dificuldades']), 'gargalos' => $this->cleanText($data['pro_dados_gargalos']), 'observacoes' => $observacoes, 'fonte_id' => $this->mapFonte($data['pro_inves_fonte']), 'fonte_outro' => $this->cleanText($data['pro_inves_fonte_outro']), 'custo_total' => $this->parseDecimal($data['pro_inves_custototal']) ?? 0, 'custeio_anual' => $this->parseDecimal($data['pro_inves_custoanual']) ?? 0, 'ppa_2022' => $this->parseDecimal($data['pro_inves_previsto1']) ?? 0, 'ppa_2023' => $this->parseDecimal($data['pro_inves_previsto2']) ?? 0, 'ppa_2024' => $this->parseDecimal($data['pro_inves_previsto3']) ?? 0, 'ppa_2025' => $this->parseDecimal($data['pro_inves_previsto4']) ?? 0, 'loa_2022' => $this->parseDecimal($data['pro_inves_loa1']) ?? 0, 'loa_2023' => $this->parseDecimal($data['pro_inves_loa2']) ?? 0, 'loa_2024' => $this->parseDecimal($data['pro_inves_loa3']) ?? 0, 'loa_2025' => $this->parseDecimal($data['pro_inves_loa4']) ?? 0, 'manutencao_2022' => $this->parseDecimal($data['pro_inves_manutencao1']) ?? 0, 'manutencao_2023' => $this->parseDecimal($data['pro_inves_manutencao2']) ?? 0, 'manutencao_2024' => $this->parseDecimal($data['pro_inves_manutencao3']) ?? 0, 'manutencao_2025' => $this->parseDecimal($data['pro_inves_manutencao4']) ?? 0, 'conve_orgao' => $this->cleanText($data['pro_conve_orgao']), 'conve_orgao_outro' => $this->cleanText($data['pro_conve_orgao_outro']), 'conve_proposta' => $this->cleanText($data['pro_conve_proposta']), 'conve_convenio' => $this->cleanText($data['pro_conve_convenio']), 'status_registro' => 'COMPLETO', 'identificacao_done' => true, 'cronograma_done' => true, 'areas_done' => true, 'contato_done' => true, 'dados_done' => true, 'investimento_done' => true, ]); // Attach ODS $odsIds = $this->parseOdsColumns($data); if (!empty($odsIds)) { $odsRecords = Ods::whereIn('codigo', array_map(function ($id) { return str_pad($id, 2, '0', STR_PAD_LEFT); }, $odsIds))->pluck('id')->toArray(); if (!empty($odsRecords)) { $project->ods()->attach($odsRecords); } } // Attach orgaos envolvidos $orgaosEnvolvidosIds = $this->parseCommaSeparatedIds($data['pro_dados_orgaos_envolvidos'] ?? ''); $structureIds = []; foreach ($orgaosEnvolvidosIds as $orgaoId) { if (isset($this->orgaoMap[$orgaoId])) { $structureIds[] = $this->orgaoMap[$orgaoId]; } } if (!empty($structureIds)) { $project->orgaosEnvolvidos()->attach($structureIds); } DB::commit(); } catch (\Exception $e) { DB::rollBack(); throw $e; } } /** * Salva novos mapeamentos no arquivo de config */ private function salvarNovosMapeamentos(): void { if (empty($this->novosMapeamentos)) { return; } $this->command->info(''); $this->command->info('Novos mapeamentos criados durante a migração:'); foreach ($this->novosMapeamentos as $idOrg => $structureId) { $structure = Structure::find($structureId); $nome = $structure ? $structure->name : 'N/A'; $this->command->info(" '{$idOrg}' => '{$structureId}', // {$nome}"); } if ($this->command->confirm('Deseja salvar estes mapeamentos no arquivo de config?', true)) { $configPath = config_path('legacy_orgaos_mapping.php'); $configContent = file_get_contents($configPath); // Adicionar novos mapeamentos ao array $novosMapeamentosStr = "\n // Novos mapeamentos adicionados em " . now()->format('Y-m-d H:i:s') . "\n"; foreach ($this->novosMapeamentos as $idOrg => $structureId) { $structure = Structure::find($structureId); $comentario = $structure ? $structure->name : ''; $novosMapeamentosStr .= " '{$idOrg}' => '{$structureId}', // {$comentario}\n"; } // Inserir antes do fechamento do array $configContent = preg_replace( '/(\];)/', $novosMapeamentosStr . '$1', $configContent ); file_put_contents($configPath, $configContent); $this->command->info("✓ Mapeamentos salvos em {$configPath}"); } } /** * Mostra estatísticas da migração */ private function showStatistics(): void { $this->command->info(''); $this->command->info('==========================================='); $this->command->info('Estatísticas da Migração'); $this->command->info('==========================================='); $this->command->info("Total de linhas processadas: {$this->stats['total']}"); $this->command->info("Projetos migrados: {$this->stats['migrated']}"); $this->command->info("Linhas ignoradas: {$this->stats['skipped']}"); $this->command->info("Erros: {$this->stats['errors']}"); $this->command->info('==========================================='); } // ============================================ // Métodos auxiliares de mapeamento de dados // (mesmos da seeder original) // ============================================ private function cleanText(?string $text): ?string { if (empty($text)) { return null; } return trim($text); } private function parseDate(?string $date): ?string { if (empty($date)) { return null; } try { $formats = ['Y-m-d', 'd/m/Y', 'd-m-Y', 'Y/m/d']; foreach ($formats as $format) { $parsed = Carbon::createFromFormat($format, trim($date)); if ($parsed) { return $parsed->format('Y-m-d'); } } $parsed = Carbon::parse(trim($date)); return $parsed->format('Y-m-d'); } catch (\Exception $e) { return null; } } private function parseDecimal(?string $value): ?float { if (empty($value) || $value === null) { return null; } $cleaned = str_replace(['R$', '$', ' ', '€'], '', (string) $value); if (strpos($cleaned, ',') !== false) { $cleaned = str_replace('.', '', $cleaned); $cleaned = str_replace(',', '.', $cleaned); } $float = filter_var($cleaned, FILTER_VALIDATE_FLOAT); return $float !== false ? (float) $float : null; } private function parseBoolean($value): bool { if (is_bool($value)) { return $value; } if (is_numeric($value)) { return (bool) (int) $value; } if (is_string($value)) { $lower = strtolower(trim($value)); return in_array($lower, ['1', 'true', 'sim', 'yes', 's']); } return false; } private function mapTipo(?string $tipo): ?int { if (empty($tipo)) { return null; } $map = [ 'Projeto' => 1, 'Programa' => 2, 'Projeto Estruturante' => 3, 'Ação/Iniciativa/Atividade' => 4, ]; $tipo = trim($tipo); foreach ($map as $nome => $id) { if (stripos($tipo, $nome) !== false || stripos($nome, $tipo) !== false) { $tipoModel = Tipo::where('nome', $nome)->first(); return $tipoModel?->id; } } return null; } private function mapPrazo(?string $prazo): ?int { if (empty($prazo)) { return null; } $prazo = trim($prazo); $prazoModel = Prazo::where('nome', 'like', "%{$prazo}%")->first(); return $prazoModel?->id; } private function mapClassificacao(?string $classificacao): ?int { if (empty($classificacao)) { return null; } $classificacao = trim($classificacao); $classificacaoModel = Classificacao::where('nome', 'like', "%{$classificacao}%")->first(); return $classificacaoModel?->id; } private function mapEtapa(?string $etapa): ?int { if (empty($etapa)) { return null; } $etapa = trim($etapa); $etapaModel = Etapa::where('nome', 'like', "%{$etapa}%")->first(); return $etapaModel?->id; } private function mapStatus(?string $status): ?int { if (empty($status)) { return null; } $map = [ 'Sem proposta' => 1, 'Projeto Básico' => 2, 'Projeto Executivo' => 3, 'Licitando' => 4, 'Tramitando para Licitar' => 5, 'Outro' => 6, ]; $status = trim($status); foreach ($map as $nome => $id) { if (stripos($status, $nome) !== false || stripos($nome, $status) !== false) { return $id; } } return null; } private function mapDificuldade(?string $dificuldade): ?int { if (empty($dificuldade)) { return null; } $map = [ 'Elaboração da Proposta' => 1, 'Execução' => 2, 'Obter fonte de recursos' => 3, 'Tramitação interna PMAR' => 4, 'Elaboração de Material Técnico para Licitação' => 5, 'Outro' => 6, ]; $dificuldade = trim($dificuldade); foreach ($map as $nome => $id) { if (stripos($dificuldade, $nome) !== false || stripos($nome, $dificuldade) !== false) { return $id; } } return null; } private function mapFonte(?string $fonte): ?int { if (empty($fonte)) { return null; } $fonte = trim($fonte); $fonteModel = Fonte::where('nome', 'like', "%{$fonte}%")->first(); return $fonteModel?->id; } private function mapEixo(?string $eixoName): ?int { if (empty($eixoName)) { return null; } $eixos = [ 'Gestão pública eficiente' => 1, 'Angra, cidade com desenvolvimento e oportunidade' => 2, 'Angra, cidade acolhedora e saudável' => 3, 'Angra, cidade moderna e do conhecimento' => 4, 'Angra, cidade sustentável' => 5, 'Angra, cidade pacífica e segura' => 6, ]; if (isset($eixos[$eixoName])) { $eixoModel = Eixo::where('nome', $eixoName)->first(); return $eixoModel?->id; } if (is_numeric($eixoName)) { $num = (int) $eixoName; if ($num >= 1 && $num <= 6) { $eixoModel = Eixo::find($num); return $eixoModel?->id; } } $eixoModel = Eixo::where('nome', 'like', "%{$eixoName}%")->first(); return $eixoModel?->id; } private function mapArea(?string $areaName): ?int { if (empty($areaName)) { return null; } $areaName = trim($areaName); $areas = DB::table('project_program_areas')->get(); foreach ($areas as $area) { if (stripos($area->nome, $areaName) !== false || stripos($areaName, $area->nome) !== false) { return $area->id; } } return null; } private function parseOdsColumns(array $data): array { $odsIds = []; for ($i = 1; $i <= 17; $i++) { $columnName = 'pro_ods_' . str_pad($i, 2, '0', STR_PAD_LEFT); if (!empty($data[$columnName]) && $this->parseBoolean($data[$columnName])) { $odsIds[] = $i; } } return $odsIds; } private function parseCommaSeparatedIds(?string $ids): array { if (empty($ids)) { return []; } $ids = trim($ids); $idsArray = explode(',', $ids); return array_filter(array_map(function ($id) { $id = trim($id); return !empty($id) && is_numeric($id) ? (int) $id : null; }, $idsArray)); } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.28 | Generation time: 0.02 |
proxy
|
phpinfo
|
Settings