diff --git a/server.js b/server.js index db573ef..d298e3c 100644 --- a/server.js +++ b/server.js @@ -3808,7 +3808,53 @@ app.get("/statuses", authMiddleware, async (req, res) => { } catch (e) { res.status(500).json({ ok: false }); } }); -app.get("/clients/search", authMiddleware, async (req, res) => { try { const { phone } = req.query; const p = normalizePhone(phone); if(!p) return res.json({ok:true,client:null}); const q = await pool.query("SELECT * FROM clients WHERE phone=$1 AND owner_id=$2 LIMIT 1", [p, req.user.accountId]); res.json({ ok: true, client: q.rows[0] || null }); } catch (e) { res.status(500).json({ ok: false }); } }); +// 🩹 FIX: antes SOLO buscaba en la tabla "clients" y exigía coincidencia EXACTA con el +// formato de teléfono "+34XXXXXXXXX". Muchos clientes reales nunca llegan a crearse en esa +// tabla (solo tienen presupuestos o servicios previos), o quedan guardados con otro formato +// de teléfono (p.ej. sin el "+"), así que la búsqueda fallaba aunque el cliente "ya existiera". +// Ahora comparamos solo los dígitos del teléfono (sea cual sea el formato guardado) y, si no +// se encuentra en "clients", buscamos también en sus presupuestos y servicios anteriores, +// sea cual sea su estado. +app.get("/clients/search", authMiddleware, async (req, res) => { + try { + const { phone } = req.query; + const bare = extractValidPhone(phone); + if (!bare) return res.json({ ok: true, client: null }); + const ownerId = req.user.accountId; + + const q = await pool.query( + `SELECT * FROM clients WHERE owner_id=$1 AND regexp_replace(phone, '\\D', '', 'g') LIKE '%' || $2 || '%' ORDER BY id DESC LIMIT 1`, + [ownerId, bare] + ); + if (q.rowCount > 0) return res.json({ ok: true, client: q.rows[0] }); + + const bq = await pool.query( + `SELECT client_name, client_phone, client_address FROM budgets + WHERE owner_id=$1 AND regexp_replace(COALESCE(client_phone,''), '\\D', '', 'g') LIKE '%' || $2 || '%' + ORDER BY created_at DESC LIMIT 1`, + [ownerId, bare] + ); + if (bq.rowCount > 0) { + const b = bq.rows[0]; + return res.json({ ok: true, client: { full_name: b.client_name, phone: b.client_phone, addresses: [b.client_address].filter(Boolean) } }); + } + + const sq = await pool.query( + `SELECT raw_data FROM scraped_services + WHERE owner_id=$1 AND regexp_replace(COALESCE(raw_data->>'Teléfono', raw_data->>'TELEFONO', raw_data->>'TELEFONOS', ''), '\\D', '', 'g') LIKE '%' || $2 || '%' + ORDER BY created_at DESC LIMIT 1`, + [ownerId, bare] + ); + if (sq.rowCount > 0) { + const raw = sq.rows[0].raw_data || {}; + const name = raw['Nombre Cliente'] || raw['NOMBRE'] || raw['Nombre'] || ''; + const addr = raw['Dirección'] || raw['DIRECCION'] || raw['Direccion'] || ''; + return res.json({ ok: true, client: { full_name: name, phone, addresses: [addr].filter(Boolean) } }); + } + + res.json({ ok: true, client: null }); + } catch (e) { res.status(500).json({ ok: false }); } +}); // --- ENDPOINT PARA GENERAR ENLACE AL PORTAL DEL CLIENTE DESDE LA APP --- app.post('/clients/ensure', authMiddleware, async (req, res) => {