Refactor invoice financials to change iva_factor type from string to numeric

- Updated the `iva_factor` field in the `InvoiceFinancials` model to use a numeric type with precision and scale.
- Adjusted related frontend components and API interfaces to reflect the new numeric type for `iva_factor`.
- Enhanced Alembic migration scripts to accommodate the schema changes, ensuring proper index management and data type conversions.

These changes improve data integrity and consistency for financial calculations in invoices.
This commit is contained in:
2026-03-23 09:48:33 -05:00
parent ebd555363f
commit fbb24f2cd3
7 changed files with 225 additions and 51 deletions

View File

@@ -110,7 +110,7 @@ export interface InvoiceFinancials {
iva_mn?: number | null;
iva_me?: number | null;
iva_mc?: number | null;
iva_factor?: string | null;
iva_factor?: number | null;
tax_value_me?: number | null;
seal_value_2500?: boolean | null;
total_quantity?: number | null;

View File

@@ -67,7 +67,7 @@
freight: null as number | null,
insurance: null as number | null,
iva_mn: null as number | null,
iva_factor: null as string | null,
iva_factor: null as number | null,
total_quantity: null as number | null,
gross_weight: null as number | null,
net_weight: null as number | null,

View File

@@ -266,7 +266,7 @@
<div>
<p class="text-sm font-medium text-muted-foreground">Factor IVA</p>
<p class="text-base">{invoice.financials.iva_factor || '-'}</p>
<p class="text-base">{formatCurrency(invoice.financials.iva_factor)}</p>
</div>
<div>
@@ -296,59 +296,57 @@
<!-- Logistics Tab -->
<Tabs.Content value="logistics" class="space-y-4">
{#if invoice.logistics && invoice.logistics.length > 0}
<div class="space-y-6">
{#each invoice.logistics as logistics, index}
<div class="border rounded-lg p-4">
<h4 class="font-semibold mb-3">Logística #{index + 1}</h4>
<div class="grid grid-cols-2 gap-4">
<div>
<p class="text-sm font-medium text-muted-foreground">Transportista</p>
<p class="text-base">{logistics.carrier_id || '-'}</p>
</div>
{#if invoice.logistics}
<div class="space-y-6">
<div class="border rounded-lg p-4">
<h4 class="font-semibold mb-3">Logística</h4>
<div class="grid grid-cols-2 gap-4">
<div>
<p class="text-sm font-medium text-muted-foreground">Transportista</p>
<p class="text-base">{invoice.logistics.carrier_id || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Tipo de Transporte</p>
<p class="text-base">{logistics.transport_type || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Tipo de Transporte</p>
<p class="text-base">{invoice.logistics.transport_type || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Modo de Transporte</p>
<p class="text-base">{logistics.transport_mode || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Modo de Transporte</p>
<p class="text-base">{invoice.logistics.transport_mode || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Conductor</p>
<p class="text-base">{logistics.driver_name || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Conductor</p>
<p class="text-base">{invoice.logistics.driver_name || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Número de Vehículo</p>
<p class="text-base">{logistics.vehicle_num || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Número de Vehículo</p>
<p class="text-base">{invoice.logistics.vehicle_num || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Placa</p>
<p class="text-base">{logistics.license_plate || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Placa</p>
<p class="text-base">{invoice.logistics.license_plate || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Número de Sello</p>
<p class="text-base">{logistics.seal_number || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Número de Sello</p>
<p class="text-base">{invoice.logistics.seal_number || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Guía</p>
<p class="text-base">{logistics.guide_number || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Guía</p>
<p class="text-base">{invoice.logistics.guide_number || '-'}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Fecha Entrada/Salida</p>
<p class="text-base">{formatDate(logistics.entry_exit_date)}</p>
</div>
<div>
<p class="text-sm font-medium text-muted-foreground">Fecha Entrada/Salida</p>
<p class="text-base">{formatDate(invoice.logistics.entry_exit_date)}</p>
</div>
</div>
{/each}
</div>
</div>
{:else}
<p class="text-muted-foreground">No hay información de logística disponible.</p>

View File

@@ -238,7 +238,7 @@ function buildFinancialsData(generalFormData: any, observationFormData: any, oth
currency_type: generalFormData?.currency_type || (generalFormData?.currency === 'foreign' ? 'USD' : null),
currency: generalFormData?.currency || null,
exchange_rate: generalFormData?.exchange_rate ? Number(generalFormData.exchange_rate) : null,
iva_factor: (InvoiceTopFieldsFormData?.iva_factor || generalFormData?.iva_factor) ? String(InvoiceTopFieldsFormData?.iva_factor || generalFormData.iva_factor) : null,
iva_factor: (InvoiceTopFieldsFormData?.iva_factor || generalFormData?.iva_factor) ? Number(InvoiceTopFieldsFormData?.iva_factor || generalFormData.iva_factor) : null,
// Costs & increments from observationFormData
freight: observationFormData?.freight || null,
insurance: observationFormData?.insurance || null,