diff --git a/backend/api/v1/modules/a76/general_catalogs/company/__init__.py b/backend/api/v1/modules/a76/general_catalogs/company/__init__.py
index 936a85fb..8078325f 100644
--- a/backend/api/v1/modules/a76/general_catalogs/company/__init__.py
+++ b/backend/api/v1/modules/a76/general_catalogs/company/__init__.py
@@ -2,6 +2,7 @@
Módulo de Company
"""
from .models import Company
+from .routes import router
from .submodels import (
CompanyAddress,
CompanyCertification,
@@ -14,6 +15,7 @@ from .submodels import (
__all__ = [
"Company",
+ "router",
"CompanyAddress",
"CompanyCertification",
"CompanyDigitalCertificate",
diff --git a/backend/api/v1/modules/a76/general_catalogs/company/models.py b/backend/api/v1/modules/a76/general_catalogs/company/models.py
index 0d96e933..c6d37213 100644
--- a/backend/api/v1/modules/a76/general_catalogs/company/models.py
+++ b/backend/api/v1/modules/a76/general_catalogs/company/models.py
@@ -2,7 +2,7 @@
Modelo principal de Company
"""
from typing import Optional, TYPE_CHECKING
-from sqlalchemy import Integer, String, SmallInteger, ForeignKey
+from sqlalchemy import Integer, String, SmallInteger, ForeignKey, Boolean
from sqlalchemy.orm import Mapped, mapped_column, relationship
from core.database import Base
from api.v1.common.base_models import TimestampMixin
@@ -64,7 +64,7 @@ class Company(Base, TimestampMixin):
logo: Mapped[Optional[str]] = mapped_column(String(255))
has_express_line: Mapped[Optional[str]] = mapped_column(String(2))
order_format_type: Mapped[Optional[str]] = mapped_column(String(19))
- is_service_company: Mapped[Optional[str]] = mapped_column(String(2))
+ is_service_company: Mapped[Optional[bool]] = mapped_column(Boolean, default=False)
client_name: Mapped[Optional[str]] = mapped_column(String(300))
subassembly_mode: Mapped[Optional[str]] = mapped_column(String(7))
diff --git a/backend/api/v1/modules/a76/general_catalogs/company/submodels/__init__.py b/backend/api/v1/modules/a76/general_catalogs/company/submodels/__init__.py
index 579ab456..8afa2f2b 100644
--- a/backend/api/v1/modules/a76/general_catalogs/company/submodels/__init__.py
+++ b/backend/api/v1/modules/a76/general_catalogs/company/submodels/__init__.py
@@ -4,7 +4,7 @@ Submodelos de Company
from .address import CompanyAddress
from .certification import CompanyCertification
from .digital_certificate import CompanyDigitalCertificate
-from .companyVU import CompanyVU
+from .vu import CompanyVU
from .electronic_agent import CompanyElectronicAgent
from .prevalidator import CompanyPrevalidator
from .cfdi import CompanyCFDI
diff --git a/frontend/src/lib/components/dashboard/clients_and_providers/columns.ts b/frontend/src/lib/components/dashboard/clients_and_providers/columns.ts
index a09246ab..b6dc5529 100644
--- a/frontend/src/lib/components/dashboard/clients_and_providers/columns.ts
+++ b/frontend/src/lib/components/dashboard/clients_and_providers/columns.ts
@@ -37,6 +37,61 @@ export function createColumns(onSuccess) {
return renderSnippet(snippet, { val: row.original.name });
}
},
+ {
+ id: "streets",
+ header: "Calles",
+ cell: ({ row }) => {
+ const snippet = createRawSnippet((getData) => {
+ const { val } = getData();
+ return { render: () => `
${val || '-'}
` };
+ });
+ return renderSnippet(snippet, { val: row.original.address?.streets });
+ }
+ },
+ {
+ id: "exterior_number",
+ header: "Num Ext.",
+ cell: ({ row }) => {
+ const snippet = createRawSnippet((getData) => {
+ const { val } = getData();
+ return { render: () => `${val || '-'}
` };
+ });
+ return renderSnippet(snippet, { val: row.original.address?.exterior_number });
+ }
+ },
+ {
+ id: "postal_code",
+ header: "Código Postal",
+ cell: ({ row }) => {
+ const snippet = createRawSnippet((getData) => {
+ const { val } = getData();
+ return { render: () => `${val || '-'}` };
+ });
+ return renderSnippet(snippet, { val: row.original.address?.postal_code });
+ }
+ },
+ {
+ id: "neighborhood",
+ header: "Colonia",
+ cell: ({ row }) => {
+ const snippet = createRawSnippet((getData) => {
+ const { val } = getData();
+ return { render: () => `${val || '-'}
` };
+ });
+ return renderSnippet(snippet, { val: row.original.address?.neighborhood });
+ }
+ },
+ {
+ id: "city",
+ header: "Ciudad",
+ cell: ({ row }) => {
+ const snippet = createRawSnippet((getData) => {
+ const { val } = getData();
+ return { render: () => `${val || '-'}
` };
+ });
+ return renderSnippet(snippet, { val: row.original.address?.city });
+ }
+ },
{
id: "country",
header: "País",
diff --git a/frontend/src/lib/components/dashboard/customs_brokers/columns.ts b/frontend/src/lib/components/dashboard/customs_brokers/columns.ts
index 4f099fd3..24400b55 100644
--- a/frontend/src/lib/components/dashboard/customs_brokers/columns.ts
+++ b/frontend/src/lib/components/dashboard/customs_brokers/columns.ts
@@ -22,9 +22,22 @@ export function createColumns(onSuccess?: () => void): ColumnDef[
return renderSnippet(keySnippet, { key: row.original.broker_key });
}
},
+ {
+ accessorKey: "type",
+ header: "Tipo",
+ cell: ({ row }) => {
+ const typeSnippet = createRawSnippet<[{ type: string | null | undefined }]>((getType) => {
+ const { type } = getType();
+ return {
+ render: () => `${type || '-'}
`
+ };
+ });
+ return renderSnippet(typeSnippet, { type: row.original.type });
+ }
+ },
{
accessorKey: "name",
- header: "Nombre",
+ header: "Nombre Completo",
cell: ({ row }) => {
const nameSnippet = createRawSnippet<[{ name: string | null | undefined }]>((getName) => {
const { name } = getName();
@@ -36,16 +49,84 @@ export function createColumns(onSuccess?: () => void): ColumnDef[
}
},
{
- accessorKey: "type",
- header: "Tipo",
+ accessorKey: "address",
+ header: "Dirección",
cell: ({ row }) => {
- const typeSnippet = createRawSnippet<[{ type: string | null | undefined }]>((getType) => {
- const { type } = getType();
+ const addressSnippet = createRawSnippet<[{ address: string | null | undefined }]>((getAddress) => {
+ const { address } = getAddress();
return {
- render: () => `${type || '-'}
`
+ render: () => `${address || '-'}
`
};
});
- return renderSnippet(typeSnippet, { type: row.original.type });
+ return renderSnippet(addressSnippet, { address: row.original.address });
+ }
+ },
+ {
+ accessorKey: "postal_code",
+ header: "Código Postal",
+ cell: ({ row }) => {
+ const postalSnippet = createRawSnippet<[{ postal: string | null | undefined }]>((getPostal) => {
+ const { postal } = getPostal();
+ return {
+ render: () =>
+ postal
+ ? `${postal}`
+ : `-`
+ };
+ });
+ return renderSnippet(postalSnippet, { postal: row.original.postal_code });
+ }
+ },
+ {
+ accessorKey: "city",
+ header: "Ciudad",
+ cell: ({ row }) => {
+ const citySnippet = createRawSnippet<[{ city: string | null | undefined }]>((getCity) => {
+ const { city } = getCity();
+ return {
+ render: () => `${city || '-'}
`
+ };
+ });
+ return renderSnippet(citySnippet, { city: row.original.city });
+ }
+ },
+ {
+ accessorKey: "state",
+ header: "Estado",
+ cell: ({ row }) => {
+ const stateSnippet = createRawSnippet<[{ state: string | null | undefined }]>((getState) => {
+ const { state } = getState();
+ return {
+ render: () => `${state || '-'}
`
+ };
+ });
+ return renderSnippet(stateSnippet, { state: row.original.state });
+ }
+ },
+ {
+ accessorKey: "phone",
+ header: "Teléfono",
+ cell: ({ row }) => {
+ const phoneSnippet = createRawSnippet<[{ phone: string | null | undefined }]>((getPhone) => {
+ const { phone } = getPhone();
+ return {
+ render: () => `${phone || '-'}
`
+ };
+ });
+ return renderSnippet(phoneSnippet, { phone: row.original.phone });
+ }
+ },
+ {
+ accessorKey: "fax",
+ header: "Número Fax",
+ cell: ({ row }) => {
+ const faxSnippet = createRawSnippet<[{ fax: string | null | undefined }]>((getFax) => {
+ const { fax } = getFax();
+ return {
+ render: () => `${fax || '-'}
`
+ };
+ });
+ return renderSnippet(faxSnippet, { fax: row.original.fax });
}
},
{
@@ -90,32 +171,6 @@ export function createColumns(onSuccess?: () => void): ColumnDef[
return renderSnippet(emailSnippet, { email: row.original.email });
}
},
- {
- accessorKey: "phone",
- header: "Teléfono",
- cell: ({ row }) => {
- const phoneSnippet = createRawSnippet<[{ phone: string | null | undefined }]>((getPhone) => {
- const { phone } = getPhone();
- return {
- render: () => `${phone || '-'}
`
- };
- });
- return renderSnippet(phoneSnippet, { phone: row.original.phone });
- }
- },
- {
- accessorKey: "city",
- header: "Ciudad",
- cell: ({ row }) => {
- const citySnippet = createRawSnippet<[{ city: string | null | undefined }]>((getCity) => {
- const { city } = getCity();
- return {
- render: () => `${city || '-'}
`
- };
- });
- return renderSnippet(citySnippet, { city: row.original.city });
- }
- },
{
id: "actions",
header: "Acciones",
diff --git a/frontend/src/lib/components/dashboard/goods/parts/columns.ts b/frontend/src/lib/components/dashboard/goods/parts/columns.ts
index 6230f6f1..1f161298 100644
--- a/frontend/src/lib/components/dashboard/goods/parts/columns.ts
+++ b/frontend/src/lib/components/dashboard/goods/parts/columns.ts
@@ -112,7 +112,25 @@ export function createColumns(onSuccess?: () => void): ColumnDef[] {
}
},
- // 7. FRACCION
+ // 7. U.M. (Unidad de Medida)
+ {
+ accessorKey: "unit_of_measure",
+ header: "U.M.",
+ cell: ({ row }) => {
+ const umSnippet = createRawSnippet<[{ um: string }]>((getUm) => {
+ const { um } = getUm();
+ return {
+ render: () =>
+ `
+ ${um}
+ `
+ };
+ });
+ return renderSnippet(umSnippet, { um: row.original.unit_of_measure });
+ }
+ },
+
+ // 8. FRACCION
{
accessorKey: "fraction",
header: "Fracción",
@@ -127,25 +145,22 @@ export function createColumns(onSuccess?: () => void): ColumnDef[] {
}
},
- // 8. UMT (Unidad de Medida)
+ // 9. U.M.T. (del inv_data)
{
- accessorKey: "unit_of_measure",
- header: "UMT",
+ id: "stock_uom",
+ header: "U.M.T.",
cell: ({ row }) => {
- const umtSnippet = createRawSnippet<[{ um: string }]>((getUm) => {
- const { um } = getUm();
+ const umtSnippet = createRawSnippet<[{ umt: string }]>((getUmt) => {
+ const { umt } = getUmt();
return {
- render: () =>
- `
- ${um}
- `
+ render: () => `${umt || '-'}
`
};
});
- return renderSnippet(umtSnippet, { um: row.original.unit_of_measure });
+ return renderSnippet(umtSnippet, { umt: row.original.inv_data?.stock_uom || '' });
}
},
- // 9. COSTO
+ // 10. COSTO
{
accessorKey: "unit_cost",
header: "Costo",
@@ -163,6 +178,78 @@ export function createColumns(onSuccess?: () => void): ColumnDef[] {
}
},
+ // 11. MONEDA
+ {
+ accessorKey: "currency_key",
+ header: "Moneda",
+ cell: ({ row }) => {
+ const currSnippet = createRawSnippet<[{ curr: string }]>((getCurr) => {
+ const { curr } = getCurr();
+ return {
+ render: () => `${curr || '-'}`
+ };
+ });
+ return renderSnippet(currSnippet, { curr: row.original.currency_key || '' });
+ }
+ },
+
+ // 12. PESO UNITARIO
+ {
+ accessorKey: "unit_weight",
+ header: "Peso Unitario",
+ cell: ({ row }) => {
+ const weightSnippet = createRawSnippet<[{ weight: number | null, type: string | null }]>((getWeight) => {
+ const { weight, type } = getWeight();
+ return {
+ render: () => {
+ if (weight === null || weight === undefined) return '-';
+ return `${weight.toFixed(4)} ${type || ''}
`;
+ }
+ };
+ });
+ return renderSnippet(weightSnippet, {
+ weight: row.original.unit_weight,
+ type: row.original.weight_type
+ });
+ }
+ },
+
+ // 13. U.M. EXIST (Stock UOM del inv_data)
+ {
+ id: "equivalent_uom",
+ header: "U.M. Exist",
+ cell: ({ row }) => {
+ const eqUomSnippet = createRawSnippet<[{ uom: string }]>((getUom) => {
+ const { uom } = getUom();
+ return {
+ render: () => `${uom || '-'}
`
+ };
+ });
+ return renderSnippet(eqUomSnippet, { uom: row.original.inv_data?.equivalent_uom || '' });
+ }
+ },
+
+ // 14. FECHA MODIFICACIÓN
+ {
+ accessorKey: "updated_at",
+ header: "Fecha Modificación",
+ cell: ({ row }) => {
+ const dateSnippet = createRawSnippet<[{ date: string }]>((getDate) => {
+ const { date } = getDate();
+ if (!date) return { render: () => '-' };
+ const formatted = new Date(date).toLocaleDateString('es-MX', {
+ year: 'numeric',
+ month: '2-digit',
+ day: '2-digit'
+ });
+ return {
+ render: () => `${formatted}
`
+ };
+ });
+ return renderSnippet(dateSnippet, { date: row.original.updated_at });
+ }
+ },
+
// ACCIONES
{
id: "actions",
diff --git a/frontend/src/lib/components/dashboard/pedimentos/columns.ts b/frontend/src/lib/components/dashboard/pedimentos/columns.ts
index 340ea641..2bdfbe51 100644
--- a/frontend/src/lib/components/dashboard/pedimentos/columns.ts
+++ b/frontend/src/lib/components/dashboard/pedimentos/columns.ts
@@ -117,6 +117,152 @@ export function createColumns(onSuccess?: () => void): ColumnDef[] {
return renderSnippet(numberSnippet, { number: fullNumber });
}
},
+ {
+ accessorKey: "pedimento_type",
+ header: "Tipo",
+ cell: ({ row }) => {
+ const typeSnippet = createRawSnippet<[{ type?: string | null }]>((getType) => {
+ const { type } = getType();
+ return {
+ render: () =>
+ `${type || '-'}
`
+ };
+ });
+ 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: () =>
+ `${code || '-'}
`
+ };
+ });
+ 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: () =>
+ `${regime || '-'}
`
+ };
+ });
+ 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: () =>
+ `${date}
`
+ };
+ });
+ 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: () =>
+ `${date}
`
+ };
+ });
+ 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: () =>
+ `${date}
`
+ };
+ });
+ 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: () =>
+ `${value || '-'}
`
+ };
+ });
+ 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: () =>
+ `${value || '-'}
`
+ };
+ });
+ 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: () =>
+ `
+ ${hasValue ? 'Sí' : 'No'}
+ `
+ };
+ });
+ 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: () =>
+ `
+ ${isPaid ? 'Sí' : 'No'}
+ `
+ };
+ });
+ return renderSnippet(paidSnippet, { value: row.original.pedimento_payments?.total_contributions });
+ }
+ },
{
accessorKey: "client_id",
header: "Cliente",
diff --git a/frontend/src/routes/dashboard/clients_and_providers/+page.svelte b/frontend/src/routes/dashboard/clients_and_providers/+page.svelte
index 2cc0ee23..78e70445 100644
--- a/frontend/src/routes/dashboard/clients_and_providers/+page.svelte
+++ b/frontend/src/routes/dashboard/clients_and_providers/+page.svelte
@@ -203,7 +203,7 @@
{#if error}
-
+
Error
@@ -214,11 +214,10 @@
{/if}
-
+
- Listado de Clientes y Proveedores
Mostrando {allItems.length} de {totalItems} registros
{#if companyStore.activeCompany}
diff --git a/frontend/src/routes/dashboard/customs_brokers/+page.svelte b/frontend/src/routes/dashboard/customs_brokers/+page.svelte
index 611dce23..19b39457 100644
--- a/frontend/src/routes/dashboard/customs_brokers/+page.svelte
+++ b/frontend/src/routes/dashboard/customs_brokers/+page.svelte
@@ -130,8 +130,13 @@
if (response.data) {
if (Array.isArray(response.data)) {
brokersList = response.data;
- } else if (response.data.items && Array.isArray(response.data.items)) {
- brokersList = response.data.items;
+ } else if (typeof response.data === 'object' && 'items' in response.data) {
+ const dataWithItems = response.data as { items?: CustomsBroker[] };
+ if (Array.isArray(dataWithItems.items)) {
+ brokersList = dataWithItems.items;
+ } else {
+ brokersList = [];
+ }
} else {
console.error("⚠️ Estructura de datos inesperada:", response.data);
brokersList = [];
@@ -171,9 +176,8 @@
-
+
- Buscar Agente Aduanal
Ingresa la clave del agente aduanal para buscarlo
{#if companyStore.activeCompany}
@@ -222,7 +226,7 @@
-
+
@@ -271,4 +275,12 @@
-
\ No newline at end of file
+
{
+ // El CreateDialog maneja la creación internamente
+ // Después de guardar exitosamente, recargar los datos
+ await handleSuccess();
+ }}
+/>
\ No newline at end of file
diff --git a/frontend/src/routes/dashboard/goods/parts/+page.svelte b/frontend/src/routes/dashboard/goods/parts/+page.svelte
index dae74cc6..bba5417e 100644
--- a/frontend/src/routes/dashboard/goods/parts/+page.svelte
+++ b/frontend/src/routes/dashboard/goods/parts/+page.svelte
@@ -121,11 +121,7 @@
-
-
- Búsqueda Rápida
- Ingresa el número de parte o descripción para filtrar.
-
+
@@ -155,7 +151,7 @@
-
+
{#if isSearching}
diff --git a/frontend/src/routes/dashboard/invoices/+page.svelte b/frontend/src/routes/dashboard/invoices/+page.svelte
index 0c70436d..7108c742 100644
--- a/frontend/src/routes/dashboard/invoices/+page.svelte
+++ b/frontend/src/routes/dashboard/invoices/+page.svelte
@@ -392,11 +392,7 @@
-
-
- Filtros
- Filtra las facturas por diferentes criterios (los filtros se aplican automáticamente)
-
+
@@ -458,7 +454,7 @@
{#if error}
-
+
Error
{error}
@@ -467,7 +463,7 @@
{/if}
-
+
diff --git a/frontend/src/routes/dashboard/pedimentos/+page.svelte b/frontend/src/routes/dashboard/pedimentos/+page.svelte
index 711d5173..28b09205 100644
--- a/frontend/src/routes/dashboard/pedimentos/+page.svelte
+++ b/frontend/src/routes/dashboard/pedimentos/+page.svelte
@@ -267,18 +267,15 @@
-
-
- Filtros
- Filtra los pedimentos por diferentes criterios
-
+
-
+
{#if error}
-
+
Error
{error}
@@ -331,7 +320,7 @@
{/if}
-
+