feat(web): el artículo muestra el nombre del almacén por defecto y los nombres de las listas de precios y de la lista base

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5.5 committed 2026-10-19 19:01:44 -05:00
1 parent 8af3b11ac2
commit d05b497cb2
5 files changed
+13 -7

No files matched your search

@@ -130,11 +130,12 @@ export const ARTICULOS_SCREENS: readonly MasterScreen[] = [
rowKey: 'PriceList', rowKey: 'PriceList',
identity: ['PriceList'], identity: ['PriceList'],
columns: [ columns: [
{ key: 'PriceList', title: 'Lista de precios', type: 'text', readonly: true, width: '130px' }, { key: 'PriceList', title: 'Lista de precios', type: 'text', readonly: true, width: '90px' },
{ key: 'PriceListName', title: 'Nombre', type: 'text', width: '260px', nameOf: { codeKey: 'PriceList', resource: 'PriceLists', valueField: 'PriceListNo', labelField: 'PriceListName' } },
{ key: 'Price', title: 'Precio', type: 'number', decimals: 2, width: '130px' }, { key: 'Price', title: 'Precio', type: 'number', decimals: 2, width: '130px' },
{ key: 'Currency', title: 'Moneda', type: 'text', width: '90px' }, { key: 'Currency', title: 'Moneda', type: 'text', width: '90px' },
{ key: 'Factor', title: 'Factor', type: 'number', readonly: true, width: '90px' }, { key: 'Factor', title: 'Factor', type: 'number', readonly: true, width: '90px' },
{ key: 'BasePriceList', title: 'Lista base', type: 'text', readonly: true, width: '100px' }, { key: 'BasePriceList', title: 'Lista base', type: 'text', readonly: true, width: '240px', nameOf: { codeKey: 'BasePriceList', resource: 'PriceLists', valueField: 'PriceListNo', labelField: 'PriceListName', withCode: true } },
], ],
}, },
}, },
@@ -225,7 +225,7 @@ describe('formulario con tablas', () => {
it('precios: solo se envía la lista que cambió, sin reemplazar la colección', async () => { it('precios: solo se envía la lista que cambió, sin reemplazar la colección', async () => {
await open('/inventario/articulos', 'A1', item()); await open('/inventario/articulos', 'A1', item());
const price = cell(4, 1, 1); const price = cell(4, 1, 2);
expect(price.value).toBe('50.00'); expect(price.value).toBe('50.00');
price.value = '777'; price.value = '777';
price.dispatchEvent(new Event('change')); price.dispatchEvent(new Event('change'));
@@ -261,7 +261,7 @@ describe('formulario con tablas', () => {
it('un artículo con cambios en un campo y en los precios envía las dos cosas juntas', async () => { it('un artículo con cambios en un campo y en los precios envía las dos cosas juntas', async () => {
await open('/inventario/articulos', 'A1', item()); await open('/inventario/articulos', 'A1', item());
page().setValue('ItemName', 'Pieza nueva'); page().setValue('ItemName', 'Pieza nueva');
const price = cell(4, 0, 1); const price = cell(4, 0, 2);
price.value = '120'; price.value = '120';
price.dispatchEvent(new Event('change')); price.dispatchEvent(new Event('change'));
await tick(); await tick();
@@ -1,6 +1,7 @@
import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core'; import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
import { CheckboxField, DateField, LookupField, NumberField, SelectField, TextField, TextareaField } from '../../shared/form'; import { CheckboxField, DateField, LookupField, NumberField, SelectField, TextField, TextareaField } from '../../shared/form';
import { WAREHOUSE_LOOKUP } from '../documents/document-layouts'; import { WAREHOUSE_LOOKUP } from '../documents/document-layouts';
import type { VhLookup } from '../../shared/value-help/value-help.types';
import type { HeaderField } from '../documents/document-layouts'; import type { HeaderField } from '../documents/document-layouts';
const text = (v: unknown): string => (v === null || v === undefined ? '' : String(v)); const text = (v: unknown): string => (v === null || v === undefined ? '' : String(v));
@@ -93,7 +94,7 @@ export class MasterField {
readonly saved = input(false); readonly saved = input(false);
readonly changed = output<string | number>(); readonly changed = output<string | number>();
protected readonly warehouse = WAREHOUSE_LOOKUP; protected readonly warehouse: VhLookup = { ...WAREHOUSE_LOOKUP, nameKey: 'WarehouseName' };
/** Un código numérico de SAP (grupo, lista de precios) se guarda como número. */ /** Un código numérico de SAP (grupo, lista de precios) se guarda como número. */
protected typed(code: string): string | number { protected typed(code: string): string | number {
+1 -1
View File
@@ -74,7 +74,7 @@ export interface DetailColumn {
* La columna muestra el nombre de lo que identifica el código de otra columna (`WarehouseCode` → nombre del almacén); * La columna muestra el nombre de lo que identifica el código de otra columna (`WarehouseCode` → nombre del almacén);
* el catálogo se consulta una sola vez. No es un campo que se guarde. * el catálogo se consulta una sola vez. No es un campo que se guarde.
*/ */
nameOf?: { codeKey: string; resource: string; valueField: string; labelField: string }; nameOf?: { codeKey: string; resource: string; valueField: string; labelField: string; /** Se ve `código · nombre` en vez de solo el nombre. */ withCode?: boolean };
/** Texto calculado de la fila (solo se muestra; no es un campo que se guarde). */ /** Texto calculado de la fila (solo se muestra; no es un campo que se guarde). */
computed?: (row: Record<string, unknown>) => string; computed?: (row: Record<string, unknown>) => string;
/** Campos de la fila que cambian además del propio al elegir o escribir un valor de la lista (la cuenta elegida primero completa el «Cuenta / socio»). */ /** Campos de la fila que cambian además del propio al elegir o escribir un valor de la lista (la cuenta elegida primero completa el «Cuenta / socio»). */
+5 -1
View File
@@ -233,7 +233,11 @@ export class RowsTable {
protected text(row: Row, c: DetailColumn): string { protected text(row: Row, c: DetailColumn): string {
if (c.computed) return c.computed(row); if (c.computed) return c.computed(row);
if (c.nameOf) return this.names()[c.nameOf.resource]?.get(String(row[c.nameOf.codeKey] ?? '')) ?? ''; if (c.nameOf) {
const code = String(row[c.nameOf.codeKey] ?? '');
const name = this.names()[c.nameOf.resource]?.get(code);
return c.nameOf.withCode ? (name ? `${code} · ${name}` : code) : (name ?? '');
}
const v = row[c.key]; const v = row[c.key];
if (c.type === 'date') return dateOnly(v); if (c.type === 'date') return dateOnly(v);
if (c.type === 'number') return v === null || v === undefined || v === '' ? '' : formatNumber(v, c.decimals); if (c.type === 'number') return v === null || v === undefined || v === '' ? '' : formatNumber(v, c.decimals);