Merge pull request 'feature/catalogo-pedimento' (#219) from feature/catalogo-pedimento into development
Reviewed-on: ADUANASOFT/anexo76#219
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
import { Input } from '$lib/components/ui/input';
|
||||
import { Label } from '$lib/components/ui/label';
|
||||
import * as Select from '$lib/components/ui/select';
|
||||
import { getLocale } from '$lib/paraglide/runtime';
|
||||
import { getExchangeRateByDate } from '$lib/api/dashboard/a76/exchange-rate';
|
||||
import { companyStore } from '$lib/stores/company.svelte';
|
||||
import type { Pedimento } from '$lib/api/dashboard/a76/pedimentos';
|
||||
@@ -12,8 +13,6 @@
|
||||
import type { CustomsBroker } from '$lib/api/dashboard/a76/customs-brokers';
|
||||
import type { ClientProvider } from '$lib/api/dashboard/a76/clients-providers';
|
||||
import type { CodePedimentoRegimen } from '$lib/api/dashboard/reference_data/code_pedimento_regimens';
|
||||
import type { TransportType } from '$lib/api/dashboard/reference_data/transport_types';
|
||||
import type { TransportMode } from '$lib/api/dashboard/reference_data/transport_modes';
|
||||
import IdentificadoresTabForm from './identifiers-tab-form.svelte';
|
||||
import ExchangeRateDialog from '$lib/components/dashboard/exchange_rate/create-edit-dialog.svelte';
|
||||
import { Calendar, Clock } from 'lucide-svelte';
|
||||
@@ -29,6 +28,13 @@
|
||||
import { shortcutStore } from '$lib/stores/shortcut-store';
|
||||
import { focusStore, interactionMode } from '$lib/stores/focus-store';
|
||||
|
||||
type PedimentoTransportCatalog = {
|
||||
code: string;
|
||||
transport_en: string;
|
||||
transport_es: string;
|
||||
payment_date_code: 'E' | 'P' | string;
|
||||
};
|
||||
|
||||
let {
|
||||
pedimento,
|
||||
formData = $bindable(),
|
||||
@@ -38,8 +44,7 @@
|
||||
customsBrokers = [],
|
||||
clients = [],
|
||||
codePedimentoRegimens = [],
|
||||
transportTypes = [],
|
||||
transportModes = [],
|
||||
pedimentoTransportCatalog = [],
|
||||
isActive = false
|
||||
}: {
|
||||
pedimento: Pedimento | null;
|
||||
@@ -50,8 +55,7 @@
|
||||
customsBrokers?: CustomsBroker[];
|
||||
clients?: ClientProvider[];
|
||||
codePedimentoRegimens?: CodePedimentoRegimen[];
|
||||
transportTypes?: TransportType[];
|
||||
transportModes?: TransportMode[];
|
||||
pedimentoTransportCatalog?: PedimentoTransportCatalog[];
|
||||
isActive?: boolean;
|
||||
} = $props();
|
||||
|
||||
@@ -352,27 +356,53 @@
|
||||
let lastFetchedDate: string | null = null;
|
||||
let lastCompanyId: number | null = null;
|
||||
|
||||
// Obtener automáticamente el tipo de cambio cuando cambie la fecha de entrada
|
||||
function getTransportByCode(code: string | null | undefined): PedimentoTransportCatalog | undefined {
|
||||
if (!code) return undefined;
|
||||
return pedimentoTransportCatalog.find((m) => m.code === code);
|
||||
}
|
||||
|
||||
function getTransportLabel(mode: PedimentoTransportCatalog | undefined): string {
|
||||
if (!mode) return '';
|
||||
const locale = getLocale();
|
||||
return locale === 'en' ? mode.transport_en : mode.transport_es;
|
||||
}
|
||||
|
||||
function getEffectiveExchangeDate(): string | null {
|
||||
const entryMethod = getTransportByCode(formData?.pedimento_transport_means?.entry_exit);
|
||||
const paymentCode = (entryMethod?.payment_date_code || 'E').toUpperCase();
|
||||
if (paymentCode === 'P') {
|
||||
return formData?.payment_date || null;
|
||||
}
|
||||
return formData?.entry_date || null;
|
||||
}
|
||||
|
||||
function getEffectiveDateLabel(): string {
|
||||
const entryMethod = getTransportByCode(formData?.pedimento_transport_means?.entry_exit);
|
||||
const paymentCode = (entryMethod?.payment_date_code || 'E').toUpperCase();
|
||||
return paymentCode === 'P' ? 'fecha de pago' : 'fecha de entrada';
|
||||
}
|
||||
|
||||
// Obtener automáticamente el tipo de cambio cuando cambie la fecha efectiva
|
||||
$effect(() => {
|
||||
const entryDate = formData?.entry_date;
|
||||
const effectiveDate = getEffectiveExchangeDate();
|
||||
const companyId = companyStore.activeCompany?.id;
|
||||
|
||||
// Solo ejecutar si los valores clave cambiaron
|
||||
if (
|
||||
formData &&
|
||||
entryDate &&
|
||||
effectiveDate &&
|
||||
companyId &&
|
||||
(entryDate !== lastFetchedDate || companyId !== lastCompanyId)
|
||||
(effectiveDate !== lastFetchedDate || companyId !== lastCompanyId)
|
||||
) {
|
||||
lastFetchedDate = entryDate;
|
||||
lastFetchedDate = effectiveDate;
|
||||
lastCompanyId = companyId;
|
||||
|
||||
getExchangeRateByDate(entryDate, companyId)
|
||||
getExchangeRateByDate(effectiveDate, companyId)
|
||||
.then((usdRate) => {
|
||||
if (usdRate && formData) {
|
||||
formData.exchange_rate = usdRate.value;
|
||||
} else {
|
||||
console.warn('⚠️ [TIPO CAMBIO] No encontrado para fecha:', entryDate);
|
||||
console.warn('⚠️ [TIPO CAMBIO] No encontrado para fecha:', effectiveDate);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -397,13 +427,14 @@
|
||||
];
|
||||
|
||||
export async function checkPaymentDateRate(date: string): Promise<boolean> {
|
||||
if (!date || !companyStore.activeCompany?.id) return true;
|
||||
const effectiveDate = date || getEffectiveExchangeDate();
|
||||
if (!effectiveDate || !companyStore.activeCompany?.id) return true;
|
||||
|
||||
try {
|
||||
const rate = await getExchangeRateByDate(date, companyStore.activeCompany.id);
|
||||
const rate = await getExchangeRateByDate(effectiveDate, companyStore.activeCompany.id);
|
||||
if (!rate) {
|
||||
// Abrir modal preventivamente
|
||||
missingExchangeRateDate = date;
|
||||
missingExchangeRateDate = effectiveDate;
|
||||
showExchangeRateDialog = true;
|
||||
return false;
|
||||
}
|
||||
@@ -411,7 +442,7 @@
|
||||
} catch (error) {
|
||||
console.error('Error checking payment date rate:', error);
|
||||
// Si hay error de red, asumimos que falta para forzar reintento/captura segura
|
||||
missingExchangeRateDate = date;
|
||||
missingExchangeRateDate = effectiveDate;
|
||||
showExchangeRateDialog = true;
|
||||
return false;
|
||||
}
|
||||
@@ -568,11 +599,16 @@
|
||||
id="exchange_rate"
|
||||
type="text"
|
||||
value={formData.exchange_rate ? Number(formData.exchange_rate).toFixed(6) : ''}
|
||||
placeholder="Se obtiene automáticamente de la fecha de entrada"
|
||||
placeholder={`Se obtiene automáticamente de la ${getEffectiveDateLabel()}`}
|
||||
readonly
|
||||
disabled
|
||||
class="cursor-not-allowed bg-muted"
|
||||
/>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
Tipo de fecha para TC: {getEffectiveDateLabel() === 'fecha de pago'
|
||||
? 'FECHA PAGO'
|
||||
: 'FECHA ENTRADA'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -829,18 +865,16 @@
|
||||
>
|
||||
<Select.Trigger id="entry_exit" class="w-full">
|
||||
<span class="truncate">
|
||||
{transportModes.find((m) => m.key === formData.pedimento_transport_means.entry_exit)
|
||||
?.name ||
|
||||
transportTypes.find(
|
||||
(t) => t.transport_code === formData.pedimento_transport_means.entry_exit
|
||||
)?.description ||
|
||||
{getTransportLabel(
|
||||
getTransportByCode(formData.pedimento_transport_means.entry_exit)
|
||||
) ||
|
||||
formData.pedimento_transport_means.entry_exit ||
|
||||
'Seleccionar...'}
|
||||
</span>
|
||||
</Select.Trigger>
|
||||
<Select.Content class="max-h-[300px]">
|
||||
{#each transportModes as mode}
|
||||
<Select.Item value={mode.key}>{mode.key} - {mode.name}</Select.Item>
|
||||
{#each pedimentoTransportCatalog as mode}
|
||||
<Select.Item value={mode.code}>{mode.code} - {getTransportLabel(mode)}</Select.Item>
|
||||
{/each}
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
@@ -856,18 +890,14 @@
|
||||
>
|
||||
<Select.Trigger id="arrival" class="w-full">
|
||||
<span class="truncate">
|
||||
{transportModes.find((m) => m.key === formData.pedimento_transport_means.arrival)
|
||||
?.name ||
|
||||
transportTypes.find(
|
||||
(t) => t.transport_code === formData.pedimento_transport_means.arrival
|
||||
)?.description ||
|
||||
{getTransportLabel(getTransportByCode(formData.pedimento_transport_means.arrival)) ||
|
||||
formData.pedimento_transport_means.arrival ||
|
||||
'Seleccionar...'}
|
||||
</span>
|
||||
</Select.Trigger>
|
||||
<Select.Content class="max-h-[300px]">
|
||||
{#each transportModes as mode}
|
||||
<Select.Item value={mode.key}>{mode.key} - {mode.name}</Select.Item>
|
||||
{#each pedimentoTransportCatalog as mode}
|
||||
<Select.Item value={mode.code}>{mode.code} - {getTransportLabel(mode)}</Select.Item>
|
||||
{/each}
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
@@ -883,18 +913,14 @@
|
||||
>
|
||||
<Select.Trigger id="departure" class="w-full">
|
||||
<span class="truncate">
|
||||
{transportModes.find((m) => m.key === formData.pedimento_transport_means.departure)
|
||||
?.name ||
|
||||
transportTypes.find(
|
||||
(t) => t.transport_code === formData.pedimento_transport_means.departure
|
||||
)?.description ||
|
||||
{getTransportLabel(getTransportByCode(formData.pedimento_transport_means.departure)) ||
|
||||
formData.pedimento_transport_means.departure ||
|
||||
'Seleccionar...'}
|
||||
</span>
|
||||
</Select.Trigger>
|
||||
<Select.Content class="max-h-[300px]">
|
||||
{#each transportModes as mode}
|
||||
<Select.Item value={mode.key}>{mode.key} - {mode.name}</Select.Item>
|
||||
{#each pedimentoTransportCatalog as mode}
|
||||
<Select.Item value={mode.code}>{mode.code} - {getTransportLabel(mode)}</Select.Item>
|
||||
{/each}
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
|
||||
Reference in New Issue
Block a user