feature/tabs for invoice
This commit is contained in:
@@ -18,6 +18,10 @@ export const GLOBAL_NAV = {
|
||||
'r': '/dashboard/reference_data/pedimento_regimens',
|
||||
'e': '/dashboard/reference_data/customs_sections#',
|
||||
'd': '/dashboard/reference_data/customs_sections',
|
||||
|
||||
// Invoices
|
||||
'i': '/dashboard/invoices',
|
||||
|
||||
// Common Actions
|
||||
'b': 'SEARCH_FOCUS', // Special case for generic focus
|
||||
'h': '/', // Home
|
||||
|
||||
@@ -6,12 +6,9 @@ export const obtenerAtajosFormularioMercancia = (acciones: {
|
||||
manejarRegresar: () => void;
|
||||
}): ShortcutDef[] => [
|
||||
// Pestañas
|
||||
{ key: 'Alt+G', description: 'Tab General', action: () => acciones.cambiarPestana('general') },
|
||||
{ key: 'Alt+I', description: 'Tab Imágenes', action: () => acciones.cambiarPestana('cont1') },
|
||||
{ key: 'Alt+E', description: 'Tab Exportación', action: () => acciones.cambiarPestana('cont2') },
|
||||
{ key: 'Alt+O', description: 'Tab Opciones', action: () => acciones.cambiarPestana('opciones') },
|
||||
{ key: 'Alt+S', description: 'Tab Sanitarias', action: () => acciones.cambiarPestana('opcionales2') },
|
||||
{ key: 'Alt+X', description: 'Tab Otros', action: () => acciones.cambiarPestana('otros') },
|
||||
{ key: 'Alt+Digit1', description: 'Tab General', action: () => acciones.cambiarPestana('general') },
|
||||
{ key: 'Alt+Digit2', description: 'Tab Imágenes', action: () => acciones.cambiarPestana('cont1') },
|
||||
{ key: 'Alt+Digit3', description: 'Tab Exportación', action: () => acciones.cambiarPestana('cont2') },
|
||||
|
||||
// Acciones Globales
|
||||
{ key: 'Ctrl+S', description: 'Guardar cambios', action: acciones.manejarGuardar },
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
import type { ShortcutDef } from '../../stores/shortcut-store';
|
||||
|
||||
export const obtenerAtajosListaPartes = (acciones: {
|
||||
manejarNuevo: () => void;
|
||||
manejarActualizar: () => void;
|
||||
manejarBorrar: () => void;
|
||||
}): ShortcutDef[] => [
|
||||
{
|
||||
key: 'Alt+Shift+N',
|
||||
description: 'Nueva Parte',
|
||||
action: acciones.manejarNuevo
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+R',
|
||||
description: 'Actualizar Lista',
|
||||
action: acciones.manejarActualizar
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+D',
|
||||
description: 'Borrar Seleccionado',
|
||||
action: acciones.manejarBorrar
|
||||
}
|
||||
];
|
||||
|
||||
export const obtenerAtajosListaClasesActivoFijo = (acciones: {
|
||||
manejarNuevo: () => void;
|
||||
manejarActualizar: () => void;
|
||||
manejarBorrar: () => void;
|
||||
}): ShortcutDef[] => [
|
||||
{
|
||||
key: 'Alt+Shift+N',
|
||||
description: 'Nueva Clase',
|
||||
action: acciones.manejarNuevo
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+R',
|
||||
description: 'Actualizar Lista',
|
||||
action: acciones.manejarActualizar
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+D',
|
||||
description: 'Borrar Seleccionado',
|
||||
action: acciones.manejarBorrar
|
||||
}
|
||||
];
|
||||
|
||||
export const obtenerAtajosFormularioParte = (acciones: {
|
||||
cambiarPestana: (pestana: string) => void;
|
||||
manejarGuardar: () => void;
|
||||
manejarCancelar: () => void;
|
||||
esActivoFijo: boolean;
|
||||
}): ShortcutDef[] => {
|
||||
const common = [
|
||||
{ key: 'Alt+Digit1', description: 'Pest. General', action: () => acciones.cambiarPestana('general') },
|
||||
{ key: 'Ctrl+S', description: 'Guardar cambios', action: acciones.manejarGuardar },
|
||||
{ key: 'Escape', description: 'Cancelar / Regresar', action: acciones.manejarCancelar }
|
||||
];
|
||||
|
||||
if (acciones.esActivoFijo) {
|
||||
return [
|
||||
...common,
|
||||
{ key: 'Alt+Digit2', description: 'Pest. Continuación 1', action: () => acciones.cambiarPestana('cont1') },
|
||||
{ key: 'Alt+Digit3', description: 'Pest. Continuación 2', action: () => acciones.cambiarPestana('cont2') }
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
...common,
|
||||
{ key: 'Alt+Digit2', description: 'Pest. Opciones', action: () => acciones.cambiarPestana('opciones') },
|
||||
{ key: 'Alt+Digit3', description: 'Pest. Opcionales 2', action: () => acciones.cambiarPestana('opcionales2') },
|
||||
{ key: 'Alt+Digit4', description: 'Pest. Otros', action: () => acciones.cambiarPestana('otros') }
|
||||
];
|
||||
};
|
||||
15
frontend/src/lib/config/shortcuts/invoice-edit-shortcuts.ts
Normal file
15
frontend/src/lib/config/shortcuts/invoice-edit-shortcuts.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { ShortcutDef } from '$lib/stores/shortcut-store';
|
||||
|
||||
export const obtenerAtajosEdicionFactura = (acciones: {
|
||||
cambiarPestana: (pestana: string) => void;
|
||||
manejarGuardar: () => void;
|
||||
manejarRegresar: () => void;
|
||||
}): ShortcutDef[] => [
|
||||
{ key: 'Alt+Q', description: 'Tab General', action: () => acciones.cambiarPestana('general') },
|
||||
{ key: 'Alt+O', description: 'Tab Observ.', action: () => acciones.cambiarPestana('observations') },
|
||||
{ key: 'Alt+A', description: 'Tab Partidas (Artículos)', action: () => acciones.cambiarPestana('items') },
|
||||
{ key: 'Alt+X', description: 'Tab Otros', action: () => acciones.cambiarPestana('others') },
|
||||
{ key: 'Alt+K', description: 'Tab Cont.', action: () => acciones.cambiarPestana('continuation') },
|
||||
{ key: 'Ctrl+S', description: 'Guardar cambios', action: acciones.manejarGuardar },
|
||||
{ key: 'Escape', description: 'Regresar / Cancelar', action: acciones.manejarRegresar }
|
||||
];
|
||||
48
frontend/src/lib/config/shortcuts/invoice-list-shortcuts.ts
Normal file
48
frontend/src/lib/config/shortcuts/invoice-list-shortcuts.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { ShortcutDef } from '$lib/stores/shortcut-store';
|
||||
|
||||
export const obtenerAtajosListaFacturas = (acciones: {
|
||||
manejarCrear: () => void;
|
||||
manejarActualizar: () => void;
|
||||
manejarEditar: () => void;
|
||||
manejarDescargarPdf: () => void;
|
||||
manejarDescargarConsolidado: () => void;
|
||||
// Filtros de navegación
|
||||
irTemporal: () => void;
|
||||
irDefinitiva: () => void;
|
||||
irNacional: () => void;
|
||||
irCambioRegimen: () => void;
|
||||
irExportacion: () => void;
|
||||
irReparacion: () => void;
|
||||
}): ShortcutDef[] => [
|
||||
{ key: 'Alt+V', description: 'Ver Temporales', action: acciones.irTemporal },
|
||||
{ key: 'Alt+F', description: 'Ver Definitivas', action: acciones.irDefinitiva },
|
||||
{ key: 'Alt+N', description: 'Ver Nacionales', action: acciones.irNacional },
|
||||
{ key: 'Alt+Z', description: 'Ver Cambio Régimen', action: acciones.irCambioRegimen },
|
||||
{ key: 'Alt+L', description: 'Ver Exportaciones', action: acciones.irExportacion },
|
||||
{ key: 'Alt+Y', description: 'Ver Reparaciones', action: acciones.irReparacion },
|
||||
{
|
||||
key: 'Alt+Shift+N',
|
||||
description: 'Nueva Factura',
|
||||
action: acciones.manejarCrear
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+R',
|
||||
description: 'Actualizar Lista',
|
||||
action: acciones.manejarActualizar
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+E',
|
||||
description: 'Editar Seleccionada',
|
||||
action: acciones.manejarEditar
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+P',
|
||||
description: 'Descargar PDF',
|
||||
action: acciones.manejarDescargarPdf
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+C',
|
||||
description: 'Descargar Consolidado',
|
||||
action: acciones.manejarDescargarConsolidado
|
||||
}
|
||||
];
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,29 +2,29 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { browser } from '$app/environment';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { page } from '$app/stores';
|
||||
import * as Tabs from '$lib/components/ui/tabs';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { Badge } from '$lib/components/ui/badge';
|
||||
import { Separator } from '$lib/components/ui/separator';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import {
|
||||
ArrowLeft,
|
||||
FileText,
|
||||
DollarSign,
|
||||
Truck,
|
||||
Package,
|
||||
import {
|
||||
ArrowLeft,
|
||||
FileText,
|
||||
DollarSign,
|
||||
Truck,
|
||||
Package,
|
||||
Eye,
|
||||
LoaderCircle,
|
||||
Save
|
||||
} from 'lucide-svelte';
|
||||
|
||||
LoaderCircle,
|
||||
Save
|
||||
} from 'lucide-svelte';
|
||||
|
||||
// Importar los componentes de cada pestaña
|
||||
import GeneralTabForm from '$lib/components/dashboard/invoices/edit/general-tab-form.svelte';
|
||||
import ObservationsTabForm from '$lib/components/dashboard/invoices/edit/observations-tab-form.svelte';
|
||||
import ItemsTabForm from '$lib/components/dashboard/invoices/edit/items/items-tab-form.svelte';
|
||||
import OthersTabForm from '$lib/components/dashboard/invoices/edit/others-tab-form.svelte';
|
||||
import InvoiceTopFields from '$lib/components/dashboard/invoices/edit/invoice-top-fields.svelte';
|
||||
import InvoiceTopFields from '$lib/components/dashboard/invoices/edit/invoice-top-fields.svelte';
|
||||
import ContinuationTabForm from '$lib/components/dashboard/invoices/edit/continuation-tab-form.svelte';
|
||||
|
||||
// Importar la API de facturas
|
||||
@@ -35,11 +35,13 @@
|
||||
import { getExchangeRateByDate } from '$lib/api/dashboard/a76/exchange-rate';
|
||||
import { getExchangeRates } from '$lib/api/dashboard/a76/general_catalogs/exchange-rate';
|
||||
import ExchangeRateDialog from '$lib/components/dashboard/exchange_rate/create-edit-dialog.svelte';
|
||||
|
||||
import { useShortcuts } from '$lib/hooks/use-shortcuts';
|
||||
import { obtenerAtajosEdicionFactura } from '$lib/config/shortcuts/invoice-edit-shortcuts';
|
||||
|
||||
// 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');
|
||||
@@ -85,7 +87,7 @@
|
||||
|
||||
let activeTab = $state('general');
|
||||
let saving = $state(false);
|
||||
|
||||
|
||||
// ID de la factura
|
||||
let invoiceId = $state<number | null>(data.invoiceId ?? null);
|
||||
|
||||
@@ -103,10 +105,12 @@
|
||||
let othersExists = $state(false);
|
||||
let continuationExists = $state(false);
|
||||
|
||||
let calculatedExchangeRate = $state<number | null>(data.invoice?.financials?.exchange_rate ?? null);
|
||||
|
||||
let calculatedExchangeRate = $state<number | null>(
|
||||
data.invoice?.financials?.exchange_rate ?? null
|
||||
);
|
||||
|
||||
let showExchangeRateDialog = $state(false);
|
||||
let missingExchangeRateDate = $state("");
|
||||
let missingExchangeRateDate = $state('');
|
||||
|
||||
async function checkExchangeRate(date: string): Promise<boolean> {
|
||||
if (!date || !companyStore?.activeCompany?.id) return true;
|
||||
@@ -120,10 +124,10 @@
|
||||
date: date,
|
||||
page_size: 1
|
||||
});
|
||||
|
||||
|
||||
const actualResponse = response as any;
|
||||
const items = actualResponse.data?.items || [];
|
||||
|
||||
|
||||
if (items.length === 0) {
|
||||
console.log('No exchange rate found for', date);
|
||||
missingExchangeRateDate = date;
|
||||
@@ -139,7 +143,7 @@
|
||||
// Por seguridad, abrimos modal.
|
||||
missingExchangeRateDate = date;
|
||||
showExchangeRateDialog = true;
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,14 +151,14 @@
|
||||
$effect(() => {
|
||||
if (mounted && companyStore?.activeCompany?.id && InvoiceTopFieldsFormData?.invoice_date) {
|
||||
getExchangeRateByDate(InvoiceTopFieldsFormData.invoice_date, companyStore.activeCompany.id)
|
||||
.then(rate => {
|
||||
.then((rate) => {
|
||||
if (rate) {
|
||||
calculatedExchangeRate = rate.value;
|
||||
calculatedExchangeRate = rate.value;
|
||||
} else {
|
||||
calculatedExchangeRate = 0;
|
||||
}
|
||||
})
|
||||
.catch(err => console.error('Error auto-updating exchange rate:', err));
|
||||
.catch((err) => console.error('Error auto-updating exchange rate:', err));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -173,7 +177,7 @@
|
||||
try {
|
||||
// Validar ID si es edición
|
||||
if (!data.isCreate && !invoiceId) {
|
||||
toast.error("Error interrrno: No se encuentra el ID de la factura para actualizar.");
|
||||
toast.error('Error interrrno: No se encuentra el ID de la factura para actualizar.');
|
||||
saving = false;
|
||||
return;
|
||||
}
|
||||
@@ -199,7 +203,7 @@
|
||||
othersFormData,
|
||||
continuationFormData
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
// Crear un error con validationErrors si existen
|
||||
@@ -212,8 +216,8 @@
|
||||
|
||||
toast.success('Todos los cambios se guardaron correctamente');
|
||||
} catch (e) {
|
||||
console.error('Error saving all:', e);
|
||||
|
||||
console.error('Error saving all:', e);
|
||||
|
||||
if (e instanceof Error && e.message.includes('401')) {
|
||||
toast.error('Sesión expirada. Recargando página...');
|
||||
setTimeout(() => {
|
||||
@@ -221,26 +225,34 @@
|
||||
}, 1500);
|
||||
} else {
|
||||
const errorMessage = e instanceof Error ? e.message : 'Error al guardar los cambios';
|
||||
|
||||
|
||||
// Intercept exchange rate error
|
||||
if (errorMessage.includes('No existe un Tipo de Cambio registrado') || errorMessage.includes('financials.exchange_rate')) {
|
||||
console.log("Interceptor: Exchange rate missing error caught (Invoice Page).");
|
||||
|
||||
if (
|
||||
errorMessage.includes('No existe un Tipo de Cambio registrado') ||
|
||||
errorMessage.includes('financials.exchange_rate')
|
||||
) {
|
||||
console.log('Interceptor: Exchange rate missing error caught (Invoice Page).');
|
||||
|
||||
const dateMatch = errorMessage.match(/(\d{4}-\d{2}-\d{2})/);
|
||||
const missingDate = dateMatch ? dateMatch[0] : (InvoiceTopFieldsFormData?.invoice_date || "");
|
||||
|
||||
const missingDate = dateMatch
|
||||
? dateMatch[0]
|
||||
: InvoiceTopFieldsFormData?.invoice_date || '';
|
||||
|
||||
missingExchangeRateDate = missingDate;
|
||||
showExchangeRateDialog = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Si hay errores de validación, mostrarlos en detalle
|
||||
if (e && typeof e === 'object' && 'validationErrors' in e && Array.isArray((e as any).validationErrors)) {
|
||||
const validationErrors = (e as any).validationErrors;
|
||||
const errorList = validationErrors.map((err: any) =>
|
||||
`• ${err.message}`
|
||||
).join('\n');
|
||||
|
||||
if (
|
||||
e &&
|
||||
typeof e === 'object' &&
|
||||
'validationErrors' in e &&
|
||||
Array.isArray((e as any).validationErrors)
|
||||
) {
|
||||
const validationErrors = (e as any).validationErrors;
|
||||
const errorList = validationErrors.map((err: any) => `• ${err.message}`).join('\n');
|
||||
|
||||
toast.error(errorMessage, {
|
||||
description: errorList
|
||||
});
|
||||
@@ -254,6 +266,15 @@
|
||||
saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
useShortcuts(
|
||||
'Invoice Edit',
|
||||
obtenerAtajosEdicionFactura({
|
||||
cambiarPestana: (pestana) => (activeTab = pestana),
|
||||
manejarGuardar: handleSaveAll,
|
||||
manejarRegresar: handleBack
|
||||
})
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="space-y-3">
|
||||
@@ -267,7 +288,9 @@
|
||||
<h1 class="text-3xl font-bold tracking-tight">
|
||||
{#if data.isCreate}
|
||||
{@const invoiceType = generalFormData?.invoice_type || data.filters?.invoice_type}
|
||||
{@const invoiceTypeInfo = invoiceType ? data.invoiceTypes?.find(t => t.key === invoiceType) : null}
|
||||
{@const invoiceTypeInfo = invoiceType
|
||||
? data.invoiceTypes?.find((t) => t.key === invoiceType)
|
||||
: null}
|
||||
Nueva Factura
|
||||
{#if invoiceTypeInfo}
|
||||
<span class="text-muted-foreground font-normal text-2xl">
|
||||
@@ -301,18 +324,18 @@
|
||||
<!-- Contenido de las tabs con padding inferior para el footer flotante -->
|
||||
<div class="pb-48">
|
||||
<Tabs.Root bind:value={activeTab}>
|
||||
<InvoiceTopFields
|
||||
invoice={data.invoice}
|
||||
bind:formData={InvoiceTopFieldsFormData}
|
||||
invoiceTypes={data.invoiceTypes || []}
|
||||
pedimentos={data.pedimentos || []}
|
||||
defaultOperationType={data.filters?.operation_type ?? undefined}
|
||||
defaultInvoiceType={data.filters?.invoice_type ?? undefined}
|
||||
<InvoiceTopFields
|
||||
invoice={data.invoice}
|
||||
bind:formData={InvoiceTopFieldsFormData}
|
||||
invoiceTypes={data.invoiceTypes || []}
|
||||
pedimentos={data.pedimentos || []}
|
||||
defaultOperationType={data.filters?.operation_type ?? undefined}
|
||||
defaultInvoiceType={data.filters?.invoice_type ?? undefined}
|
||||
/>
|
||||
|
||||
<Tabs.Content value="general">
|
||||
<GeneralTabForm
|
||||
invoice={data.invoice}
|
||||
<Tabs.Content value="general">
|
||||
<GeneralTabForm
|
||||
invoice={data.invoice}
|
||||
bind:formData={generalFormData}
|
||||
invoiceTypes={data.invoiceTypes || []}
|
||||
customsBrokers={data.customsBrokers || []}
|
||||
@@ -323,45 +346,46 @@
|
||||
transporters={data.transporters || []}
|
||||
vehicles={data.vehicles || []}
|
||||
drivers={data.drivers || []}
|
||||
trailers={data.trailers || []}
|
||||
trailers={data.trailers || []}
|
||||
customsSections={data.customsSections || []}
|
||||
codePedimentoRegimens={data.codePedimentoRegimens || []}
|
||||
codePedimentoRegimens={data.codePedimentoRegimens || []}
|
||||
defaultOperationType={data.filters?.operation_type ?? undefined}
|
||||
defaultInvoiceType={data.filters?.invoice_type ?? undefined}
|
||||
operationType={
|
||||
InvoiceTopFieldsFormData?.operation_type === 'exp' ? 1
|
||||
: InvoiceTopFieldsFormData?.operation_type === 'imp' ? 2
|
||||
: data.invoice?.operation_type === 'exp' ? 1
|
||||
: data.invoice?.operation_type === 'imp' ? 2
|
||||
: undefined
|
||||
}
|
||||
operationType={InvoiceTopFieldsFormData?.operation_type === 'exp'
|
||||
? 1
|
||||
: InvoiceTopFieldsFormData?.operation_type === 'imp'
|
||||
? 2
|
||||
: data.invoice?.operation_type === 'exp'
|
||||
? 1
|
||||
: data.invoice?.operation_type === 'imp'
|
||||
? 2
|
||||
: undefined}
|
||||
exchangeRate={calculatedExchangeRate}
|
||||
/>
|
||||
</Tabs.Content>
|
||||
|
||||
<Tabs.Content value="observations">
|
||||
<ObservationsTabForm
|
||||
invoice={data.invoice}
|
||||
<ObservationsTabForm
|
||||
invoice={data.invoice}
|
||||
bind:formData={observationFormData}
|
||||
bind:exists={observationExists}
|
||||
seals={data.seals || []}
|
||||
incoterms={data.incoterms || []}
|
||||
enclosure={data.enclosure || []}
|
||||
|
||||
/>
|
||||
</Tabs.Content>
|
||||
|
||||
<Tabs.Content value="items">
|
||||
<ItemsTabForm
|
||||
invoice={data.invoice}
|
||||
<ItemsTabForm
|
||||
invoice={data.invoice}
|
||||
bind:formData={itemsFormData}
|
||||
bind:exists={itemsExists}
|
||||
/>
|
||||
</Tabs.Content>
|
||||
|
||||
<Tabs.Content value="others">
|
||||
<OthersTabForm
|
||||
invoice={data.invoice}
|
||||
<OthersTabForm
|
||||
invoice={data.invoice}
|
||||
bind:formData={othersFormData}
|
||||
bind:exists={othersExists}
|
||||
transportModes={data.transportModes || []}
|
||||
@@ -369,31 +393,33 @@
|
||||
</Tabs.Content>
|
||||
|
||||
<Tabs.Content value="continuation">
|
||||
<ContinuationTabForm
|
||||
invoice={data.invoice}
|
||||
bind:formData={continuationFormData}
|
||||
bind:exists={continuationExists}
|
||||
/>
|
||||
<ContinuationTabForm
|
||||
invoice={data.invoice}
|
||||
bind:formData={continuationFormData}
|
||||
bind:exists={continuationExists}
|
||||
/>
|
||||
</Tabs.Content>
|
||||
</Tabs.Root>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer fijo en la parte inferior -->
|
||||
<ExchangeRateDialog
|
||||
bind:open={showExchangeRateDialog}
|
||||
<ExchangeRateDialog
|
||||
bind:open={showExchangeRateDialog}
|
||||
initialDate={missingExchangeRateDate}
|
||||
onSuccess={() => {
|
||||
// Actualizar el tipo de cambio mostrado
|
||||
if (InvoiceTopFieldsFormData.invoice_date && companyStore?.activeCompany?.id) {
|
||||
getExchangeRateByDate(InvoiceTopFieldsFormData.invoice_date, companyStore.activeCompany.id)
|
||||
.then(rate => {
|
||||
getExchangeRateByDate(
|
||||
InvoiceTopFieldsFormData.invoice_date,
|
||||
companyStore.activeCompany.id
|
||||
).then((rate) => {
|
||||
if (rate) calculatedExchangeRate = rate.value;
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
<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] group-has-data-[state=collapsed]/sidebar-wrapper:ml-[calc(var(--sidebar-width-icon))] ml-[calc(var(--sidebar-width))]"
|
||||
>
|
||||
<div class="px-4 py-4 space-y-4 max-w-[1400px] mx-auto">
|
||||
@@ -413,7 +439,7 @@
|
||||
<DollarSign size={16} class="mr-2" />
|
||||
Partidas
|
||||
</Tabs.Trigger>
|
||||
<Tabs.Trigger value="others" disabled={false} class="whitespace-nowrap">
|
||||
<Tabs.Trigger value="others" disabled={false} class="whitespace-nowrap">
|
||||
<Truck size={16} class="mr-2" />
|
||||
Otros
|
||||
</Tabs.Trigger>
|
||||
|
||||
Reference in New Issue
Block a user