Añade endpoint /services/search para el nuevo buscador global de la App
Busca en TODO el histórico de la cuenta (cualquier técnico, cualquier estado: citado/anulado/finalizado), filtrando por fecha de expediente o de cita, texto libre y compañía, con paginación (limit/offset). Exige fecha o texto para no devolver la tabla entera.
This commit is contained in:
69
server.js
69
server.js
@@ -3682,6 +3682,75 @@ app.get("/services/active", authMiddleware, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ==========================================
|
||||
// 🔎 BUSCADOR GLOBAL (App): cualquier servicio de la empresa, cualquier estado, filtrando por fechas
|
||||
// ==========================================
|
||||
// A diferencia de /services/active (que para un operario solo enseña lo suyo, y solo lo archivado
|
||||
// de los últimos 15 días), este endpoint busca en TODO el histórico de la cuenta —cualquier técnico,
|
||||
// cualquier estado (citado, anulado, finalizado...)— pero exige un filtro (fecha o texto) para no
|
||||
// volcar la base de datos entera de golpe.
|
||||
app.get("/services/search", authMiddleware, async (req, res) => {
|
||||
try {
|
||||
const ownerId = req.user.accountId;
|
||||
const { q, date_field, date_from, date_to, company } = req.query;
|
||||
const limit = Math.min(parseInt(req.query.limit) || 30, 100);
|
||||
const offset = Math.max(parseInt(req.query.offset) || 0, 0);
|
||||
|
||||
const useCitaDate = date_field === 'scheduled_date';
|
||||
const conditions = ["s.owner_id = $1", "s.provider != 'SYSTEM_BLOCK'"];
|
||||
const params = [ownerId];
|
||||
let idx = 2;
|
||||
|
||||
if (useCitaDate) {
|
||||
if (date_from) { conditions.push(`(s.raw_data->>'scheduled_date') >= $${idx++}`); params.push(date_from); }
|
||||
if (date_to) { conditions.push(`(s.raw_data->>'scheduled_date') <= $${idx++}`); params.push(date_to); }
|
||||
} else {
|
||||
if (date_from) { conditions.push(`s.created_at >= $${idx++}::date`); params.push(date_from); }
|
||||
if (date_to) { conditions.push(`s.created_at < ($${idx++}::date + INTERVAL '1 day')`); params.push(date_to); }
|
||||
}
|
||||
|
||||
if (company) {
|
||||
conditions.push(`COALESCE(s.raw_data->>'Compañía', s.raw_data->>'COMPAÑIA', s.raw_data->>'Procedencia', '') ILIKE $${idx++}`);
|
||||
params.push(company);
|
||||
}
|
||||
|
||||
const hasDateRange = !!(date_from || date_to);
|
||||
const term = (q || "").trim();
|
||||
if (term !== "") {
|
||||
conditions.push(`(
|
||||
s.service_ref ILIKE $${idx} OR
|
||||
COALESCE(s.raw_data->>'Nombre Cliente', s.raw_data->>'CLIENTE', '') ILIKE $${idx} OR
|
||||
COALESCE(s.raw_data->>'Dirección', s.raw_data->>'DOMICILIO', '') ILIKE $${idx} OR
|
||||
COALESCE(s.raw_data->>'Población', s.raw_data->>'POBLACION-PROVINCIA', '') ILIKE $${idx} OR
|
||||
COALESCE(s.raw_data->>'Teléfono', s.raw_data->>'TELEFONO', s.raw_data->>'TELEFONOS', '') ILIKE $${idx} OR
|
||||
COALESCE(s.raw_data->>'Compañía', s.raw_data->>'COMPAÑIA', '') ILIKE $${idx}
|
||||
)`);
|
||||
params.push(`%${term}%`);
|
||||
idx++;
|
||||
} else if (!hasDateRange) {
|
||||
// Ni fecha ni texto: no devolvemos nada para no volcar el histórico entero.
|
||||
return res.json({ ok: true, services: [], hasMore: false, needsFilter: true });
|
||||
}
|
||||
|
||||
params.push(limit, offset);
|
||||
const query = `
|
||||
SELECT s.*, u.full_name as assigned_name
|
||||
FROM scraped_services s
|
||||
LEFT JOIN users u ON s.assigned_to = u.id
|
||||
WHERE ${conditions.join(' AND ')}
|
||||
ORDER BY s.created_at DESC
|
||||
LIMIT $${idx++} OFFSET $${idx}
|
||||
`;
|
||||
|
||||
const result = await pool.query(query, params);
|
||||
const servicesWithPhones = result.rows.map(s => ({ ...s, phones: extractAllPhones(s.raw_data) }));
|
||||
res.json({ ok: true, services: servicesWithPhones, hasMore: result.rows.length === limit });
|
||||
} catch (e) {
|
||||
console.error("Error en /services/search:", e);
|
||||
res.status(500).json({ ok: false });
|
||||
}
|
||||
});
|
||||
|
||||
app.put("/services/set-appointment/:id", authMiddleware, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
Reference in New Issue
Block a user