feat: implement exchange rate filtering and validation enhancements in invoice processing
This commit is contained in:
@@ -26,20 +26,13 @@ export interface ExchangeRateListResponse {
|
||||
*/
|
||||
export async function getExchangeRateByDate(date: string, companyId: number): Promise<ExchangeRate | null> {
|
||||
try {
|
||||
// Get all exchange rates and filter by date on client side
|
||||
const response = await api.get<ExchangeRateListResponse>(`/v1/a76/exchange-rate/?company_id=${companyId}`);
|
||||
const dateOnly = date.split('T')[0]; // Ensure YYYY-MM-DD
|
||||
// Filter by date on server side
|
||||
const response = await api.get<ExchangeRateListResponse>(`/v1/a76/exchange-rate/?company_id=${companyId}&date=${dateOnly}`);
|
||||
|
||||
if (response.data && response.data.items && response.data.items.length > 0) {
|
||||
// Filter by date and find USD exchange rate
|
||||
const dateOnly = date.split('T')[0]; // Get YYYY-MM-DD part
|
||||
|
||||
const matchingRates = response.data.items.filter(rate => {
|
||||
const rateDate = rate.date.split('T')[0];
|
||||
const matches = rateDate === dateOnly && rate.foreign_currency === 'USD';
|
||||
return matches;
|
||||
});
|
||||
|
||||
return matchingRates.length > 0 ? matchingRates[0] : null;
|
||||
// Find USD exchange rate (backend might return multiple currencies for same date if they exist)
|
||||
return response.data.items[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
codePedimentoRegimens = [],
|
||||
defaultOperationType = undefined,
|
||||
defaultInvoiceType = undefined,
|
||||
operationType = undefined
|
||||
operationType = undefined,
|
||||
exchangeRate = undefined
|
||||
}: {
|
||||
invoice: Invoice | null;
|
||||
formData?: any;
|
||||
@@ -44,7 +45,15 @@
|
||||
defaultOperationType?: number | null;
|
||||
defaultInvoiceType?: string | null;
|
||||
operationType?: number | null;
|
||||
} = $props();
|
||||
exchangeRate?: number | null;
|
||||
} = $props();
|
||||
|
||||
// Sync exchangeRate prop to formData
|
||||
$effect(() => {
|
||||
if (exchangeRate !== undefined && formData) {
|
||||
formData.exchange_rate = exchangeRate;
|
||||
}
|
||||
});
|
||||
|
||||
if (!formData) {
|
||||
if (invoice) {
|
||||
@@ -62,8 +71,9 @@
|
||||
|
||||
// RIGHT fields
|
||||
currency_type: invoice.financials?.currency_type || '',
|
||||
currency: invoice.financials?.currency || 'foreign', // foreign, local, manual
|
||||
weight_type: 'kgs',
|
||||
currency: invoice.financials?.currency || 'foreign', // foreign, local, manual
|
||||
exchange_rate: invoice.financials?.exchange_rate || null, // Added exchange_rate
|
||||
weight_type: 'kgs',
|
||||
iva_factor: invoice.financials?.iva_factor || null,
|
||||
carrier_id: invoice.logistics?.[0]?.carrier_id || null,
|
||||
transport_id: '',
|
||||
@@ -72,8 +82,7 @@
|
||||
transport_num: invoice.logistics?.[0]?.vehicle_num || '',
|
||||
aduana: invoice.compliance_mx?.aduana || '',
|
||||
document_type: invoice.document_type || '',
|
||||
};
|
||||
console.log('FormData cargado para edición:', formData);
|
||||
};
|
||||
} else {
|
||||
// Creando una nueva factura
|
||||
formData = {
|
||||
@@ -90,6 +99,7 @@
|
||||
// RIGHT fields
|
||||
currency_type: '',
|
||||
currency: 'foreign', // foreign, local, manual
|
||||
exchange_rate: null, // Added exchange_rate
|
||||
weight_type: 'kgs',
|
||||
iva_factor: null,
|
||||
carrier_id: null,
|
||||
@@ -410,7 +420,14 @@
|
||||
<div class="border rounded-md p-3 space-y-2">
|
||||
<div class="flex justify-between">
|
||||
<h4 class="text-xs font-semibold text-muted-foreground uppercase">Tipo de Moneda - Pesos Netos y Brutos</h4>
|
||||
<h4 class="text-xs font-semibold text-muted-foreground uppercase">Tipo de cambio: </h4>
|
||||
<h4 class="text-xs font-semibold text-muted-foreground uppercase">
|
||||
Tipo de cambio:
|
||||
<span class="text-primary ml-1">
|
||||
{(exchangeRate !== undefined && exchangeRate !== null)
|
||||
? (exchangeRate === 0 ? 'N/A' : Number(exchangeRate).toFixed(4))
|
||||
: (formData.exchange_rate ? Number(formData.exchange_rate).toFixed(4) : 'N/A')}
|
||||
</span>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<!-- Radio buttons para tipo de moneda -->
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
pedimento: invoice?.compliance_mx?.pedimento || '',
|
||||
remesa: invoice?.compliance_mx?.remesa || '',
|
||||
invoice_number: invoice?.invoice_number || '',
|
||||
invoice_date: invoice?.invoice_date || '',
|
||||
emission_date: '',
|
||||
invoice_date: invoice?.invoice_date || new Date().toISOString().split('T')[0],
|
||||
emission_date: new Date().toISOString().split('T')[0],
|
||||
operation_type: operationType,
|
||||
invoice_type: invoice?.invoice_type || (defaultInvoiceType ?? ''),
|
||||
// Campos del pedimento (se llenarán al seleccionar un pedimento)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
import type { CustomsBroker } from '$lib/api/dashboard/a76/customs-brokers';
|
||||
import type { ClientProvider } from '$lib/api/dashboard/a76/clients-providers';
|
||||
import { saveInvoice } from '$lib/components/dashboard/invoices/edit/save-invoice';
|
||||
import { getExchangeRateByDate } from '$lib/api/dashboard/a76/exchange-rate';
|
||||
|
||||
// Cargar companyStore solo en el cliente - no usamos sidebar en esta página
|
||||
let companyStore: any = $state(undefined);
|
||||
@@ -99,6 +100,23 @@
|
||||
let othersExists = $state(false);
|
||||
let continuationExists = $state(false);
|
||||
|
||||
let calculatedExchangeRate = $state<number | null>(data.invoice?.financials?.exchange_rate ?? null);
|
||||
|
||||
// Efecto para actualizar el tipo de cambio cuando cambia la fecha de factura
|
||||
$effect(() => {
|
||||
if (mounted && companyStore?.activeCompany?.id && InvoiceTopFieldsFormData?.invoice_date) {
|
||||
getExchangeRateByDate(InvoiceTopFieldsFormData.invoice_date, companyStore.activeCompany.id)
|
||||
.then(rate => {
|
||||
if (rate) {
|
||||
calculatedExchangeRate = rate.value;
|
||||
} else {
|
||||
calculatedExchangeRate = 0;
|
||||
}
|
||||
})
|
||||
.catch(err => console.error('Error auto-updating exchange rate:', err));
|
||||
}
|
||||
});
|
||||
|
||||
function handleBack() {
|
||||
goto('/dashboard/invoices');
|
||||
}
|
||||
@@ -223,6 +241,7 @@
|
||||
defaultOperationType={data.filters?.operation_type ?? undefined}
|
||||
defaultInvoiceType={data.filters?.invoice_type ?? undefined}
|
||||
operationType={InvoiceTopFieldsFormData?.operation_type}
|
||||
exchangeRate={calculatedExchangeRate}
|
||||
/>
|
||||
</Tabs.Content>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user