Files
clube67_newwhats.local/base-scoreodonto/playwright-engine/lancar-guia-odonto.js
T
VPS 4 Deploy Agent 5ec6bd6354
continuous-integration/webhook Falha no deploy de clube67_newwhats.local (VPS 4)
chore(ops): migrate clube67 to newwhats.clube67.com directory
2026-05-18 03:26:41 +02:00

222 lines
10 KiB
JavaScript

const { chromium } = require('playwright');
const fs = require('fs');
(async () => {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
});
const page = await context.newPage();
try {
console.log('🚀 Iniciando Automação de Guia Odontológica...');
// LOGIN
await page.goto('https://viventerisportalcredenciado.topsaudehub.com.br/', { waitUntil: 'networkidle' });
await page.fill('#usuario', '0005010');
await page.fill('#senha', 'Cclinic#03');
await page.click('#login-submit');
await page.waitForURL('**/AreaLogada**');
// 1. Tratamento Odontológico
console.log('1. Acessando Tratamento Odontológico...');
await page.click('text="Tratamento Odontológico"');
await page.waitForTimeout(2000);
// 2. Lupa de pesquisa
console.log('2. Clicando na pesquisa (lupa)...');
// Tentativa de achar o botão de busca que abre o modal de beneficiário
const searchBtn = page.locator('.fa-search, .glyphicon-search, button[title*="Pesquisar"]').first();
await searchBtn.click();
await page.waitForTimeout(1000);
// 3. CPF do Beneficiário
console.log('3. Inserindo CPF: 005.983.051-49...');
// Esperar o campo ficar visível no modal
const cpfInput = page.locator('input[id*="cpf"], input[name*="cpf"], .cpf-mask').first();
await cpfInput.fill('005.983.051-49');
// 4. Pesquisar
console.log('4. Clicando em Pesquisar...');
await page.click('button:has-text("Pesquisar"), #btnPesquisarBeneficiario');
await page.waitForTimeout(2000);
// 5. Clica na coluna número beneficiário
console.log('5. Selecionando beneficiário resultado...');
// Espera especificamente por um link que pareça um número de cartão ou nome
const linkBeneficiario = page.locator('table tbody tr td a').first();
await linkBeneficiario.waitFor({ state: 'visible', timeout: 5000 });
await linkBeneficiario.click();
await page.waitForTimeout(2000); // Espera carregar os dados dele
// 6. Botão +
console.log('6. Clicando em Adicionar (+)...');
// O botão + muitas vezes só aparece após selecionar o beneficiário
const btnMais = page.locator('.fa-plus, .btn-success, #btnNovoRegistro, a:has-text("Novo"), button:has-text("+")').first();
await btnMais.waitFor({ state: 'visible', timeout: 5000 });
await btnMais.click();
await page.waitForTimeout(2000);
// 7. Dropdown tipo atendimento
console.log('7. Selecionando Tipo de Atendimento...');
await page.waitForTimeout(2000);
// Verifica se existe um select de endereço primeiro
const enderecoSelect = page.locator('select[id*="endereco"], select[name*="endereco"]').first();
if (await enderecoSelect.count() > 0) {
console.log('Selecionando endereço de atendimento...');
await enderecoSelect.selectOption({ index: 1 });
await page.waitForTimeout(1000);
}
// Tenta encontrar o select de tipo de atendimento especificamente
const selectTipo = page.locator('select[id*="tipo_solicitacao"], select[id*="tipoAtendimento"], select:has-text("Tratamento")').first();
await selectTipo.waitFor({ state: 'visible', timeout: 5000 }).catch(() => console.log('Aviso: Select de tipo não visível ainda.'));
const options = await selectTipo.evaluate(sel => Array.from(sel.options).map(o => o.text)).catch(() => []);
console.log('Opções no select de tipo:', options);
try {
await selectTipo.selectOption({ label: /Tratamento Odontológico/i });
} catch (e) {
console.log('Tentando selecionar pelo índice 1...');
await selectTipo.selectOption({ index: 1 });
}
// 8 e 9. Lupa Profissional Executante
console.log('8. Selecionando Profissional Executante...');
await page.waitForTimeout(2000);
// Agora temos o ID exato do botão!
const btnBuscaProf = page.locator('#btnBuscaPrestadorExecutante').first();
await btnBuscaProf.waitFor({ state: 'visible', timeout: 5000 });
await btnBuscaProf.click();
await page.waitForTimeout(2000);
// Clica no profissional na tabela
console.log('Selecionando o primeiro profissional da lista...');
const linkProf = page.locator('table tbody tr td a').first();
if (await linkProf.count() > 0) {
await linkProf.click();
} else {
console.log('⚠️ Nenhum profissional encontrado na tabela. Aguardando instrução.');
return; // PARA e aguarda
}
await page.waitForTimeout(1000);
// 10. Profissional Solicitante
console.log('10. Preenchendo Solicitante: Murilo...');
const solicitanteInput = page.locator('input[id*="solicitante"], input[name*="Solicitante"]').first();
if (await solicitanteInput.count() === 0) {
console.log('⚠️ Campo "Profissional Solicitante" não encontrado. Aguardando instrução.');
return;
}
await solicitanteInput.waitFor({ state: 'visible', timeout: 5000 });
await solicitanteInput.clear();
await solicitanteInput.fill('Murilo');
// 11. Justificativa (APENAS se for urgência - Valor 4)
const tipoAtendimentoValue = await page.locator('#tipoAtendimento').inputValue();
if (tipoAtendimentoValue === '4') {
console.log('Detectado Urgência / Emergência. Preenchendo Justificativa...');
await page.fill('#observacaoJustificativa', 'Paciente com dor aguda, necessidade de atendimento de urgência.');
} else {
console.log('Tipo de atendimento normal. Pulando justificativa.');
}
// 12. Próximo
console.log('12. Clicando em Próximo...');
await page.click('button:has-text("Próximo"), #btnProximo');
await page.waitForTimeout(2000);
// 13. Incluir
console.log('13. Clicando em Incluir...');
await page.click('#adicionarProcedimeto');
await page.waitForTimeout(2000);
// EXTRAÇÃO DE CÓDIGOS (Como solicitado pelo usuário na primeira vez)
console.log('🔍 Extraindo lista de procedimentos disponíveis...');
const procedimentos = await page.evaluate(() => {
const items = Array.from(document.querySelectorAll('input[id*="procedimento"], select[id*="procedimento"], .lista-procedimentos td'));
// Tenta pegar de um select se houver
const sel = document.querySelector('select[id*="procedimento"]');
if (sel) return Array.from(sel.options).map(o => `${o.value} - ${o.text}`);
return items.map(i => i.innerText || i.value).filter(t => t && t.length > 5);
});
if (procedimentos.length > 0) {
fs.writeFileSync('procedimentos_encontrados.txt', procedimentos.join('\n'));
console.log('✅ Lista de procedimentos salva em procedimentos_encontrados.txt');
}
// 15, 16 e 17. Dados do Tratamento
console.log('15. Lançando procedimento 85100196...');
const procInput = page.locator('#codProcedimento').first();
await procInput.waitFor({ state: 'visible', timeout: 10000 });
await procInput.fill('85100196');
// Espera e clica no item do autocomplete
console.log('Selecionando item no autocomplete...');
const autocompleteItem = page.locator('.ui-menu-item-wrapper:has-text("85100196")').first();
await autocompleteItem.waitFor({ state: 'visible', timeout: 5000 });
await autocompleteItem.click();
await page.waitForTimeout(2000);
console.log('16. Selecionando Dente 18...');
const selectDente = page.locator('#cmbDente').first();
await selectDente.waitFor({ state: 'visible', timeout: 5000 });
await selectDente.selectOption('18');
await page.waitForTimeout(1000);
// Selecionar a checkbox da Face "V"
console.log('17. Selecionando Face V...');
const checkV = page.locator('#codFaceV').first();
await checkV.waitFor({ state: 'visible', timeout: 5000 });
// Tenta clicar forçado no input ou clica na label (que é o que o usuário vê)
try {
await checkV.check({ force: true });
} catch (e) {
await page.click('label[for="codFaceV"]');
}
// 18. Incluir procedimento (Botão Incluir dentro do modal)
console.log('18. Incluindo procedimento na lista...');
await page.click('#btnIncluirProcedimento');
await page.waitForTimeout(2000);
// Se houver um botão de fechar/salvar o popup geral (como o btnSalvarPopUP que vimos antes)
const btnFechar = page.locator('#btnSalvarPopUP').first();
if (await btnFechar.isVisible()) {
console.log('Fechando popup de procedimentos...');
await btnFechar.click();
await page.waitForTimeout(1000);
}
// 19. Finalizar
console.log('19. Finalizando guia...');
await page.click('button:has-text("Próximo")');
await page.waitForTimeout(1000);
await page.click('button:has-text("Próximo"), #btnFinalizar');
// 20. Captura de GTO
console.log('20. Capturando resultado da GTO...');
await page.waitForTimeout(3000);
const resultadoHTML = await page.content();
const gtoMatch = resultadoHTML.match(/\d{8,12}/); // Tenta achar um número longo que seria a GTO
const status = resultadoHTML.includes('Autorizado') ? 'AUTORIZADO' : 'VERIFICAR STATUS';
console.log(`--- RESULTADO --- GTO: ${gtoMatch ? gtoMatch[0] : 'Não localizada'} | STATUS: ${status}`);
} catch (error) {
console.error('❌ Erro na automação:', error.message);
await page.screenshot({ path: 'erro-guia-odonto.png' });
} finally {
console.log('Processo interrompido para análise. O navegador ficará aberto por 60s.');
await page.waitForTimeout(60000);
await browser.close();
}
})();