feat(web): transferencias de stock y solicitudes de traslado con socio de negocio, persona de contacto, destino, lista de precios y empleado

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5.5 committed 2026-10-19 14:47:23 -05:00
1 parent b85383dda1
commit c002c2cf3e
10 files changed
+147 -9

No files matched your search

@@ -62,6 +62,13 @@ export type HeaderField =
| { type: 'rounding'; label: string }
/** Moneda del documento (`DocCurrency`) y su tipo de cambio (`DocRate`): el de la fecha del documento si no es la local. */
| { type: 'currency'; label: string }
/** Persona de contacto del socio (`ContactPerson`): se elige de las del socio de negocio. */
| { type: 'contact'; key: string; label: string }
/**
* Dirección de envío (`ShipToCode`) o de facturación (`PayToCode`) del socio: se elige de sus direcciones y debajo se
* muestra su texto. `side` dice cuáles direcciones de la lista de direcciones del socio se ofrecen.
*/
| { type: 'address'; key: string; label: string; side: 'ship' | 'bill' }
| { type: 'computed'; label: string; source: ComputedSource };
/** Las listas de valores (ventanas modales) de un formulario. */
@@ -122,7 +129,40 @@ export const today = (): string => todayIso();
// --- catálogo de campos ---------------------------------------------------------------------
/** Catálogo de campos: cada pantalla elige cuáles lleva. */
/** Lista de precios de un documento (`PriceList`): las números de SAP y, en negativo, los costos (-2 último precio de compra). */
export const PRICE_LIST_LOOKUP: VhLookup = {
title: 'Listas de precios',
resource: 'PriceLists',
orderby: 'PriceListNo',
valueType: 'number',
columns: [
{ key: 'PriceListNo', title: 'Código', width: '90px', mono: true },
{ key: 'PriceListName', title: 'Nombre' },
],
};
/** Empleado de ventas o compras del documento (`SalesPersonCode`). */
export const SALES_PERSON_LOOKUP: VhLookup = {
title: 'Empleados de ventas',
resource: 'SalesPersons',
orderby: 'SalesEmployeeCode',
valueType: 'number',
baseFilter: `Active eq 'tYES'`,
columns: [
{ key: 'SalesEmployeeCode', title: 'Código', width: '90px', mono: true },
{ key: 'SalesEmployeeName', title: 'Nombre' },
],
};
export const FIELDS = {
/** Persona de contacto del socio. */
contact: { type: 'contact', key: 'ContactPerson', label: 'Persona de contacto' },
/** Dirección de destino (envío) del socio. */
shipTo: { type: 'address', key: 'ShipToCode', label: 'Destino', side: 'ship' },
/** Dirección de facturación del socio. */
payTo: { type: 'address', key: 'PayToCode', label: 'Dirección de facturación', side: 'bill' },
priceList: { type: 'lookup', key: 'PriceList', label: 'Lista de precios', lookup: PRICE_LIST_LOOKUP },
salesPerson: { type: 'lookup', key: 'SalesPersonCode', label: 'Empleado del departamento', lookup: SALES_PERSON_LOOKUP },
/** Tipo del documento: de artículos o de servicio (las líneas cambian). */
docType: {
type: 'select',
@@ -371,6 +411,8 @@ export const hasSeries = (layout: DocumentLayout): boolean => allFields(layout).
export const hasExpenses = (layout: DocumentLayout): boolean => allFields(layout).some((f) => f.type === 'expenses');
export const hasPartnerData = (layout: DocumentLayout): boolean => allFields(layout).some((f) => f.type === 'contact' || f.type === 'address');
export const hasCurrency = (layout: DocumentLayout): boolean => allFields(layout).some((f) => f.type === 'currency');
export const hasFolio = (layout: DocumentLayout): boolean => allFields(layout).some((f) => f.type === 'folio' || (f.type === 'group' && f.cells.some((c) => c.key === 'FolioNumber')));