fix(impuestos): desactivar JIT en queries con subplans correlacionados
- Agrega helper withJitOff en impuestos.service.ts - Ejecuta getResumenIva, getIvaMensual y readResumenIvaFromCache con SET LOCAL jit = off - Evita compilación JIT de ~17s en queries con costo estimado alto feat(contribuyentes): auto-asignar a cartera del supervisor - Al crear contribuyente con supervisorUserId, se agrega automáticamente a todas las carteras top-level del supervisor feat(permisos): restricciones de UI por rol en contribuyentes - Oculta botón Add-ons para roles distintos de owner/cfo - Oculta botón Eliminar contribuyente para no-owner - Oculta botón Agregar RFC para auxiliar/visor/cliente/contador feat(cfdi): ver CFDI desde conceptos y forma de pago en Excel - Agrega botón Ver CFDI en cada fila de la tabla de Conceptos - Agrega columna Forma de Pago en export Excel de CFDIs - Agrega columna Forma de Pago en export individual de CFDI chore(migraciones): índices GIN para relaciones de activos - 048: índices btree parciales para activos - 049: índices GIN para cfdis_relacionados y uuid_relacionado
This commit is contained in:
@@ -96,12 +96,32 @@ export async function getAsignacionesPorSupervisor(
|
||||
): Promise<{ obligaciones: AsignacionObligacion[]; tareas: AsignacionTarea[] }> {
|
||||
const isOwner = role === 'owner' || role === 'cfo' || role === 'contador';
|
||||
|
||||
// Relación supervisor → auxiliar se infiere desde carteras (directas y
|
||||
// subcarteras) con fallback a la tabla legacy auxiliar_supervisores.
|
||||
const supervisorFilter = isOwner
|
||||
? ''
|
||||
: `AND EXISTS (
|
||||
SELECT 1 FROM (
|
||||
SELECT c.auxiliar_user_id
|
||||
FROM carteras c
|
||||
WHERE c.supervisor_user_id = $1
|
||||
AND c.auxiliar_user_id IS NOT NULL
|
||||
UNION
|
||||
SELECT sub.auxiliar_user_id
|
||||
FROM carteras sub
|
||||
JOIN carteras p ON p.id = sub.parent_id
|
||||
WHERE p.supervisor_user_id = $1
|
||||
AND sub.auxiliar_user_id IS NOT NULL
|
||||
UNION
|
||||
SELECT auxiliar_user_id FROM auxiliar_supervisores WHERE supervisor_user_id = $1
|
||||
) sup_aux WHERE sup_aux.auxiliar_user_id = __AUX_COL__
|
||||
)`;
|
||||
const whereObl = isOwner
|
||||
? 'WHERE 1=1'
|
||||
: 'WHERE EXISTS (SELECT 1 FROM auxiliar_supervisores asp WHERE asp.auxiliar_user_id = oa.auxiliar_user_id AND asp.supervisor_user_id = $1)';
|
||||
: `WHERE 1=1 ${supervisorFilter.replace(/__AUX_COL__/g, 'oa.auxiliar_user_id')}`;
|
||||
const whereTarea = isOwner
|
||||
? 'WHERE 1=1'
|
||||
: 'WHERE EXISTS (SELECT 1 FROM auxiliar_supervisores asp WHERE asp.auxiliar_user_id = ta.auxiliar_user_id AND asp.supervisor_user_id = $1)';
|
||||
: `WHERE 1=1 ${supervisorFilter.replace(/__AUX_COL__/g, 'ta.auxiliar_user_id')}`;
|
||||
const params = isOwner ? [] : [supervisorUserId];
|
||||
|
||||
const { rows: obligaciones } = await pool.query<AsignacionObligacion>(
|
||||
@@ -301,3 +321,23 @@ export async function getAuxiliarAsignadoTarea(
|
||||
const names = await resolveUserNames([auxId]);
|
||||
return { auxiliarUserId: auxId, auxiliarNombre: names.get(auxId) ?? null };
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve los userIds de auxiliares que tienen al contribuyente en alguna
|
||||
* de sus subcarteras (carteras con auxiliar_user_id no nulo que contienen
|
||||
* al contribuyente en cartera_entidades).
|
||||
*/
|
||||
export async function getAuxiliaresElegibles(
|
||||
pool: Pool,
|
||||
contribuyenteId: string,
|
||||
): Promise<string[]> {
|
||||
const { rows } = await pool.query<{ auxiliar_user_id: string }>(
|
||||
`SELECT DISTINCT c.auxiliar_user_id
|
||||
FROM carteras c
|
||||
JOIN cartera_entidades ce ON ce.cartera_id = c.id
|
||||
WHERE ce.entidad_id = $1
|
||||
AND c.auxiliar_user_id IS NOT NULL`,
|
||||
[contribuyenteId],
|
||||
);
|
||||
return rows.map(r => r.auxiliar_user_id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user