Refactor invoice edit flow: enhance error handling, load reference data, and improve token management
This commit is contained in:
@@ -134,48 +134,63 @@ export async function authenticatedFetch(
|
||||
fetch: typeof globalThis.fetch,
|
||||
redirectUrl?: string
|
||||
): Promise<Response> {
|
||||
const baseUrl = getServerApiUrl();
|
||||
let { accessToken } = getAuthTokens(cookies);
|
||||
try {
|
||||
const baseUrl = getServerApiUrl();
|
||||
let { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
// Si no hay token, redirigir o lanzar error
|
||||
if (!accessToken) {
|
||||
if (redirectUrl) {
|
||||
throw redirect(303, redirectUrl);
|
||||
}
|
||||
throw new Error('No access token available');
|
||||
}
|
||||
|
||||
// Construir URL completa
|
||||
const url = endpoint.startsWith('http') ? endpoint : `${baseUrl}${endpoint}`;
|
||||
|
||||
// Realizar la petición inicial
|
||||
const headers = createAuthHeaders(accessToken, options.headers as Record<string, string>);
|
||||
let response = await fetch(url, {
|
||||
...options,
|
||||
headers
|
||||
});
|
||||
|
||||
// Si es 401, intentar refrescar el token
|
||||
if (response.status === 401) {
|
||||
const newToken = await refreshAccessToken(cookies, fetch);
|
||||
|
||||
if (newToken) {
|
||||
// Reintentar la petición con el nuevo token
|
||||
const newHeaders = createAuthHeaders(newToken, options.headers as Record<string, string>);
|
||||
response = await fetch(url, {
|
||||
...options,
|
||||
headers: newHeaders
|
||||
});
|
||||
} else {
|
||||
// No se pudo refrescar, limpiar y redirigir
|
||||
clearAuthTokens(cookies);
|
||||
// Si no hay token, redirigir o lanzar error
|
||||
if (!accessToken) {
|
||||
if (redirectUrl) {
|
||||
throw redirect(303, redirectUrl);
|
||||
}
|
||||
throw new Error('No access token available');
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
// Construir URL completa
|
||||
const url = endpoint.startsWith('http') ? endpoint : `${baseUrl}${endpoint}`;
|
||||
|
||||
// Realizar la petición inicial
|
||||
const headers = createAuthHeaders(accessToken, options.headers as Record<string, string>);
|
||||
let response = await fetch(url, {
|
||||
...options,
|
||||
headers
|
||||
});
|
||||
|
||||
// Si es 401, intentar refrescar el token
|
||||
if (response.status === 401) {
|
||||
const newToken = await refreshAccessToken(cookies, fetch);
|
||||
|
||||
if (newToken) {
|
||||
// Reintentar la petición con el nuevo token
|
||||
const newHeaders = createAuthHeaders(newToken, options.headers as Record<string, string>);
|
||||
response = await fetch(url, {
|
||||
...options,
|
||||
headers: newHeaders
|
||||
});
|
||||
} else {
|
||||
// No se pudo refrescar, limpiar y redirigir
|
||||
clearAuthTokens(cookies);
|
||||
if (redirectUrl) {
|
||||
throw redirect(303, redirectUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
// Si es un redirect, re-lanzarlo
|
||||
if (error && typeof error === 'object' && 'status' in error && 'location' in error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.error('🔴 [API] Error en authenticatedFetch:', endpoint, error);
|
||||
|
||||
// Retornar una respuesta de error simulada en lugar de lanzar
|
||||
return new Response(JSON.stringify({ error: 'Network error', details: String(error) }), {
|
||||
status: 500,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
80
frontend/src/routes/api/invoices/[id]/edit-data/+server.ts
Normal file
80
frontend/src/routes/api/invoices/[id]/edit-data/+server.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import type { RequestHandler } from './$types';
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import { getAuthTokens, getActiveCompanyId, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const GET: RequestHandler = async ({ params, cookies, fetch }) => {
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!accessToken) {
|
||||
throw error(401, 'Not authenticated');
|
||||
}
|
||||
|
||||
const companyId = await getActiveCompanyId(cookies, fetch);
|
||||
|
||||
if (!companyId) {
|
||||
throw error(400, 'No company selected');
|
||||
}
|
||||
|
||||
const invoiceId = parseInt(params.id);
|
||||
if (isNaN(invoiceId)) {
|
||||
throw error(400, 'Invalid invoice ID');
|
||||
}
|
||||
|
||||
try {
|
||||
// Cargar la factura y datos de referencia en paralelo
|
||||
const [
|
||||
invoiceResponse,
|
||||
invoiceTypesResponse,
|
||||
customsBrokersResponse,
|
||||
clientsResponse,
|
||||
providersResponse,
|
||||
currencyTypesResponse,
|
||||
transportTypesResponse,
|
||||
sealsResponse,
|
||||
incotermsResponse,
|
||||
pedimentosResponse
|
||||
] = await Promise.all([
|
||||
authenticatedFetch(`v1/a76/invoices/${invoiceId}?company_id=${companyId}`, {}, cookies, fetch),
|
||||
authenticatedFetch('v1/public/refrence_data/invoice-types/?page=1&page_size=100', {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/customs-brokers/?company_id=${companyId}&page=1&page_size=100`, {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/clients-providers/?company_id=${companyId}&type=client&page=1&page_size=1000`, {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/clients-providers/?company_id=${companyId}&type=provider&page=1&page_size=1000`, {}, cookies, fetch),
|
||||
authenticatedFetch('v1/public/refrence_data/currency-types/?page=1&page_size=100', {}, cookies, fetch),
|
||||
authenticatedFetch('v1/public/refrence_data/transport-types/?page=1&page_size=100', {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/seals/?company_id=${companyId}&page=1&page_size=100`, {}, cookies, fetch),
|
||||
authenticatedFetch('v1/public/refrence_data/incoterms/?page=1&page_size=100', {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/pedimentos/?company_id=${companyId}&page=1&page_size=100`, {}, cookies, fetch)
|
||||
]);
|
||||
|
||||
if (!invoiceResponse.ok) {
|
||||
throw error(invoiceResponse.status, 'Error loading invoice');
|
||||
}
|
||||
|
||||
const invoice = await invoiceResponse.json();
|
||||
const invoiceTypes = invoiceTypesResponse.ok ? await invoiceTypesResponse.json() : { items: [] };
|
||||
const customsBrokers = customsBrokersResponse.ok ? await customsBrokersResponse.json() : { items: [] };
|
||||
const clients = clientsResponse.ok ? await clientsResponse.json() : { items: [] };
|
||||
const providers = providersResponse.ok ? await providersResponse.json() : { items: [] };
|
||||
const currencyTypes = currencyTypesResponse.ok ? await currencyTypesResponse.json() : { items: [] };
|
||||
const transportTypes = transportTypesResponse.ok ? await transportTypesResponse.json() : { items: [] };
|
||||
const seals = sealsResponse.ok ? await sealsResponse.json() : { items: [] };
|
||||
const incoterms = incotermsResponse.ok ? await incotermsResponse.json() : { items: [] };
|
||||
const pedimentos = pedimentosResponse.ok ? await pedimentosResponse.json() : { items: [] };
|
||||
|
||||
return json({
|
||||
invoice,
|
||||
invoiceTypes: invoiceTypes.items || [],
|
||||
customsBrokers: customsBrokers.items || [],
|
||||
clients: clients.items || [],
|
||||
providers: providers.items || [],
|
||||
currencyTypes: currencyTypes.items || [],
|
||||
transportTypes: transportTypes.items || [],
|
||||
seals: seals.items || [],
|
||||
incoterms: incoterms.items || [],
|
||||
pedimentos: pedimentos.items || []
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Error loading invoice edit data:', err);
|
||||
throw error(500, 'Error loading invoice');
|
||||
}
|
||||
};
|
||||
67
frontend/src/routes/api/invoices/reference-data/+server.ts
Normal file
67
frontend/src/routes/api/invoices/reference-data/+server.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import type { RequestHandler } from './$types';
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { getAuthTokens, getActiveCompanyId, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const GET: RequestHandler = async ({ cookies, fetch }) => {
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!accessToken) {
|
||||
return json({ error: 'Not authenticated' }, { status: 401 });
|
||||
}
|
||||
|
||||
const companyId = await getActiveCompanyId(cookies, fetch);
|
||||
|
||||
if (!companyId) {
|
||||
return json({ error: 'No company selected' }, { status: 400 });
|
||||
}
|
||||
|
||||
try {
|
||||
// Cargar todos los datos de referencia en paralelo
|
||||
const [
|
||||
invoiceTypesResponse,
|
||||
customsBrokersResponse,
|
||||
clientsResponse,
|
||||
providersResponse,
|
||||
currencyTypesResponse,
|
||||
transportTypesResponse,
|
||||
sealsResponse,
|
||||
incotermsResponse,
|
||||
pedimentosResponse
|
||||
] = await Promise.all([
|
||||
authenticatedFetch('v1/public/refrence_data/invoice-types/?page=1&page_size=100', {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/customs-brokers/?company_id=${companyId}&page=1&page_size=100`, {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/clients-providers/?company_id=${companyId}&type=client&page=1&page_size=1000`, {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/clients-providers/?company_id=${companyId}&type=provider&page=1&page_size=1000`, {}, cookies, fetch),
|
||||
authenticatedFetch('v1/public/refrence_data/currency-types/?page=1&page_size=100', {}, cookies, fetch),
|
||||
authenticatedFetch('v1/public/refrence_data/transport-types/?page=1&page_size=100', {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/seals/?company_id=${companyId}&page=1&page_size=100`, {}, cookies, fetch),
|
||||
authenticatedFetch('v1/public/refrence_data/incoterms/?page=1&page_size=100', {}, cookies, fetch),
|
||||
authenticatedFetch(`v1/a76/pedimentos/?company_id=${companyId}&page=1&page_size=100`, {}, cookies, fetch)
|
||||
]);
|
||||
|
||||
const invoiceTypes = invoiceTypesResponse.ok ? await invoiceTypesResponse.json() : { items: [] };
|
||||
const customsBrokers = customsBrokersResponse.ok ? await customsBrokersResponse.json() : { items: [] };
|
||||
const clients = clientsResponse.ok ? await clientsResponse.json() : { items: [] };
|
||||
const providers = providersResponse.ok ? await providersResponse.json() : { items: [] };
|
||||
const currencyTypes = currencyTypesResponse.ok ? await currencyTypesResponse.json() : { items: [] };
|
||||
const transportTypes = transportTypesResponse.ok ? await transportTypesResponse.json() : { items: [] };
|
||||
const seals = sealsResponse.ok ? await sealsResponse.json() : { items: [] };
|
||||
const incoterms = incotermsResponse.ok ? await incotermsResponse.json() : { items: [] };
|
||||
const pedimentos = pedimentosResponse.ok ? await pedimentosResponse.json() : { items: [] };
|
||||
|
||||
return json({
|
||||
invoiceTypes: invoiceTypes.items || [],
|
||||
customsBrokers: customsBrokers.items || [],
|
||||
clients: clients.items || [],
|
||||
providers: providers.items || [],
|
||||
currencyTypes: currencyTypes.items || [],
|
||||
transportTypes: transportTypes.items || [],
|
||||
seals: seals.items || [],
|
||||
incoterms: incoterms.items || [],
|
||||
pedimentos: pedimentos.items || []
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Error loading reference data:', err);
|
||||
return json({ error: 'Error loading reference data' }, { status: 500 });
|
||||
}
|
||||
};
|
||||
@@ -97,57 +97,80 @@ export const load: PageServerLoad = async ({ params, cookies, fetch, url }) => {
|
||||
|
||||
// Si el ID es "new", es una creación
|
||||
if (params.id === 'new') {
|
||||
const [
|
||||
invoiceTypesResponse,
|
||||
customsBrokersResponse,
|
||||
clientsResponse,
|
||||
providersResponse,
|
||||
currencyTypesResponse,
|
||||
transportTypesResponse,
|
||||
sealsResponse,
|
||||
incotermsResponse,
|
||||
pedimentosResponse
|
||||
] = await Promise.all([
|
||||
invoiceTypesPromise,
|
||||
customsBrokersPromise,
|
||||
clientsPromise,
|
||||
providersPromise,
|
||||
currencyTypesPromise,
|
||||
transportTypesPromise,
|
||||
sealsPromise,
|
||||
incotermsPromise,
|
||||
pedimentosPromise
|
||||
]);
|
||||
try {
|
||||
const [
|
||||
invoiceTypesResponse,
|
||||
customsBrokersResponse,
|
||||
clientsResponse,
|
||||
providersResponse,
|
||||
currencyTypesResponse,
|
||||
transportTypesResponse,
|
||||
sealsResponse,
|
||||
incotermsResponse,
|
||||
pedimentosResponse
|
||||
] = await Promise.all([
|
||||
invoiceTypesPromise,
|
||||
customsBrokersPromise,
|
||||
clientsPromise,
|
||||
providersPromise,
|
||||
currencyTypesPromise,
|
||||
transportTypesPromise,
|
||||
sealsPromise,
|
||||
incotermsPromise,
|
||||
pedimentosPromise
|
||||
]);
|
||||
|
||||
const invoiceTypes = invoiceTypesResponse.ok ? await invoiceTypesResponse.json() : { items: [] };
|
||||
const customsBrokers = customsBrokersResponse.ok ? await customsBrokersResponse.json() : { items: [] };
|
||||
const clients = clientsResponse.ok ? await clientsResponse.json() : { items: [] };
|
||||
const providers = providersResponse.ok ? await providersResponse.json() : { items: [] };
|
||||
const currencyTypes = currencyTypesResponse.ok ? await currencyTypesResponse.json() : { items: [] };
|
||||
const transportTypes = transportTypesResponse.ok ? await transportTypesResponse.json() : { items: [] };
|
||||
const seals = sealsResponse.ok ? await sealsResponse.json() : { items: [] };
|
||||
const incoterms = incotermsResponse.ok ? await incotermsResponse.json() : { items: [] };
|
||||
const pedimentos = pedimentosResponse.ok ? await pedimentosResponse.json() : { items: [] };
|
||||
const invoiceTypes = invoiceTypesResponse.ok ? await invoiceTypesResponse.json() : { items: [] };
|
||||
const customsBrokers = customsBrokersResponse.ok ? await customsBrokersResponse.json() : { items: [] };
|
||||
const clients = clientsResponse.ok ? await clientsResponse.json() : { items: [] };
|
||||
const providers = providersResponse.ok ? await providersResponse.json() : { items: [] };
|
||||
const currencyTypes = currencyTypesResponse.ok ? await currencyTypesResponse.json() : { items: [] };
|
||||
const transportTypes = transportTypesResponse.ok ? await transportTypesResponse.json() : { items: [] };
|
||||
const seals = sealsResponse.ok ? await sealsResponse.json() : { items: [] };
|
||||
const incoterms = incotermsResponse.ok ? await incotermsResponse.json() : { items: [] };
|
||||
const pedimentos = pedimentosResponse.ok ? await pedimentosResponse.json() : { items: [] };
|
||||
|
||||
return {
|
||||
invoice: null,
|
||||
invoiceId: null,
|
||||
isCreate: true,
|
||||
invoiceTypes: invoiceTypes.items || [],
|
||||
customsBrokers: customsBrokers.items || [],
|
||||
clients: clients.items || [],
|
||||
providers: providers.items || [],
|
||||
currencyTypes: currencyTypes.items || [],
|
||||
transportTypes: transportTypes.items || [],
|
||||
seals: seals.items || [],
|
||||
incoterms: incoterms.items || [],
|
||||
pedimentos: pedimentos.items || [],
|
||||
// Filtros desde query parameters para preselección
|
||||
filters: {
|
||||
operation_type: parsedOperationType,
|
||||
invoice_type: invoiceTypeParam || null
|
||||
}
|
||||
};
|
||||
return {
|
||||
invoice: null,
|
||||
invoiceId: null,
|
||||
isCreate: true,
|
||||
invoiceTypes: invoiceTypes.items || [],
|
||||
customsBrokers: customsBrokers.items || [],
|
||||
clients: clients.items || [],
|
||||
providers: providers.items || [],
|
||||
currencyTypes: currencyTypes.items || [],
|
||||
transportTypes: transportTypes.items || [],
|
||||
seals: seals.items || [],
|
||||
incoterms: incoterms.items || [],
|
||||
pedimentos: pedimentos.items || [],
|
||||
// Filtros desde query parameters para preselección
|
||||
filters: {
|
||||
operation_type: parsedOperationType,
|
||||
invoice_type: invoiceTypeParam || null
|
||||
}
|
||||
};
|
||||
} catch (err) {
|
||||
console.error('Error loading data for new invoice:', err);
|
||||
// En caso de error, devolver estructura mínima para que la página pueda cargar
|
||||
return {
|
||||
invoice: null,
|
||||
invoiceId: null,
|
||||
isCreate: true,
|
||||
invoiceTypes: [],
|
||||
customsBrokers: [],
|
||||
clients: [],
|
||||
providers: [],
|
||||
currencyTypes: [],
|
||||
transportTypes: [],
|
||||
seals: [],
|
||||
incoterms: [],
|
||||
pedimentos: [],
|
||||
filters: {
|
||||
operation_type: parsedOperationType,
|
||||
invoice_type: invoiceTypeParam || null
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const invoiceId = parseInt(params.id);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { browser } from '$app/environment';
|
||||
import { goto } from '$app/navigation';
|
||||
import * as Tabs from '$lib/components/ui/tabs';
|
||||
import * as Alert from '$lib/components/ui/alert';
|
||||
@@ -17,8 +19,6 @@
|
||||
LoaderCircle,
|
||||
Save
|
||||
} from 'lucide-svelte';
|
||||
import { useSidebar } from '$lib/components/ui/sidebar/context.svelte';
|
||||
import { companyStore } from '$lib/stores/company.svelte';
|
||||
|
||||
// Importar los componentes de cada pestaña
|
||||
import GeneralTabForm from '$lib/components/dashboard/invoices/edit/general-tab-form.svelte';
|
||||
@@ -34,8 +34,20 @@
|
||||
import type { CustomsBroker } from '$lib/api/dashboard/a76/customs-brokers';
|
||||
import type { ClientProvider } from '$lib/api/dashboard/a76/clients-providers';
|
||||
|
||||
// Get sidebar context
|
||||
const sidebar = useSidebar();
|
||||
// Cargar companyStore solo en el cliente - no usamos sidebar en esta página
|
||||
let companyStore: any = $state(undefined);
|
||||
let mounted = $state(false);
|
||||
|
||||
onMount(async () => {
|
||||
try {
|
||||
const companyStoreModule = await import('$lib/stores/company.svelte');
|
||||
companyStore = companyStoreModule.companyStore;
|
||||
mounted = true;
|
||||
} catch (err) {
|
||||
console.error('Error loading client modules:', err);
|
||||
mounted = true;
|
||||
}
|
||||
});
|
||||
|
||||
interface ExtendedPageData {
|
||||
invoiceId?: number | null;
|
||||
@@ -471,7 +483,7 @@
|
||||
|
||||
if (data.isCreate) {
|
||||
// Crear nueva factura con todos sus sub-recursos
|
||||
const response = await invoicesApi.create(companyStore.activeCompany?.id || 0, payload as CreateInvoiceData);
|
||||
const response = await invoicesApi.create(companyStore?.activeCompany?.id || 0, payload as CreateInvoiceData);
|
||||
if (response.error) {
|
||||
const errorMsg = typeof response.error === 'string' ? response.error : 'Error al crear la factura';
|
||||
throw new Error(errorMsg);
|
||||
@@ -484,7 +496,7 @@
|
||||
return;
|
||||
} else {
|
||||
// Actualizar factura existente con todos sus sub-recursos
|
||||
const response = await invoicesApi.update(invoiceId!, companyStore.activeCompany?.id || 0, payload as UpdateInvoiceData);
|
||||
const response = await invoicesApi.update(invoiceId!, companyStore?.activeCompany?.id || 0, payload as UpdateInvoiceData);
|
||||
if (response.error) throw new Error(response.error);
|
||||
}
|
||||
|
||||
@@ -635,8 +647,7 @@
|
||||
|
||||
<!-- Footer fijo en la parte inferior -->
|
||||
<div
|
||||
class="fixed bottom-0 left-0 right-0 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 border-t shadow-lg z-[5] transition-[left] duration-200 ease-linear"
|
||||
style:left={sidebar.isMobile ? '0' : (sidebar.open ? 'var(--sidebar-width)' : '0')}
|
||||
class="fixed bottom-0 left-0 right-0 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 border-t shadow-lg z-[5]"
|
||||
>
|
||||
<div class="px-4 py-4 space-y-4 max-w-[1400px] mx-auto">
|
||||
<!-- Tabs Navigation -->
|
||||
|
||||
132
frontend/src/routes/dashboard/invoices/edit/[id]/+page.ts
Normal file
132
frontend/src/routes/dashboard/invoices/edit/[id]/+page.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
import type { PageLoad } from './$types';
|
||||
import { error } from '@sveltejs/kit';
|
||||
|
||||
// Deshabilitar SSR para esta página debido al layout de dashboard que usa stores del cliente
|
||||
export const ssr = false;
|
||||
|
||||
export const load: PageLoad = async ({ params, url, parent }) => {
|
||||
// Obtener datos del layout padre
|
||||
const parentData = await parent();
|
||||
|
||||
const operationTypeParam = url.searchParams.get('operation_type');
|
||||
const invoiceTypeParam = url.searchParams.get('invoice_type');
|
||||
|
||||
let parsedOperationType: number | null = null;
|
||||
if (operationTypeParam) {
|
||||
const parsed = parseInt(operationTypeParam, 10);
|
||||
if (!isNaN(parsed)) {
|
||||
parsedOperationType = parsed;
|
||||
}
|
||||
}
|
||||
|
||||
// Si el ID es "new", cargar datos de referencia
|
||||
if (params.id === 'new') {
|
||||
try {
|
||||
// Llamar a la ruta de servidor que ya existe
|
||||
const response = await fetch(`/api/invoices/reference-data`);
|
||||
|
||||
if (!response.ok) {
|
||||
console.error('Error loading reference data:', response.status);
|
||||
// Retornar estructura vacía en caso de error
|
||||
return {
|
||||
invoice: null,
|
||||
invoiceId: null,
|
||||
isCreate: true,
|
||||
invoiceTypes: [],
|
||||
customsBrokers: [],
|
||||
clients: [],
|
||||
providers: [],
|
||||
currencyTypes: [],
|
||||
transportTypes: [],
|
||||
seals: [],
|
||||
incoterms: [],
|
||||
pedimentos: [],
|
||||
filters: {
|
||||
operation_type: parsedOperationType,
|
||||
invoice_type: invoiceTypeParam || null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
return {
|
||||
invoice: null,
|
||||
invoiceId: null,
|
||||
isCreate: true,
|
||||
invoiceTypes: data.invoiceTypes || [],
|
||||
customsBrokers: data.customsBrokers || [],
|
||||
clients: data.clients || [],
|
||||
providers: data.providers || [],
|
||||
currencyTypes: data.currencyTypes || [],
|
||||
transportTypes: data.transportTypes || [],
|
||||
seals: data.seals || [],
|
||||
incoterms: data.incoterms || [],
|
||||
pedimentos: data.pedimentos || [],
|
||||
filters: {
|
||||
operation_type: parsedOperationType,
|
||||
invoice_type: invoiceTypeParam || null
|
||||
}
|
||||
};
|
||||
} catch (err) {
|
||||
console.error('Error loading data for new invoice:', err);
|
||||
return {
|
||||
invoice: null,
|
||||
invoiceId: null,
|
||||
isCreate: true,
|
||||
invoiceTypes: [],
|
||||
customsBrokers: [],
|
||||
clients: [],
|
||||
providers: [],
|
||||
currencyTypes: [],
|
||||
transportTypes: [],
|
||||
seals: [],
|
||||
incoterms: [],
|
||||
pedimentos: [],
|
||||
filters: {
|
||||
operation_type: parsedOperationType,
|
||||
invoice_type: invoiceTypeParam || null
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Si es un ID numérico, cargar la factura
|
||||
const invoiceId = parseInt(params.id);
|
||||
if (isNaN(invoiceId)) {
|
||||
throw error(400, 'ID de factura inválido');
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/invoices/${invoiceId}/edit-data`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw error(response.status, 'Error al cargar la factura');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
return {
|
||||
invoice: data.invoice,
|
||||
invoiceId,
|
||||
isCreate: false,
|
||||
invoiceTypes: data.invoiceTypes || [],
|
||||
customsBrokers: data.customsBrokers || [],
|
||||
clients: data.clients || [],
|
||||
providers: data.providers || [],
|
||||
currencyTypes: data.currencyTypes || [],
|
||||
transportTypes: data.transportTypes || [],
|
||||
seals: data.seals || [],
|
||||
incoterms: data.incoterms || [],
|
||||
pedimentos: data.pedimentos || [],
|
||||
filters: {
|
||||
operation_type: parsedOperationType,
|
||||
invoice_type: invoiceTypeParam || null
|
||||
}
|
||||
};
|
||||
} catch (err) {
|
||||
console.error('Error loading invoice:', err);
|
||||
throw error(500, 'Error al cargar la factura');
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user