feat(web): la lista de clientes y proveedores muestra el Grupo (código y nombre, una sola consulta al catálogo)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8ed44aa55b
commit
f985667b90
3 files changed
+35
-3
No files matched your search
@@ -1,7 +1,9 @@
|
|||||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||||
|
import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { API_URL } from '../../core/api';
|
||||||
import { ListView } from '../../shared/list/list-view';
|
import { ListView } from '../../shared/list/list-view';
|
||||||
import type { ListRow } from '../../shared/list/list.types';
|
import type { ListColumn, ListRow } from '../../shared/list/list.types';
|
||||||
import type { MasterScreen } from './master-types';
|
import type { MasterScreen } from './master-types';
|
||||||
|
|
||||||
/** Lista de un maestro (clientes, proveedores, artículos); abre uno o crea uno nuevo. */
|
/** Lista de un maestro (clientes, proveedores, artículos); abre uno o crea uno nuevo. */
|
||||||
@@ -13,7 +15,7 @@ import type { MasterScreen } from './master-types';
|
|||||||
<sbo-list-view
|
<sbo-list-view
|
||||||
[title]="title"
|
[title]="title"
|
||||||
[resource]="screen.resource"
|
[resource]="screen.resource"
|
||||||
[columns]="screen.columns"
|
[columns]="columns"
|
||||||
[extraFields]="screen.extraFields ?? []"
|
[extraFields]="screen.extraFields ?? []"
|
||||||
[filters]="screen.filters"
|
[filters]="screen.filters"
|
||||||
[orderby]="screen.orderby"
|
[orderby]="screen.orderby"
|
||||||
@@ -32,6 +34,32 @@ export class MasterListPage {
|
|||||||
|
|
||||||
protected readonly screen = this.route.snapshot.data['screen'] as MasterScreen;
|
protected readonly screen = this.route.snapshot.data['screen'] as MasterScreen;
|
||||||
protected readonly title = this.route.snapshot.data['title'] as string;
|
protected readonly title = this.route.snapshot.data['title'] as string;
|
||||||
|
private readonly http = inject(HttpClient);
|
||||||
|
private readonly names = signal<Record<string, Map<string, string>>>({});
|
||||||
|
|
||||||
|
/** Las columnas de la pantalla; las de un catálogo muestran `código · nombre` apenas llega el catálogo (una sola consulta). */
|
||||||
|
protected readonly columns: readonly ListColumn[] = this.screen.columns.map((c) => {
|
||||||
|
if (!this.screen.listNames?.some((n) => n.key === c.key)) return c;
|
||||||
|
return {
|
||||||
|
...c,
|
||||||
|
format: (r: ListRow) => {
|
||||||
|
const code = r[c.key];
|
||||||
|
if (code === null || code === undefined || code === '') return '';
|
||||||
|
const name = this.names()[c.key]?.get(String(code));
|
||||||
|
return name ? `${code} · ${name}` : String(code);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
for (const n of this.screen.listNames ?? []) {
|
||||||
|
const params = new HttpParams().set('$select', `${n.valueField},${n.labelField}`).set('$top', 500);
|
||||||
|
this.http.get<{ value?: Record<string, unknown>[] }>(`${API_URL}/sl/${n.resource}`, { params }).subscribe({
|
||||||
|
next: (res) => this.names.update((m) => ({ ...m, [n.key]: new Map((res.value ?? []).map((x) => [String(x[n.valueField]), String(x[n.labelField] ?? '')])) })),
|
||||||
|
error: () => undefined, // sin nombres se ve el código
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected open(row: ListRow): void {
|
protected open(row: ListRow): void {
|
||||||
void this.router.navigate([String(row[this.screen.keyField])], { relativeTo: this.route });
|
void this.router.navigate([String(row[this.screen.keyField])], { relativeTo: this.route });
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ export interface MasterScreen {
|
|||||||
createLabel: string;
|
createLabel: string;
|
||||||
columns: readonly ListColumn[];
|
columns: readonly ListColumn[];
|
||||||
extraFields?: readonly string[];
|
extraFields?: readonly string[];
|
||||||
|
/** Columnas de la lista cuyo valor es un código de otro catálogo: se muestra `código · nombre` (`GroupCode` → `BusinessPartnerGroups`). */
|
||||||
|
listNames?: readonly { key: string; resource: string; valueField: string; labelField: string }[];
|
||||||
filters: readonly ListFilter[];
|
filters: readonly ListFilter[];
|
||||||
orderby: string;
|
orderby: string;
|
||||||
/** Filtro fijo de la lista y de la navegación (ej. solo los clientes). */
|
/** Filtro fijo de la lista y de la navegación (ej. solo los clientes). */
|
||||||
|
|||||||
@@ -40,10 +40,12 @@ const partner = (opts: { path: string; type: 'cCustomer' | 'cSupplier'; singular
|
|||||||
orderby: 'CardCode',
|
orderby: 'CardCode',
|
||||||
baseFilter: `CardType eq '${opts.type}'`,
|
baseFilter: `CardType eq '${opts.type}'`,
|
||||||
extraFields: ['Frozen'],
|
extraFields: ['Frozen'],
|
||||||
|
listNames: [{ key: 'GroupCode', resource: 'BusinessPartnerGroups', valueField: 'Code', labelField: 'Name' }],
|
||||||
columns: [
|
columns: [
|
||||||
{ key: 'CardCode', title: 'Código', width: '130px', mono: true, searchable: true },
|
{ key: 'CardCode', title: 'Código', width: '130px', mono: true, searchable: true },
|
||||||
{ key: 'CardName', title: 'Nombre', searchable: true },
|
{ key: 'CardName', title: 'Nombre', searchable: true },
|
||||||
{ key: 'FederalTaxID', title: 'RUT', width: '120px', mono: true, searchable: true },
|
{ key: 'FederalTaxID', title: 'RUT', width: '120px', mono: true, searchable: true },
|
||||||
|
{ key: 'GroupCode', title: 'Grupo', type: 'number', align: 'left', width: '170px' },
|
||||||
{ key: 'Phone1', title: 'Teléfono', width: '130px', searchable: true },
|
{ key: 'Phone1', title: 'Teléfono', width: '130px', searchable: true },
|
||||||
{ key: 'EmailAddress', title: 'Correo electrónico', searchable: true },
|
{ key: 'EmailAddress', title: 'Correo electrónico', searchable: true },
|
||||||
statusColumn,
|
statusColumn,
|
||||||
|
|||||||
Reference in new issue
Block a user