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:
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',
|
||||
identity: ['PriceList'],
|
||||
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: 'Currency', title: 'Moneda', type: 'text', 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 () => {
|
||||
await open('/inventario/articulos', 'A1', item());
|
||||
const price = cell(4, 1, 1);
|
||||
const price = cell(4, 1, 2);
|
||||
expect(price.value).toBe('50.00');
|
||||
price.value = '777';
|
||||
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 () => {
|
||||
await open('/inventario/articulos', 'A1', item());
|
||||
page().setValue('ItemName', 'Pieza nueva');
|
||||
const price = cell(4, 0, 1);
|
||||
const price = cell(4, 0, 2);
|
||||
price.value = '120';
|
||||
price.dispatchEvent(new Event('change'));
|
||||
await tick();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
|
||||
import { CheckboxField, DateField, LookupField, NumberField, SelectField, TextField, TextareaField } from '../../shared/form';
|
||||
import { WAREHOUSE_LOOKUP } from '../documents/document-layouts';
|
||||
import type { VhLookup } from '../../shared/value-help/value-help.types';
|
||||
import type { HeaderField } from '../documents/document-layouts';
|
||||
|
||||
const text = (v: unknown): string => (v === null || v === undefined ? '' : String(v));
|
||||
@@ -93,7 +94,7 @@ export class MasterField {
|
||||
readonly saved = input(false);
|
||||
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. */
|
||||
protected typed(code: string): string | number {
|
||||
|
||||
@@ -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);
|
||||
* 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). */
|
||||
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»). */
|
||||
|
||||
@@ -233,7 +233,11 @@ export class RowsTable {
|
||||
|
||||
protected text(row: Row, c: DetailColumn): string {
|
||||
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];
|
||||
if (c.type === 'date') return dateOnly(v);
|
||||
if (c.type === 'number') return v === null || v === undefined || v === '' ? '' : formatNumber(v, c.decimals);
|
||||
|
||||
Reference in new issue
Block a user