chore: catálogo obligaciones, cierre automático, fixes SAT y facturación

- Catálogo de obligaciones fiscales expandido a 30 entradas con campo requierePago.
- Soporte de frecuencia cuatrimestral en obligaciones y declaraciones.
- Automatización de cierre de obligaciones fiscales desde Documentos › Declaraciones.
- Nuevas tablas obligacion_evidencias, obligacion_periodos estados y declaracion_obligaciones.
- Nuevo servicio obligacion-evidencias.service.ts y endpoints REST.
- Refactor de declaraciones.service.ts para vincular obligaciones y crear evidencias.
- Notificaciones por email para evidencias de obligaciones.
- Adjuntar PDFs en correo de declaración subida.
- Fix drill-down de CFDIs: carga completa al visualizar.
- Fix sincronización SAT: tipos P/N, UUID case-insensitive, no reutilizar requestId.
- Fix suscripciones pending en /configuracion/planes-despacho.
- Fix sugerencias de Clave Producto SAT: importar catálogo y robustecer autocomplete.
- Quitar toggle manual de completado en Configuración › Obligaciones fiscales › Tareas.
- Scripts de soporte para Demo Ventas y utilerías (change-user-email, resend-welcome, import-clave-prod-serv).
- Documentación de cambios en docs/CAMBIOS-2026-05-04.md.
This commit is contained in:
Horux Dev
2026-06-22 04:53:59 +00:00
parent b217342a96
commit 7df27ce66d
39 changed files with 2791 additions and 191 deletions

View File

@@ -554,12 +554,26 @@ export default function FacturacionPage() {
? clavesUnidad?.filter(u => !SERVICE_UNITS.includes(u.clave))
: clavesUnidad;
const prodSearchAbort = useRef<AbortController | null>(null);
const handleSearchProduct = async (q: string, idx: number) => {
setProdSearch(q);
setSearchingIdx(idx);
if (q.length < 2) { setProdResults([]); return; }
const results = await searchClaveProdServ(q);
setProdResults(results);
setProdResults([]);
if (q.length < 2) return;
prodSearchAbort.current?.abort();
prodSearchAbort.current = new AbortController();
try {
const results = await searchClaveProdServ(q, prodSearchAbort.current.signal);
setProdResults(results ?? []);
} catch (err: any) {
if (err.name !== 'AbortError' && err.code !== 'ERR_CANCELED') {
console.error('Error buscando clave SAT:', err);
}
setProdResults([]);
}
};
const selectProduct = (idx: number, clave: string, descripcion: string) => {
@@ -1418,6 +1432,7 @@ export default function FacturacionPage() {
onChange={e => handleSearchProduct(e.target.value, idx)}
onFocus={() => { setSearchingIdx(idx); setProdSearch(c.productKey); }}
placeholder="Buscar clave SAT..."
autoComplete="off"
required
/>
<Search className="absolute right-3 top-2.5 h-4 w-4 text-muted-foreground" />