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 633aa249..4b82e31d 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
@@ -18,6 +18,7 @@
defaultInvoiceType = undefined,
invoiceType = undefined,
isSettings = false,
+ isCreate = false,
highlightFieldId = null,
onDismissHighlightForField = undefined
}: {
@@ -29,6 +30,7 @@
defaultInvoiceType?: string | null;
invoiceType?: string;
isSettings?: boolean;
+ isCreate?: boolean;
highlightFieldId?: string | null;
onDismissHighlightForField?: (fieldKey: string) => void;
} = $props();
@@ -233,16 +235,38 @@
id="invoice-field-invoice_type"
tabindex="-1"
class={cn(
- 'min-w-[100px] flex-1 space-y-1 rounded-md outline-none',
+ 'min-w-[140px] flex-[1.2] space-y-1 rounded-md outline-none',
hl('invoice_type')
)}
>
-
- {formData.invoice_type ? `${formData.invoice_type}` : '...'}
-
+ {#if isCreate && !isSettings && formData.operation_type === 'exp'}
+ {
+ formData.invoice_type = v || '';
+ }}
+ >
+
+
+ {filteredInvoiceTypes.find((t) => t.key === formData.invoice_type)?.description ||
+ m.invoice_edit_form_invoice_type_placeholder()}
+
+
+
+ {#each filteredInvoiceTypes as t}
+ {t.description}
+ {/each}
+
+
+ {:else}
+
+ {formData.invoice_type ? `${formData.invoice_type}` : '...'}
+
+ {/if}
{/if}
diff --git a/frontend/src/lib/components/sidebar/modules.ts b/frontend/src/lib/components/sidebar/modules.ts
index 41a544fe..08930b11 100644
--- a/frontend/src/lib/components/sidebar/modules.ts
+++ b/frontend/src/lib/components/sidebar/modules.ts
@@ -447,7 +447,7 @@ export function getSidebarData(): SidebarData {
items: [
{
title: m["sidebar.export_invoices.exportation"](),
- url: "/dashboard/invoices?operation_type=exp&invoice_type=EXDEF",
+ url: "/dashboard/invoices?operation_type=exp",
permission: "invoice.exp.view"
},
{
diff --git a/frontend/src/lib/components/sidebar/team-switcher.svelte b/frontend/src/lib/components/sidebar/team-switcher.svelte
index ed91bfcc..c18b3458 100644
--- a/frontend/src/lib/components/sidebar/team-switcher.svelte
+++ b/frontend/src/lib/components/sidebar/team-switcher.svelte
@@ -73,32 +73,9 @@
}
}
- function normalizeIdentity(value: string | undefined | null): string {
- return (value ?? '').trim().toLowerCase();
- }
-
- let tenantIdentitySet = $derived.by(() => {
- const set = new Set();
- for (const tenant of userTenants) {
- set.add(normalizeIdentity(tenant.name));
- set.add(normalizeIdentity(tenant.slug));
- }
- set.delete('');
- return set;
- });
-
- // Excluir del listado de companias cualquier registro que realmente represente al tenant.
- let myCompanies = $derived(
- companyStore.companies.filter((company) => !tenantIdentitySet.has(normalizeIdentity(company.name)))
- );
-
- $effect(() => {
- const active = companyStore.activeCompany;
- if (!active) return;
- if (!tenantIdentitySet.has(normalizeIdentity(active.name))) return;
- if (myCompanies.length === 0) return;
- void companyStore.setActiveCompany(myCompanies[0], true);
- });
+ // Misma lista que devuelve my-companies; no filtrar por tenant (nombre/slug equivalentes
+ // ocultaban la empresa creada al primer login).
+ let myCompanies = $derived(companyStore.companies);
diff --git a/frontend/src/routes/dashboard/invoices/+page.svelte b/frontend/src/routes/dashboard/invoices/+page.svelte
index cf1b1bbd..63cab881 100644
--- a/frontend/src/routes/dashboard/invoices/+page.svelte
+++ b/frontend/src/routes/dashboard/invoices/+page.svelte
@@ -275,26 +275,39 @@
}
});
- // Título dinámico según el tipo de operación y factura
+ // Título dinámico según el tipo de operación y tipo de factura (i18n para casos clásicos; catálogo API para el resto)
const viewTitle = $derived.by(() => {
const op = filters.operation_type;
- const type = filters.invoice_type;
-
+ const type = (filters.invoice_type || '').trim();
+
const base = m['invoice_list.titles.base']();
-
+
+ const titleFromInvoiceTypesCatalog = (): string | null => {
+ if (!type || !data.invoiceTypes?.length) return null;
+ const hit = data.invoiceTypes.find((t: { key: string }) => t.key === type);
+ if (!hit?.description) return null;
+ return `${base} DE ${String(hit.description).trim().toUpperCase()}`;
+ };
+
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']()}`;
+ const catalogTitle = titleFromInvoiceTypesCatalog();
+ if (catalogTitle) return catalogTitle;
return `${base} ${m['invoice_list.titles.import']()}`;
- } else if (op === 'exp') {
+ }
+
+ 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']()}`;
+ const catalogTitle = titleFromInvoiceTypesCatalog();
+ if (catalogTitle) return catalogTitle;
return `${base} ${m['invoice_list.titles.export']()}`;
}
-
+
return m['invoice_list.header.title']();
});
@@ -1355,13 +1368,6 @@
}
}
- // Opciones de tipo de operación para el filtro
- const operationTypeOptions = $derived.by(() => [
- { value: '', label: m.invoice_list_operation_types_all() },
- { value: 'imp', label: m.invoice_list_operation_types_import() },
- { value: 'exp', label: m.invoice_list_operation_types_export() }
- ]);
-
// Todas las opciones de tipo de factura con su operación correspondiente
const allInvoiceTypeOptions = $derived(() => {
const options = [{ value: '', label: m.invoice_list_operation_types_all(), operation: 'both' }];
@@ -1445,35 +1451,6 @@
{m.invoice_list_header_description()}
-
-
-
-
-
-
-
+ {#if filters.operation_type === 'exp'}
+
+ {/if}
{
parsedOperationType = operationTypeParam;
}
- // Para creación ('new'), es obligatorio tener operation_type e invoice_type
- if (params.id === 'new' && (!parsedOperationType || !invoiceTypeParam)) {
+ // Para creación ('new'): siempre operation_type; invoice_type obligatorio solo en importación.
+ if (params.id === 'new' && !parsedOperationType) {
+ throw redirect(302, '/dashboard');
+ }
+ if (params.id === 'new' && parsedOperationType === 'imp' && !invoiceTypeParam) {
throw redirect(302, '/dashboard');
}
diff --git a/frontend/src/routes/dashboard/invoices/edit/[id]/+page.svelte b/frontend/src/routes/dashboard/invoices/edit/[id]/+page.svelte
index 9b3ca724..78f4ac96 100644
--- a/frontend/src/routes/dashboard/invoices/edit/[id]/+page.svelte
+++ b/frontend/src/routes/dashboard/invoices/edit/[id]/+page.svelte
@@ -498,14 +498,20 @@
let lastFetchedDate = $state('');
let originalInvoiceDate = $state(data.invoice?.invoice_date || '');
- // Derivados reactivos para el tipo de factura y operación
+ // Tipo de factura efectivo (cabecera + tabs): prioridad campos superiores, luego URL/factura.
+ // En importación sin tipo aún, se asume TEM como antes; en exportación sin tipo, cadena vacía (sin forzar TEM).
let invoiceType = $derived.by(() => {
- return (
- InvoiceTopFieldsFormData?.invoice_type ||
- data.filters?.invoice_type ||
- data.invoice?.invoice_type ||
- 'TEM'
- ); // Default to TEM if not found
+ const top = InvoiceTopFieldsFormData?.invoice_type;
+ if (top !== undefined && top !== null && String(top).trim() !== '') {
+ return String(top).trim();
+ }
+ if (data.filters?.invoice_type) return String(data.filters.invoice_type).trim();
+ if (data.invoice?.invoice_type) return String(data.invoice.invoice_type).trim();
+ const op =
+ InvoiceTopFieldsFormData?.operation_type ||
+ data.invoice?.operation_type ||
+ data.filters?.operation_type;
+ return op === 'imp' ? 'TEM' : '';
});
let operationTypeText = $derived.by(() => {
@@ -1044,19 +1050,18 @@
{#if data.isCreate}
- {@const invoiceType = generalFormData?.invoice_type || data.filters?.invoice_type}
- {@const invoiceTypeInfo = invoiceType
- ? data.invoiceTypes?.find((t) => t.key === invoiceType)
- : null}
{m.invoice_edit_new_title()}
- {#if invoiceTypeInfo}
-
- - {invoiceTypeInfo.description}
-
- {/if}
{:else}
{m.invoice_edit_page_invoice_prefix()}{data.invoice.id}
{/if}
+ {#if invoiceType}
+ {@const headerInvoiceTypeInfo = data.invoiceTypes?.find((t) => t.key === invoiceType)}
+ {#if headerInvoiceTypeInfo}
+
+ - {headerInvoiceTypeInfo.description}
+
+ {/if}
+ {/if}
{operationTypeText}
@@ -1088,6 +1093,7 @@
defaultOperationType={data.filters?.operation_type ?? undefined}
defaultInvoiceType={data.filters?.invoice_type ?? undefined}
{invoiceType}
+ isCreate={data.isCreate === true}
highlightFieldId={validationHighlightField}
onDismissHighlightForField={dismissValidationHighlight}
/>