fix(despacho-stats): contar obligaciones y tareas pendientes correctamente
- Obligaciones: las obligaciones activas sin registro en obligacion_periodos para el periodo actual ahora se cuentan como pendientes (antes daban 0) - Tareas: se materializan los periodos antes de contar para que las tareas sin registro previo aparezcan como pendientes - Usa CTEs separadas para obligaciones y tareas evitando producto cartesiano
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { Pool } from 'pg';
|
||||
import { prisma } from '../config/database.js';
|
||||
import { materializarPeriodos } from './tareas.service.js';
|
||||
|
||||
export interface ContribuyentesStats {
|
||||
totalContribuyentes: number;
|
||||
@@ -210,30 +211,62 @@ export async function getMisAsignados(
|
||||
const inicioMes = `${_año}-${String(_mes).padStart(2, '0')}-01`;
|
||||
const finMes = new Date(_año, _mes, 0).toISOString().split('T')[0];
|
||||
|
||||
// Materializar periodos de tareas antes de contar (evita que tareas sin
|
||||
// registro en tarea_periodos aparezcan como 0).
|
||||
await Promise.all(ids.map(id => materializarPeriodos(pool, id).catch(() => {})));
|
||||
|
||||
const { rows: stats } = await pool.query(
|
||||
`WITH obl AS (
|
||||
SELECT oc.contribuyente_id,
|
||||
COUNT(*) FILTER (WHERE op.completada = false AND op.periodo = $1)::int AS pendientes,
|
||||
COUNT(*) FILTER (WHERE op.completada = false AND op.periodo < $1)::int AS atrasadas,
|
||||
COUNT(*) FILTER (WHERE op.completada = true AND op.periodo = $1)::int AS completadas
|
||||
FROM obligaciones_contribuyente oc
|
||||
LEFT JOIN obligacion_periodos op ON op.obligacion_id = oc.id
|
||||
WHERE oc.contribuyente_id = ANY($4::uuid[]) AND oc.activa = true
|
||||
GROUP BY oc.contribuyente_id
|
||||
`WITH obligaciones_activas AS (
|
||||
SELECT id, contribuyente_id FROM obligaciones_contribuyente
|
||||
WHERE contribuyente_id = ANY($4::uuid[]) AND activa = true
|
||||
),
|
||||
op_actual AS (
|
||||
SELECT obligacion_id, completada FROM obligacion_periodos
|
||||
WHERE obligacion_id IN (SELECT id FROM obligaciones_activas) AND periodo = $1
|
||||
),
|
||||
op_atrasadas AS (
|
||||
SELECT obligacion_id, COUNT(*) as atrasadas FROM obligacion_periodos
|
||||
WHERE obligacion_id IN (SELECT id FROM obligaciones_activas) AND periodo < $1 AND completada = false
|
||||
GROUP BY obligacion_id
|
||||
),
|
||||
obl AS (
|
||||
SELECT oa.contribuyente_id,
|
||||
COUNT(*) FILTER (WHERE op_a.completada IS NULL OR op_a.completada = false)::int AS pendientes,
|
||||
COALESCE(SUM(op_atr.atrasadas), 0)::int AS atrasadas,
|
||||
COUNT(*) FILTER (WHERE op_a.completada = true)::int AS completadas
|
||||
FROM obligaciones_activas oa
|
||||
LEFT JOIN op_actual op_a ON op_a.obligacion_id = oa.id
|
||||
LEFT JOIN op_atrasadas op_atr ON op_atr.obligacion_id = oa.id
|
||||
GROUP BY oa.contribuyente_id
|
||||
),
|
||||
tareas_activas AS (
|
||||
SELECT id, contribuyente_id FROM tareas_catalogo
|
||||
WHERE contribuyente_id = ANY($4::uuid[]) AND active = true
|
||||
),
|
||||
tar_actual AS (
|
||||
SELECT tarea_id, completada FROM tarea_periodos
|
||||
WHERE tarea_id IN (SELECT id FROM tareas_activas)
|
||||
AND fecha_limite BETWEEN $2::date AND $3::date
|
||||
),
|
||||
tar_atrasadas AS (
|
||||
SELECT tarea_id, COUNT(*) as atrasadas FROM tarea_periodos
|
||||
WHERE tarea_id IN (SELECT id FROM tareas_activas)
|
||||
AND fecha_limite < $2::date AND completada = false
|
||||
GROUP BY tarea_id
|
||||
),
|
||||
tar AS (
|
||||
SELECT tc.contribuyente_id,
|
||||
COUNT(*) FILTER (WHERE tp.completada = false AND tp.fecha_limite BETWEEN $2::date AND $3::date)::int AS pendientes,
|
||||
COUNT(*) FILTER (WHERE tp.completada = false AND tp.fecha_limite < $2::date)::int AS atrasadas,
|
||||
COUNT(*) FILTER (WHERE tp.completada = true AND tp.fecha_limite BETWEEN $2::date AND $3::date)::int AS completadas
|
||||
FROM tareas_catalogo tc
|
||||
LEFT JOIN tarea_periodos tp ON tp.tarea_id = tc.id
|
||||
WHERE tc.contribuyente_id = ANY($4::uuid[]) AND tc.active = true
|
||||
GROUP BY tc.contribuyente_id
|
||||
SELECT ta.contribuyente_id,
|
||||
COUNT(*) FILTER (WHERE tar_a.completada IS NULL OR tar_a.completada = false)::int AS pendientes,
|
||||
COALESCE(SUM(tar_atr.atrasadas), 0)::int AS atrasadas,
|
||||
COUNT(*) FILTER (WHERE tar_a.completada = true)::int AS completadas
|
||||
FROM tareas_activas ta
|
||||
LEFT JOIN tar_actual tar_a ON tar_a.tarea_id = ta.id
|
||||
LEFT JOIN tar_atrasadas tar_atr ON tar_atr.tarea_id = ta.id
|
||||
GROUP BY ta.contribuyente_id
|
||||
)
|
||||
SELECT
|
||||
obl.contribuyente_id AS obl_id, obl.pendientes AS obl_pen, obl.atrasadas AS obl_atr, obl.completadas AS obl_com,
|
||||
tar.contribuyente_id AS tar_id, tar.pendientes AS tar_pen, tar.atrasadas AS tar_atr, tar.completadas AS tar_com
|
||||
obl.contribuyente_id AS obl_id, obl.pendientes AS obl_pen, obl.atrasadas AS obl_atr, obl.completadas AS obl_com,
|
||||
tar.contribuyente_id AS tar_id, tar.pendientes AS tar_pen, tar.atrasadas AS tar_atr, tar.completadas AS tar_com
|
||||
FROM obl
|
||||
FULL OUTER JOIN tar ON tar.contribuyente_id = obl.contribuyente_id`,
|
||||
[periodoMes, inicioMes, finMes, ids],
|
||||
|
||||
Reference in New Issue
Block a user