Update: nueva version Horux Despachos
This commit is contained in:
172
apps/web/lib/api/facturacion.ts
Normal file
172
apps/web/lib/api/facturacion.ts
Normal file
@@ -0,0 +1,172 @@
|
||||
import { apiClient } from './client';
|
||||
|
||||
export interface OrgStatus {
|
||||
configured: boolean;
|
||||
orgId?: string;
|
||||
legalName?: string;
|
||||
hasCsd?: boolean;
|
||||
}
|
||||
|
||||
export interface TimbreStatus {
|
||||
configured: boolean;
|
||||
// Backward compat (flat fields representan el pool mensual)
|
||||
tipo?: string;
|
||||
limite?: number;
|
||||
usados?: number;
|
||||
disponibles?: number;
|
||||
periodoFin?: string;
|
||||
// Shape extendido
|
||||
mensual?: {
|
||||
tipo: string;
|
||||
limite: number;
|
||||
usados: number;
|
||||
disponibles: number;
|
||||
periodoFin: string;
|
||||
};
|
||||
adicionales?: {
|
||||
total: number;
|
||||
usados: number;
|
||||
disponibles: number;
|
||||
paquetes: Array<{
|
||||
id: number;
|
||||
cantidad: number;
|
||||
usados: number;
|
||||
disponibles: number;
|
||||
adquiridoEn: string;
|
||||
expiraEn: string;
|
||||
}>;
|
||||
};
|
||||
totalDisponibles?: number;
|
||||
}
|
||||
|
||||
export interface InvoiceCustomer {
|
||||
legalName: string;
|
||||
taxId: string;
|
||||
taxSystem: string;
|
||||
email?: string;
|
||||
zip: string;
|
||||
}
|
||||
|
||||
export interface InvoiceLineItem {
|
||||
description: string;
|
||||
productKey: string;
|
||||
unitKey?: string;
|
||||
unitName?: string;
|
||||
quantity: number;
|
||||
price: number;
|
||||
taxIncluded?: boolean;
|
||||
taxes?: Array<{ type: string; rate: number }>;
|
||||
}
|
||||
|
||||
export interface InvoiceData {
|
||||
customer: InvoiceCustomer;
|
||||
items: InvoiceLineItem[];
|
||||
use: string;
|
||||
paymentForm: string;
|
||||
paymentMethod?: string;
|
||||
currency?: string;
|
||||
exchangeRate?: number;
|
||||
series?: string;
|
||||
folioNumber?: number;
|
||||
conditions?: string;
|
||||
}
|
||||
|
||||
export interface InvoiceResult {
|
||||
id: string;
|
||||
uuid: string;
|
||||
total: number;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export const getOrgStatus = () => apiClient.get<OrgStatus>('/facturacion/org/status').then(r => r.data);
|
||||
export const createOrg = () => apiClient.post('/facturacion/org').then(r => r.data);
|
||||
export const uploadCsd = (data: { cerFile: string; keyFile: string; password: string }) =>
|
||||
apiClient.post('/facturacion/csd', data).then(r => r.data);
|
||||
export const getTimbres = () => apiClient.get<TimbreStatus>('/facturacion/timbres').then(r => r.data);
|
||||
|
||||
export interface PaqueteCatalogo {
|
||||
id: number;
|
||||
cantidad: number;
|
||||
precio: number;
|
||||
}
|
||||
|
||||
export const getPaquetesCatalogo = () =>
|
||||
apiClient.get<PaqueteCatalogo[]>('/facturacion/timbres/paquetes-catalogo').then(r => r.data);
|
||||
|
||||
export const comprarPaquete = (catalogoId: number) =>
|
||||
apiClient.post<{ paymentId: string; checkoutUrl: string }>('/facturacion/timbres/paquetes/comprar', { catalogoId })
|
||||
.then(r => r.data);
|
||||
|
||||
export interface PaqueteCatalogoAdmin {
|
||||
id: number;
|
||||
cantidad: number;
|
||||
precio: number;
|
||||
active: boolean;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export const getPaquetesCatalogoAdmin = () =>
|
||||
apiClient.get<PaqueteCatalogoAdmin[]>('/facturacion/timbres/paquetes-catalogo/admin').then(r => r.data);
|
||||
|
||||
export const updatePaqueteCatalogo = (id: number, data: { precio?: number; active?: boolean }) =>
|
||||
apiClient.put<PaqueteCatalogoAdmin>(`/facturacion/timbres/paquetes-catalogo/${id}`, data).then(r => r.data);
|
||||
export const emitirFactura = (data: InvoiceData) =>
|
||||
apiClient.post<InvoiceResult>('/facturacion/emitir', data).then(r => r.data);
|
||||
export const cancelarFactura = (uuid: string, motive?: string, substitution?: string) =>
|
||||
apiClient.post(`/facturacion/cancelar/${uuid}`, { motive, substitution }).then(r => r.data);
|
||||
export const downloadPdf = (id: string) =>
|
||||
apiClient.get(`/facturacion/pdf/${id}`, { responseType: 'blob' }).then(r => r.data);
|
||||
export const downloadXml = (id: string) =>
|
||||
apiClient.get(`/facturacion/xml/${id}`, { responseType: 'blob' }).then(r => r.data);
|
||||
|
||||
export interface RfcSearchResult {
|
||||
id: number;
|
||||
rfc: string;
|
||||
razonSocial: string | null;
|
||||
regimenFiscal: string | null;
|
||||
codigoPostal: string | null;
|
||||
}
|
||||
|
||||
export const searchRfcs = (q: string) =>
|
||||
apiClient.get<RfcSearchResult[]>(`/facturacion/rfcs/search?q=${encodeURIComponent(q)}`).then(r => r.data);
|
||||
|
||||
export interface CfdiPpdPendiente {
|
||||
uuid: string;
|
||||
serie: string | null;
|
||||
folio: string | null;
|
||||
totalMxn: number;
|
||||
fechaEmision: string;
|
||||
rfcReceptor: string;
|
||||
nombreReceptor: string;
|
||||
ivaTrasladoMxn: number;
|
||||
saldoPendiente: number;
|
||||
}
|
||||
|
||||
export const getCfdisPpd = (rfc: string) =>
|
||||
apiClient.get<CfdiPpdPendiente[]>(`/facturacion/cfdis-ppd?rfc=${encodeURIComponent(rfc)}`).then(r => r.data);
|
||||
|
||||
export interface ConceptoPrevio {
|
||||
claveProdServ: string;
|
||||
descripcion: string;
|
||||
claveUnidad: string | null;
|
||||
unidad: string | null;
|
||||
valorUnitario: number;
|
||||
importe: number;
|
||||
ivaTraslado: number;
|
||||
isrRetencion: number;
|
||||
ivaRetencion: number;
|
||||
tipoCfdi: string;
|
||||
rfcEmisor: string;
|
||||
nombreEmisor: string;
|
||||
rfcReceptor: string;
|
||||
nombreReceptor: string;
|
||||
fechaEmision: string;
|
||||
}
|
||||
|
||||
export const searchConceptos = (q: string, tipo?: string, contribuyenteId?: string | null) => {
|
||||
const params = new URLSearchParams();
|
||||
if (q) params.set('q', q);
|
||||
if (tipo) params.set('tipo', tipo);
|
||||
if (contribuyenteId) params.set('contribuyenteId', contribuyenteId);
|
||||
return apiClient.get<ConceptoPrevio[]>(`/facturacion/conceptos/search?${params}`).then(r => r.data);
|
||||
};
|
||||
Reference in New Issue
Block a user