From 9567a584a5465ab8f35d5ae59401df24ba6f9922 Mon Sep 17 00:00:00 2001 From: Galindo97 Date: Fri, 16 Jan 2026 17:15:17 -0600 Subject: [PATCH] feat: enhance various components with new fields and improved styling for better user experience --- .../a76/general_catalogs/company/__init__.py | 2 + .../a76/general_catalogs/company/models.py | 4 +- .../company/submodels/__init__.py | 2 +- .../clients_and_providers/columns.ts | 55 +++++++ .../dashboard/customs_brokers/columns.ts | 121 +++++++++++---- .../dashboard/goods/parts/columns.ts | 111 +++++++++++-- .../dashboard/pedimentos/columns.ts | 146 ++++++++++++++++++ .../clients_and_providers/+page.svelte | 5 +- .../dashboard/customs_brokers/+page.svelte | 24 ++- .../routes/dashboard/goods/parts/+page.svelte | 8 +- .../routes/dashboard/invoices/+page.svelte | 10 +- .../routes/dashboard/pedimentos/+page.svelte | 27 +--- 12 files changed, 426 insertions(+), 89 deletions(-) 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 - + -
{ e.preventDefault(); applyFilters(); }} class="grid grid-cols-1 md:grid-cols-4 gap-4"> +
- -
- - -
- +
{#if error} - + Error {error} @@ -331,7 +320,7 @@ {/if} - +