@open-mercato/core 0.6.1-develop.3291.1.6fad645fd0 → 0.6.1

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 (122) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +14 -0
  3. package/dist/modules/auth/backend/roles/[id]/edit/page.js +2 -1
  4. package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
  5. package/dist/modules/auth/backend/users/[id]/edit/page.js +2 -5
  6. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  7. package/dist/modules/catalog/ai-agents.js +47 -5
  8. package/dist/modules/catalog/ai-agents.js.map +2 -2
  9. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +2 -5
  10. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
  11. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +4 -3
  12. package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
  13. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +2 -9
  14. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  15. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +2 -9
  16. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
  17. package/dist/modules/customers/ai-agents.js +174 -1
  18. package/dist/modules/customers/ai-agents.js.map +2 -2
  19. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +196 -0
  20. package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +7 -0
  21. package/dist/modules/customers/ai-tools.js +3 -1
  22. package/dist/modules/customers/ai-tools.js.map +2 -2
  23. package/dist/modules/customers/backend/customers/companies/page.js +11 -1
  24. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  25. package/dist/modules/customers/backend/customers/deals/page.js +11 -1
  26. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  27. package/dist/modules/customers/backend/customers/people/page.js +11 -1
  28. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  29. package/dist/modules/customers/commands/companies.js +37 -15
  30. package/dist/modules/customers/commands/companies.js.map +2 -2
  31. package/dist/modules/customers/components/detail/AiActionChips.js +2 -2
  32. package/dist/modules/customers/components/detail/AiActionChips.js.map +2 -2
  33. package/dist/modules/customers/components/detail/ChangelogTab.js +3 -9
  34. package/dist/modules/customers/components/detail/ChangelogTab.js.map +2 -2
  35. package/dist/modules/customers/components/detail/changelogValues.js +35 -0
  36. package/dist/modules/customers/components/detail/changelogValues.js.map +7 -0
  37. package/dist/modules/customers/components/detail/customFieldUtils.js +1 -1
  38. package/dist/modules/customers/components/detail/customFieldUtils.js.map +1 -1
  39. package/dist/modules/customers/components/formConfig.js +3 -2
  40. package/dist/modules/customers/components/formConfig.js.map +2 -2
  41. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js +4 -9
  42. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js.map +2 -2
  43. package/dist/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.client.js +302 -0
  44. package/dist/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.client.js.map +7 -0
  45. package/dist/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.js +17 -0
  46. package/dist/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.js.map +7 -0
  47. package/dist/modules/customers/widgets/injection/ai-deal-detail-trigger/widget.client.js +2 -2
  48. package/dist/modules/customers/widgets/injection/ai-deal-detail-trigger/widget.client.js.map +2 -2
  49. package/dist/modules/customers/widgets/injection-table.js +2 -2
  50. package/dist/modules/customers/widgets/injection-table.js.map +2 -2
  51. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +2 -5
  52. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
  53. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +2 -5
  54. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
  55. package/dist/modules/resources/backend/resources/resources/[id]/page.js +2 -5
  56. package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
  57. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +2 -25
  58. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
  59. package/dist/modules/sales/components/channels/ChannelOfferForm.js +2 -43
  60. package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
  61. package/dist/modules/sales/components/documents/LineItemDialog.js +162 -42
  62. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  63. package/dist/modules/sales/components/documents/customFieldHelpers.js +4 -31
  64. package/dist/modules/sales/components/documents/customFieldHelpers.js.map +2 -2
  65. package/package.json +16 -8
  66. package/src/modules/auth/backend/roles/[id]/edit/page.tsx +2 -1
  67. package/src/modules/auth/backend/users/[id]/edit/page.tsx +2 -5
  68. package/src/modules/business_rules/migrations/.snapshot-open-mercato.json +746 -394
  69. package/src/modules/catalog/ai-agents.ts +62 -4
  70. package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +2 -5
  71. package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +4 -3
  72. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +2 -12
  73. package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +2 -10
  74. package/src/modules/catalog/migrations/.snapshot-open-mercato.json +2519 -1307
  75. package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +828 -834
  76. package/src/modules/customers/AGENTS.md +6 -1
  77. package/src/modules/customers/ai-agents.ts +213 -6
  78. package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +286 -0
  79. package/src/modules/customers/ai-tools.ts +2 -0
  80. package/src/modules/customers/backend/customers/companies/page.tsx +10 -0
  81. package/src/modules/customers/backend/customers/deals/page.tsx +10 -0
  82. package/src/modules/customers/backend/customers/people/page.tsx +10 -0
  83. package/src/modules/customers/commands/companies.ts +38 -14
  84. package/src/modules/customers/components/detail/AiActionChips.tsx +2 -2
  85. package/src/modules/customers/components/detail/ChangelogTab.tsx +3 -10
  86. package/src/modules/customers/components/detail/changelogValues.ts +42 -0
  87. package/src/modules/customers/components/detail/customFieldUtils.ts +1 -1
  88. package/src/modules/customers/components/formConfig.tsx +3 -2
  89. package/src/modules/customers/i18n/de.json +7 -0
  90. package/src/modules/customers/i18n/en.json +7 -0
  91. package/src/modules/customers/i18n/es.json +7 -0
  92. package/src/modules/customers/i18n/pl.json +7 -0
  93. package/src/modules/customers/migrations/.snapshot-open-mercato.json +2313 -2336
  94. package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.tsx +4 -6
  95. package/src/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.client.tsx +358 -0
  96. package/src/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.ts +34 -0
  97. package/src/modules/customers/widgets/injection/ai-deal-detail-trigger/widget.client.tsx +2 -2
  98. package/src/modules/customers/widgets/injection-table.ts +12 -9
  99. package/src/modules/data_sync/migrations/.snapshot-open-mercato.json +554 -210
  100. package/src/modules/dictionaries/migrations/.snapshot-open-mercato.json +146 -146
  101. package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +2 -5
  102. package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +2 -5
  103. package/src/modules/directory/migrations/.snapshot-open-mercato.json +273 -140
  104. package/src/modules/feature_toggles/migrations/.snapshot-open-mercato.json +242 -137
  105. package/src/modules/integrations/migrations/.snapshot-open-mercato.json +498 -195
  106. package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +158 -157
  107. package/src/modules/perspectives/migrations/.snapshot-open-mercato.json +274 -129
  108. package/src/modules/planner/migrations/.snapshot-open-mercato.json +327 -157
  109. package/src/modules/progress/AGENTS.md +72 -0
  110. package/src/modules/resources/backend/resources/resources/[id]/page.tsx +2 -5
  111. package/src/modules/resources/migrations/.snapshot-open-mercato.json +920 -470
  112. package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +2 -27
  113. package/src/modules/sales/components/channels/ChannelOfferForm.tsx +2 -49
  114. package/src/modules/sales/components/documents/LineItemDialog.tsx +214 -78
  115. package/src/modules/sales/components/documents/customFieldHelpers.ts +4 -43
  116. package/src/modules/sales/i18n/de.json +3 -0
  117. package/src/modules/sales/i18n/en.json +3 -0
  118. package/src/modules/sales/i18n/es.json +3 -0
  119. package/src/modules/sales/i18n/pl.json +3 -0
  120. package/src/modules/sales/migrations/.snapshot-open-mercato.json +4740 -4778
  121. package/src/modules/shipping_carriers/migrations/.snapshot-open-mercato.json +340 -81
  122. package/src/modules/staff/migrations/.snapshot-open-mercato.json +1439 -729
@@ -19,6 +19,11 @@ import {
19
19
  } from "@open-mercato/ui/primitives/dialog";
20
20
  import { Button } from "@open-mercato/ui/primitives/button";
21
21
  import { Input } from "@open-mercato/ui/primitives/input";
22
+ import {
23
+ Alert,
24
+ AlertDescription,
25
+ AlertTitle
26
+ } from "@open-mercato/ui/primitives/alert";
22
27
  import {
23
28
  Select,
24
29
  SelectContent,
@@ -133,6 +138,36 @@ function normalizeUnitPriceInputValue(value) {
133
138
  if (!Number.isFinite(rounded)) return "";
134
139
  return rounded.toString();
135
140
  }
141
+ function mapProductOption(item) {
142
+ const id = typeof item.id === "string" ? item.id : null;
143
+ if (!id) return null;
144
+ const productItem = item;
145
+ const title = typeof item.title === "string" ? item.title : typeof productItem.name === "string" ? productItem.name : id;
146
+ const sku = typeof productItem.sku === "string" ? productItem.sku : null;
147
+ const thumbnail = typeof productItem.default_media_url === "string" ? productItem.default_media_url : typeof productItem.defaultMediaUrl === "string" ? productItem.defaultMediaUrl : null;
148
+ const pricing = typeof productItem.pricing === "object" && productItem.pricing ? productItem.pricing : null;
149
+ const metadata = typeof productItem.metadata === "object" && productItem.metadata ? productItem.metadata : null;
150
+ const pricingMeta = pricing;
151
+ const metaMeta = metadata;
152
+ const pricingTaxRateId = typeof pricingMeta?.tax_rate_id === "string" && pricingMeta.tax_rate_id.trim().length ? pricingMeta.tax_rate_id.trim() : typeof pricingMeta?.taxRateId === "string" && pricingMeta.taxRateId.trim().length ? pricingMeta.taxRateId.trim() : null;
153
+ const metaTaxRateId = typeof metaMeta?.taxRateId === "string" && metaMeta.taxRateId.trim().length ? metaMeta.taxRateId.trim() : typeof metaMeta?.tax_rate_id === "string" && metaMeta.tax_rate_id.trim().length ? metaMeta.tax_rate_id.trim() : null;
154
+ const taxRateValue = normalizeNumber(
155
+ pricingMeta?.tax_rate ?? pricingMeta?.taxRate ?? productItem.tax_rate ?? productItem.taxRate,
156
+ Number.NaN
157
+ );
158
+ const uomFields = getUomProductFields(item);
159
+ return {
160
+ id,
161
+ title,
162
+ sku,
163
+ thumbnailUrl: thumbnail,
164
+ taxRateId: pricingTaxRateId ?? metaTaxRateId ?? null,
165
+ taxRate: Number.isFinite(taxRateValue) ? taxRateValue : null,
166
+ defaultUnit: uomFields.defaultUnit,
167
+ defaultSalesUnit: uomFields.defaultSalesUnit,
168
+ defaultSalesUnitQuantity: Number.isFinite(uomFields.defaultSalesUnitQuantity) ? uomFields.defaultSalesUnitQuantity : null
169
+ };
170
+ }
136
171
  function LineItemDialog({
137
172
  open,
138
173
  kind,
@@ -163,6 +198,7 @@ function LineItemDialog({
163
198
  const [taxRates, setTaxRates] = React.useState([]);
164
199
  const [lineStatuses, setLineStatuses] = React.useState([]);
165
200
  const [unitOptions, setUnitOptions] = React.useState([]);
201
+ const [deletedCatalogReference, setDeletedCatalogReference] = React.useState(false);
166
202
  const [, setLineStatusLoading] = React.useState(false);
167
203
  const productOptionsRef = React.useRef(/* @__PURE__ */ new Map());
168
204
  const variantOptionsRef = React.useRef(/* @__PURE__ */ new Map());
@@ -228,6 +264,7 @@ function LineItemDialog({
228
264
  setVariantOption(null);
229
265
  setPriceOptions([]);
230
266
  setUnitOptions([]);
267
+ setDeletedCatalogReference(false);
231
268
  setEditingId(null);
232
269
  setFormResetKey((prev) => prev + 1);
233
270
  },
@@ -272,6 +309,23 @@ function LineItemDialog({
272
309
  return [];
273
310
  }
274
311
  }, []);
312
+ const loadProductOptionById = React.useCallback(
313
+ async (productId) => {
314
+ if (!productId) return null;
315
+ const response = await apiCall(
316
+ `/api/catalog/products?id=${encodeURIComponent(productId)}&pageSize=1`,
317
+ void 0,
318
+ { fallback: { items: [] } }
319
+ );
320
+ const items = Array.isArray(response.result?.items) ? response.result.items : [];
321
+ const matched = items.find((entry) => entry.id === productId) ?? items[0] ?? null;
322
+ if (!matched) return null;
323
+ const option = mapProductOption(matched);
324
+ if (option) productOptionsRef.current.set(option.id, option);
325
+ return option;
326
+ },
327
+ []
328
+ );
275
329
  const loadProductOptions = React.useCallback(
276
330
  async (query) => {
277
331
  const params = new URLSearchParams({ pageSize: "8" });
@@ -285,51 +339,21 @@ function LineItemDialog({
285
339
  });
286
340
  const items = Array.isArray(response.result?.items) ? response.result?.items ?? [] : [];
287
341
  const mapped = items.map((item) => {
288
- const id = typeof item.id === "string" ? item.id : null;
289
- if (!id) return null;
290
- const productItem = item;
291
- const title = typeof item.title === "string" ? item.title : typeof productItem.name === "string" ? productItem.name : id;
292
- const sku = typeof productItem.sku === "string" ? productItem.sku : null;
293
- const thumbnail = typeof productItem.default_media_url === "string" ? productItem.default_media_url : typeof productItem.defaultMediaUrl === "string" ? productItem.defaultMediaUrl : null;
294
- const pricing = typeof productItem.pricing === "object" && productItem.pricing ? productItem.pricing : null;
295
- const metadata = typeof productItem.metadata === "object" && productItem.metadata ? productItem.metadata : null;
296
- const pricingMeta = pricing;
297
- const metaMeta = metadata;
298
- const pricingTaxRateId = typeof pricingMeta?.tax_rate_id === "string" && pricingMeta.tax_rate_id.trim().length ? pricingMeta.tax_rate_id.trim() : typeof pricingMeta?.taxRateId === "string" && pricingMeta.taxRateId.trim().length ? pricingMeta.taxRateId.trim() : null;
299
- const metaTaxRateId = typeof metaMeta?.taxRateId === "string" && metaMeta.taxRateId.trim().length ? metaMeta.taxRateId.trim() : typeof metaMeta?.tax_rate_id === "string" && metaMeta.tax_rate_id.trim().length ? metaMeta.tax_rate_id.trim() : null;
300
- const taxRateValue = normalizeNumber(
301
- pricingMeta?.tax_rate ?? pricingMeta?.taxRate ?? productItem.tax_rate ?? productItem.taxRate,
302
- Number.NaN
303
- );
304
- const uomFields = getUomProductFields(item);
305
- const defaultUnit = uomFields.defaultUnit;
306
- const defaultSalesUnit = uomFields.defaultSalesUnit;
307
- const defaultSalesUnitQuantity = uomFields.defaultSalesUnitQuantity;
342
+ const option = mapProductOption(item);
343
+ if (!option) return null;
308
344
  return {
309
- id,
310
- title,
311
- subtitle: sku ?? void 0,
312
- icon: thumbnail ? /* @__PURE__ */ jsx(
345
+ id: option.id,
346
+ title: option.title,
347
+ subtitle: option.sku ?? void 0,
348
+ icon: option.thumbnailUrl ? /* @__PURE__ */ jsx(
313
349
  "img",
314
350
  {
315
- src: thumbnail,
316
- alt: title,
351
+ src: option.thumbnailUrl,
352
+ alt: option.title,
317
353
  className: "h-8 w-8 rounded object-cover"
318
354
  }
319
- ) : buildPlaceholder(title),
320
- option: {
321
- id,
322
- title,
323
- sku,
324
- thumbnailUrl: thumbnail,
325
- taxRateId: pricingTaxRateId ?? metaTaxRateId ?? null,
326
- taxRate: Number.isFinite(taxRateValue) ? taxRateValue : null,
327
- defaultUnit,
328
- defaultSalesUnit,
329
- defaultSalesUnitQuantity: Number.isFinite(
330
- defaultSalesUnitQuantity
331
- ) ? defaultSalesUnitQuantity : null
332
- }
355
+ ) : buildPlaceholder(option.title),
356
+ option
333
357
  };
334
358
  }).filter(
335
359
  (entry) => Boolean(entry)
@@ -897,6 +921,18 @@ function LineItemDialog({
897
921
  setFormValue?.("catalogSnapshot", null);
898
922
  setFormValue?.("quantityUnit", null);
899
923
  } else {
924
+ if (deletedCatalogReference) {
925
+ setDeletedCatalogReference(false);
926
+ setProductOption(null);
927
+ setVariantOption(null);
928
+ setPriceOptions([]);
929
+ setUnitOptions([]);
930
+ setFormValue?.("productId", null);
931
+ setFormValue?.("variantId", null);
932
+ setFormValue?.("priceId", null);
933
+ setFormValue?.("catalogSnapshot", null);
934
+ setFormValue?.("quantityUnit", null);
935
+ }
900
936
  setFormValue?.("unitPrice", "");
901
937
  setFormValue?.("priceMode", "gross");
902
938
  }
@@ -931,6 +967,27 @@ function LineItemDialog({
931
967
  ] });
932
968
  }
933
969
  },
970
+ ...deletedCatalogReference ? [
971
+ {
972
+ id: "deletedCatalogReference",
973
+ label: t(
974
+ "sales.documents.items.deletedCatalogReference.label",
975
+ "Deleted catalog item"
976
+ ),
977
+ type: "custom",
978
+ layout: "full",
979
+ component: () => /* @__PURE__ */ jsxs(Alert, { status: "information", style: "lighter", children: [
980
+ /* @__PURE__ */ jsx(AlertTitle, { children: t(
981
+ "sales.documents.items.deletedCatalogReference.title",
982
+ "This catalog item was deleted"
983
+ ) }),
984
+ /* @__PURE__ */ jsx(AlertDescription, { children: t(
985
+ "sales.documents.items.deletedCatalogReference.description",
986
+ "The saved line data is kept and the line is shown as a custom line. Switch to Catalog item to replace it with an existing product."
987
+ ) })
988
+ ] })
989
+ }
990
+ ] : [],
934
991
  ...!isCustomLine ? [
935
992
  {
936
993
  id: "productId",
@@ -949,6 +1006,7 @@ function LineItemDialog({
949
1006
  value: typeof value === "string" ? value : null,
950
1007
  onChange: (next) => {
951
1008
  const selectedOption = next ? productOptionsRef.current.get(next) ?? null : null;
1009
+ if (next) setDeletedCatalogReference(false);
952
1010
  setProductOption(selectedOption);
953
1011
  setVariantOption(null);
954
1012
  setPriceOptions([]);
@@ -1622,6 +1680,7 @@ function LineItemDialog({
1622
1680
  loadProductOptions,
1623
1681
  loadVariantOptions,
1624
1682
  fetchLineStatusItems,
1683
+ deletedCatalogReference,
1625
1684
  priceLoading,
1626
1685
  priceOptions,
1627
1686
  productOption,
@@ -1652,6 +1711,8 @@ function LineItemDialog({
1652
1711
  resetForm();
1653
1712
  return;
1654
1713
  }
1714
+ let cancelled = false;
1715
+ setDeletedCatalogReference(false);
1655
1716
  setEditingId(initialLine.id);
1656
1717
  const nextForm = defaultForm(initialLine.currencyCode ?? currencyCode);
1657
1718
  const meta = initialLine.metadata ?? {};
@@ -1767,18 +1828,72 @@ function LineItemDialog({
1767
1828
  variantOptionsRef.current.set(initialLine.productVariantId, option);
1768
1829
  resolvedVariantOption = option;
1769
1830
  }
1770
- if (resolvedProductOption) setProductOption(resolvedProductOption);
1771
- if (resolvedVariantOption) setVariantOption(resolvedVariantOption);
1831
+ if (resolvedProductOption) {
1832
+ setProductOption(resolvedProductOption);
1833
+ } else {
1834
+ setProductOption(null);
1835
+ }
1836
+ if (resolvedVariantOption) {
1837
+ setVariantOption(resolvedVariantOption);
1838
+ } else {
1839
+ setVariantOption(null);
1840
+ }
1772
1841
  const customValues = extractCustomFieldValues(
1773
1842
  initialLine
1774
1843
  );
1775
1844
  const merged = { ...nextForm, ...customValues };
1845
+ const markDeletedCatalogReference = () => {
1846
+ if (cancelled) return;
1847
+ const nextMerged = { ...merged, lineMode: "custom" };
1848
+ setDeletedCatalogReference(true);
1849
+ setProductOption(null);
1850
+ setVariantOption(null);
1851
+ setPriceOptions([]);
1852
+ setUnitOptions([]);
1853
+ setInitialValues(nextMerged);
1854
+ setLineMode("custom");
1855
+ setFormResetKey((prev) => prev + 1);
1856
+ };
1776
1857
  setInitialValues(merged);
1777
1858
  setLineMode(merged.lineMode);
1778
1859
  setFormResetKey((prev) => prev + 1);
1779
1860
  if (initialLine.productId) {
1861
+ void (async () => {
1862
+ try {
1863
+ const currentProduct = await loadProductOptionById(
1864
+ initialLine.productId
1865
+ );
1866
+ if (cancelled) return;
1867
+ if (!currentProduct) {
1868
+ markDeletedCatalogReference();
1869
+ return;
1870
+ }
1871
+ if (merged.lineMode !== "custom") {
1872
+ setProductOption(currentProduct);
1873
+ }
1874
+ if (initialLine.productVariantId) {
1875
+ await loadVariantOptions(
1876
+ initialLine.productId,
1877
+ currentProduct.thumbnailUrl
1878
+ );
1879
+ if (cancelled) return;
1880
+ const currentVariant = variantOptionsRef.current.get(initialLine.productVariantId) ?? null;
1881
+ if (!currentVariant) {
1882
+ markDeletedCatalogReference();
1883
+ return;
1884
+ }
1885
+ if (merged.lineMode !== "custom") {
1886
+ setVariantOption(currentVariant);
1887
+ }
1888
+ }
1889
+ setDeletedCatalogReference(false);
1890
+ } catch (err) {
1891
+ console.error("sales.document.items.verifyCatalogReference", err);
1892
+ }
1893
+ })();
1780
1894
  void loadProductUnits(initialLine.productId, resolvedProductOption).then(
1781
1895
  (options) => {
1896
+ if (cancelled) return;
1782
1897
  const requestedUnit = normalizeUnitCode(nextForm.quantityUnit);
1783
1898
  if (requestedUnit && !options.some((entry) => entry.code === requestedUnit)) {
1784
1899
  setUnitOptions((prev) => [
@@ -1798,12 +1913,17 @@ function LineItemDialog({
1798
1913
  setPriceOptions([]);
1799
1914
  setUnitOptions([]);
1800
1915
  }
1916
+ return () => {
1917
+ cancelled = true;
1918
+ };
1801
1919
  }, [
1802
1920
  currencyCode,
1803
1921
  findTaxRateIdByValue,
1804
1922
  initialLine,
1923
+ loadProductOptionById,
1805
1924
  loadPrices,
1806
1925
  loadProductUnits,
1926
+ loadVariantOptions,
1807
1927
  open,
1808
1928
  resetForm
1809
1929
  ]);