Files
HoruxDespachosNuevo/apps/web/lib/api/declaraciones.ts
Horux Dev 7df27ce66d 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.
2026-06-22 04:53:59 +00:00

91 lines
3.0 KiB
TypeScript

import { apiClient } from './client';
export type Impuesto = 'IVA' | 'ISR' | 'IEPS' | 'ISN' | 'DIOT' | 'OTRO' | 'ISH';
export type Periodicidad = 'mensual' | 'bimestral' | 'trimestral' | 'semestral' | 'anual';
export interface Declaracion {
id: number;
año: number;
mes: number;
tipo: 'normal' | 'complementaria';
periodicidad: Periodicidad;
impuestos: Impuesto[];
montoPago: number | null;
pdfFilename: string | null;
ligaPagoFilename: string | null;
pdfPagoFilename: string | null;
pagadoAt: string | null;
creadoPor: string | null;
notas: string | null;
createdAt: string;
updatedAt: string;
tieneLigaPago: boolean;
tienePagoPdf: boolean;
}
export interface CreateDeclaracionData {
año: number;
mes: number;
tipo: 'normal' | 'complementaria';
periodicidad?: Periodicidad;
/** Legacy: se infiere en backend si se envían obligacionesIds. */
impuestos?: Impuesto[];
/** Obligaciones fiscales que cubre esta declaración. */
obligacionesIds?: string[];
montoPago?: number;
pdfBase64: string;
pdfFilename: string;
ligaPagoBase64?: string;
ligaPagoFilename?: string;
notas?: string;
contribuyenteId?: string;
}
export const listDeclaraciones = (fechaDesde?: string, fechaHasta?: string, contribuyenteId?: string | null) => {
const params = new URLSearchParams();
if (fechaDesde) params.set('fechaDesde', fechaDesde);
if (fechaHasta) params.set('fechaHasta', fechaHasta);
if (contribuyenteId) params.set('contribuyenteId', contribuyenteId);
return apiClient.get<Declaracion[]>(`/documentos/declaraciones?${params}`).then(r => r.data);
};
export const createDeclaracion = (data: CreateDeclaracionData) =>
apiClient.post<{ declaracion: Declaracion; alertasResueltas: number }>('/documentos/declaraciones', data).then(r => r.data);
export const uploadComprobantePago = (id: number, pdfBase64: string, pdfFilename: string) =>
apiClient.post<{ declaracion: Declaracion; alertasResueltas: number }>(
`/documentos/declaraciones/${id}/comprobante-pago`,
{ pdfBase64, pdfFilename },
).then(r => r.data);
export const deleteDeclaracion = (id: number) =>
apiClient.delete(`/documentos/declaraciones/${id}`).then(r => r.data);
export const downloadDeclaracionPdf = (id: number, variant: 'declaracion' | 'liga' | 'pago') =>
apiClient.get(`/documentos/declaraciones/${id}/pdf/${variant}`, { responseType: 'blob' }).then(r => r.data as Blob);
export function fileToBase64(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const result = reader.result as string;
// result format: "data:application/pdf;base64,..."
const base64 = result.split(',')[1] || '';
resolve(base64);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
export function downloadBlob(blob: Blob, filename: string) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
}