feat: add financial calculations for multiple currencies and enhance summary section with customs values

This commit is contained in:
2026-02-19 08:36:54 -06:00
parent d4b52b32ed
commit fbce3efe5f
4 changed files with 82 additions and 8 deletions

View File

@@ -35,11 +35,13 @@ export interface LineFinancials {
unit_cost_commercial_usd?: number; unit_cost_commercial_usd?: number;
// Values // Values
value_mc?: number;
value_usd?: number; value_usd?: number;
value_mxn?: number; value_mxn?: number;
value_returned_usd?: number; value_returned_usd?: number;
value_returned_mxn?: number; value_returned_mxn?: number;
customs_value_usd?: number; customs_value_usd?: number;
customs_value_mxn?: number;
} }
export interface LineQuantities { export interface LineQuantities {

View File

@@ -135,6 +135,8 @@
<SummarySection <SummarySection
bind:financials={editingItem.financial!} bind:financials={editingItem.financial!}
bind:quantities={editingItem.quantity!} bind:quantities={editingItem.quantity!}
lineItem={editingItem}
{invoice}
/> />
</div> </div>
</Tabs.Content> </Tabs.Content>

View File

@@ -293,8 +293,7 @@
<div class="flex items-end gap-6"> <div class="flex items-end gap-6">
<div class="space-y-1"> <div class="space-y-1">
<Label for="tipo_tarifa" class="text-xs font-medium">Tariff Type: <span class="text-red-500">*</span></Label> <Label for="tipo_tarifa" class="text-xs font-medium">Tariff Type: <span class="text-red-500">*</span></Label>
<select id="tipo_tarifa" bind:value={customs.fraction_type} class="flex h-8 w-auto min-w-[140px] rounded-md border border-input bg-background px-2 py-1 text-xs ring-offset-background"> <select id="tipo_tarifa" bind:value={customs.fraction_type} class="flex h-8 w-auto min-w-[140px] rounded-md border border-input bg-background px-2 py-1 text-xs ring-offset-background">
<option value={undefined}>Selecciona...</option>
<option value="GENERAL">GENERAL</option> <option value="GENERAL">GENERAL</option>
<option value="PROSEC">PROSEC</option> <option value="PROSEC">PROSEC</option>
<option value="ALADI">ALADI</option> <option value="ALADI">ALADI</option>

View File

@@ -1,13 +1,82 @@
<script lang="ts"> <script lang="ts">
import type { LineFinancials, LineQuantities } from '$lib/api/dashboard/a76/items'; import type { LineFinancials, LineQuantities, Item } from '$lib/api/dashboard/a76/items';
import type { Invoice } from '$lib/api/dashboard/a76/invoices';
import type { Part } from '$lib/api/dashboard/a76/parts';
import { companyStore } from '$lib/stores/company.svelte';
let { financials = $bindable(), quantities = $bindable() }: { financials: LineFinancials; quantities: LineQuantities } = $props(); let {
financials = $bindable(),
quantities = $bindable(),
lineItem,
invoice
}: {
financials: LineFinancials;
quantities: LineQuantities;
lineItem?: Partial<Item>;
invoice?: Invoice | null;
} = $props();
// Helper function to safely format numbers // Helper function to safely format numbers
function formatNumber(value: any, decimals: number = 8): string { function formatNumber(value: any, decimals: number = 8): string {
const num = Number(value); const num = Number(value);
return isNaN(num) ? '0.00000000' : num.toFixed(decimals); return isNaN(num) ? '0.00000000' : num.toFixed(decimals);
} }
// ========== ESTRUCTURA DE COMPARACIÓN DE MONEDAS ==========
// Extraer las monedas del invoice y del part
let invoiceCurrency = $derived(invoice?.financials?.currency_type);
// Effect para actualizar los costos unitarios en diferentes monedas cuando cambie unit_cost_capture
$effect(() => {
const exchangeRate = invoice?.financials?.exchange_rate || 1;
const unitCostCapture = financials.unit_cost_capture || 1;
// Calcular unit_cost_usd y unit_cost_mxn basado en la moneda del invoice
if (invoiceCurrency === 'USD') {
financials.unit_cost_usd = unitCostCapture;
financials.unit_cost_mxn = unitCostCapture * exchangeRate;
} else if (invoiceCurrency === 'MXN') {
financials.unit_cost_mxn = unitCostCapture;
financials.unit_cost_usd = unitCostCapture / exchangeRate;
} else {
// Por defecto, si no hay moneda definida, asumir USD
financials.unit_cost_usd = unitCostCapture;
financials.unit_cost_mxn = unitCostCapture * exchangeRate;
}
});
let calculatedValueCapture = $derived.by(() => {
const quantity = quantities.quantity || 0;
const unitCost = financials.unit_cost_capture;
// Calcular el valor total (costo unitario * cantidad)
return (unitCost || 0) * quantity;
});
// Effect para actualizar los valores en diferentes monedas cuando cambie calculatedValueCapture
$effect(() => {
const exchangeRate = invoice?.financials?.exchange_rate || 1;
const valueCapture = calculatedValueCapture;
// value_mc es el valor en la moneda de captura (invoice currency)
financials.value_mc = valueCapture;
// Calcular value_usd y value_mxn basado en la moneda del invoice
if (invoiceCurrency === 'USD') {
financials.value_usd = valueCapture;
financials.value_mxn = valueCapture * exchangeRate;
} else if (invoiceCurrency === 'MXN') {
financials.value_mxn = valueCapture;
financials.value_usd = valueCapture / exchangeRate;
} else {
// Por defecto, si no hay moneda definida, asumir USD
financials.value_usd = valueCapture;
financials.value_mxn = valueCapture * exchangeRate;
}
});
// ========== FIN ESTRUCTURA DE COMPARACIÓN ==========
</script> </script>
<div> <div>
@@ -27,7 +96,7 @@
<div class="font-semibold">WEIGHTS (Pounds)</div> <div class="font-semibold">WEIGHTS (Pounds)</div>
<div>Net: <span class="text-gray-900 dark:text-gray-100">{formatNumber(quantities.net_weight)}</span></div> <div>Net: <span class="text-gray-900 dark:text-gray-100">{formatNumber(quantities.net_weight)}</span></div>
<div><span class="text-gray-900 dark:text-gray-100">0.00000000</span></div> <div><span class="text-gray-900 dark:text-gray-100">0.00000000</span></div>
<div>Whole: <span class="text-gray-900 dark:text-gray-100">{formatNumber(quantities.gross_weight)}</span></div> <div>Gross: <span class="text-gray-900 dark:text-gray-100">{formatNumber(quantities.gross_weight)}</span></div>
<div><span class="text-gray-900 dark:text-gray-100">0.00000000</span></div> <div><span class="text-gray-900 dark:text-gray-100">0.00000000</span></div>
</div> </div>
</fieldset> </fieldset>
@@ -43,9 +112,11 @@
<div><span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.unit_cost_mxn)}</span></div> <div><span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.unit_cost_mxn)}</span></div>
<div>Value: <span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.value_usd)}</span></div> <div>Value: <span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.value_usd)}</span></div>
<div><span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.value_mxn)}</span></div> <div><span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.value_mxn)}</span></div>
<div class="text-xs">Capture Cost: <span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.unit_cost_capture)}</span> <span class="text-gray-900 dark:text-gray-100">USD</span></div> <div class="text-xs">Customs Value: <span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.customs_value_usd)}</span></div>
<div class="text-xs">Capture Value: <span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.value_usd)}</span> <span class="text-gray-900 dark:text-gray-100">USD</span></div> <div class="text-xs">Customs Value: <span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.customs_value_mxn)}</span></div>
<div class="text-xs">Customs Value: <span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.customs_value_usd)}</span> <span class="text-gray-900 dark:text-gray-100">USD</span></div> <div class="text-xs">Capture Cost: <span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.unit_cost_capture)}</span> <span class="text-gray-900 dark:text-gray-100">{invoiceCurrency}</span></div>
<div></div>
<div class="text-xs">Capture Value: <span class="text-gray-900 dark:text-gray-100">{formatNumber(financials.value_mc)}</span> <span class="text-gray-900 dark:text-gray-100">{invoiceCurrency}</span></div>
</div> </div>
</fieldset> </fieldset>
</div> </div>