Files
plantillas-proyectos/frontend/src/lib/components/dashboard/pedimentos/columns.ts

390 lines
11 KiB
TypeScript

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";
import type { Pedimento } from "$lib/api/dashboard/a76/pedimentos";
/**
* Formatea un número como moneda
*/
function formatCurrency(value?: number | null): string {
if (value === null || value === undefined) return '-';
return new Intl.NumberFormat('es-MX', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(value);
}
/**
* Formatea un número con separadores de miles
*/
function formatNumber(value?: number | null, decimals = 2): string {
if (value === null || value === undefined) return '-';
return new Intl.NumberFormat('es-MX', {
minimumFractionDigits: decimals,
maximumFractionDigits: decimals
}).format(value);
}
/**
* Formatea una fecha
*/
function formatDate(date?: string | null): string {
if (!date) return '-';
return new Date(date).toLocaleDateString('es-MX', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
}
/**
* Obtiene el color del badge según el status
*/
function getStatusColor(status?: string | null): string {
if (!status) return 'bg-gray-100 text-gray-800';
const statusUpper = status.toUpperCase();
// Estados completados/exitosos - Verde
if (statusUpper === 'VALIDADO' || statusUpper === 'PAGADO' || statusUpper === 'CARTA CUPO') {
return 'bg-green-100 text-green-800';
}
// Estados en espera/proceso - Amarillo
if (statusUpper.startsWith('ESPERA')) {
return 'bg-yellow-100 text-yellow-800';
}
// Estados con firma - Azul
if (statusUpper === 'CON FIRMA DE PREVIO') {
return 'bg-blue-100 text-blue-800';
}
// Estados modificables/editables - Índigo
if (statusUpper === 'MODIFICABLE') {
return 'bg-indigo-100 text-indigo-800';
}
// Estados de borrado - Naranja
if (statusUpper.includes('BORRADA')) {
return 'bg-orange-100 text-orange-800';
}
// Estados cancelados/desistidos - Rojo
if (statusUpper === 'DESISTIO') {
return 'bg-red-100 text-red-800';
}
// Default - Gris
return 'bg-gray-100 text-gray-800';
}
export function createColumns(onSuccess?: () => void): ColumnDef<Pedimento>[] {
return [
{
accessorKey: "id",
header: "ID",
cell: ({ row }) => {
const idSnippet = createRawSnippet<[{ id: number }]>((getId) => {
const { id } = getId();
return {
render: () =>
`<div class="font-medium">#${id}</div>`
};
});
return renderSnippet(idSnippet, { id: row.original.id });
}
},
{
accessorKey: "pedimento_number",
header: "Número de Pedimento",
cell: ({ row }) => {
const pedimento = row.original;
const fullNumber = `${pedimento.year || ''}-${pedimento.customs_office || ''}-${pedimento.license || ''}-${pedimento.pedimento_number || ''}`;
const numberSnippet = createRawSnippet<[{ number: string }]>((getNumber) => {
const { number } = getNumber();
return {
render: () =>
`<code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">${number || 'N/A'}</code>`
};
});
return renderSnippet(numberSnippet, { number: fullNumber });
}
},
{
accessorKey: "pedimento_type",
header: "Tipo",
cell: ({ row }) => {
const typeSnippet = createRawSnippet<[{ type?: string | null }]>((getType) => {
const { type } = getType();
return {
render: () =>
`<div class="text-sm">${type || '-'}</div>`
};
});
return renderSnippet(typeSnippet, { type: row.original.pedimento_type });
}
},
{
accessorKey: "pedimento_code",
header: "Clave",
cell: ({ row }) => {
const codeSnippet = createRawSnippet<[{ code?: string | null }]>((getCode) => {
const { code } = getCode();
return {
render: () =>
`<div class="text-sm">${code || '-'}</div>`
};
});
return renderSnippet(codeSnippet, { code: row.original.pedimento_code });
}
},
{
accessorKey: "regime",
header: "Régimen",
cell: ({ row }) => {
const regimeSnippet = createRawSnippet<[{ regime?: string | null }]>((getRegime) => {
const { regime } = getRegime();
return {
render: () =>
`<div class="text-sm">${regime || '-'}</div>`
};
});
return renderSnippet(regimeSnippet, { regime: row.original.regime });
}
},
{
accessorKey: "pedimento_dates.start_date",
header: "Fecha Inicio",
cell: ({ row }) => {
const dateSnippet = createRawSnippet<[{ date: string }]>((getDate) => {
const { date } = getDate();
return {
render: () =>
`<div class="text-sm text-muted-foreground">${date}</div>`
};
});
return renderSnippet(dateSnippet, { date: formatDate(row.original.pedimento_dates?.start_date) });
}
},
{
accessorKey: "pedimento_dates.end_date",
header: "Fecha Final",
cell: ({ row }) => {
const dateSnippet = createRawSnippet<[{ date: string }]>((getDate) => {
const { date } = getDate();
return {
render: () =>
`<div class="text-sm text-muted-foreground">${date}</div>`
};
});
return renderSnippet(dateSnippet, { date: formatDate(row.original.pedimento_dates?.end_date) });
}
},
{
accessorKey: "pedimento_dates.payment_date",
header: "Fecha de Pago",
cell: ({ row }) => {
const dateSnippet = createRawSnippet<[{ date: string }]>((getDate) => {
const { date } = getDate();
return {
render: () =>
`<div class="text-sm text-muted-foreground">${date}</div>`
};
});
return renderSnippet(dateSnippet, { date: formatDate(row.original.pedimento_dates?.payment_date) });
}
},
{
accessorKey: "pedimento_config_update_rectification.pediment_rectifed_18",
header: "Pedimento 18",
cell: ({ row }) => {
const ped18Snippet = createRawSnippet<[{ value?: string | null }]>((getValue) => {
const { value } = getValue();
return {
render: () =>
`<div class="text-sm">${value || '-'}</div>`
};
});
return renderSnippet(ped18Snippet, { value: row.original.pedimento_config_update_rectification?.pediment_rectifed_18 });
}
},
{
accessorKey: "pedimento_config_update_rectification.r1",
header: "Pedimento R1",
cell: ({ row }) => {
const r1Snippet = createRawSnippet<[{ value?: string | null }]>((getValue) => {
const { value } = getValue();
return {
render: () =>
`<div class="text-sm">${value || '-'}</div>`
};
});
return renderSnippet(r1Snippet, { value: row.original.pedimento_config_update_rectification?.r1 });
}
},
{
accessorKey: "pedimento_validation.electronic_signature",
header: "Acuse Electrónico",
cell: ({ row }) => {
const ackSnippet = createRawSnippet<[{ value?: string | null }]>((getValue) => {
const { value } = getValue();
const hasValue = value && value !== '';
return {
render: () =>
`<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${hasValue ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}">
${hasValue ? 'Sí' : 'No'}
</span>`
};
});
return renderSnippet(ackSnippet, { value: row.original.pedimento_validation?.electronic_signature });
}
},
{
accessorKey: "pedimento_payments.total_contributions",
header: "¿Se pagó el impuesto?",
cell: ({ row }) => {
const paidSnippet = createRawSnippet<[{ value?: string | null }]>((getValue) => {
const { value } = getValue();
const isPaid = value && parseFloat(value) > 0;
return {
render: () =>
`<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${isPaid ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}">
${isPaid ? 'Sí' : 'No'}
</span>`
};
});
return renderSnippet(paidSnippet, { value: row.original.pedimento_payments?.total_contributions });
}
},
{
accessorKey: "client_id",
header: "Cliente",
cell: ({ row }) => {
const clientSnippet = createRawSnippet<[{ clientId?: number | null }]>((getClient) => {
const { clientId } = getClient();
return {
render: () =>
`<div>${clientId ? `Cliente #${clientId}` : '-'}</div>`
};
});
return renderSnippet(clientSnippet, { clientId: row.original.client_id });
}
},
{
accessorKey: "status",
header: "Estado",
cell: ({ row }) => {
const status = row.original.status;
const colorClass = getStatusColor(status);
const formattedStatus = status
? status.charAt(0).toUpperCase() + status.slice(1).toLowerCase()
: 'N/A';
const statusSnippet = createRawSnippet<[{ status: string; colorClass: string }]>((getStatus) => {
const { status, colorClass } = getStatus();
return {
render: () =>
`<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${colorClass}">
${status}
</span>`
};
});
return renderSnippet(statusSnippet, { status: formattedStatus, colorClass });
}
},
{
accessorKey: "usd_value",
header: () => {
const headerSnippet = createRawSnippet(() => {
return {
render: () => `<div class="text-right">Valor USD</div>`
};
});
return renderSnippet(headerSnippet, {});
},
cell: ({ row }) => {
const valueSnippet = createRawSnippet<[{ value: string }]>((getValue) => {
const { value } = getValue();
return {
render: () =>
`<div class="text-right font-medium">${value}</div>`
};
});
return renderSnippet(valueSnippet, { value: formatCurrency(row.original.usd_value) });
}
},
{
accessorKey: "paid_price",
header: () => {
const headerSnippet = createRawSnippet(() => {
return {
render: () => `<div class="text-right">Precio Pagado</div>`
};
});
return renderSnippet(headerSnippet, {});
},
cell: ({ row }) => {
const priceSnippet = createRawSnippet<[{ price: string }]>((getPrice) => {
const { price } = getPrice();
return {
render: () =>
`<div class="text-right font-medium">${price}</div>`
};
});
return renderSnippet(priceSnippet, { price: formatCurrency(row.original.paid_price) });
}
},
{
accessorKey: "gross_weight",
header: () => {
const headerSnippet = createRawSnippet(() => {
return {
render: () => `<div class="text-right">Peso Bruto</div>`
};
});
return renderSnippet(headerSnippet, {});
},
cell: ({ row }) => {
const weightSnippet = createRawSnippet<[{ weight: string }]>((getWeight) => {
const { weight } = getWeight();
return {
render: () =>
`<div class="text-right">${weight}</div>`
};
});
return renderSnippet(weightSnippet, { weight: formatNumber(row.original.gross_weight, 3) });
}
},
{
accessorKey: "created_at",
header: "Fecha de Creación",
cell: ({ row }) => {
const dateSnippet = createRawSnippet<[{ date: string }]>((getDate) => {
const { date } = getDate();
return {
render: () =>
`<div class="text-sm text-muted-foreground">${date}</div>`
};
});
return renderSnippet(dateSnippet, { date: formatDate(row.original.created_at) });
}
},
{
id: "actions",
cell: ({ row }) => {
return renderComponent(DataTableActions, { item: row.original, onSuccess });
}
}
];
}
// Mantener compatibilidad hacia atrás
export const columns = createColumns();