diff --git a/apps/web/src/app/core/sl/account-codes.ts b/apps/web/src/app/core/sl/account-codes.ts index 16d8b0f..1f61ef1 100644 --- a/apps/web/src/app/core/sl/account-codes.ts +++ b/apps/web/src/app/core/sl/account-codes.ts @@ -9,6 +9,8 @@ import { escapeODataString } from './odata'; /** `Code` de la cuenta → su `FormatCode` (el código que conoce el usuario). */ const formats = signal>(new Map()); +/** `Code` de la cuenta → su nombre. */ +const names = signal>(new Map()); /** Cuántos códigos se piden por consulta. */ const BATCH = 20; @@ -28,10 +30,15 @@ export const ACCOUNT_CODES: CodeDisplay = { ensure(codes: readonly string[]): void { void service?.ensure(codes); }, + label(code: string): string { + return names().get(code) ?? ''; + }, remember(row: VhRow): void { const code = String(row['Code'] ?? ''); const format = String(row['FormatCode'] ?? '').trim(); + const name = String(row['Name'] ?? '').trim(); if (code && format && formats().get(code) !== format) formats.update((m) => new Map(m).set(code, format)); + if (code && name && names().get(code) !== name) names.update((m) => new Map(m).set(code, name)); }, }; @@ -46,12 +53,12 @@ export class AccountCodesService { } async ensure(codes: readonly string[]): Promise { - const missing = [...new Set(codes.filter((c) => c && !formats().has(c) && !this.asked.has(c)))]; + const missing = [...new Set(codes.filter((c) => c && !(formats().has(c) && names().has(c)) && !this.asked.has(c)))]; for (const c of missing) this.asked.add(c); for (let i = 0; i < missing.length; i += BATCH) { const filter = missing.slice(i, i + BATCH).map((c) => `Code eq '${escapeODataString(c)}'`).join(' or '); try { - const params = new HttpParams().set('$select', 'Code,FormatCode').set('$filter', filter); + const params = new HttpParams().set('$select', 'Code,FormatCode,Name').set('$filter', filter); const res = await firstValueFrom(this.http.get>(`${API_URL}/sl/ChartOfAccounts`, { params })); for (const row of res.value) ACCOUNT_CODES.remember(row); } catch { diff --git a/apps/web/src/app/features/documents/line-columns.ts b/apps/web/src/app/features/documents/line-columns.ts index 71c20f1..28c13b3 100644 --- a/apps/web/src/app/features/documents/line-columns.ts +++ b/apps/web/src/app/features/documents/line-columns.ts @@ -1,4 +1,5 @@ import type { GridColumn, GridLine, GridMultiAdd } from '../../shared/grid/grid.types'; +import { ACCOUNT_CODES } from '../../core/sl/account-codes'; import { ACCOUNT_LOOKUP, PROJECT_LOOKUP, dimensionLookup } from './dimension-lookups'; import { hasBaseRef, objectLabel } from './document-objects'; @@ -227,6 +228,8 @@ export const serviceLineColumns = (taxResource = 'SalesTaxCodes'): readonly Grid }), }, }, + // el nombre de la cuenta (SAP lo muestra aunque la línea no tenga descripción propia): solo se ve, no se guarda + { key: '_AccountName', title: 'Nombre de la cuenta', width: '230px', format: (l) => ACCOUNT_CODES.label?.(String(l['AccountCode'] ?? '')) ?? '' }, { ...LINE_COLUMNS.description, width: '260px' }, LINE_COLUMNS.tax, { ...LINE_COLUMNS.total, readonly: false, required: true }, diff --git a/apps/web/src/app/shared/value-help/value-help.types.ts b/apps/web/src/app/shared/value-help/value-help.types.ts index 83a6f05..c2b29c1 100644 --- a/apps/web/src/app/shared/value-help/value-help.types.ts +++ b/apps/web/src/app/shared/value-help/value-help.types.ts @@ -30,4 +30,6 @@ export interface CodeDisplay { ensure(codes: readonly string[]): void; /** Aprende el texto de una fila elegida o encontrada. */ remember(row: VhRow): void; + /** Nombre de lo que identifica el código (el de la cuenta), si ya se conoce. */ + label?(code: string): string; }