panels-origin/docs/plan-pendientes-arctec.md
Cursor Agent ea705c6c92
docs: plan de pendientes de facturas, nómina e IMSS
Contrasta las observaciones de arctec-ar con gastos, proveedores y nómina actuales, y deja el orden de implementación reutilizando el catálogo de proveedores.

Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
2026-09-23 03:56:12 +00:00

17 KiB
Raw Permalink Blame History

Pendientes arctec-ar: análisis y plan de implementación

Fuente: observaciones de Pendientes página (facturas, nómina, IMSS/SUA). Alcance de este documento: contrastar cada punto con el sistema actual y definir el orden de construcción. No implementa las pantallas ni las migraciones.

Resumen

El sistema ya cubre captura manual de gastos, catálogo de proveedores, nómina semanal (jornal, destajo y administrativa), préstamos con descuento al pagar la semana, y datos básicos de IMSS en el padrón. No existe un módulo de facturas CFDI, ni descuentos varios estructurados, ni finiquitos, ni dispersión, ni historial de movimientos de personal, ni reportes de nómina por mes o año, ni jornal distinto para el IMSS.

La administración de proveedores ya existe y debe reutilizarse. No conviene un segundo catálogo. Las facturas y los gastos deben resolver el proveedor por supplier_id y por RFC.

Qué hay hoy

Área Dónde vive Qué hace
Proveedores core.suppliers, fn_supplier_list/create/update, GET/POST/PATCH /v1/suppliers, pestaña Proveedores en Configuración, SupplierFormDialog Alta y edición de nombre, razón social, RFC único por tenant, contacto y domicilio. Estatus activo / inactivo en base, sin baja en la pantalla.
Uso del proveedor Gastos (expense_entries.supplier_id) y materiales de almacén (warehouse_material_suppliers) En Gastos se elige del catálogo. El RFC se copia al gasto.
Gastos expense_entries, página Gastos Captura uno a uno: empresa, obra, fecha, concepto de presupuesto, importes, IVA y PDF. Filtro de texto (descripción, proveedor, concepto) y “sin clasificar”. El listado de API filtra obra, empresa, fechas, concepto y origen.
Nómina payroll_weeks (draft / assembled / paid), hojas obra, destajo, admin Asistencia por día (presente o falta). Jornal = días × workers.daily_wage. Se arma desde el jueves. Al pagar se descuenta el préstamo y se sincroniza el gasto. Exportación: CSV de la semana. PDF solo de recibos de préstamo.
Préstamos loans, loan_payments, ficha del trabajador Alta, saldo en ficha y recuperación en el tablero. No hay edición del préstamo ya registrado.
Personal workers.status, imss_alta_at, imss_baja_at, last_rehire_at, assignments.start_date/end_date Una fecha de reingreso y una alta/baja IMSS. No hay bitácora de varios movimientos.
IMSS Empresa: registro patronal y clase de riesgo. Persona: NSS, salario diario único, estatus y fechas de alta/baja, documentos alta_imss / baja_imss No hay jornal IMSS separado, ni desglose de cuotas, ni archivo SUA.

Análisis por observación

1. Facturas y comprobantes

Carga masiva de Excel (recibidas o emitidas) y concepto de material a la obra. No existe. Gastos se capturan de uno en uno y solo modelan egresos. Una factura emitida (ingreso) no cabe en expense_entries sin un tipo de movimiento. El concepto de presupuesto ya se puede ligar a un gasto manual (budget_item_id), pero no desde un Excel ni por línea de material.

Filtros en facturas recibidas (proveedor, monto, RFC, UUID). No hay UUID, folio fiscal ni serie. La búsqueda de Gastos es un texto libre en el cliente. El API de gastos no filtra por proveedor, RFC ni rango de monto.

Decisión: las facturas son un registro propio, ligado al proveedor del catálogo. Una factura recibida clasificada puede generar o actualizar un gasto. Una emitida queda como ingreso y no entra al control de costos.

2. Nómina

Bono. No hay concepto de percepción aparte del jornal, el destajo o el sueldo administrativo. payroll_week_lines tiene gross, discounts y loan_discount, sin tipo de percepción.

Descuentos varios con observación. La columna discounts es un importe. El periodo legado acepta extra_discounts como número por trabajador, sin concepto, fecha, obra ni motivo. La pantalla de nómina no captura ese dato.

Ajuste por horas trabajadas. La asistencia es sí/no por día (attendance.present). days es la cuenta de días presentes. No hay horas ni fracción de jornal por hora.

Días festivos. No hay calendario ni regla (pagar el día, no descontarlo, o pagarlo doble). Un festivo hoy se trata como falta si no se marca presente.

Consulta y descarga Excel y PDF. Hay CSV de la semana abierta (fn_payroll_week_csv). No hay libro Excel ni PDF de la nómina. El generador PDF actual solo arma recibos de préstamo (api/pdf.ts).

Descuentos varios (sección propia)

No existe tabla ni pantalla. Cada descuento del pendiente pide concepto, importe, fecha, trabajador, obra y observación. Eso es un movimiento, no un campo suelto en la línea semanal. Al armar la semana, los descuentos vigentes de esa obra y persona se suman a discounts.

Préstamos

Alta y lectura sí. fn_loan_create fija entregado, saldo, cuota, comisión y plan. No hay fn_loan_update. El saldo se ve en la ficha y el descuento de la semana en la línea (loan_label, loan_discount). No hay un estado de cuenta: saldo inicial, descuentos aplicados y saldo pendiente en un solo lugar. Editar un préstamo con pagos ya aplicados debe quedar restringido (solo nota, cuota futura o corrección si la semana sigue en borrador).

Finiquitos y liquidaciones

No hay módulo. La baja de padrón cambia status / pipeline_status y no calcula proporcional, vacaciones, aguinaldo, prima ni finiquito. Hace falta un cálculo consultable (conceptos e importe final) y un pago que no se mezcle con el jornal semanal.

Dispersión

No hay entidad de dispersión. Lo más cercano es el estado de la semana: borrador, armada y pagada. Después de pagada no se edita, y no se anexa el comprobante de la transferencia. El “corte semanal” hoy es la propia semana de nómina (se arma el jueves). Falta un corte explícito: congelar el neto a dispersar, permitir corrección mientras no sea definitivo, y adjuntar el comprobante al cerrarlo.

Historial de movimientos del trabajador

Se guarda el estado actual y, como mucho, una fecha: imss_alta_at, imss_baja_at, last_rehire_at, inicio y fin de asignación. Un segundo reingreso pisa last_rehire_at. No se puede listar alta, baja y reingresos sucesivos.

Reportes de nómina

No hay reporte mensual ni anual, ni filtro combinado por trabajador, obra y periodo, ni exportación Excel/PDF de ese corte. El CSV semanal no sustituye esos reportes.

3. IMSS / SUA

workers.daily_wage es el único jornal. No se distingue el jornal real del jornal diario para IMSS (salario base de cotización diario). La empresa tiene registro patronal y clase de riesgo; la persona tiene NSS y movimiento de alta/baja como fechas sueltas. No se calculan ni se consultan cuotas (enfermedad, invalidez, retiro, cesantía, infonavit, riesgo de trabajo) ni se arma el layout del SUA. El pendiente pide facilitar la revisión, no sustituir al SUA: guardar el jornal IMSS, los movimientos y el desglose usado en el cálculo, y poder exportarlo para cotejo.

La opción de administrar proveedores ya está hecha y es la base de facturas y almacén.

Se mantiene:

  • Un solo catálogo por tenant (core.suppliers).
  • RFC único cuando viene informado.
  • Alta desde Configuración y, como atajo, desde Gastos y desde el catálogo de materiales.
  • El gasto y la factura guardan supplier_id y una copia de nombre y RFC por si el catálogo cambia después.

Se completa, sin abrir otro módulo:

  • Activar e inactivar desde la pestaña Proveedores (el campo status ya existe; la tabla no lo muestra ni lo edita).
  • Búsqueda en servidor por nombre y RFC, alineada al filtro de facturas.
  • Al importar Excel de facturas, emparejar por RFC. Si el RFC no existe, la fila queda en revisión para crear el proveedor o asignarlo; no se duplica el catálogo en silencio.
  • Datos que el catálogo aún no tiene y la factura sí va a necesitar: régimen fiscal y código postal fiscal, opcionales, para cotejar el CFDI. Cuenta bancaria no entra en esta fase; la dispersión es de nómina, no de proveedores.

Plan de implementación

Cada fase cierra con migración Liquibase en db/core/changesets/, funciones core.fn_*, rutas en la API y pantalla en web-panel. Los permisos siguen el patrón modulo.view/create/update/delete.

Fase 1. Proveedores listos para facturas

Objetivo: el catálogo que ya existe queda usable como maestro de las facturas.

  • Mostrar estatus y permitir pasarlo a inactivo (no se borra si tiene gastos o facturas).
  • Campos opcionales regimen_fiscal y codigo_postal.
  • Listado filtrable por nombre, RFC y estatus.
  • Prueba de API: alta, RFC duplicado, inactivar, y que Gastos solo ofrezca activos.

No cambia el flujo de captura de un gasto.

Fase 2. Facturas recibidas y emitidas

Objetivo: registrar comprobantes en lote y clasificar la recibida a la obra.

Tablas nuevas:

  • invoices: tenant, dirección recibida | emitida, supplier_id, nombre y RFC copiados, UUID, serie, folio, fecha, subtotal, IVA, total, moneda, estatus borrador | registrada | clasificada | anulada.
  • invoice_lines: factura, descripción, cantidad, unidad, importe, project_id, budget_item_id.
  • UUID único por tenant cuando viene informado.

Excel de carga (una fila por partida, se agrupa por UUID o, si no hay UUID, por RFC + folio + fecha):

  • Dirección, RFC, nombre proveedor, UUID, serie, folio, fecha, descripción, cantidad, unidad, importe, IVA, total, clave de obra, clave de concepto.

Reglas:

  • RFC conocido asigna supplier_id. RFC nuevo no crea proveedor hasta que alguien lo confirme en la revisión.
  • Concepto y obra vacíos dejan la factura recibida como registrada (equivalente al gasto sin clasificar). Al asignar concepto se puede generar el gasto con source = 'invoice' y source_ref_id = id de factura, reusando la unicidad que ya tiene expense_entries.
  • La emitida no genera gasto.
  • Filtros del listado de recibidas: proveedor (id o nombre), RFC, UUID, folio, rango de monto, rango de fechas, obra, con o sin concepto.
  • Edición de concepto y obra mientras la factura no esté anulada. Si ya generó gasto confirmado, la reclasificación pasa por la misma regla que fn_expense_update.

Pantalla: apartado Facturas, pestañas Recibidas y Emitidas, acción Importar Excel y diálogo de clasificación. Gastos sigue siendo la captura manual y el reflejo de nómina; no se le pide que sea el CFDI.

Fase 3. Conceptos de nómina de la semana

Objetivo: bono, descuento con motivo, horas y festivo dentro del cálculo semanal que ya arma y paga.

  • Percepciones de la línea: jornal, bono (importe y nota). El bruto pasa a ser jornal + bono + destajo o sueldo admin, según la hoja.
  • payroll_adjustments: tipo descuento | bono | horas, trabajador, obra opcional, semana o fecha, concepto, importe o horas, observación. Un descuento sin observación no se guarda.
  • Horas: además del día presente/ausente, un ajuste de horas × (jornal / jornada, por defecto 8). Puede sumar o restar del jornal de esa semana. No reemplaza la asistencia por día.
  • holidays: fecha, nombre, tenant. Si el día cae en la semana y la persona está asignada, cuenta como día pagado aunque no haya marca de asistencia, y se identifica en la línea. No se paga doble en esta fase; si más adelante se pide festivo trabajado, será otro tipo de ajuste.
  • El armado de la semana (fn_payroll_week_assemble) suma estos conceptos antes de congelar payable_net. En semana paid no se editan.
  • Pantalla Nómina: captura de bono y de descuento (concepto, importe, obra, observación) sobre la persona de la semana, y marcas de festivo en el calendario de la semana.

La sección “Descuentos varios” del pendiente es esta misma captura, también consultable fuera de la semana: listado por trabajador, obra y fechas. No es un módulo aparte del cálculo.

Fase 4. Préstamos editables y estado de cuenta

  • fn_loan_update mientras no haya loan_payments, o solo nota y cuota si ya hay pagos. El saldo no se teclea: se recalcula como entregado − suma de pagos.
  • Ficha y diálogo de préstamo: entregado, comisión, cuota, saldo pendiente y tabla de descuentos aplicados (semana, importe, etiqueta).
  • Corregir un préstamo no reabre una semana ya pagada.

Fase 5. Finiquitos y liquidaciones

  • settlements: trabajador, tipo finiquito | liquidacion, fecha de baja, obra, estatus borrador | pagado.
  • settlement_lines: concepto (sueldo pendiente, vacaciones, prima vacacional, aguinaldo, otro), días o base, importe, observación.
  • El importe final es la suma de líneas menos descuentos y saldo de préstamo vigentes, mostrados en el detalle antes de pagar.
  • Pagar el finiquito no lo mete en la semana de jornal. Puede generar un gasto de nómina distinto, con referencia al finiquito, para que el control de costos lo vea.

Los factores (días de aguinaldo, porcentaje de prima) salen de configuración del tenant, con valores editables. El primer corte usa los días capturados en cada línea para no bloquear el módulo por una tabla fiscal incompleta.

Fase 6. Dispersión y corte semanal

  • payroll_dispersions: semana, estatus abierta | corte | definitiva, neto, nota.
  • Mientras está abierta o en corte, se puede corregir el neto por persona (ajuste que también queda en la línea de la semana si la semana no está pagada).
  • definitiva bloquea la edición y exige, o al menos permite, el comprobante (mismo almacenamiento cifrado que los PDF de gastos).
  • El corte semanal es la acción que pasa la dispersión a corte con el payable_net de esa semana. No crea otra periodicidad: la semana de nómina sigue siendo el periodo.

Fase 7. Historial de movimientos

  • worker_movements: trabajador, tipo alta | baja | reingreso, fecha, motivo, usuario.
  • Alta de persona, baja de padrón y reactivación escriben un renglón. Las fechas actuales (last_rehire_at, alta y baja IMSS) se siguen actualizando para no romper el expediente.
  • La ficha muestra la lista en orden de fecha. No se edita el pasado desde la ficha; una corrección es otro movimiento o una nota.

Fase 8. Reportes de nómina

  • Consulta por periodo (semana, mes o año), trabajador y obra, leyendo líneas de semanas, ajustes, préstamos y finiquitos pagados en el rango.
  • Exportación Excel (libro con el mismo detalle que la pantalla) y PDF (resumen por persona y totales). El CSV semanal se conserva.
  • Mes y año agrupan por week_start / fecha del movimiento, en la zona horaria del tenant.

Fase 9. Jornal IMSS y apoyo a SUA

  • workers.imss_daily_wage: jornal diario para cotización. Si está vacío, el cálculo usa daily_wage y lo indica en pantalla.
  • Movimientos IMSS que alimentan el historial de la fase 7 con tipo alta_imss, baja_imss, modificacion_salario, más registro patronal de la empresa.
  • Consulta por persona y periodo: jornal real, jornal IMSS, días, salario base de cotización del periodo y cuotas calculadas con las tasas vigentes guardadas en configuración (no hardcodeadas en la pantalla).
  • Exportación de esa consulta a Excel para cotejar contra el SUA. No se genera el archivo propietario del SUA en esta fase: faltan tablas de ausentismo, incapacidades y el layout oficial completo. Eso queda como fase posterior si el cotejo en Excel no basta.

Orden y dependencias

  1. Proveedores (fase 1) antes que facturas, porque el Excel casa por RFC.
  2. Facturas (fase 2) no bloquea nómina. Puede ir en paralelo con la fase 3 después de la 1.
  3. Ajustes de nómina (fase 3) antes que reportes (fase 8) y antes que dispersión (fase 6), para que el neto a dispersar ya incluya bono, horas, festivo y descuentos.
  4. Préstamos (fase 4) antes que finiquitos (fase 5), porque el finiquito resta el saldo.
  5. Historial (fase 7) puede avanzar en paralelo con nómina; la fase 9 lo reutiliza para movimientos IMSS.
  6. IMSS/SUA (fase 9) al final: depende del jornal y de los movimientos, y no cambia el pago semanal.

Fuera de este plan

  • Timbrado CFDI o descarga automática del SAT.
  • Archivo de pago bancario (layout de dispersión del banco).
  • Archivo SUA de carga directa.
  • Sustituir la asistencia por día con un reloj checador.

Verificación por fase

  • Fase 1: crear, editar, RFC repetido, inactivar, y que un gasto nuevo no liste al inactivo.
  • Fase 2: Excel con proveedor existente, RFC desconocido, UUID repetido, clasificación a concepto y gasto generado una sola vez.
  • Fase 3: semana con bono, descuento con motivo, horas y un festivo; el neto armado cuadra con la suma; semana pagada rechaza cambios.
  • Fase 4: editar préstamo sin pagos; con pagos, el saldo es entregado menos pagos.
  • Fase 5: detalle de conceptos igual al importe a pagar.
  • Fase 6: corrección antes de definitiva; comprobante adjunto; definitiva no editable.
  • Fase 7: alta, baja y reingreso aparecen en orden y no se pierden al repetir el ciclo.
  • Fase 8: el mes suma las semanas del mes; Excel y PDF coinciden con la pantalla.
  • Fase 9: jornal IMSS distinto del real se ve en la consulta de cuotas y en el Excel.