diff --git a/backend/newwhats/agenda-bridge.js b/backend/newwhats/agenda-bridge.js index 04af2f0..bc8e48d 100644 --- a/backend/newwhats/agenda-bridge.js +++ b/backend/newwhats/agenda-bridge.js @@ -123,6 +123,44 @@ async function findConflict(db, dentistaId, start, end, excludeId = null) { return rows[0] || null; } +// ── Comunicação interna: janelas de horário permitido p/ contatar um número ────── +const toMin = (t) => { const [h, m] = String(t ?? '').split(':').map(Number); return (h || 0) * 60 + (m || 0); }; +// Retorna o 1º número contactável AGORA (dia/horário dentro de alguma janela) ou null. +function contatoPermitidoAgora(numeros, now = new Date()) { + const dow = now.getDay(); + const hm = now.getHours() * 60 + now.getMinutes(); + for (const n of (numeros || [])) { + const tel = String(n?.numero || '').replace(/\D/g, ''); + if (tel.length < 10) continue; + for (const j of (n.janelas || [])) { + if (!Array.isArray(j.dias) || !j.dias.includes(dow)) continue; + if (hm >= toMin(j.inicio) && hm <= toMin(j.fim)) return { numero: tel, descricao: n.descricao || null, situacoes: n.situacoes || null }; + } + } + return null; +} +// Próxima janela permitida (varre os próximos 7 dias) → "segunda-feira às 08:00" | null. +function proximaJanela(numeros, now = new Date()) { + const nowDow = now.getDay(); + const nowHm = now.getHours() * 60 + now.getMinutes(); + let best = null; // { offset, ini } + for (const n of (numeros || [])) { + if (String(n?.numero || '').replace(/\D/g, '').length < 10) continue; + for (const j of (n.janelas || [])) { + if (!Array.isArray(j.dias)) continue; + for (const d of j.dias) { + let offset = (d - nowDow + 7) % 7; + const ini = toMin(j.inicio); + if (offset === 0 && ini <= nowHm) offset = 7; // hoje já passou → próxima semana + if (!best || offset < best.offset || (offset === best.offset && ini < best.ini)) best = { offset, ini, dow: d, inicio: j.inicio }; + } + } + } + if (!best) return null; + const quando = best.offset === 0 ? 'hoje' : best.offset === 1 ? 'amanhã' : DIAS_NOME[best.dow]; + return `${quando} às ${best.inicio}`; +} + export function createAgendaBridge(pool) { const router = express.Router(); @@ -408,11 +446,26 @@ export function createAgendaBridge(pool) { if (req.query.dentista_id) { params.push(String(req.query.dentista_id)); where += ` AND id = $${params.length}`; } else if (req.query.nome) { params.push(String(req.query.nome)); where += ` AND lower(nome) LIKE '%'||lower($${params.length})||'%'`; } const { rows } = await pool.query( - `SELECT id, nome, telefone FROM dentistas WHERE ${where} AND ativo IS DISTINCT FROM 0 ORDER BY nome LIMIT 1`, params); + `SELECT id, nome, telefone, usuario_id FROM dentistas WHERE ${where} AND ativo IS DISTINCT FROM 0 ORDER BY nome LIMIT 1`, params); if (!rows.length) return res.json({ encontrado: false }); const d = rows[0]; - const tel = String(d.telefone || '').replace(/\D/g, ''); - res.json({ encontrado: true, dentista_id: d.id, nome: d.nome, telefone: tel || null }); + const legacyTel = String(d.telefone || '').replace(/\D/g, '') || null; + // Perfil de comunicação interna (múltiplos números + janelas de horário permitido). + let numeros = [], temPerfil = false; + if (d.usuario_id) { + const { rows: pc } = await pool.query('SELECT numeros FROM pessoa_comunicacao WHERE usuario_id=$1 AND clinica_id=$2', [d.usuario_id, clinicaId]); + if (pc[0]) { temPerfil = true; numeros = Array.isArray(pc[0].numeros) ? pc[0].numeros : []; } + } + // Sem perfil → back-compat: usa o telefone legado e NÃO bloqueia (não quebra dentistas antigos). + if (!temPerfil) { + return res.json({ encontrado: true, dentista_id: d.id, nome: d.nome, telefone: legacyTel, tem_perfil: false, + contato_agora: legacyTel ? { numero: legacyTel, descricao: null } : null, bloqueado_por_janela: false, proxima_janela: null }); + } + // Com perfil → só permite contato dentro de uma janela; senão devolve a próxima. + const agora = contatoPermitidoAgora(numeros); + res.json({ encontrado: true, dentista_id: d.id, nome: d.nome, tem_perfil: true, + telefone: agora ? agora.numero : null, contato_agora: agora, + bloqueado_por_janela: !agora, proxima_janela: agora ? null : proximaJanela(numeros) }); } catch (e) { res.status(500).json({ error: e.message }); } });