diff --git a/apps/api/src/controllers/facturacion.controller.ts b/apps/api/src/controllers/facturacion.controller.ts index 1fa9632..7b5c2d6 100644 --- a/apps/api/src/controllers/facturacion.controller.ts +++ b/apps/api/src/controllers/facturacion.controller.ts @@ -580,7 +580,13 @@ export async function searchConceptos(req: Request, res: Response, next: NextFun const params: any[] = []; if (q.length >= 2) { 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(` @@ -605,6 +611,7 @@ export async function searchConceptos(req: Request, res: Response, next: NextFun WHERE c.status NOT IN ('Cancelado', '0') ${whereType} ${whereSearch} + ${whereContribuyente} ORDER BY cc.clave_prod_serv, cc.descripcion, c.fecha_emision DESC LIMIT 30 `, params); @@ -708,7 +715,7 @@ export async function searchRfcs(req: Request, res: Response, next: NextFunction const q = (req.query.q as string || '').trim(); 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!; // 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 || ''; - // Búsqueda en el catálogo completo de RFCs. El contribuyente activo solo - // filtra CFDIs relacionados / PPD, no el autocompleto de RFCs — de lo - // contrario no se podría facturar a un cliente nuevo que nunca haya - // aparecido en un CFDI previo. + const params: any[] = [tenantRfc, `%${q}%`]; + let whereContribuyente = ''; + if (contribuyenteId) { + 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(` SELECT id, rfc, razon_social as "razonSocial", regimen_fiscal as "regimenFiscal", @@ -730,9 +744,10 @@ export async function searchRfcs(req: Request, res: Response, next: NextFunction FROM rfcs WHERE rfc != $1 AND (rfc ILIKE $2 OR razon_social ILIKE $2) + ${whereContribuyente} ORDER BY razon_social LIMIT 10 - `, [tenantRfc, `%${q}%`]); + `, params); res.json(rows); } catch (error) { next(error); }