- Implemented a new API endpoint for fetching countries with pagination support. - Added a new Svelte component for managing contributions in the dashboard, including CRUD operations for contributions and general contributions. - Introduced dynamic tab navigation for different contribution types (DTA, PREV, ECI, MULT, REC). - Enhanced user interface with dialogs for adding and editing contributions and general contributions.
772 lines
22 KiB
Svelte
772 lines
22 KiB
Svelte
<script lang="ts">
|
|
import { Card, CardContent } 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 * as Select from '$lib/components/ui/select';
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow
|
|
} from '$lib/components/ui/table';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogFooter
|
|
} from '$lib/components/ui/dialog';
|
|
import { Checkbox } from '$lib/components/ui/checkbox';
|
|
import {
|
|
Plus,
|
|
Pencil,
|
|
Trash2
|
|
} from 'lucide-svelte';
|
|
|
|
const opcionesContribuciones = [
|
|
'DTA ',
|
|
'REC G',
|
|
'OTROS',
|
|
'DTI',
|
|
'MULT',
|
|
'RT',
|
|
'PRV',
|
|
'REU',
|
|
'ECI',
|
|
'IVA PRV',
|
|
'DFC'
|
|
];
|
|
|
|
interface Contribucion {
|
|
id?: number;
|
|
contribucion: string;
|
|
tipo_tasa: string;
|
|
tasa: number;
|
|
forma_pago: string;
|
|
importe: number;
|
|
gravamen: string;
|
|
abreviacion: string;
|
|
forma_pago_2: string;
|
|
importe_2: number;
|
|
contribuciones_generales?: Array<{
|
|
pedimento_sys_id: string;
|
|
clave_contribucion: string;
|
|
clave_tasa: string;
|
|
tasa_contribucion: number;
|
|
clave_forma_pago: string;
|
|
importe_contribucion: number;
|
|
}>;
|
|
}
|
|
|
|
interface ContribucionGeneral {
|
|
id?: number;
|
|
pedimento_sys_id: string;
|
|
clave_contribucion: string;
|
|
clave_tasa: string;
|
|
tasa_contribucion: number;
|
|
clave_forma_pago: string;
|
|
importe_contribucion: number;
|
|
}
|
|
|
|
let {
|
|
formData = $bindable({
|
|
// Campos por pestaña
|
|
dta: {
|
|
forma_pago_recargo: 0,
|
|
tasa_recargo: 0.0,
|
|
importe_recargo: 0
|
|
},
|
|
prev: {
|
|
forma_pago_prevalidacion: 0
|
|
},
|
|
eci: {
|
|
forma_pago_eci: 0,
|
|
importe_eci: 0
|
|
},
|
|
mult: {
|
|
forma_pago_multa: 0,
|
|
importe_multa: 0
|
|
},
|
|
rec: {
|
|
forma_pago_uia: 0,
|
|
importe_compensar: 0
|
|
},
|
|
// Configuración
|
|
calculo_manual: false,
|
|
operaciones_regla_31_40: false,
|
|
// Contribuciones (tabla compartida)
|
|
contribuciones: [] as Contribucion[],
|
|
contribuciones_generales: [] as ContribucionGeneral[]
|
|
})
|
|
}: {
|
|
formData: {
|
|
dta: {
|
|
forma_pago_recargo: number;
|
|
tasa_recargo: number;
|
|
importe_recargo: number;
|
|
};
|
|
prev: {
|
|
forma_pago_prevalidacion: number;
|
|
};
|
|
eci: {
|
|
forma_pago_eci: number;
|
|
importe_eci: number;
|
|
};
|
|
mult: {
|
|
forma_pago_multa: number;
|
|
importe_multa: number;
|
|
};
|
|
rec: {
|
|
forma_pago_uia: number;
|
|
importe_compensar: number;
|
|
};
|
|
calculo_manual: boolean;
|
|
operaciones_regla_31_40: boolean;
|
|
contribuciones: Contribucion[];
|
|
contribuciones_generales: ContribucionGeneral[];
|
|
};
|
|
} = $props();
|
|
|
|
// Pestaña activa
|
|
let activeTab = $state('DTA');
|
|
|
|
// Estados para diálogo
|
|
let isDialogOpen = $state(false);
|
|
let editingIndex = $state<number | null>(null);
|
|
|
|
// Estados para contribuciones generales (dentro del diálogo)
|
|
let isContribGenDialogOpen = $state(false);
|
|
let editingContribGenIndex = $state<number | null>(null);
|
|
|
|
// Estado temporal para contribución general dentro del diálogo de contribución
|
|
let tempContribGen = $state({
|
|
pedimento_sys_id: '',
|
|
clave_contribucion: '',
|
|
clave_tasa: '',
|
|
tasa_contribucion: 0,
|
|
clave_forma_pago: '',
|
|
importe_contribucion: 0
|
|
});
|
|
|
|
let currentContribucion = $state<Contribucion>({
|
|
contribucion: '',
|
|
tipo_tasa: '',
|
|
tasa: 0,
|
|
forma_pago: '',
|
|
importe: 0,
|
|
gravamen: '',
|
|
abreviacion: '',
|
|
forma_pago_2: '',
|
|
importe_2: 0,
|
|
contribuciones_generales: []
|
|
});
|
|
|
|
let currentContribGen = $state<ContribucionGeneral>({
|
|
pedimento_sys_id: '',
|
|
clave_contribucion: '',
|
|
clave_tasa: '',
|
|
tasa_contribucion: 0,
|
|
clave_forma_pago: '',
|
|
importe_contribucion: 0
|
|
});
|
|
|
|
function openNewContribucion() {
|
|
editingIndex = null;
|
|
currentContribucion = {
|
|
contribucion: '',
|
|
tipo_tasa: '',
|
|
tasa: 0,
|
|
forma_pago: '',
|
|
importe: 0,
|
|
gravamen: '',
|
|
abreviacion: '',
|
|
forma_pago_2: '',
|
|
importe_2: 0,
|
|
contribuciones_generales: []
|
|
};
|
|
isDialogOpen = true;
|
|
}
|
|
|
|
function openEditContribucion(index: number) {
|
|
if (!formData?.contribuciones) return;
|
|
editingIndex = index;
|
|
currentContribucion = { ...formData.contribuciones[index] };
|
|
isDialogOpen = true;
|
|
}
|
|
|
|
function saveContribucion() {
|
|
if (!formData?.contribuciones) return;
|
|
if (editingIndex !== null) {
|
|
formData.contribuciones[editingIndex] = { ...currentContribucion };
|
|
} else {
|
|
formData.contribuciones = [...formData.contribuciones, { ...currentContribucion }];
|
|
}
|
|
isDialogOpen = false;
|
|
}
|
|
|
|
function deleteContribucion(index: number) {
|
|
if (!formData?.contribuciones) return;
|
|
if (confirm('¿Está seguro de eliminar esta contribución?')) {
|
|
formData.contribuciones = formData.contribuciones.filter((_, i) => i !== index);
|
|
}
|
|
}
|
|
|
|
// Funciones para Contribuciones Generales (Registro 510) dentro del diálogo de contribución
|
|
function openNewContribGenInDialog() {
|
|
tempContribGen = {
|
|
pedimento_sys_id: '',
|
|
clave_contribucion: '',
|
|
clave_tasa: '',
|
|
tasa_contribucion: 0,
|
|
clave_forma_pago: '',
|
|
importe_contribucion: 0
|
|
};
|
|
isContribGenDialogOpen = true;
|
|
}
|
|
|
|
function saveContribGenInDialog() {
|
|
if (!currentContribucion.contribuciones_generales) {
|
|
currentContribucion.contribuciones_generales = [];
|
|
}
|
|
currentContribucion.contribuciones_generales.push({
|
|
pedimento_sys_id: tempContribGen.pedimento_sys_id,
|
|
clave_contribucion: tempContribGen.clave_contribucion,
|
|
clave_tasa: tempContribGen.clave_tasa,
|
|
tasa_contribucion: tempContribGen.tasa_contribucion,
|
|
clave_forma_pago: tempContribGen.clave_forma_pago,
|
|
importe_contribucion: tempContribGen.importe_contribucion
|
|
});
|
|
isContribGenDialogOpen = false;
|
|
}
|
|
|
|
// Funciones para Contribuciones Generales (Registro 510)
|
|
function openNewContribGen() {
|
|
editingContribGenIndex = null;
|
|
currentContribGen = {
|
|
pedimento_sys_id: '',
|
|
clave_contribucion: '',
|
|
clave_tasa: '',
|
|
tasa_contribucion: 0,
|
|
clave_forma_pago: '',
|
|
importe_contribucion: 0
|
|
};
|
|
isContribGenDialogOpen = true;
|
|
}
|
|
|
|
function openEditContribGen(index: number) {
|
|
if (!formData?.contribuciones_generales) return;
|
|
editingContribGenIndex = index;
|
|
currentContribGen = { ...formData.contribuciones_generales[index] };
|
|
isContribGenDialogOpen = true;
|
|
}
|
|
|
|
function saveContribGen() {
|
|
if (!formData?.contribuciones_generales) return;
|
|
if (editingContribGenIndex !== null) {
|
|
formData.contribuciones_generales[editingContribGenIndex] = { ...currentContribGen };
|
|
} else {
|
|
formData.contribuciones_generales = [...formData.contribuciones_generales, { ...currentContribGen }];
|
|
}
|
|
isContribGenDialogOpen = false;
|
|
}
|
|
|
|
function deleteContribGen(index: number) {
|
|
if (!formData?.contribuciones_generales) return;
|
|
if (confirm('¿Está seguro de eliminar esta contribución general?')) {
|
|
formData.contribuciones_generales = formData.contribuciones_generales.filter((_, i) => i !== index);
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<Card>
|
|
<CardContent class="p-6 space-y-4">
|
|
<!-- Pestañas de navegación -->
|
|
<div class="flex gap-1 border-b">
|
|
<button
|
|
class="px-4 py-2 text-sm font-medium border-b-2 transition-colors {activeTab === 'DTA'
|
|
? 'border-primary text-primary'
|
|
: 'border-transparent text-muted-foreground hover:text-foreground'}"
|
|
onclick={() => (activeTab = 'DTA')}
|
|
>
|
|
DTA
|
|
</button>
|
|
<button
|
|
class="px-4 py-2 text-sm font-medium border-b-2 transition-colors {activeTab === 'PREV'
|
|
? 'border-primary text-primary'
|
|
: 'border-transparent text-muted-foreground hover:text-foreground'}"
|
|
onclick={() => (activeTab = 'PREV')}
|
|
>
|
|
PREV
|
|
</button>
|
|
<button
|
|
class="px-4 py-2 text-sm font-medium border-b-2 transition-colors {activeTab === 'ECI'
|
|
? 'border-primary text-primary'
|
|
: 'border-transparent text-muted-foreground hover:text-foreground'}"
|
|
onclick={() => (activeTab = 'ECI')}
|
|
>
|
|
ECI
|
|
</button>
|
|
<button
|
|
class="px-4 py-2 text-sm font-medium border-b-2 transition-colors {activeTab === 'MULT'
|
|
? 'border-primary text-primary'
|
|
: 'border-transparent text-muted-foreground hover:text-foreground'}"
|
|
onclick={() => (activeTab = 'MULT')}
|
|
>
|
|
MULT
|
|
</button>
|
|
<button
|
|
class="px-4 py-2 text-sm font-medium border-b-2 transition-colors {activeTab === 'REC'
|
|
? 'border-primary text-primary'
|
|
: 'border-transparent text-muted-foreground hover:text-foreground'}"
|
|
onclick={() => (activeTab = 'REC')}
|
|
>
|
|
REC
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Contenido dinámico según pestaña -->
|
|
<div class="border rounded-lg p-4 bg-muted/30">
|
|
{#if activeTab === 'DTA'}
|
|
<div class="grid grid-cols-3 gap-4">
|
|
<div class="space-y-2">
|
|
<Label for="forma_pago_recargo">Forma de pago Recargo:</Label>
|
|
<Input
|
|
id="forma_pago_recargo"
|
|
type="number"
|
|
bind:value={formData.dta.forma_pago_recargo}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
<div class="space-y-2">
|
|
<Label for="tasa_recargo">Tasa Recargo:</Label>
|
|
<Input
|
|
id="tasa_recargo"
|
|
type="number"
|
|
step="0.00001"
|
|
bind:value={formData.dta.tasa_recargo}
|
|
placeholder="0.00000"
|
|
/>
|
|
<p class="text-xs text-muted-foreground">(dejar en cero para calcular automático)</p>
|
|
</div>
|
|
<div class="space-y-2">
|
|
<Label for="importe_recargo">Importe Recargo:</Label>
|
|
<Input
|
|
id="importe_recargo"
|
|
type="number"
|
|
bind:value={formData.dta.importe_recargo}
|
|
placeholder="0"
|
|
/>
|
|
<p class="text-xs text-muted-foreground">(dejar en cero para calcular automático)</p>
|
|
</div>
|
|
</div>
|
|
{:else if activeTab === 'PREV'}
|
|
<div class="grid grid-cols-1 gap-4 max-w-md">
|
|
<div class="space-y-2">
|
|
<Label for="forma_pago_prevalidacion">Forma de pago Prevalidación:</Label>
|
|
<Input
|
|
id="forma_pago_prevalidacion"
|
|
type="number"
|
|
bind:value={formData.prev.forma_pago_prevalidacion}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
</div>
|
|
{:else if activeTab === 'ECI'}
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div class="space-y-2">
|
|
<Label for="forma_pago_eci">Forma de pago ECI:</Label>
|
|
<Input
|
|
id="forma_pago_eci"
|
|
type="number"
|
|
bind:value={formData.eci.forma_pago_eci}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
<div class="space-y-2">
|
|
<Label for="importe_eci">Importe ECI:</Label>
|
|
<Input
|
|
id="importe_eci"
|
|
type="number"
|
|
bind:value={formData.eci.importe_eci}
|
|
placeholder="0"
|
|
/>
|
|
<p class="text-xs text-muted-foreground">
|
|
(dejar en cero para que el sistema calcule el importe)
|
|
</p>
|
|
</div>
|
|
</div>
|
|
{:else if activeTab === 'MULT'}
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div class="space-y-2">
|
|
<Label for="forma_pago_multa">Forma de pago Multa:</Label>
|
|
<Input
|
|
id="forma_pago_multa"
|
|
type="number"
|
|
bind:value={formData.mult.forma_pago_multa}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
<div class="space-y-2">
|
|
<Label for="importe_multa">Importe Multa:</Label>
|
|
<Input
|
|
id="importe_multa"
|
|
type="number"
|
|
bind:value={formData.mult.importe_multa}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
</div>
|
|
{:else if activeTab === 'REC'}
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div class="space-y-2">
|
|
<Label for="forma_pago_uia">Forma de pago U I A:</Label>
|
|
<Input
|
|
id="forma_pago_uia"
|
|
type="number"
|
|
bind:value={formData.rec.forma_pago_uia}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
<div class="space-y-2">
|
|
<Label for="importe_compensar">Importe a Compensar:</Label>
|
|
<Input
|
|
id="importe_compensar"
|
|
type="number"
|
|
bind:value={formData.rec.importe_compensar}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
<!-- Tabla de contribuciones -->
|
|
<div class="border rounded-lg overflow-hidden">
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Contribución</TableHead>
|
|
<TableHead>T.T.</TableHead>
|
|
<TableHead>Tasa</TableHead>
|
|
<TableHead>F.P.</TableHead>
|
|
<TableHead class="text-right">Importe</TableHead>
|
|
<TableHead>Gravamen</TableHead>
|
|
<TableHead>Abreviación</TableHead>
|
|
<TableHead>F.P.</TableHead>
|
|
<TableHead class="text-right">Importe</TableHead>
|
|
<TableHead class="w-[100px]">Acciones</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{#if !formData?.contribuciones || formData.contribuciones.length === 0}
|
|
<TableRow>
|
|
<TableCell colspan={10} class="text-center text-muted-foreground py-8">
|
|
No hay contribuciones registradas
|
|
</TableCell>
|
|
</TableRow>
|
|
{:else}
|
|
{#each formData.contribuciones as contribucion, index}
|
|
<TableRow>
|
|
<TableCell>{contribucion.contribucion}</TableCell>
|
|
<TableCell>{contribucion.tipo_tasa}</TableCell>
|
|
<TableCell class="text-right"
|
|
>{contribucion.tasa.toLocaleString('es-MX', {
|
|
minimumFractionDigits: 2,
|
|
maximumFractionDigits: 5
|
|
})}</TableCell
|
|
>
|
|
<TableCell>{contribucion.forma_pago}</TableCell>
|
|
<TableCell class="text-right"
|
|
>{contribucion.importe.toLocaleString('es-MX', {
|
|
minimumFractionDigits: 2,
|
|
maximumFractionDigits: 2
|
|
})}</TableCell
|
|
>
|
|
<TableCell>{contribucion.gravamen}</TableCell>
|
|
<TableCell>{contribucion.abreviacion}</TableCell>
|
|
<TableCell>{contribucion.forma_pago_2}</TableCell>
|
|
<TableCell class="text-right"
|
|
>{contribucion.importe_2.toLocaleString('es-MX', {
|
|
minimumFractionDigits: 2,
|
|
maximumFractionDigits: 2
|
|
})}</TableCell
|
|
>
|
|
<TableCell>
|
|
<div class="flex gap-1">
|
|
<Button size="sm" variant="ghost" onclick={() => openEditContribucion(index)}>
|
|
<Pencil size={14} />
|
|
</Button>
|
|
<Button size="sm" variant="ghost" onclick={() => deleteContribucion(index)}>
|
|
<Trash2 size={14} />
|
|
</Button>
|
|
</div>
|
|
</TableCell>
|
|
</TableRow>
|
|
{/each}
|
|
{/if}
|
|
</TableBody>
|
|
</Table>
|
|
</div>
|
|
|
|
<!-- Controles inferiores -->
|
|
<div class="flex items-center justify-between border-t pt-4">
|
|
<div class="flex items-center gap-6">
|
|
<div class="flex items-center space-x-2">
|
|
<Checkbox
|
|
id="calculo_manual"
|
|
checked={formData?.calculo_manual ?? false}
|
|
onCheckedChange={(checked: boolean | 'indeterminate') =>
|
|
formData && (formData.calculo_manual = checked === true)}
|
|
/>
|
|
<Label for="calculo_manual" class="font-normal cursor-pointer text-sm"
|
|
>Cálculo Manual</Label
|
|
>
|
|
</div>
|
|
|
|
<div class="flex items-center space-x-2">
|
|
<Checkbox
|
|
id="operaciones_regla"
|
|
checked={formData?.operaciones_regla_31_40 ?? false}
|
|
onCheckedChange={(checked: boolean | 'indeterminate') =>
|
|
formData && (formData.operaciones_regla_31_40 = checked === true)}
|
|
/>
|
|
<Label for="operaciones_regla" class="font-normal cursor-pointer text-sm"
|
|
>Operaciones al amparo de la regla 31.40</Label
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-2">
|
|
<Button size="sm" onclick={openNewContribucion}>
|
|
<Plus class="mr-1.5" size={14} />
|
|
Nuevo
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
disabled={formData?.contribuciones?.length === 0}
|
|
onclick={() => {
|
|
const index = 0;
|
|
if (formData?.contribuciones?.[index]) openEditContribucion(index);
|
|
}}
|
|
>
|
|
<Pencil class="mr-1.5" size={14} />
|
|
Editar
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="destructive"
|
|
disabled={formData?.contribuciones?.length === 0}
|
|
onclick={() => {
|
|
const index = 0;
|
|
if (formData?.contribuciones?.[index]) deleteContribucion(index);
|
|
}}
|
|
>
|
|
<Trash2 class="mr-1.5" size={14} />
|
|
Borrar
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<!-- Dialog para Contribuciones -->
|
|
<Dialog bind:open={isDialogOpen}>
|
|
<DialogContent class="max-w-2xl max-h-[90vh] overflow-y-auto">
|
|
<DialogHeader>
|
|
<DialogTitle>
|
|
{editingIndex !== null ? 'Editar Contribución' : 'Nueva Contribución'}
|
|
</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
<div class="space-y-6 py-4">
|
|
<!-- Tasas Pedimento - Registro 509 -->
|
|
<div class="space-y-4">
|
|
<h3 class="font-semibold text-sm">Tasas Pedimento - Registro 509</h3>
|
|
|
|
<div class="space-y-2">
|
|
<Label for="contribucion">Contribución:</Label>
|
|
<Select.Root
|
|
type="single"
|
|
value={currentContribucion.contribucion}
|
|
onValueChange={(v: string | undefined) => v && (currentContribucion.contribucion = v)}
|
|
>
|
|
<Select.Trigger id="contribucion">
|
|
<span class="truncate">{currentContribucion.contribucion || 'Seleccionar'}</span>
|
|
</Select.Trigger>
|
|
<Select.Content>
|
|
{#each opcionesContribuciones as opcion}
|
|
<Select.Item value={opcion}>{opcion}</Select.Item>
|
|
{/each}
|
|
</Select.Content>
|
|
</Select.Root>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label for="tipo_tasa">Tipo de Tasa:</Label>
|
|
<div class="flex gap-2">
|
|
<Select.Root
|
|
type="single"
|
|
value={currentContribucion.tipo_tasa}
|
|
onValueChange={(v: string | undefined) => v && (currentContribucion.tipo_tasa = v)}
|
|
>
|
|
<Select.Trigger id="tipo_tasa" class="flex-1">
|
|
<span class="truncate">{currentContribucion.tipo_tasa || 'Seleccionar'}</span>
|
|
</Select.Trigger>
|
|
<Select.Content>
|
|
<Select.Item value="Porcentual">Porcentual</Select.Item>
|
|
<Select.Item value="Especifico">Específico</Select.Item>
|
|
<Select.Item value="CuotaMinimaDTA">Cuota minima (DTA)</Select.Item>
|
|
<Select.Item value="CuotaFijaDTA">Cuota fija (DTA)</Select.Item>
|
|
<Select.Item value="TasaDescuentoAdValorem">Tasa de descuento sobre ad valorem</Select.Item>
|
|
<Select.Item value="FactorAplicacionTIGIE">Factor de aplicación sobre tigie.</Select.Item>
|
|
<Select.Item value="AlMillarDTA">Al millar (DTA)</Select.Item>
|
|
<Select.Item value="TasaDescuentoArancelEspecifico">Tasa de descuento sobre el arancel específico</Select.Item>
|
|
<Select.Item value="TasaEspecificaPreciosReferencia">Tasa especifica sobre precios de referencia</Select.Item>
|
|
<Select.Item value="TasaEspecificaPreciosReferenciaUM">Tasa especifica sobre precios de referencia con UM</Select.Item>
|
|
</Select.Content>
|
|
</Select.Root>
|
|
<Button size="icon" variant="outline">
|
|
<Plus class="h-4 w-4" />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label for="tasa">Tasa:</Label>
|
|
<Input
|
|
id="tasa"
|
|
type="number"
|
|
step="0.00001"
|
|
bind:value={currentContribucion.tasa}
|
|
placeholder="0.00000"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Contribuciones Generales - Registro 510 -->
|
|
<div class="space-y-4">
|
|
<h3 class="font-semibold text-sm">Contribuciones Generales - Registro 510</h3>
|
|
|
|
<!-- Tabla de Contribuciones Generales -->
|
|
{#if currentContribucion.contribuciones_generales && currentContribucion.contribuciones_generales.length > 0}
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Clave Contribución</TableHead>
|
|
<TableHead>Forma de Pago</TableHead>
|
|
<TableHead>Importe</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{#each currentContribucion.contribuciones_generales as contribGen, i}
|
|
<TableRow>
|
|
<TableCell>{contribGen.clave_contribucion}</TableCell>
|
|
<TableCell>{contribGen.clave_forma_pago}</TableCell>
|
|
<TableCell>${contribGen.importe_contribucion.toFixed(2)}</TableCell>
|
|
</TableRow>
|
|
{/each}
|
|
</TableBody>
|
|
</Table>
|
|
{:else}
|
|
<p class="text-sm text-muted-foreground">No hay contribuciones generales registradas</p>
|
|
{/if}
|
|
|
|
<div class="flex gap-2">
|
|
<Button size="sm" variant="outline" onclick={openNewContribGenInDialog}>
|
|
<Plus class="h-4 w-4 mr-1" /> Nuevo
|
|
</Button>
|
|
<Button size="sm" variant="outline" disabled>
|
|
<Pencil class="h-4 w-4 mr-1" /> Editar
|
|
</Button>
|
|
<Button size="sm" variant="outline" disabled>
|
|
<Trash2 class="h-4 w-4 mr-1" /> Borrar
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
<Button variant="outline" onclick={() => (isDialogOpen = false)}>Cancelar</Button>
|
|
<Button onclick={saveContribucion}>Aceptar</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
|
|
<!-- Dialog para Contribución General (510) dentro del diálogo de Contribución -->
|
|
<Dialog bind:open={isContribGenDialogOpen}>
|
|
<DialogContent class="max-w-md">
|
|
<DialogHeader>
|
|
<DialogTitle>Insertando</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
<div class="space-y-4 py-4">
|
|
<div class="space-y-2">
|
|
<Label for="pedimento_sys_id_temp">PedimentoSysID:</Label>
|
|
<Input
|
|
id="pedimento_sys_id_temp"
|
|
bind:value={tempContribGen.pedimento_sys_id}
|
|
placeholder="39,641"
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label for="clave_contribucion_temp">Clave de Contribución:</Label>
|
|
<Input
|
|
id="clave_contribucion_temp"
|
|
bind:value={tempContribGen.clave_contribucion}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label for="clave_tasa_temp">Clave de Tasa:</Label>
|
|
<Input
|
|
id="clave_tasa_temp"
|
|
bind:value={tempContribGen.clave_tasa}
|
|
placeholder=""
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label for="tasa_contribucion_temp">Tasa de Contribución:</Label>
|
|
<Input
|
|
id="tasa_contribucion_temp"
|
|
type="number"
|
|
step="0.00001"
|
|
bind:value={tempContribGen.tasa_contribucion}
|
|
placeholder="0.00000"
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label for="clave_forma_pago_temp">Clave Forma de Pago:</Label>
|
|
<Input
|
|
id="clave_forma_pago_temp"
|
|
bind:value={tempContribGen.clave_forma_pago}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<Label for="importe_contribucion_temp">Importe de Contribución:</Label>
|
|
<Input
|
|
id="importe_contribucion_temp"
|
|
type="number"
|
|
step="0.01"
|
|
bind:value={tempContribGen.importe_contribucion}
|
|
placeholder="0"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
<Button variant="outline" onclick={() => (isContribGenDialogOpen = false)}>Cancelar</Button>
|
|
<Button onclick={saveContribGenInDialog}>Aceptar</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|