@asteby/metacore-runtime-react 49.7.0 → 49.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/business/document-editor-model.d.ts +27 -2
  3. package/dist/business/document-editor-model.d.ts.map +1 -1
  4. package/dist/business/document-editor-model.js +53 -3
  5. package/dist/business/document-editor.d.ts +7 -2
  6. package/dist/business/document-editor.d.ts.map +1 -1
  7. package/dist/business/document-editor.js +116 -21
  8. package/dist/business/document-lines.d.ts +21 -1
  9. package/dist/business/document-lines.d.ts.map +1 -1
  10. package/dist/business/document-lines.js +69 -7
  11. package/dist/business/line-items-editor.d.ts +21 -1
  12. package/dist/business/line-items-editor.d.ts.map +1 -1
  13. package/dist/business/line-items-editor.js +74 -15
  14. package/dist/business/line-items.d.ts +28 -0
  15. package/dist/business/line-items.d.ts.map +1 -1
  16. package/dist/business/line-items.js +1 -0
  17. package/dist/business/line-product-cell.d.ts +6 -0
  18. package/dist/business/line-product-cell.d.ts.map +1 -1
  19. package/dist/business/line-product-cell.js +9 -3
  20. package/dist/business/product-options.js +1 -1
  21. package/dist/dialogs/dynamic-record.js +1 -1
  22. package/dist/field-grid.d.ts +4 -3
  23. package/dist/field-grid.d.ts.map +1 -1
  24. package/dist/field-grid.js +1 -1
  25. package/dist/record-picker.d.ts +2 -0
  26. package/dist/record-picker.d.ts.map +1 -1
  27. package/dist/record-picker.js +11 -4
  28. package/package.json +1 -1
  29. package/src/__tests__/document-editor-inline-selects.test.tsx +11 -4
  30. package/src/__tests__/line-row-create-edit.test.tsx +312 -0
  31. package/src/business/document-editor-model.ts +60 -2
  32. package/src/business/document-editor.tsx +132 -17
  33. package/src/business/document-lines.ts +79 -7
  34. package/src/business/line-items-editor.tsx +158 -30
  35. package/src/business/line-items.ts +31 -0
  36. package/src/business/line-product-cell.tsx +32 -5
  37. package/src/business/product-options.tsx +1 -1
  38. package/src/dialogs/dynamic-record.tsx +1 -1
  39. package/src/field-grid.tsx +5 -4
  40. package/src/record-picker.tsx +16 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @asteby/metacore-runtime-react
2
2
 
3
+ ## 49.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 13e4aaf: DocumentEditor: crear y editar el producto desde la celda del renglón. «Crear producto «texto»» y «+» abren el alta del modelo de catálogo (metacore:create-record) prellenada con lo buscado y el producto nuevo llena ESE renglón con el mismo mapeo que al elegirlo; el lápiz (hover/foco, accesible por teclado) abre la edición (metacore:edit-record) y al guardar el renglón se actualiza salvo los campos que el usuario sobrescribió (dirty por campo contra la foto del catálogo), con aviso «Precio de catálogo cambió a $X — aplicar». Los renglones de un documento origen no cambian cantidad, tope ni precios. Tarjeta de la contraparte con etiquetas de la metadata (clave corta si la larga no resuelve) y valores de catálogo «G03 · Gastos en general», sin vacíos. Placeholder corto «Buscar producto…» con la ayuda como tooltip y en el estado vacío; el buscador del renglón vacío usa el ancho de las columnas que aún no llena; la unidad bajo el SKU sale con su etiqueta (nunca la clave cruda). RecordPicker: la lista se acota al alto disponible (no se sale del viewport al abrirse hacia arriba), `maxListWidth` y nombres a 2 líneas. FieldLabel y el modal genérico usan sentence case por defecto.
8
+
3
9
  ## 49.7.0
4
10
 
5
11
  ### Minor Changes
@@ -61,8 +61,33 @@ export declare function gatedOptionFixes(fields: readonly ActionFieldDef[], valu
61
61
  * Solo llena lo que está vacío: nunca pisa lo que el usuario ya capturó.
62
62
  */
63
63
  export declare function partyDefaults(party: Record<string, any> | null, documentFieldKeys: readonly string[], current: Record<string, unknown>): Record<string, unknown>;
64
- /** Filas de la tarjeta de contraparte: resumen declarado + extensiones (máximo `limit`). */
65
- export declare function partySummaryRows(party: Record<string, any> | null, summary?: readonly string[], labels?: Record<string, string>, limit?: number): Array<{
64
+ /** Etiqueta y opciones de catálogo de un campo (de la metadata del modelo o del propio tipo). */
65
+ export interface FieldDisplayMeta {
66
+ label?: string;
67
+ options?: ReadonlyArray<{
68
+ value: unknown;
69
+ label?: unknown;
70
+ }>;
71
+ }
72
+ /**
73
+ * Metadata de pantalla por clave a partir de listas de campos/columnas
74
+ * (`/metadata/modal` → fields, `/metadata/table` → columns, campos del tipo).
75
+ * La primera lista que trae etiqueta u opciones para una clave gana.
76
+ */
77
+ export declare function fieldDisplayMeta(lists: ReadonlyArray<ReadonlyArray<unknown> | null | undefined>, translate?: (s: string) => string): Record<string, FieldDisplayMeta>;
78
+ /** `tax_id` → «Tax id»: último recurso cuando ningún metadata etiqueta la columna. */
79
+ export declare function humanizeKey(key: string): string;
80
+ /**
81
+ * Valor de catálogo legible: `G03` con la opción «Gastos en general» →
82
+ * «G03 · Gastos en general» (si la etiqueta ya trae el código, tal cual).
83
+ */
84
+ export declare function formatOptionValue(value: unknown, options?: FieldDisplayMeta['options']): string;
85
+ /**
86
+ * Filas de la tarjeta de contraparte: resumen declarado + extensiones (máximo
87
+ * `limit`). Etiqueta del campo (metadata / labels declarados, ya traducidos),
88
+ * valores de catálogo con su texto y nunca claves crudas ni vacíos.
89
+ */
90
+ export declare function partySummaryRows(party: Record<string, any> | null, summary?: readonly string[], labels?: Record<string, string>, limit?: number, meta?: Record<string, FieldDisplayMeta>): Array<{
66
91
  key: string;
67
92
  label: string;
68
93
  value: string;
@@ -1 +1 @@
1
- {"version":3,"file":"document-editor-model.d.ts","sourceRoot":"","sources":["../../src/business/document-editor-model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"document-editor-model.d.ts","sourceRoot":"","sources":["../../src/business/document-editor-model.ts"],"names":[],"mappings":"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"}
@@ -152,8 +152,55 @@ export function partyDefaults(party, documentFieldKeys, current) {
152
152
  }
153
153
  return out;
154
154
  }
155
- /** Filas de la tarjeta de contraparte: resumen declarado + extensiones (máximo `limit`). */
156
- export function partySummaryRows(party, summary = [], labels = {}, limit = 6) {
155
+ /**
156
+ * Metadata de pantalla por clave a partir de listas de campos/columnas
157
+ * (`/metadata/modal` → fields, `/metadata/table` → columns, campos del tipo).
158
+ * La primera lista que trae etiqueta u opciones para una clave gana.
159
+ */
160
+ export function fieldDisplayMeta(lists, translate = (s) => s) {
161
+ const out = {};
162
+ for (const list of lists) {
163
+ for (const raw of list ?? []) {
164
+ const f = raw;
165
+ const key = typeof f?.key === 'string' ? f.key : typeof f?.name === 'string' ? f.name : undefined;
166
+ if (!key)
167
+ continue;
168
+ const cur = (out[key] ??= {});
169
+ if (!cur.label && typeof f.label === 'string' && f.label)
170
+ cur.label = translate(f.label);
171
+ if (!cur.options && Array.isArray(f.options) && f.options.length > 0) {
172
+ cur.options = f.options.map((o) => ({ value: o?.value, label: typeof o?.label === 'string' ? translate(o.label) : o?.label }));
173
+ }
174
+ }
175
+ }
176
+ return out;
177
+ }
178
+ /** `tax_id` → «Tax id»: último recurso cuando ningún metadata etiqueta la columna. */
179
+ export function humanizeKey(key) {
180
+ const base = key.replace(EXTENSION_PREFIX, '').replace(/[_.]+/g, ' ').trim();
181
+ return base ? base.charAt(0).toUpperCase() + base.slice(1) : key;
182
+ }
183
+ /**
184
+ * Valor de catálogo legible: `G03` con la opción «Gastos en general» →
185
+ * «G03 · Gastos en general» (si la etiqueta ya trae el código, tal cual).
186
+ */
187
+ export function formatOptionValue(value, options) {
188
+ const raw = String(value);
189
+ const opt = options?.find((o) => String(o.value) === raw);
190
+ const label = opt && typeof opt.label === 'string' ? opt.label.trim() : '';
191
+ if (!label || label === raw)
192
+ return raw;
193
+ if (label.includes(raw))
194
+ return label;
195
+ const codeLike = /^[A-Z0-9]{1,5}$/.test(raw) && /\d/.test(raw);
196
+ return codeLike ? `${raw} · ${label}` : label;
197
+ }
198
+ /**
199
+ * Filas de la tarjeta de contraparte: resumen declarado + extensiones (máximo
200
+ * `limit`). Etiqueta del campo (metadata / labels declarados, ya traducidos),
201
+ * valores de catálogo con su texto y nunca claves crudas ni vacíos.
202
+ */
203
+ export function partySummaryRows(party, summary = [], labels = {}, limit = 6, meta = {}) {
157
204
  if (!party)
158
205
  return [];
159
206
  const keys = new Set(summary);
@@ -166,7 +213,10 @@ export function partySummaryRows(party, summary = [], labels = {}, limit = 6) {
166
213
  const v = readPath(party, key);
167
214
  if (!hasValue(v) || typeof v === 'object')
168
215
  continue;
169
- rows.push({ key, label: labels[key] ?? key.replace(EXTENSION_PREFIX, ''), value: String(v) });
216
+ if (typeof v === 'string' && !v.trim())
217
+ continue;
218
+ const m = meta[key];
219
+ rows.push({ key, label: labels[key] ?? m?.label ?? humanizeKey(key), value: formatOptionValue(v, m?.options) });
170
220
  }
171
221
  return rows.slice(0, limit);
172
222
  }
@@ -16,8 +16,13 @@ export interface DocumentEditorProps {
16
16
  onSaved?: (record?: unknown) => void;
17
17
  onCancel: () => void;
18
18
  searchProducts?: DocumentLinesGridProps['search'];
19
- /** Modelo de catálogo del buscador por defecto. Default `products.Product`. */
19
+ /**
20
+ * Modelo de catálogo: buscador por defecto y alta/edición del producto
21
+ * desde la celda del renglón. Default `products.Product`.
22
+ */
20
23
  productModel?: string;
24
+ /** Columna del modelo de catálogo que recibe lo buscado al crear. Default `name`. */
25
+ productLabelField?: string;
21
26
  defaultTaxRate?: number;
22
27
  currency?: string;
23
28
  /** Hoy (días de atraso del reparto; inyectable en tests). */
@@ -29,5 +34,5 @@ export interface DocumentEditorProps {
29
34
  */
30
35
  fullscreen?: boolean;
31
36
  }
32
- export declare function DocumentEditor({ model, endpoint, forms, type, record, initialSource, onSaved, onCancel, searchProducts, productModel, defaultTaxRate, currency, today, fullscreen, }: DocumentEditorProps): import("react").JSX.Element;
37
+ export declare function DocumentEditor({ model, endpoint, forms, type, record, initialSource, onSaved, onCancel, searchProducts, productModel, productLabelField, defaultTaxRate, currency, today, fullscreen, }: DocumentEditorProps): import("react").JSX.Element;
33
38
  //# sourceMappingURL=document-editor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"document-editor.d.ts","sourceRoot":"","sources":["../../src/business/document-editor.tsx"],"names":[],"mappings":"AA4BA,OAAO,EAAqB,KAAK,sBAAsB,EAAwB,MAAM,qBAAqB,CAAA;AAkD1G,OAAO,KAAK,EAAsC,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAE3G,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,qBAAqB,CAAA;IAC5B,IAAI,EAAE,gBAAgB,CAAA;IACtB,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,oEAAoE;IACpE,aAAa,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3C,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,cAAc,CAAC,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAA;IACjD,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACvB;AAID,wBAAgB,cAAc,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,MAAM,EACN,aAAa,EACb,OAAO,EACP,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,KAAK,EACL,UAAkB,GACrB,EAAE,mBAAmB,+BA4xBrB"}
1
+ {"version":3,"file":"document-editor.d.ts","sourceRoot":"","sources":["../../src/business/document-editor.tsx"],"names":[],"mappings":"AA4BA,OAAO,EAAqB,KAAK,sBAAsB,EAAwB,MAAM,qBAAqB,CAAA;AAsD1G,OAAO,KAAK,EAAsC,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAE3G,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,qBAAqB,CAAA;IAC5B,IAAI,EAAE,gBAAgB,CAAA;IACtB,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,oEAAoE;IACpE,aAAa,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3C,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,cAAc,CAAC,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAA;IACjD;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACvB;AAID,wBAAgB,cAAc,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,MAAM,EACN,aAAa,EACb,OAAO,EACP,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,iBAA0B,EAC1B,cAAc,EACd,QAAQ,EACR,KAAK,EACL,UAAkB,GACrB,EAAE,mBAAmB,+BAo2BrB"}
@@ -30,8 +30,9 @@ import { FormErrorBanner } from './feedback';
30
30
  import { DocumentLinesGrid } from './line-items-editor';
31
31
  import { computeTotals, serializeLineItems, taxBreakdown } from './line-items';
32
32
  import { roundMoney, toAmount, useFormatter } from './format';
33
- import { createCatalogProductSearch } from './catalog-product-search';
34
- import { allocationAmountField, allocationIssueMessages, allocationPayload, creditStatus, editorLinesConfig, linesFromSource, localIssues, sourceLoadSummary, sourceTracksRemaining, partyDefaults, partySummaryRows, recordLabel, seedRecord, sourceHeaderSeeds, splitEditorFields, toOpenDocuments, friendlyOptionLabel, gatedOptionFixes, gatedOptions, withFriendlyOptions, } from './document-editor-model';
33
+ import { catalogRecordToProduct, createCatalogProductSearch } from './catalog-product-search';
34
+ import { requestRecordCreate, requestRecordEdit, withSearchPrefill } from '../record-picker-actions';
35
+ import { allocationAmountField, allocationIssueMessages, allocationPayload, creditStatus, editorLinesConfig, fieldDisplayMeta, linesFromSource, localIssues, sourceLoadSummary, sourceTracksRemaining, partyDefaults, partySummaryRows, recordLabel, seedRecord, sourceHeaderSeeds, splitEditorFields, toOpenDocuments, friendlyOptionLabel, gatedOptionFixes, gatedOptions, withFriendlyOptions, } from './document-editor-model';
35
36
  import { CollapsibleSection, DraftPreview, EditorSection, PartyCard, PreviewPanel, TotalsPanel, ValidationChecklist, } from './document-editor-panels';
36
37
  import { PaymentAllocator } from './payment-allocator';
37
38
  import { actionErrorBannerMessage, buildFieldDefaults, prefillFromFieldRelationRequest, renderField } from '../action-modal-dispatcher';
@@ -43,7 +44,7 @@ import { evaluateVisibleWhen, getVisibleWhen } from '../dynamic-form-schema';
43
44
  import { useInstalledAddons } from '../installed-addons-context';
44
45
  import { allocatePayment, validateAllocation } from '../primitives/allocation';
45
46
  import { useDocumentContributions } from '../primitives/use-contributions';
46
- export function DocumentEditor({ model, endpoint, forms, type, record, initialSource, onSaved, onCancel, searchProducts, productModel, defaultTaxRate, currency, today, fullscreen = false, }) {
47
+ export function DocumentEditor({ model, endpoint, forms, type, record, initialSource, onSaved, onCancel, searchProducts, productModel, productLabelField = 'name', defaultTaxRate, currency, today, fullscreen = false, }) {
47
48
  const { t, i18n } = useTranslation();
48
49
  const lang = i18n?.language;
49
50
  const api = useApi();
@@ -64,7 +65,8 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
64
65
  const [linesFromSourceDoc, setLinesFromSourceDoc] = useState(false);
65
66
  const [extFields, setExtFields] = useState([]);
66
67
  const [party, setParty] = useState(null);
67
- const [partyLabels, setPartyLabels] = useState({});
68
+ const [partyFieldLists, setPartyFieldLists] = useState([]);
69
+ const [catalogMeta, setCatalogMeta] = useState(null);
68
70
  // Etiquetas de los selectores que el editor llena por código (contraparte y
69
71
  // documento origen de «Cargar desde…»): sin ellas el selector cerrado pinta el UUID.
70
72
  const [seeds, setSeeds] = useState({});
@@ -156,28 +158,86 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
156
158
  cancelled = true;
157
159
  };
158
160
  }, [api, type.party, partyId]);
159
- // Etiquetas de la tarjeta (RFC, régimen…): las del formulario del modelo de
160
- // la contraparte, incluidas sus extensiones; sin ellas se ve la columna cruda.
161
+ // Etiquetas de la tarjeta (RFC, régimen…) y texto de sus catálogos: la
162
+ // metadata del modelo de la contraparte (formulario, con extensiones, y
163
+ // tabla); sin ellas se veía la columna cruda (`tax_id`).
161
164
  const partyModel = type.party?.model;
162
165
  useEffect(() => {
163
166
  if (!partyModel)
164
167
  return;
165
168
  let cancelled = false;
166
- api.get(`/metadata/modal/${partyModel}`)
167
- .then((res) => {
168
- const fields = res?.data?.data?.fields ?? res?.data?.fields ?? [];
169
- const out = {};
170
- for (const f of fields)
171
- if (typeof f?.key === 'string' && typeof f?.label === 'string' && f.label)
172
- out[f.key] = f.label;
169
+ void loadModelFieldLists(api, partyModel).then((lists) => {
173
170
  if (!cancelled)
174
- setPartyLabels(out);
175
- })
176
- .catch(() => { });
171
+ setPartyFieldLists(lists);
172
+ });
177
173
  return () => {
178
174
  cancelled = true;
179
175
  };
180
176
  }, [api, partyModel]);
177
+ // Modelo de catálogo del renglón: alta/edición desde la celda y etiquetas
178
+ // de sus catálogos (unidad «unit» → «Pieza»).
179
+ const catalogModel = productModel ?? 'products.Product';
180
+ // Perezoso: solo cuando ya hay un renglón con producto (no compite con la
181
+ // carga inicial del editor).
182
+ const hasCatalogLine = lines.some((l) => l.kind === 'item' && !!l.product_id);
183
+ const wantsCatalogMeta = !!lineCfg && !isAllocation && hasCatalogLine;
184
+ useEffect(() => {
185
+ if (!wantsCatalogMeta)
186
+ return;
187
+ let cancelled = false;
188
+ void loadModelFieldLists(api, catalogModel).then((lists) => {
189
+ if (!cancelled)
190
+ setCatalogMeta(fieldDisplayMeta(lists, tl));
191
+ });
192
+ return () => {
193
+ cancelled = true;
194
+ };
195
+ }, [api, catalogModel, tl, wantsCatalogMeta]);
196
+ /** Lee el producto guardado con la misma proyección del buscador (catalogRecordToProduct). */
197
+ const loadCatalogProduct = useCallback(async (id, saved) => {
198
+ try {
199
+ const res = await api.get(`/data/${catalogModel}`, { params: { f_id: `eq:${id}`, per_page: 1 } });
200
+ const rows = res?.data?.data;
201
+ const row = Array.isArray(rows) ? rows[0] : null;
202
+ if (row)
203
+ return catalogRecordToProduct({ ...(saved ?? {}), ...row }, taxRate);
204
+ }
205
+ catch {
206
+ // Sin lectura, lo que devolvió el guardado.
207
+ }
208
+ return saved && saved.id != null ? catalogRecordToProduct(saved, taxRate) : null;
209
+ }, [api, catalogModel, taxRate]);
210
+ const createProduct = useCallback((query) => new Promise((resolve) => {
211
+ requestRecordCreate({
212
+ model: catalogModel,
213
+ defaults: withSearchPrefill(query, productLabelField),
214
+ onCreated: (rec) => {
215
+ if (rec?.id == null)
216
+ return resolve(null);
217
+ void loadCatalogProduct(String(rec.id), rec).then(resolve);
218
+ },
219
+ });
220
+ }), [catalogModel, productLabelField, loadCatalogProduct]);
221
+ const editProduct = useCallback((line) => new Promise((resolve) => {
222
+ const id = line.catalog?.product_ref ?? line.product_id;
223
+ if (!id)
224
+ return resolve(null);
225
+ requestRecordEdit({
226
+ model: catalogModel,
227
+ recordId: id,
228
+ onSaved: (rec) => void loadCatalogProduct(id, rec && typeof rec === 'object' ? { id, ...rec } : undefined).then(resolve),
229
+ });
230
+ }), [catalogModel, loadCatalogProduct]);
231
+ /** Unidad visible: la opción del catálogo; sin opciones declaradas, el valor tal cual. */
232
+ const unitLabel = useCallback((u) => {
233
+ if (!catalogMeta)
234
+ return undefined;
235
+ const opts = catalogMeta.unit_of_measure?.options ?? catalogMeta.unit?.options;
236
+ if (!opts)
237
+ return u;
238
+ const o = opts.find((x) => String(x.value) === u);
239
+ return typeof o?.label === 'string' && o.label && o.label !== u ? o.label : undefined;
240
+ }, [catalogMeta]);
181
241
  // Cobro: documentos abiertos de la contraparte.
182
242
  const openCfg = lineCfg?.open_documents;
183
243
  const allocPartyId = openCfg ? header[openCfg.party_field] ?? partyId : undefined;
@@ -483,10 +543,10 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
483
543
  };
484
544
  const fieldRecord = useMemo(() => seedRecord(seeds, record), [seeds, record]);
485
545
  const fieldCell = (field, fullWidth = false, className) => visible(field) ? (_jsxs(FieldCell, { fullWidth: fullWidth, className: className, children: [_jsx(FieldLabel, { htmlFor: field.key, required: field.required, tone: "sentence", children: tl(field.label) }), renderField(withFriendlyOptions(gatedOptions(field, header)), header[field.key], (v) => updateField(field.key, v), header, fieldRecord, fieldErrors), fieldErrors[field.key] && _jsx("p", { className: "mt-1 text-xs text-destructive", children: fieldErrors[field.key] })] }, field.key)) : null;
486
- const summaryRows = partySummaryRows(party, type.party?.summary, {
487
- ...Object.fromEntries(Object.entries(partyLabels).map(([k, v]) => [k, tl(v)])),
488
- ...Object.fromEntries(allFields.map((f) => [f.key, tl(f.label)])),
489
- });
546
+ // Etiquetas y catálogos: la metadata de la contraparte y, para las
547
+ // extensiones compartidas (`fiscal_data.uso_cfdi`), los campos del propio documento.
548
+ const summaryMeta = useMemo(() => fieldDisplayMeta([...partyFieldLists, allFields], tl), [partyFieldLists, allFields, tl]);
549
+ const summaryRows = partySummaryRows(party, type.party?.summary, {}, 6, summaryMeta);
490
550
  const advancedSummary = groups.advanced
491
551
  .filter(visible)
492
552
  .map((f) => {
@@ -546,7 +606,7 @@ export function DocumentEditor({ model, endpoint, forms, type, record, initialSo
546
606
  const linesSection = lineCfg && (_jsxs(EditorSection, { slot: isAllocation ? 'editor-allocation' : 'editor-lines', title: linesTitle, hint: isAllocation && openBalance > 0 && amountKey ? (_jsx("button", { type: "button", className: "underline-offset-2 hover:underline", onClick: () => updateField(amountKey, openBalance), children: t('documentEditor.pay_all', { defaultValue: 'Cobrar todo ({{amount}})', amount: fmt.money(openBalance) }) })) : undefined, children: [isAllocation ? (allocPartyId ? (_jsx(PaymentAllocator, { documents: openDocs, result: allocation, value: alloc, onChange: setAlloc, currency: currency, loading: docsLoading, today: today })) : (_jsx("p", { className: "text-sm text-muted-foreground", children: t('documentEditor.pick_party_first', { defaultValue: 'Elige el cliente para ver sus documentos con saldo.' }) }))) : (_jsx(DocumentLinesGrid, { value: lines, onChange: (next) => {
547
607
  setLines(next);
548
608
  setServerIssues([]);
549
- }, columns: lineCfg.columns ?? ['discount', 'tax'], priceSource: lineCfg.price_source ?? (kind === 'purchase' ? 'cost' : 'sale'), discountMode: lineCfg.discount_mode, mode: linesFromSourceDoc ? 'from_source' : 'free', policy: kind === 'credit' ? { allowZeroQuantity: linesFromSourceDoc } : undefined, search: search, currency: currency, showTotals: false })), !fullscreen && totalsPanel] }));
609
+ }, columns: lineCfg.columns ?? ['discount', 'tax'], priceSource: lineCfg.price_source ?? (kind === 'purchase' ? 'cost' : 'sale'), discountMode: lineCfg.discount_mode, mode: linesFromSourceDoc ? 'from_source' : 'free', policy: kind === 'credit' ? { allowZeroQuantity: linesFromSourceDoc } : undefined, search: search, currency: currency, showTotals: false, onCreateProduct: kind === 'credit' ? undefined : createProduct, onEditProduct: editProduct, unitLabel: unitLabel })), !fullscreen && totalsPanel] }));
550
610
  const advanced = (groups.advanced.length > 0 || headerContribs.length > 0) && (_jsxs(CollapsibleSection, { slot: "advanced-options", title: t('documentEditor.advanced', { defaultValue: 'Opciones fiscales' }), summary: advancedSummary || t('documentEditor.advanced_defaults', { defaultValue: 'Valores sugeridos' }), open: advancedOpen, onOpenChange: setAdvancedOpen, children: [groups.advanced.length > 0 && _jsx(FieldGrid, { children: groups.advanced.map((f) => fieldCell(f)) }), headerContribs.map(({ id, component: C }) => (_jsx(C, { ...contribProps }, id)))] }));
551
611
  const contributedSections = [...bodyContribs, ...sideContribs].map(({ id, component: C }) => (_jsx("section", { "data-contribution": id, children: _jsx(C, { ...contribProps }) }, id)));
552
612
  const notes = groups.notes.length > 0 && _jsx(FieldGrid, { children: groups.notes.map((f) => fieldCell(f, true)) });
@@ -580,3 +640,38 @@ function SourcePicker({ source, value, seed, header, label, onPick, }) {
580
640
  }), [source, label]);
581
641
  return (_jsx("div", { className: "min-w-60 flex-1", "data-source": source.key, children: renderField(field, value, (v) => onPick(v == null || v === '' ? '' : String(v)), header, seed ? { id: seed.value, label: seed.label } : undefined) }));
582
642
  }
643
+ /**
644
+ * Campos y columnas de un modelo para etiquetar sus valores: formulario
645
+ * (`/metadata/modal`, con extensiones) y tabla (`/metadata/table`). Si la
646
+ * clave con módulo (`customers.Customer`) no resuelve en el host, prueba la
647
+ * corta (`Customer`), como el puente de alta del host. Nunca lanza.
648
+ */
649
+ async function loadModelFieldLists(api, model) {
650
+ const short = model.includes('.') ? model.slice(model.lastIndexOf('.') + 1) : undefined;
651
+ // `undefined` = la petición falló (el host no conoce esa clave); `[]` = respondió sin campos.
652
+ const read = async (url, key) => {
653
+ try {
654
+ const res = await api.get(url);
655
+ const list = res?.data?.data?.[key] ?? res?.data?.[key];
656
+ return Array.isArray(list) ? list : [];
657
+ }
658
+ catch {
659
+ return undefined;
660
+ }
661
+ };
662
+ // En serie y solo lo necesario (una lectura en el caso normal): el
663
+ // formulario; la clave corta solo si la larga falló; la tabla solo si
664
+ // ningún formulario respondió con campos.
665
+ const candidates = short ? [model, short] : [model];
666
+ for (const kind of ['modal', 'table']) {
667
+ for (const m of candidates) {
668
+ const list = await read(`/metadata/${kind}/${m}`, kind === 'modal' ? 'fields' : 'columns');
669
+ if (list === undefined)
670
+ continue;
671
+ if (list.length > 0)
672
+ return [list];
673
+ break;
674
+ }
675
+ }
676
+ return [];
677
+ }
@@ -1,4 +1,4 @@
1
- import { type LineItem } from './line-items';
1
+ import { type CatalogLineField, type LineItem } from './line-items';
2
2
  import { type ProductResult, type ProductVariant } from './product-search';
3
3
  export type PriceSource = 'sale' | 'cost' | 'origin';
4
4
  export type DocumentLinesMode = 'free' | 'from_source';
@@ -10,6 +10,26 @@ export declare function applyProductToLine(line: LineItem, product: ProductResul
10
10
  warehouseId?: string;
11
11
  quantity?: number;
12
12
  }): LineItem;
13
+ /**
14
+ * Campos que el usuario cambió a mano respecto de lo que puso el catálogo
15
+ * («dirty» por campo). Sin foto (renglón libre, o cargado de un documento
16
+ * origen con sus propios precios) todo cuenta como capturado: nada se pisa.
17
+ */
18
+ export declare function lineOverrides(line: LineItem): Set<CatalogLineField>;
19
+ /**
20
+ * El producto del renglón cambió en el catálogo (se editó desde la celda):
21
+ * actualiza SOLO los campos que siguen igual a lo que el catálogo había puesto;
22
+ * lo que el usuario sobrescribió se respeta y el valor nuevo queda en
23
+ * `catalog_pending` para ofrecer «aplicar». Nunca toca la cantidad, el tope de
24
+ * lo pendiente ni el vínculo con el documento origen. Siempre refresca lo que
25
+ * no se captura en el renglón (precio de catálogo, costo, extensiones, existencia).
26
+ */
27
+ export declare function refreshLineFromProduct(line: LineItem, product: ProductResult, opts?: {
28
+ priceSource?: PriceSource;
29
+ warehouseId?: string;
30
+ }): LineItem;
31
+ /** «Aplicar» el aviso del catálogo: los valores pendientes entran al renglón. */
32
+ export declare function applyCatalogPending(line: LineItem): LineItem;
13
33
  /**
14
34
  * Agrega el producto como renglón. Por defecto, un segundo clic del mismo
15
35
  * producto incrementa la cantidad (como el catálogo de Compras) y respeta `max_quantity`.
@@ -1 +1 @@
1
- {"version":3,"file":"document-lines.d.ts","sourceRoot":"","sources":["../../src/business/document-lines.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAA;AACtD,OAAO,EAAkB,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAE1F,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;AACpD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,aAAa,CAAA;AAEtD,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,MAAM,EAAE,WAAW,GACpB,MAAM,CAKR;AAED,uGAAuG;AACvG,wBAAgB,kBAAkB,CAC9B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,cAAc,EACxB,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClF,QAAQ,CAuBV;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC1B,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,cAAc,EACxB,IAAI,GAAE;IACF,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CACxB,GACP,QAAQ,EAAE,CAeZ;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEhE,2GAA2G;AAC3G,wBAAgB,kBAAkB,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,iBAAiB,CAAA;CAAO,GACxF,eAAe,CAKjB"}
1
+ {"version":3,"file":"document-lines.d.ts","sourceRoot":"","sources":["../../src/business/document-lines.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,gBAAgB,EAA4B,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5H,OAAO,EAAkB,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAE1F,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;AACpD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,aAAa,CAAA;AAEtD,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,MAAM,EAAE,WAAW,GACpB,MAAM,CAKR;AAED,uGAAuG;AACvG,wBAAgB,kBAAkB,CAC9B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,cAAc,EACxB,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClF,QAAQ,CAsBV;AAwBD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAInE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAClC,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,EACtB,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/D,QAAQ,CAmBV;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAI5D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC1B,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,cAAc,EACxB,IAAI,GAAE;IACF,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CACxB,GACP,QAAQ,EAAE,CAeZ;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEhE,2GAA2G;AAC3G,wBAAgB,kBAAkB,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,iBAAiB,CAAA;CAAO,GACxF,eAAe,CAKjB"}
@@ -1,7 +1,7 @@
1
1
  // Helpers del editor único de renglones (DocumentLinesGrid / LineItemsEditor).
2
2
  // Puros: el componente solo pinta. `serializeLineItems` sigue siendo la puerta al backend.
3
3
  import { toAmount } from './format';
4
- import { makeLine } from './line-items';
4
+ import { CATALOG_LINE_FIELDS, makeLine } from './line-items';
5
5
  import { availableStock } from './product-search';
6
6
  /** Precio que se escribe en el renglón según el documento. */
7
7
  export function priceFromProduct(product, variant, source) {
@@ -20,22 +20,84 @@ export function applyProductToLine(line, product, variant, opts = {}) {
20
20
  const catalog = source === 'cost' ? (cost ?? list) : list;
21
21
  // Nunca cantidad 0: un renglón vacío (o con la celda borrada) entra con 1.
22
22
  const qty = opts.quantity ?? toAmount(line.quantity);
23
+ const values = catalogLineValues(line, product, variant, source);
24
+ const { catalog_pending: _pending, ...rest } = line;
23
25
  return {
24
- ...line,
26
+ ...rest,
25
27
  kind: 'item',
26
28
  product_id: variant?.id ?? product.id,
27
- sku: variant?.sku ?? product.sku,
28
- description: variant ? `${product.name} · ${variant.label}` : product.name,
29
+ ...values,
29
30
  quantity: qty !== 0 ? qty : 1,
30
- unit_price: priceFromProduct(product, variant, source),
31
31
  catalog_price: catalog,
32
32
  cost,
33
- tax_rate: product.tax_rate ?? line.tax_rate ?? 0,
34
- unit: product.unit ?? line.unit,
35
33
  extensions: product.extensions ? { ...(line.extensions ?? {}), ...product.extensions } : line.extensions,
36
34
  available: availableStock(src, opts.warehouseId) ?? availableStock(product, opts.warehouseId),
35
+ catalog: { ...values, product_ref: product.id, variant },
36
+ };
37
+ }
38
+ /**
39
+ * Lo que el producto escribe en los campos editables del renglón. Es EL mapeo
40
+ * producto → renglón: lo usan elegir, crear y editar desde la celda.
41
+ */
42
+ function catalogLineValues(line, product, variant, source) {
43
+ return {
44
+ description: variant ? `${product.name} · ${variant.label}` : product.name,
45
+ sku: variant?.sku ?? product.sku,
46
+ unit_price: priceFromProduct(product, variant, source),
47
+ tax_rate: product.tax_rate ?? line.tax_rate ?? 0,
48
+ unit: product.unit ?? line.unit,
37
49
  };
38
50
  }
51
+ const sameValue = (a, b) => typeof a === 'number' || typeof b === 'number' ? toAmount(a) === toAmount(b) : (a ?? '') === (b ?? '');
52
+ /**
53
+ * Campos que el usuario cambió a mano respecto de lo que puso el catálogo
54
+ * («dirty» por campo). Sin foto (renglón libre, o cargado de un documento
55
+ * origen con sus propios precios) todo cuenta como capturado: nada se pisa.
56
+ */
57
+ export function lineOverrides(line) {
58
+ const snap = line.catalog;
59
+ if (!snap)
60
+ return new Set(CATALOG_LINE_FIELDS);
61
+ return new Set(CATALOG_LINE_FIELDS.filter((f) => !sameValue(line[f], snap[f])));
62
+ }
63
+ /**
64
+ * El producto del renglón cambió en el catálogo (se editó desde la celda):
65
+ * actualiza SOLO los campos que siguen igual a lo que el catálogo había puesto;
66
+ * lo que el usuario sobrescribió se respeta y el valor nuevo queda en
67
+ * `catalog_pending` para ofrecer «aplicar». Nunca toca la cantidad, el tope de
68
+ * lo pendiente ni el vínculo con el documento origen. Siempre refresca lo que
69
+ * no se captura en el renglón (precio de catálogo, costo, extensiones, existencia).
70
+ */
71
+ export function refreshLineFromProduct(line, product, opts = {}) {
72
+ const source = opts.priceSource ?? 'sale';
73
+ const variant = line.catalog?.variant;
74
+ const fresh = applyProductToLine(line, product, variant, { ...opts, quantity: toAmount(line.quantity) });
75
+ const overrides = lineOverrides(line);
76
+ const next = { ...fresh, product_id: line.product_id ?? fresh.product_id, quantity: line.quantity, max_quantity: line.max_quantity, source_line_id: line.source_line_id };
77
+ const pending = {};
78
+ const values = catalogLineValues(line, product, variant, source);
79
+ for (const f of CATALOG_LINE_FIELDS) {
80
+ if (!overrides.has(f))
81
+ continue;
82
+ next[f] = line[f];
83
+ if (!sameValue(values[f], line[f]))
84
+ pending[f] = values[f];
85
+ }
86
+ // La foto avanza a los valores nuevos del catálogo: el override sigue siéndolo.
87
+ next.catalog = { ...values, product_ref: line.catalog?.product_ref ?? product.id, variant };
88
+ if (Object.keys(pending).length > 0)
89
+ next.catalog_pending = pending;
90
+ else
91
+ delete next.catalog_pending;
92
+ return next;
93
+ }
94
+ /** «Aplicar» el aviso del catálogo: los valores pendientes entran al renglón. */
95
+ export function applyCatalogPending(line) {
96
+ if (!line.catalog_pending)
97
+ return line;
98
+ const { catalog_pending: pending, ...rest } = line;
99
+ return { ...rest, ...pending };
100
+ }
39
101
  /**
40
102
  * Agrega el producto como renglón. Por defecto, un segundo clic del mismo
41
103
  * producto incrementa la cantidad (como el catálogo de Compras) y respeta `max_quantity`.
@@ -45,10 +45,30 @@ export interface DocumentLinesGridProps {
45
45
  * ya muestra sus propios totales (DocumentEditor) lo apaga.
46
46
  */
47
47
  showTotals?: boolean;
48
+ /**
49
+ * Alta del producto desde la celda («+» y «Crear producto «texto»»). Resuelve
50
+ * con el producto guardado (o nada si se canceló): el renglón se llena con
51
+ * el mismo mapeo que al elegir uno existente.
52
+ */
53
+ onCreateProduct?: (query: string) => Promise<ProductResult | null | undefined>;
54
+ /**
55
+ * Edición del producto del renglón (lápiz en la celda). Resuelve con el
56
+ * producto ya guardado: el renglón se actualiza salvo los campos que el
57
+ * usuario sobrescribió (ver `refreshLineFromProduct`).
58
+ */
59
+ onEditProduct?: (line: LineItem) => Promise<ProductResult | null | undefined>;
60
+ /** Nombre del modelo de catálogo para «Crear …» / «Editar …» (default «producto»). */
61
+ productLabel?: string;
62
+ /**
63
+ * Etiqueta visible de la unidad (`unit` → «pza»). Si devuelve vacío, la
64
+ * unidad no se muestra bajo el SKU (nunca la clave cruda). Sin esta prop se
65
+ * muestra el valor tal cual.
66
+ */
67
+ unitLabel?: (unit: string) => string | undefined;
48
68
  }
49
69
  /** @deprecated Usa `DocumentLinesGridProps`. Es el mismo contrato. */
50
70
  export type LineItemsEditorProps = DocumentLinesGridProps;
51
- export declare function DocumentLinesGrid({ value, onChange, columns, policy, serverErrors, onValidate, onRequestProduct, search, priceSource, mode, discountMode, quantityStepper, mergeSameProduct, warehouseId, allowSections, readOnly, editPermission, currency, showTotals, }: DocumentLinesGridProps): import("react").JSX.Element;
71
+ export declare function DocumentLinesGrid({ value, onChange, columns, policy, serverErrors, onValidate, onRequestProduct, search, priceSource, mode, discountMode, quantityStepper, mergeSameProduct, warehouseId, allowSections, readOnly, editPermission, currency, showTotals, onCreateProduct, onEditProduct, productLabel, unitLabel, }: DocumentLinesGridProps): import("react").JSX.Element;
52
72
  /** Mismo componente. El nombre anterior sigue exportado. */
53
73
  export declare const LineItemsEditor: typeof DocumentLinesGrid;
54
74
  //# sourceMappingURL=line-items-editor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"line-items-editor.d.ts","sourceRoot":"","sources":["../../src/business/line-items-editor.tsx"],"names":[],"mappings":"AASA,OAAO,EAIH,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAKH,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAC3B,MAAM,cAAc,CAAA;AAErB,OAAO,EACH,KAAK,YAAY,EACjB,KAAK,aAAa,EAErB,MAAM,kBAAkB,CAAA;AAEzB,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;AAExF,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,gEAAgE;IAChE,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAA;IACrC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;IAC3B,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,uFAAuF;IACvF,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAA;IAC7C,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;IAC3G,4FAA4F;IAC5F,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,mFAAmF;IACnF,IAAI,CAAC,EAAE,iBAAiB,CAAA;IACxB,oFAAoF;IACpF,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAA;IAC5C,6DAA6D;IAC7D,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,sEAAsE;AACtE,MAAM,MAAM,oBAAoB,GAAG,sBAAsB,CAAA;AAIzD,wBAAgB,iBAAiB,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,OAAsB,EACtB,MAAM,EACN,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,MAAM,EACN,WAAoB,EACpB,IAAa,EACb,YAAwB,EACxB,eAAe,EACf,gBAAuB,EACvB,WAAW,EACX,aAAoB,EACpB,QAAgB,EAChB,cAAc,EACd,QAAQ,EACR,UAAiB,GACpB,EAAE,sBAAsB,+BAwbxB;AAED,4DAA4D;AAC5D,eAAO,MAAM,eAAe,0BAAoB,CAAA"}
1
+ {"version":3,"file":"line-items-editor.d.ts","sourceRoot":"","sources":["../../src/business/line-items-editor.tsx"],"names":[],"mappings":"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"}