fix(facturacion): filtrar searchConceptos y searchRfcs por contribuyenteId
- searchConceptos: agrega AND c.contribuyente_id = cuando se recibe contribuyenteId
- searchRfcs: restringe el catálogo global de rfcs a aquellos que aparecen en CFDIs del contribuyente (como emisor o receptor)
- Usa parametrización dinámica (3800099{params.length}) para evitar errores de índice
This commit is contained in:
@@ -580,7 +580,13 @@ export async function searchConceptos(req: Request, res: Response, next: NextFun
|
|||||||
const params: any[] = [];
|
const params: any[] = [];
|
||||||
if (q.length >= 2) {
|
if (q.length >= 2) {
|
||||||
params.push(`%${q}%`);
|
params.push(`%${q}%`);
|
||||||
whereSearch = `AND (cc.descripcion ILIKE $1 OR cc.clave_prod_serv ILIKE $1)`;
|
whereSearch = `AND (cc.descripcion ILIKE $${params.length} OR cc.clave_prod_serv ILIKE $${params.length})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let whereContribuyente = '';
|
||||||
|
if (contribuyenteId) {
|
||||||
|
params.push(contribuyenteId);
|
||||||
|
whereContribuyente = `AND c.contribuyente_id = $${params.length}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { rows } = await pool.query(`
|
const { rows } = await pool.query(`
|
||||||
@@ -605,6 +611,7 @@ export async function searchConceptos(req: Request, res: Response, next: NextFun
|
|||||||
WHERE c.status NOT IN ('Cancelado', '0')
|
WHERE c.status NOT IN ('Cancelado', '0')
|
||||||
${whereType}
|
${whereType}
|
||||||
${whereSearch}
|
${whereSearch}
|
||||||
|
${whereContribuyente}
|
||||||
ORDER BY cc.clave_prod_serv, cc.descripcion, c.fecha_emision DESC
|
ORDER BY cc.clave_prod_serv, cc.descripcion, c.fecha_emision DESC
|
||||||
LIMIT 30
|
LIMIT 30
|
||||||
`, params);
|
`, params);
|
||||||
@@ -708,7 +715,7 @@ export async function searchRfcs(req: Request, res: Response, next: NextFunction
|
|||||||
const q = (req.query.q as string || '').trim();
|
const q = (req.query.q as string || '').trim();
|
||||||
if (q.length < 3) return res.json([]);
|
if (q.length < 3) return res.json([]);
|
||||||
|
|
||||||
const contribuyenteId = (req.query.contribuyenteId as string || '').trim();
|
const contribuyenteId = (req.query.contribuyenteId as string || '').replace(/[^a-f0-9-]/gi, '');
|
||||||
const pool = req.tenantPool!;
|
const pool = req.tenantPool!;
|
||||||
|
|
||||||
// RFC del tenant despacho para excluirlo (no se factura a sí mismo)
|
// RFC del tenant despacho para excluirlo (no se factura a sí mismo)
|
||||||
@@ -719,10 +726,17 @@ export async function searchRfcs(req: Request, res: Response, next: NextFunction
|
|||||||
});
|
});
|
||||||
const tenantRfc = tenant?.rfc || '';
|
const tenantRfc = tenant?.rfc || '';
|
||||||
|
|
||||||
// Búsqueda en el catálogo completo de RFCs. El contribuyente activo solo
|
const params: any[] = [tenantRfc, `%${q}%`];
|
||||||
// filtra CFDIs relacionados / PPD, no el autocompleto de RFCs — de lo
|
let whereContribuyente = '';
|
||||||
// contrario no se podría facturar a un cliente nuevo que nunca haya
|
if (contribuyenteId) {
|
||||||
// aparecido en un CFDI previo.
|
params.push(contribuyenteId);
|
||||||
|
whereContribuyente = `AND id IN (
|
||||||
|
SELECT rfc_receptor_id FROM cfdis WHERE contribuyente_id = $${params.length} AND rfc_receptor_id IS NOT NULL
|
||||||
|
UNION
|
||||||
|
SELECT rfc_emisor_id FROM cfdis WHERE contribuyente_id = $${params.length} AND rfc_emisor_id IS NOT NULL
|
||||||
|
)`;
|
||||||
|
}
|
||||||
|
|
||||||
const { rows } = await pool.query(`
|
const { rows } = await pool.query(`
|
||||||
SELECT id, rfc, razon_social as "razonSocial",
|
SELECT id, rfc, razon_social as "razonSocial",
|
||||||
regimen_fiscal as "regimenFiscal",
|
regimen_fiscal as "regimenFiscal",
|
||||||
@@ -730,9 +744,10 @@ export async function searchRfcs(req: Request, res: Response, next: NextFunction
|
|||||||
FROM rfcs
|
FROM rfcs
|
||||||
WHERE rfc != $1
|
WHERE rfc != $1
|
||||||
AND (rfc ILIKE $2 OR razon_social ILIKE $2)
|
AND (rfc ILIKE $2 OR razon_social ILIKE $2)
|
||||||
|
${whereContribuyente}
|
||||||
ORDER BY razon_social
|
ORDER BY razon_social
|
||||||
LIMIT 10
|
LIMIT 10
|
||||||
`, [tenantRfc, `%${q}%`]);
|
`, params);
|
||||||
|
|
||||||
res.json(rows);
|
res.json(rows);
|
||||||
} catch (error) { next(error); }
|
} catch (error) { next(error); }
|
||||||
|
|||||||
Reference in New Issue
Block a user