From 43caaeffd3e82f9eddd672842e49d01f66b30cf6 Mon Sep 17 00:00:00 2001 From: hreyes Date: Fri, 24 Apr 2026 07:09:28 -0600 Subject: [PATCH] feature/tipo-operacion-invoice --- frontend/messages/en.json | 12 +++ frontend/messages/es.json | 12 +++ .../dashboard/invoices/data-table.svelte | 12 +-- .../invoices/edit/invoice-top-fields.svelte | 60 ++++---------- .../src/lib/components/sidebar/modules.ts | 2 +- .../routes/dashboard/invoices/+page.server.ts | 27 ++++--- .../routes/dashboard/invoices/+page.svelte | 78 ++++++++++++------- .../invoices/edit/[id]/+page.server.ts | 5 ++ 8 files changed, 121 insertions(+), 87 deletions(-) diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 8e68d3a7..d6ee1686 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -193,6 +193,18 @@ "title": "Invoices", "description": "Manage system invoices" }, + "titles": { + "base": "INVOICE CATALOG", + "import": "IMPORT", + "export": "EXPORT", + "import_temporal": "TEMPORARY IMPORT", + "import_definitive": "DEFINITIVE IMPORT", + "import_mexican": "MEXICAN PURCHASES", + "import_regime_change": "REGIME CHANGE AND REGULARIZATION", + "import_repair": "IMPORT REPAIR", + "export_definitive": "DEFINITIVE EXIT", + "export_repair": "REPAIR" + }, "filters": { "operation_label": "Operation Type", "operation_all_option": "Operation: All", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 3141240c..3921448f 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -192,6 +192,18 @@ "title": "Facturas", "description": "Gestiona las facturas del sistema" }, + "titles": { + "base": "CATALOGO DE FACTURAS", + "import": "DE IMPORTACION", + "export": "DE EXPORTACION", + "import_temporal": "DE IMPORTACION TEMPORAL", + "import_definitive": "DE IMPORTACION DEFINITIVA", + "import_mexican": "DE COMPRAS MEXICANAS", + "import_regime_change": "DE CAMBIO DE REGIMEN Y REGULARIZACION", + "import_repair": "DE IMPO. DE REPARACION", + "export_definitive": "DE SALIDA DEFINITIVA", + "export_repair": "DE REPARACION" + }, "filters": { "operation_label": "Tipo de Operacion", "operation_all_option": "Operacion: Todas", diff --git a/frontend/src/lib/components/dashboard/invoices/data-table.svelte b/frontend/src/lib/components/dashboard/invoices/data-table.svelte index b6c53490..b1e955ab 100644 --- a/frontend/src/lib/components/dashboard/invoices/data-table.svelte +++ b/frontend/src/lib/components/dashboard/invoices/data-table.svelte @@ -82,7 +82,11 @@ let loadingTrigger = $state(); // Intersection Observer para detectar cuando el usuario llega al final - onMount(() => { + $effect(() => { + const target = loadingTrigger; + const root = scrollContainer; + if (!target) return; + const observer = new IntersectionObserver( (entries) => { const [entry] = entries; @@ -91,14 +95,12 @@ } }, { - root: scrollContainer, + root: root, threshold: 0.1 } ); - if (loadingTrigger) { - observer.observe(loadingTrigger); - } + observer.observe(target); return () => { observer.disconnect(); diff --git a/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte b/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte index 891a6b60..d2ad0bd4 100644 --- a/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte +++ b/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte @@ -152,56 +152,26 @@
{#if !isSettings} +
- {m.invoice_edit_form_operation_type_label()} - { - formData.operation_type = v; - }} - > - - - {formData.operation_type - ? (formData.operation_type === 'exp' - ? m.invoice_edit_form_operation_type_export() - : m.invoice_edit_form_operation_type_import()) - : '...'} - - - - {m.invoice_edit_form_operation_type_export()} - {m.invoice_edit_form_operation_type_import()} - - +

+ {formData.operation_type + ? (formData.operation_type === 'exp' + ? m.invoice_edit_form_operation_type_export() + : m.invoice_edit_form_operation_type_import()) + : '...'} +

- {m.invoice_edit_form_invoice_type_label()} - { - formData.invoice_type = v ?? ''; - }} - > - - - {formData.invoice_type ? `${formData.invoice_type}` : '...'} - - - - {#each filteredInvoiceTypes as type} - - {type.key} - {type.description} - - {/each} - - +

+ {formData.invoice_type ? `${formData.invoice_type}` : '...'} +

{/if} diff --git a/frontend/src/lib/components/sidebar/modules.ts b/frontend/src/lib/components/sidebar/modules.ts index b93e3d29..c1b7f0bf 100644 --- a/frontend/src/lib/components/sidebar/modules.ts +++ b/frontend/src/lib/components/sidebar/modules.ts @@ -443,7 +443,7 @@ export function getSidebarData(): SidebarData { items: [ { title: m["sidebar.export_invoices.exportation"](), - url: "/dashboard/invoices?operation_type=exp", + url: "/dashboard/invoices?operation_type=exp&invoice_type=EXDEF", }, { title: m["sidebar.export_invoices.repair"](), diff --git a/frontend/src/routes/dashboard/invoices/+page.server.ts b/frontend/src/routes/dashboard/invoices/+page.server.ts index 245527e2..12ce133f 100644 --- a/frontend/src/routes/dashboard/invoices/+page.server.ts +++ b/frontend/src/routes/dashboard/invoices/+page.server.ts @@ -6,14 +6,22 @@ import { } from '$lib/server/api'; export const load: PageServerLoad = async ({ fetch, cookies, url, parent }) => { + const invoiceType = url.searchParams.get('invoice_type'); + const operationType = url.searchParams.get('operation_type'); + + if (!operationType) { + throw redirect(302, '/dashboard'); + } + // Esperar a que el layout padre valide/refresque el token const parentData = await parent(); // Verificar autenticación - const { accessToken } = getAuthTokens(cookies); + const tokens = getAuthTokens(cookies); + const accessToken = tokens.accessToken; if (!accessToken) { - throw redirect(302, '/login'); + throw redirect(302, '/auth/login'); } try { @@ -43,7 +51,6 @@ export const load: PageServerLoad = async ({ fetch, cookies, url, parent }) => { } // Construir parámetros de consulta - // Los query parameters invoice_type y operation_type se pasan al endpoint const params = new URLSearchParams({ company_id: companyId.toString(), page: '1', @@ -51,8 +58,6 @@ export const load: PageServerLoad = async ({ fetch, cookies, url, parent }) => { }); // Agregar filtros opcionales desde query parameters - const invoiceType = url.searchParams.get('invoice_type'); - const operationType = url.searchParams.get('operation_type'); const invoiceNumber = url.searchParams.get('invoice_number'); const projectNumber = url.searchParams.get('project_number'); const year = url.searchParams.get('year'); @@ -70,14 +75,14 @@ export const load: PageServerLoad = async ({ fetch, cookies, url, parent }) => { {}, cookies, fetch, - '/login' + '/auth/login' ), authenticatedFetch( 'v1/public/reference_data/invoice-types?page=1&page_size=100', {}, cookies, fetch, - '/login' + '/auth/login' ) ]); @@ -90,9 +95,9 @@ export const load: PageServerLoad = async ({ fetch, cookies, url, parent }) => { error: 'Error al cargar facturas', companies: parentData.companies || [], currentCompanyId: companyId, - // Preservar los filtros aplicados filters: { - invoice_type: invoiceType, + invoice_type: invoiceType, + operation_type: operationType } }; } @@ -108,7 +113,6 @@ export const load: PageServerLoad = async ({ fetch, cookies, url, parent }) => { companies: parentData.companies || [], currentCompanyId: companyId, invoiceTypes: invoiceTypesData.items || [], - // Preservar los filtros aplicados filters: { invoice_type: invoiceType, operation_type: operationType, @@ -119,6 +123,9 @@ export const load: PageServerLoad = async ({ fetch, cookies, url, parent }) => { }; } catch (error) { console.error('Error loading invoices:', error); + if (error instanceof Response && error.status >= 300 && error.status < 400) { + throw error; // Propagate redirects + } return { items: [], total: 0, diff --git a/frontend/src/routes/dashboard/invoices/+page.svelte b/frontend/src/routes/dashboard/invoices/+page.svelte index 97743e07..e8c80fe4 100644 --- a/frontend/src/routes/dashboard/invoices/+page.svelte +++ b/frontend/src/routes/dashboard/invoices/+page.svelte @@ -274,6 +274,29 @@ } }); + // Título dinámico según el tipo de operación y factura + const viewTitle = $derived.by(() => { + const op = filters.operation_type; + const type = filters.invoice_type; + + const base = m.invoice_list_titles_base(); + + if (op === 'imp') { + if (type === 'TEM') return `${base} ${m.invoice_list_titles_import_temporal()}`; + if (type === 'DEF') return `${base} ${m.invoice_list_titles_import_definitive()}`; + if (type === 'MEX') return `${base} ${m.invoice_list_titles_import_mexican()}`; + if (type === 'CR') return `${base} ${m.invoice_list_titles_import_regime_change()}`; + if (type === 'REP') return `${base} ${m.invoice_list_titles_import_repair()}`; + return `${base} ${m.invoice_list_titles_import()}`; + } else if (op === 'exp') { + if (type === 'EXDEF') return `${base} ${m.invoice_list_titles_export_definitive()}`; + if (type === 'REPAR') return `${base} ${m.invoice_list_titles_export_repair()}`; + return `${base} ${m.invoice_list_titles_export()}`; + } + + return m.invoice_list_header_title(); + }); + async function loadMore() { if (loading || !hasMore) return; @@ -1360,35 +1383,38 @@
-

{m.invoice_list_header_title()}

+

{viewTitle}

{m.invoice_list_header_description()}

- - - + +