pedimentos UI
This commit is contained in:
@@ -2,26 +2,7 @@ import type { ColumnDef } from "@tanstack/table-core";
|
||||
import { renderComponent, renderSnippet } from "$lib/components/ui/data-table/index.js";
|
||||
import { createRawSnippet } from "svelte";
|
||||
import DataTableActions from "./data-table-actions.svelte";
|
||||
|
||||
export type Pedimento = {
|
||||
id: number;
|
||||
tenant_id: number;
|
||||
year?: string | null;
|
||||
customs_office?: string | null;
|
||||
license?: string | null;
|
||||
pedimento_number?: string | null;
|
||||
client_id?: number | null;
|
||||
operation_type?: number | null;
|
||||
pedimento_type?: number | null;
|
||||
pedimento_code?: string | null;
|
||||
regime?: string | null;
|
||||
status?: string | null;
|
||||
usd_value?: number | null;
|
||||
paid_price?: number | null;
|
||||
gross_weight?: number | null;
|
||||
exchange_rate?: number | null;
|
||||
created_at: string;
|
||||
};
|
||||
import type { Pedimento } from "$lib/api/dashboard/a76/pedimentos";
|
||||
|
||||
/**
|
||||
* Formatea un número como moneda
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { Button } from "$lib/components/ui/button";
|
||||
import * as DropdownMenu from "$lib/components/ui/dropdown-menu";
|
||||
import { pedimentosApi, type Pedimento } from "$lib/api/dashboard/a76/pedimentos";
|
||||
import { companyStore } from "$lib/stores/company.svelte";
|
||||
import { EllipsisVertical, Pencil, LoaderCircle, Trash2 } from 'lucide-svelte';
|
||||
|
||||
let {
|
||||
@@ -24,7 +25,8 @@
|
||||
error = null;
|
||||
|
||||
try {
|
||||
const response = await pedimentosApi.delete(item.id);
|
||||
const companyId = companyStore.activeCompany?.id;
|
||||
const response = await pedimentosApi.delete(item.id, companyId);
|
||||
|
||||
if (response.error) {
|
||||
if (response.status === 401) {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
DialogTitle,
|
||||
DialogFooter
|
||||
} from '$lib/components/ui/dialog';
|
||||
import Checkbox from '$lib/components/ui/checkbox/checkbox.svelte';
|
||||
import { Checkbox } from '$lib/components/ui/checkbox';
|
||||
import {
|
||||
Plus,
|
||||
Pencil,
|
||||
@@ -17,14 +17,18 @@
|
||||
pedimentoNumber?: string;
|
||||
} = $props();
|
||||
|
||||
// Inicializar formData
|
||||
if (!formData) {
|
||||
formData = {
|
||||
observaciones: pedimento?.observaciones || ''
|
||||
};
|
||||
}
|
||||
|
||||
exists = !!pedimento?.observaciones;
|
||||
// Asegurar que formData siempre tenga un valor por defecto
|
||||
formData = formData || { observaciones: '' };
|
||||
|
||||
// Actualizar formData cuando el pedimento cambie
|
||||
$effect(() => {
|
||||
if (pedimento?.observations !== undefined) {
|
||||
formData = {
|
||||
observaciones: pedimento.observations || ''
|
||||
};
|
||||
exists = !!pedimento.observations;
|
||||
}
|
||||
});
|
||||
|
||||
// Mapear el tipo de pedimento a un nombre legible
|
||||
const tipoPedimentoNombre = $derived.by(() => {
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
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/refrence_data/code_pedimento_regimens';
|
||||
import IdentificadoresTabForm from './identifiers-tab-form.svelte';
|
||||
|
||||
let {
|
||||
pedimento,
|
||||
formData = $bindable(),
|
||||
identificadoresFormData = $bindable(),
|
||||
pedimentoCodes = [],
|
||||
customsSections = [],
|
||||
customsBrokers = [],
|
||||
@@ -23,6 +25,7 @@
|
||||
}: {
|
||||
pedimento: Pedimento | null;
|
||||
formData?: any;
|
||||
identificadoresFormData?: any;
|
||||
pedimentoCodes?: PedimentoCode[];
|
||||
customsSections?: CustomsSection[];
|
||||
customsBrokers?: CustomsBroker[];
|
||||
@@ -249,19 +252,23 @@
|
||||
// Obtener automáticamente el tipo de cambio cuando cambie la fecha de entrada
|
||||
$effect(() => {
|
||||
if (formData && formData.entry_date && companyStore.activeCompany) {
|
||||
console.log('Buscando tipo de cambio para fecha:', formData.entry_date);
|
||||
console.log('🔍 [TIPO CAMBIO] Buscando para fecha:', formData.entry_date, 'Company ID:', companyStore.activeCompany.id);
|
||||
|
||||
getExchangeRateByDate(formData.entry_date, companyStore.activeCompany.id)
|
||||
.then(usdRate => {
|
||||
console.log('Tipo de cambio USD encontrado:', usdRate);
|
||||
console.log('✅ [TIPO CAMBIO] Respuesta recibida:', usdRate);
|
||||
if (usdRate && formData) {
|
||||
formData.exchange_rate = usdRate.value;
|
||||
console.log('Tipo de cambio actualizado a:', usdRate.value);
|
||||
console.log('✅ [TIPO CAMBIO] Actualizado a:', usdRate.value);
|
||||
} else {
|
||||
console.warn('No se encontró tipo de cambio USD para la fecha:', formData.entry_date);
|
||||
console.warn('⚠️ [TIPO CAMBIO] No encontrado para fecha:', formData.entry_date);
|
||||
}
|
||||
})
|
||||
.catch(err => console.error('Error al obtener tipo de cambio:', err));
|
||||
.catch(err => {
|
||||
console.error('❌ [TIPO CAMBIO] Error:', err);
|
||||
});
|
||||
} else {
|
||||
console.log('⏭️ [TIPO CAMBIO] Saltado - formData:', !!formData, 'entry_date:', formData?.entry_date, 'company:', !!companyStore.activeCompany);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -417,10 +424,9 @@
|
||||
<Label for="exchange_rate">Tipo de Cambio <span class="text-red-500">*</span></Label>
|
||||
<Input
|
||||
id="exchange_rate"
|
||||
type="number"
|
||||
step="0.0001"
|
||||
bind:value={formData.exchange_rate}
|
||||
placeholder="En fecha de entrada"
|
||||
type="text"
|
||||
value={formData.exchange_rate ? Number(formData.exchange_rate).toFixed(6) : ''}
|
||||
placeholder="Se obtiene automáticamente de la fecha de entrada"
|
||||
readonly
|
||||
disabled
|
||||
class="bg-muted cursor-not-allowed"
|
||||
@@ -898,9 +904,7 @@
|
||||
</div>
|
||||
{:else if activeSection === 'identificadores'}
|
||||
<!-- Identificadores -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<p class="text-muted-foreground col-span-full">Campos de Identificadores - Por configurar</p>
|
||||
</div>
|
||||
<IdentificadoresTabForm bind:formData={identificadoresFormData} />
|
||||
{:else if activeSection === 'indices'}
|
||||
<!-- Indices -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
<script lang="ts">
|
||||
import { Card } from '$lib/components/ui/card';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { Input } from '$lib/components/ui/input';
|
||||
import { Label } from '$lib/components/ui/label';
|
||||
import { Textarea } from '$lib/components/ui/textarea';
|
||||
import * as Table from '$lib/components/ui/table';
|
||||
import * as Dialog from '$lib/components/ui/dialog';
|
||||
|
||||
interface Identificador {
|
||||
caso: string;
|
||||
complemento1: string;
|
||||
complemento2: string;
|
||||
complemento3: string;
|
||||
nodo: string;
|
||||
observaciones: string;
|
||||
}
|
||||
|
||||
let {
|
||||
formData = $bindable({
|
||||
identificadores: []
|
||||
})
|
||||
}: {
|
||||
formData: {
|
||||
identificadores: Identificador[];
|
||||
};
|
||||
} = $props();
|
||||
|
||||
let isIdentificadorDialogOpen = $state(false);
|
||||
let editingIdentificadorIndex = $state<number | null>(null);
|
||||
let currentIdentificador = $state<Identificador>({
|
||||
caso: '',
|
||||
complemento1: '',
|
||||
complemento2: '',
|
||||
complemento3: '',
|
||||
nodo: '',
|
||||
observaciones: ''
|
||||
});
|
||||
|
||||
function handleNuevoIdentificador() {
|
||||
currentIdentificador = {
|
||||
caso: '',
|
||||
complemento1: '',
|
||||
complemento2: '',
|
||||
complemento3: '',
|
||||
nodo: '',
|
||||
observaciones: ''
|
||||
};
|
||||
editingIdentificadorIndex = null;
|
||||
isIdentificadorDialogOpen = true;
|
||||
}
|
||||
|
||||
function handleEditarIdentificador(index: number) {
|
||||
currentIdentificador = { ...formData.identificadores[index] };
|
||||
editingIdentificadorIndex = index;
|
||||
isIdentificadorDialogOpen = true;
|
||||
}
|
||||
|
||||
function handleBorrarIdentificador(index: number) {
|
||||
formData.identificadores = formData.identificadores.filter((_, i) => i !== index);
|
||||
}
|
||||
|
||||
function saveIdentificador() {
|
||||
if (editingIdentificadorIndex !== null) {
|
||||
formData.identificadores[editingIdentificadorIndex] = { ...currentIdentificador };
|
||||
} else {
|
||||
formData.identificadores = [...formData.identificadores, { ...currentIdentificador }];
|
||||
}
|
||||
isIdentificadorDialogOpen = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Card class="p-6">
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-semibold">Identificadores</h3>
|
||||
<Button size="sm" onclick={handleNuevoIdentificador}>
|
||||
Nuevo
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{#if formData.identificadores.length === 0}
|
||||
<p class="text-sm text-muted-foreground text-center py-8">
|
||||
No hay identificadores registrados
|
||||
</p>
|
||||
{:else}
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.Head>Caso</Table.Head>
|
||||
<Table.Head>Complemento 1</Table.Head>
|
||||
<Table.Head>Complemento 2</Table.Head>
|
||||
<Table.Head>Complemento 3</Table.Head>
|
||||
<Table.Head>Nodo</Table.Head>
|
||||
<Table.Head>Observaciones</Table.Head>
|
||||
<Table.Head class="text-right">Acciones</Table.Head>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{#each formData.identificadores as identificador, index}
|
||||
<Table.Row>
|
||||
<Table.Cell>{identificador.caso}</Table.Cell>
|
||||
<Table.Cell>{identificador.complemento1}</Table.Cell>
|
||||
<Table.Cell>{identificador.complemento2}</Table.Cell>
|
||||
<Table.Cell>{identificador.complemento3}</Table.Cell>
|
||||
<Table.Cell>{identificador.nodo}</Table.Cell>
|
||||
<Table.Cell class="max-w-xs truncate">{identificador.observaciones}</Table.Cell>
|
||||
<Table.Cell class="text-right">
|
||||
<div class="flex justify-end gap-2">
|
||||
<Button size="sm" variant="outline" onclick={() => handleEditarIdentificador(index)}>
|
||||
Editar
|
||||
</Button>
|
||||
<Button size="sm" variant="destructive" onclick={() => handleBorrarIdentificador(index)}>
|
||||
Borrar
|
||||
</Button>
|
||||
</div>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
{/each}
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
{/if}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<!-- Dialog para agregar/editar identificador -->
|
||||
<Dialog.Root bind:open={isIdentificadorDialogOpen}>
|
||||
<Dialog.Content class="max-w-2xl">
|
||||
<Dialog.Header>
|
||||
<Dialog.Title>
|
||||
{editingIdentificadorIndex !== null ? 'Editar' : 'Nuevo'} Identificador
|
||||
</Dialog.Title>
|
||||
</Dialog.Header>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="space-y-2">
|
||||
<Label for="caso">Caso</Label>
|
||||
<Input id="caso" bind:value={currentIdentificador.caso} />
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<Label for="complemento1">Complemento 1</Label>
|
||||
<Input id="complemento1" bind:value={currentIdentificador.complemento1} />
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<Label for="complemento2">Complemento 2</Label>
|
||||
<Input id="complemento2" bind:value={currentIdentificador.complemento2} />
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<Label for="complemento3">Complemento 3</Label>
|
||||
<Input id="complemento3" bind:value={currentIdentificador.complemento3} />
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<Label for="nodo">Nodo</Label>
|
||||
<Input id="nodo" bind:value={currentIdentificador.nodo} />
|
||||
</div>
|
||||
|
||||
<div class="space-y-2 col-span-2">
|
||||
<Label for="observaciones">Observaciones</Label>
|
||||
<Textarea id="observaciones" bind:value={currentIdentificador.observaciones} rows={3} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog.Footer>
|
||||
<Button variant="outline" onclick={() => (isIdentificadorDialogOpen = false)}>
|
||||
Cancelar
|
||||
</Button>
|
||||
<Button onclick={saveIdentificador}>Aceptar</Button>
|
||||
</Dialog.Footer>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
@@ -4,7 +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 Checkbox from '$lib/components/ui/checkbox/checkbox.svelte';
|
||||
import { Checkbox } from '$lib/components/ui/checkbox';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -447,32 +447,7 @@
|
||||
currentPartesIIPage = totalPartesIIPages - 1;
|
||||
}
|
||||
|
||||
function goToNotasFirstPage() {
|
||||
currentNotasPage = 0;
|
||||
}
|
||||
|
||||
function goToNotasPreviousPage() {
|
||||
if (currentNotasPage > 0) currentNotasPage--;
|
||||
}
|
||||
|
||||
function goToNotasNextPage() {
|
||||
if (currentNotasPage < totalNotasPages - 1) currentNotasPage++;
|
||||
}
|
||||
|
||||
function goToNotasLastPage() {
|
||||
currentNotasPage = totalNotasPages - 1;
|
||||
}
|
||||
|
||||
function toggleSelectAll() {
|
||||
if (selectedEmbarques.length === embarquesParciales.length) {
|
||||
selectedEmbarques = [];
|
||||
} else {
|
||||
selectedEmbarques = embarquesParciales.map((_, i) => i);
|
||||
}
|
||||
}
|
||||
|
||||
function handleNuevoEmbarque() {
|
||||
editingEmbarqueIndex = null;
|
||||
currentEmbarque = {
|
||||
numero: '',
|
||||
peso: 0,
|
||||
@@ -495,6 +470,14 @@
|
||||
isEmbarqueDialogOpen = true;
|
||||
}
|
||||
|
||||
function toggleSelectAll() {
|
||||
if (selectedEmbarques.length === embarquesParciales.length) {
|
||||
selectedEmbarques = [];
|
||||
} else {
|
||||
selectedEmbarques = embarquesParciales.map((_, i) => i);
|
||||
}
|
||||
}
|
||||
|
||||
function handleEditarEmbarque() {
|
||||
alert('Editar Embarque no implementado');
|
||||
}
|
||||
@@ -654,6 +637,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
function goToNotasFirstPage() {
|
||||
currentNotasPage = 0;
|
||||
}
|
||||
|
||||
function goToNotasPreviousPage() {
|
||||
if (currentNotasPage > 0) currentNotasPage--;
|
||||
}
|
||||
|
||||
function goToNotasNextPage() {
|
||||
if (currentNotasPage < totalNotasPages - 1) currentNotasPage++;
|
||||
}
|
||||
|
||||
function goToNotasLastPage() {
|
||||
currentNotasPage = totalNotasPages - 1;
|
||||
}
|
||||
|
||||
function handleSeleccionAutomatizada() {
|
||||
showBitacora = false;
|
||||
showPartesII = false;
|
||||
Reference in New Issue
Block a user