import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core'; import { CheckboxField, DateField, LookupField, NumberField, SelectField, TextField, TextareaField, UdfField } 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)); /** * Dibuja un campo de un formulario de maestro según su tipo. Recibe el valor tal como está en SAP * (las casillas son `tYES` / `tNO`) y emite el nuevo valor en esa misma forma. */ @Component({ selector: 'sbo-master-field', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CheckboxField, DateField, LookupField, NumberField, SelectField, TextField, TextareaField, UdfField], template: ` @switch (field().type) { @case ('checkbox') { } @case ('lookup') { } @case ('warehouse') { } @case ('udf') { } @case ('select') { } @case ('number') { } @case ('date') { } @case ('textarea') { } @default { } } `, styles: ':host { display: block; }', }) export class MasterField { readonly field = input.required(); readonly value = input(''); /** Todo el formulario en solo lectura. */ readonly readOnly = input(false); /** El registro ya existe: los campos `immutable` (el código) no se pueden cambiar. */ readonly saved = input(false); readonly changed = output(); protected readonly udf = computed(() => { const f = this.field(); if (f.type !== 'udf') throw new Error('campo sin definición de usuario'); return f; }); 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 { const f = this.field(); return f.type === 'lookup' && f.lookup.valueType === 'number' && /^\d+$/.test(code.trim()) ? Number(code) : code; } /** El texto del campo; una fecha de SAP llega como `2031-10-31T00:00:00Z` y el selector de fecha pide `yyyy-MM-dd`. */ protected readonly dbName = computed(() => { const f = this.field(); return 'key' in f ? f.key : undefined; }); protected readonly str = computed(() => (this.field().type === 'date' ? text(this.value()).slice(0, 10) : text(this.value()))); protected readonly num = computed(() => (this.value() === '' || this.value() === null || this.value() === undefined ? null : Number(this.value()))); protected readonly required = computed(() => { const f = this.field(); return 'required' in f && f.required === true; }); protected readonly ro = computed(() => { const f = this.field(); if ('immutable' in f && f.immutable && this.saved()) return true; return 'readonly' in f ? !!f.readonly : false; }); protected readonly lookup = computed(() => { const f = this.field(); if (f.type !== 'lookup') throw new Error('campo sin lista de valores'); return f.lookup; }); protected readonly options = computed(() => { const f = this.field(); return f.type === 'select' ? f.options : []; }); protected readonly decimals = computed(() => { const f = this.field(); return f.type === 'number' ? f.decimals : undefined; }); }