@open-mercato/core 0.6.8-develop.7082.1.f2a845b020 → 0.6.8-develop.7090.1.4dbca7b350

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 (62) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/customers/components/DealsKpiStrip.js +7 -6
  3. package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
  4. package/dist/modules/customers/components/detail/CompanyKpiBar.js +5 -4
  5. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
  6. package/dist/modules/customers/components/detail/DealsSection.js +6 -5
  7. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  8. package/dist/modules/customers/components/detail/utils.js +5 -5
  9. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  10. package/dist/modules/sales/backend/sales/documents/[id]/page.js +10 -8
  11. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  12. package/dist/modules/sales/components/PriceWithCurrency.js +7 -5
  13. package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
  14. package/dist/modules/sales/components/documents/AdjustmentsSection.js +8 -6
  15. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  16. package/dist/modules/sales/components/documents/ItemsSection.js +14 -7
  17. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  18. package/dist/modules/sales/components/documents/LineItemDialog.js +8 -7
  19. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  20. package/dist/modules/sales/components/documents/PaymentsSection.js +9 -8
  21. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  22. package/dist/modules/sales/components/documents/ReturnsSection.js +8 -6
  23. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  24. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +5 -4
  25. package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
  26. package/dist/modules/sales/components/documents/ShipmentDialog.js +5 -4
  27. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  28. package/dist/modules/sales/components/documents/ShipmentsSection.js +8 -6
  29. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  30. package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
  31. package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
  32. package/dist/modules/sales/data/entities.js +8 -2
  33. package/dist/modules/sales/data/entities.js.map +2 -2
  34. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +32 -0
  35. package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +7 -0
  36. package/dist/modules/staff/backend/staff/timesheets/page.js +29 -18
  37. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  38. package/package.json +7 -7
  39. package/src/modules/auth/i18n/de.json +3 -0
  40. package/src/modules/auth/i18n/en.json +3 -0
  41. package/src/modules/auth/i18n/es.json +3 -0
  42. package/src/modules/auth/i18n/ko.json +3 -0
  43. package/src/modules/auth/i18n/pl.json +3 -0
  44. package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
  45. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +5 -4
  46. package/src/modules/customers/components/detail/DealsSection.tsx +11 -5
  47. package/src/modules/customers/components/detail/utils.ts +15 -5
  48. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +14 -8
  49. package/src/modules/sales/components/PriceWithCurrency.tsx +17 -5
  50. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +6 -5
  51. package/src/modules/sales/components/documents/ItemsSection.tsx +8 -1
  52. package/src/modules/sales/components/documents/LineItemDialog.tsx +9 -8
  53. package/src/modules/sales/components/documents/PaymentsSection.tsx +9 -8
  54. package/src/modules/sales/components/documents/ReturnsSection.tsx +6 -5
  55. package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +5 -4
  56. package/src/modules/sales/components/documents/ShipmentDialog.tsx +5 -4
  57. package/src/modules/sales/components/documents/ShipmentsSection.tsx +6 -5
  58. package/src/modules/sales/components/documents/lineItemUtils.ts +7 -2
  59. package/src/modules/sales/data/entities.ts +6 -0
  60. package/src/modules/sales/migrations/.snapshot-open-mercato.json +60 -0
  61. package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +87 -0
  62. package/src/modules/staff/backend/staff/timesheets/page.tsx +12 -1
@@ -1,14 +1,15 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
+ import { useOptionalLocale } from "@open-mercato/shared/lib/i18n/context";
4
5
  import { cn } from "@open-mercato/shared/lib/utils";
5
- function formatPriceWithCurrency(amount, currency, fallback = "\u2014") {
6
+ function formatPriceWithCurrency(amount, currency, fallback = "\u2014", locale) {
6
7
  if (amount === null || amount === void 0) return fallback;
7
8
  const parsed = typeof amount === "string" ? Number(amount) : amount;
8
9
  if (Number.isNaN(parsed)) return fallback;
9
10
  if (currency) {
10
11
  try {
11
- return new Intl.NumberFormat(void 0, {
12
+ return new Intl.NumberFormat(locale, {
12
13
  style: "currency",
13
14
  currency,
14
15
  minimumFractionDigits: 2,
@@ -17,12 +18,13 @@ function formatPriceWithCurrency(amount, currency, fallback = "\u2014") {
17
18
  } catch {
18
19
  }
19
20
  }
20
- return parsed.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
21
+ return parsed.toLocaleString(locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
21
22
  }
22
23
  function PriceWithCurrency({ amount, currency, fallback = "\u2014", className }) {
24
+ const locale = useOptionalLocale();
23
25
  const label = React.useMemo(
24
- () => formatPriceWithCurrency(amount, currency, fallback),
25
- [amount, currency, fallback]
26
+ () => formatPriceWithCurrency(amount, currency, fallback, locale),
27
+ [amount, currency, fallback, locale]
26
28
  );
27
29
  return /* @__PURE__ */ jsx("span", { className: cn("font-mono text-sm text-foreground", className), children: label });
28
30
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/sales/components/PriceWithCurrency.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nexport function formatPriceWithCurrency(\n amount: number | string | null | undefined,\n currency: string | null | undefined,\n fallback = '\u2014'\n): string {\n if (amount === null || amount === undefined) return fallback\n const parsed = typeof amount === 'string' ? Number(amount) : amount\n if (Number.isNaN(parsed)) return fallback\n if (currency) {\n try {\n return new Intl.NumberFormat(undefined, {\n style: 'currency',\n currency,\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(parsed)\n } catch {\n // fall through to plain number formatting\n }\n }\n return parsed.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })\n}\n\ntype PriceWithCurrencyProps = {\n amount: number | string | null | undefined\n currency: string | null | undefined\n fallback?: string\n className?: string\n}\n\nexport function PriceWithCurrency({ amount, currency, fallback = '\u2014', className }: PriceWithCurrencyProps) {\n const label = React.useMemo(\n () => formatPriceWithCurrency(amount, currency, fallback),\n [amount, currency, fallback]\n )\n return <span className={cn('font-mono text-sm text-foreground', className)}>{label}</span>\n}\n"],
5
- "mappings": ";AAwCS;AAtCT,YAAY,WAAW;AACvB,SAAS,UAAU;AAEZ,SAAS,wBACd,QACA,UACA,WAAW,UACH;AACR,MAAI,WAAW,QAAQ,WAAW,OAAW,QAAO;AACpD,QAAM,SAAS,OAAO,WAAW,WAAW,OAAO,MAAM,IAAI;AAC7D,MAAI,OAAO,MAAM,MAAM,EAAG,QAAO;AACjC,MAAI,UAAU;AACZ,QAAI;AACF,aAAO,IAAI,KAAK,aAAa,QAAW;AAAA,QACtC,OAAO;AAAA,QACP;AAAA,QACA,uBAAuB;AAAA,QACvB,uBAAuB;AAAA,MACzB,CAAC,EAAE,OAAO,MAAM;AAAA,IAClB,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO,OAAO,eAAe,QAAW,EAAE,uBAAuB,GAAG,uBAAuB,EAAE,CAAC;AAChG;AASO,SAAS,kBAAkB,EAAE,QAAQ,UAAU,WAAW,UAAK,UAAU,GAA2B;AACzG,QAAM,QAAQ,MAAM;AAAA,IAClB,MAAM,wBAAwB,QAAQ,UAAU,QAAQ;AAAA,IACxD,CAAC,QAAQ,UAAU,QAAQ;AAAA,EAC7B;AACA,SAAO,oBAAC,UAAK,WAAW,GAAG,qCAAqC,SAAS,GAAI,iBAAM;AACrF;",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useOptionalLocale } from '@open-mercato/shared/lib/i18n/context'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\n/**\n * Pass `locale` to format in the application locale (`useLocale()` in client components).\n * Omitting it keeps the runtime default, which varies per machine and is therefore not\n * assertable in tests.\n */\nexport function formatPriceWithCurrency(\n amount: number | string | null | undefined,\n currency: string | null | undefined,\n fallback = '\u2014',\n locale?: string\n): string {\n if (amount === null || amount === undefined) return fallback\n const parsed = typeof amount === 'string' ? Number(amount) : amount\n if (Number.isNaN(parsed)) return fallback\n if (currency) {\n try {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(parsed)\n } catch {\n // fall through to plain number formatting\n }\n }\n return parsed.toLocaleString(locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 })\n}\n\ntype PriceWithCurrencyProps = {\n amount: number | string | null | undefined\n currency: string | null | undefined\n fallback?: string\n className?: string\n}\n\nexport function PriceWithCurrency({ amount, currency, fallback = '\u2014', className }: PriceWithCurrencyProps) {\n // `useOptionalLocale` rather than `useLocale`: this component is deep-importable and had no i18n\n // dependency at all before it started formatting in the app locale, so making it throw outside\n // `I18nProvider` would narrow its mounting contract. Without a provider it falls back to the\n // runtime default, which is exactly the behaviour it had before.\n const locale = useOptionalLocale()\n const label = React.useMemo(\n () => formatPriceWithCurrency(amount, currency, fallback, locale),\n [amount, currency, fallback, locale]\n )\n return <span className={cn('font-mono text-sm text-foreground', className)}>{label}</span>\n}\n"],
5
+ "mappings": ";AAoDS;AAlDT,YAAY,WAAW;AACvB,SAAS,yBAAyB;AAClC,SAAS,UAAU;AAOZ,SAAS,wBACd,QACA,UACA,WAAW,UACX,QACQ;AACR,MAAI,WAAW,QAAQ,WAAW,OAAW,QAAO;AACpD,QAAM,SAAS,OAAO,WAAW,WAAW,OAAO,MAAM,IAAI;AAC7D,MAAI,OAAO,MAAM,MAAM,EAAG,QAAO;AACjC,MAAI,UAAU;AACZ,QAAI;AACF,aAAO,IAAI,KAAK,aAAa,QAAQ;AAAA,QACnC,OAAO;AAAA,QACP;AAAA,QACA,uBAAuB;AAAA,QACvB,uBAAuB;AAAA,MACzB,CAAC,EAAE,OAAO,MAAM;AAAA,IAClB,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO,OAAO,eAAe,QAAQ,EAAE,uBAAuB,GAAG,uBAAuB,EAAE,CAAC;AAC7F;AASO,SAAS,kBAAkB,EAAE,QAAQ,UAAU,WAAW,UAAK,UAAU,GAA2B;AAKzG,QAAM,SAAS,kBAAkB;AACjC,QAAM,QAAQ,MAAM;AAAA,IAClB,MAAM,wBAAwB,QAAQ,UAAU,UAAU,MAAM;AAAA,IAChE,CAAC,QAAQ,UAAU,UAAU,MAAM;AAAA,EACrC;AACA,SAAO,oBAAC,UAAK,WAAW,GAAG,qCAAqC,SAAS,GAAI,iBAAM;AACrF;",
6
6
  "names": []
7
7
  }
@@ -17,7 +17,7 @@ import {
17
17
  } from "@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents";
18
18
  import { PriceWithCurrency } from "../PriceWithCurrency.js";
19
19
  import { AdjustmentDialog } from "./AdjustmentDialog.js";
20
- import { useT } from "@open-mercato/shared/lib/i18n/context";
20
+ import { useT, useLocale } from "@open-mercato/shared/lib/i18n/context";
21
21
  import { useOrganizationScopeDetail } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
22
22
  import { extractCustomFieldValues } from "./customFieldHelpers.js";
23
23
  import { createLogger } from "@open-mercato/shared/lib/logger";
@@ -37,9 +37,9 @@ function normalizeNumber(value, fallback = 0) {
37
37
  }
38
38
  return fallback;
39
39
  }
40
- function formatPercent(value) {
40
+ function formatPercent(value, locale) {
41
41
  if (value === null || value === void 0) return "\u2014";
42
- const formatter = new Intl.NumberFormat(void 0, { style: "percent", maximumFractionDigits: 2 });
42
+ const formatter = new Intl.NumberFormat(locale, { style: "percent", maximumFractionDigits: 2 });
43
43
  return formatter.format(value / 100);
44
44
  }
45
45
  function SalesDocumentAdjustmentsSection({
@@ -53,6 +53,7 @@ function SalesDocumentAdjustmentsSection({
53
53
  onRowsChange
54
54
  }) {
55
55
  const t = useT();
56
+ const locale = useLocale();
56
57
  const { organizationId, tenantId } = useOrganizationScopeDetail();
57
58
  const resolvedOrganizationId = orgFromProps ?? organizationId ?? null;
58
59
  const resolvedTenantId = tenantFromProps ?? tenantId ?? null;
@@ -342,7 +343,7 @@ function SalesDocumentAdjustmentsSection({
342
343
  {
343
344
  id: "rate",
344
345
  header: t("sales.documents.adjustments.rate", "Rate"),
345
- cell: ({ row }) => /* @__PURE__ */ jsx("span", { className: "font-mono text-sm text-muted-foreground", children: formatPercent(row.original.rate) })
346
+ cell: ({ row }) => /* @__PURE__ */ jsx("span", { className: "font-mono text-sm text-muted-foreground", children: formatPercent(row.original.rate, locale) })
346
347
  },
347
348
  {
348
349
  id: "position",
@@ -350,7 +351,7 @@ function SalesDocumentAdjustmentsSection({
350
351
  cell: ({ row }) => /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: row.original.position })
351
352
  }
352
353
  ],
353
- [currencyCode, resolveKindLabel, t]
354
+ [currencyCode, locale, resolveKindLabel, t]
354
355
  );
355
356
  const showLoadingState = loading && rows.length === 0;
356
357
  const renderRowActions = React.useCallback(
@@ -430,6 +431,7 @@ function SalesDocumentAdjustmentsSection({
430
431
  ] });
431
432
  }
432
433
  export {
433
- SalesDocumentAdjustmentsSection
434
+ SalesDocumentAdjustmentsSection,
435
+ formatPercent
434
436
  };
435
437
  //# sourceMappingURL=AdjustmentsSection.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/sales/components/documents/AdjustmentsSection.tsx"],
4
- "sourcesContent": ["// @ts-nocheck\n\n\"use client\"\n\nimport * as React from 'react'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { ErrorMessage, LoadingMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { createCrud, deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { handleSectionMutationError } from './optimisticLock'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { type DictionaryOption } from '@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect'\nimport {\n emitSalesDocumentTotalsRefresh,\n subscribeSalesDocumentTotalsRefresh,\n} from '@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents'\nimport type { SectionAction } from '@open-mercato/core/modules/customers/components/detail/types'\nimport type { SalesAdjustmentKind } from '../../data/entities'\nimport { PriceWithCurrency } from '../PriceWithCurrency'\nimport { AdjustmentDialog, type AdjustmentRowData, type AdjustmentSubmitPayload } from './AdjustmentDialog'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { extractCustomFieldValues } from './customFieldHelpers'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype AdjustmentRow = AdjustmentRowData\n\ntype SalesDocumentAdjustmentsSectionProps = {\n documentId: string\n kind: 'order' | 'quote'\n currencyCode: string | null | undefined\n documentUpdatedAt?: string | null\n organizationId?: string | null\n tenantId?: string | null\n onActionChange?: (action: SectionAction | null) => void\n onRowsChange?: (rows: AdjustmentRow[]) => void\n}\n\nconst FALLBACK_ADJUSTMENT_KIND_VALUES: SalesAdjustmentKind[] = [\n 'discount',\n 'tax',\n 'shipping',\n 'surcharge',\n 'custom',\n]\n\nfunction normalizeNumber(value: unknown, fallback = 0): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return fallback\n}\n\nfunction formatPercent(value: number | null | undefined): string {\n if (value === null || value === undefined) return '\u2014'\n const formatter = new Intl.NumberFormat(undefined, { style: 'percent', maximumFractionDigits: 2 })\n return formatter.format(value / 100)\n}\n\nexport function SalesDocumentAdjustmentsSection({\n documentId,\n kind,\n currencyCode,\n documentUpdatedAt,\n organizationId: orgFromProps,\n tenantId: tenantFromProps,\n onActionChange,\n onRowsChange,\n}: SalesDocumentAdjustmentsSectionProps) {\n const t = useT()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const resolvedOrganizationId = orgFromProps ?? organizationId ?? null\n const resolvedTenantId = tenantFromProps ?? tenantId ?? null\n const [rows, setRows] = React.useState<AdjustmentRow[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const [dialogOpen, setDialogOpen] = React.useState(false)\n const [activeAdjustment, setActiveAdjustment] = React.useState<AdjustmentRow | null>(null)\n const [kindOptions, setKindOptions] = React.useState<DictionaryOption[]>([])\n const kindLoadingRef = React.useRef(false)\n\n const apiResourcePath = React.useMemo(\n () => (kind === 'order' ? '/api/sales/order-adjustments' : '/api/sales/quote-adjustments'),\n [kind]\n )\n const crudResourcePath = React.useMemo(\n () => (kind === 'order' ? 'sales/order-adjustments' : 'sales/quote-adjustments'),\n [kind]\n )\n const documentKey = kind === 'order' ? 'orderId' : 'quoteId'\n const fallbackKindOptions = React.useMemo<DictionaryOption[]>(\n () =>\n FALLBACK_ADJUSTMENT_KIND_VALUES.map((value) => ({\n value,\n label: t(`sales.documents.adjustments.kindLabels.${value}`, value),\n color: null,\n icon: null,\n })),\n [t]\n )\n const kindOptionMap = React.useMemo(\n () =>\n kindOptions.reduce<Record<string, DictionaryOption>>((acc, entry) => {\n acc[entry.value] = entry\n return acc\n }, {}),\n [kindOptions]\n )\n const loadKindOptions = React.useCallback(async (): Promise<DictionaryOption[]> => {\n if (kindOptions.length) return kindOptions\n if (kindLoadingRef.current) return kindOptions.length ? kindOptions : fallbackKindOptions\n kindLoadingRef.current = true\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/adjustment-kinds?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const parsed = items\n .map((item) => {\n const value = typeof (item as any).value === 'string' ? (item as any).value.trim() : ''\n if (!value) return null\n const label =\n typeof (item as any).label === 'string' && (item as any).label.trim().length\n ? (item as any).label.trim()\n : value\n const color =\n typeof (item as any).color === 'string' && /^#([0-9a-fA-F]{6})$/.test((item as any).color)\n ? `#${(item as any).color.slice(1).toLowerCase()}`\n : null\n const icon =\n typeof (item as any).icon === 'string' && (item as any).icon.trim().length\n ? (item as any).icon.trim()\n : null\n return { value, label, color, icon }\n })\n .filter((entry): entry is DictionaryOption => Boolean(entry))\n const merged = new Map<string, DictionaryOption>()\n fallbackKindOptions.forEach((entry) => merged.set(entry.value, entry))\n parsed.forEach((entry) => merged.set(entry.value, entry))\n const options = Array.from(merged.values()).sort((a, b) =>\n a.label.localeCompare(b.label, undefined, { sensitivity: 'base' })\n )\n setKindOptions(options)\n kindLoadingRef.current = false\n return options\n } catch (err) {\n logger.error('sales.adjustment-kinds.fetch', { err })\n kindLoadingRef.current = false\n setKindOptions(fallbackKindOptions)\n return fallbackKindOptions\n }\n }, [fallbackKindOptions, kindOptions])\n\n React.useEffect(() => {\n loadKindOptions().catch(() => {})\n }, [loadKindOptions, resolvedOrganizationId, resolvedTenantId])\n\n const loadAdjustments = React.useCallback(async () => {\n setLoading(true)\n setError(null)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', [documentKey]: documentId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `${apiResourcePath}?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const mapped: AdjustmentRow[] = items\n .map((item) => {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const amountNet = normalizeNumber(\n (item as any).amount_net ?? (item as any).amountNet ?? (item as any).amount_net_amount,\n NaN\n )\n const amountGross = normalizeNumber(\n (item as any).amount_gross ?? (item as any).amountGross ?? (item as any).amount_gross_amount,\n NaN\n )\n const rateRaw = normalizeNumber((item as any).rate, NaN)\n const kindValue =\n typeof item.kind === 'string' && item.kind.trim().length\n ? (item.kind.trim() as SalesAdjustmentKind)\n : 'custom'\n const currency =\n typeof (item as any).currency_code === 'string'\n ? (item as any).currency_code\n : typeof (item as any).currencyCode === 'string'\n ? (item as any).currencyCode\n : currencyCode ?? null\n const customFields = extractCustomFieldValues(item as Record<string, unknown>)\n const customFieldSetId =\n typeof (item as any).custom_field_set_id === 'string'\n ? (item as any).custom_field_set_id\n : typeof (item as any).customFieldSetId === 'string'\n ? (item as any).customFieldSetId\n : null\n const metadata =\n typeof (item as any).metadata === 'object' && (item as any).metadata\n ? ((item as any).metadata as Record<string, unknown>)\n : null\n return {\n id,\n label: typeof item.label === 'string' ? item.label : null,\n code: typeof item.code === 'string' ? item.code : null,\n kind: kindValue,\n calculatorKey:\n typeof (item as any).calculator_key === 'string'\n ? (item as any).calculator_key\n : typeof (item as any).calculatorKey === 'string'\n ? (item as any).calculatorKey\n : null,\n rate: Number.isFinite(rateRaw) ? rateRaw : null,\n amountNet: Number.isFinite(amountNet) ? amountNet : null,\n amountGross: Number.isFinite(amountGross) ? amountGross : null,\n currencyCode: currency,\n position:\n typeof item.position === 'number'\n ? item.position\n : typeof (item as any).position === 'string'\n ? Number((item as any).position)\n : 0,\n customFields: Object.keys(customFields).length ? customFields : null,\n customFieldSetId,\n metadata,\n }\n })\n .filter((entry): entry is AdjustmentRow => Boolean(entry))\n const ordered = [...mapped].sort((a, b) => (a.position ?? 0) - (b.position ?? 0))\n setRows(ordered)\n if (onRowsChange) onRowsChange(ordered)\n } catch (err) {\n logger.error('sales.document.adjustments.load', { err })\n setError(t('sales.documents.adjustments.errorLoad', 'Failed to load adjustments.'))\n } finally {\n setLoading(false)\n }\n }, [apiResourcePath, currencyCode, documentId, documentKey, onRowsChange, t])\n\n React.useEffect(() => {\n void loadAdjustments()\n }, [loadAdjustments])\n\n React.useEffect(\n () =>\n subscribeSalesDocumentTotalsRefresh((detail) => {\n if (detail.documentId !== documentId) return\n if (detail.kind && detail.kind !== kind) return\n void loadAdjustments()\n }),\n [documentId, kind, loadAdjustments],\n )\n\n const resolveKindLabel = React.useCallback(\n (kindValue: SalesAdjustmentKind) => {\n const option = kindOptionMap[kindValue]\n if (option) return option.label\n return t(`sales.documents.adjustments.kindLabels.${kindValue}`, typeof kindValue === 'string' ? kindValue : String(kindValue))\n },\n [kindOptionMap, t]\n )\n\n const handleOpenCreate = React.useCallback(() => {\n setActiveAdjustment(null)\n setDialogOpen(true)\n }, [])\n\n const handleEdit = React.useCallback((row: AdjustmentRow) => {\n setActiveAdjustment(row)\n setDialogOpen(true)\n }, [])\n\n const handleCloseDialog = React.useCallback(() => {\n setDialogOpen(false)\n setActiveAdjustment(null)\n }, [])\n\n React.useEffect(() => {\n if (!onActionChange) return\n onActionChange({\n label: t('sales.documents.adjustments.add', 'Add adjustment'),\n onClick: handleOpenCreate,\n disabled: false,\n })\n return () => onActionChange(null)\n }, [handleOpenCreate, onActionChange, t])\n\n const handleFormSubmit = React.useCallback(\n async (values: AdjustmentSubmitPayload) => {\n if (!resolvedOrganizationId || !resolvedTenantId) {\n throw createCrudFormError(\n t('sales.documents.adjustments.errorScope', 'Organization and tenant are required.')\n )\n }\n const payload: Record<string, unknown> = {\n [documentKey]: String(documentId),\n organizationId: String(resolvedOrganizationId),\n tenantId: String(resolvedTenantId),\n scope: 'order',\n kind: values.kind ?? 'custom',\n code: values.code ?? undefined,\n label: values.label ?? undefined,\n calculatorKey: values.calculatorKey ?? undefined,\n rate: Number.isFinite(values.rate) ? values.rate : undefined,\n amountNet: Number.isFinite(values.amountNet) ? values.amountNet : undefined,\n amountGross: Number.isFinite(values.amountGross) ? values.amountGross : undefined,\n currencyCode: (values.currencyCode ?? currencyCode ?? '').toUpperCase(),\n position: Number.isFinite(values.position) ? values.position : undefined,\n customFields: values.customFields ?? undefined,\n metadata: values.metadata ?? undefined,\n }\n\n const action = values.id ? updateCrud : createCrud\n try {\n const result = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(documentUpdatedAt),\n () =>\n action(\n crudResourcePath,\n values.id ? { id: values.id, ...payload } : payload,\n {\n successMessage: values.id\n ? t('sales.documents.adjustments.updated', 'Adjustment updated.')\n : t('sales.documents.adjustments.created', 'Adjustment added.'),\n errorMessage: t('sales.documents.adjustments.errorSave', 'Failed to save adjustment.'),\n }\n )\n )\n if (result.ok) {\n await loadAdjustments()\n emitSalesDocumentTotalsRefresh({ documentId, kind })\n setDialogOpen(false)\n setActiveAdjustment(null)\n }\n } catch (err) {\n if (\n handleSectionMutationError(err, t, () => void loadAdjustments())\n ) {\n setDialogOpen(false)\n setActiveAdjustment(null)\n return\n }\n throw err\n }\n },\n [\n currencyCode,\n documentId,\n documentKey,\n documentUpdatedAt,\n kind,\n loadAdjustments,\n crudResourcePath,\n resolvedOrganizationId,\n resolvedTenantId,\n t,\n ]\n )\n\n const handleDelete = React.useCallback(\n async (row: AdjustmentRow) => {\n try {\n const result = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(documentUpdatedAt),\n () =>\n deleteCrud(crudResourcePath, {\n body: {\n id: row.id,\n [documentKey]: documentId,\n organizationId: resolvedOrganizationId ?? undefined,\n tenantId: resolvedTenantId ?? undefined,\n },\n errorMessage: t('sales.documents.adjustments.errorDelete', 'Failed to delete adjustment.'),\n })\n )\n if (result.ok) {\n await loadAdjustments()\n emitSalesDocumentTotalsRefresh({ documentId, kind })\n }\n } catch (err) {\n if (handleSectionMutationError(err, t, () => void loadAdjustments())) return\n logger.error('sales.document.adjustments.delete', { err })\n flash(t('sales.documents.adjustments.errorDelete', 'Failed to delete adjustment.'), 'error')\n }\n },\n [crudResourcePath, documentId, documentKey, documentUpdatedAt, kind, loadAdjustments, resolvedOrganizationId, resolvedTenantId, t]\n )\n\n const columns = React.useMemo<ColumnDef<AdjustmentRow>[]>(\n () => [\n {\n id: 'label',\n header: t('sales.documents.adjustments.label', 'Label'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium text-foreground\">{row.original.label ?? t('sales.documents.adjustments.untitled', 'Untitled')}</span>\n {row.original.code ? <span className=\"text-xs text-muted-foreground\">{row.original.code}</span> : null}\n </div>\n ),\n },\n {\n id: 'kind',\n header: t('sales.documents.adjustments.kindLabel', 'Kind'),\n cell: ({ row }) => <Badge variant=\"outline\">{resolveKindLabel(row.original.kind)}</Badge>,\n },\n {\n id: 'amountNet',\n header: t('sales.documents.adjustments.amountNet', 'Net amount'),\n cell: ({ row }) => (\n <PriceWithCurrency amount={row.original.amountNet} currency={row.original.currencyCode ?? currencyCode} className=\"font-mono text-sm\" />\n ),\n },\n {\n id: 'amountGross',\n header: t('sales.documents.adjustments.amountGross', 'Gross amount'),\n cell: ({ row }) => (\n <PriceWithCurrency amount={row.original.amountGross} currency={row.original.currencyCode ?? currencyCode} className=\"font-mono text-sm\" />\n ),\n },\n {\n id: 'rate',\n header: t('sales.documents.adjustments.rate', 'Rate'),\n cell: ({ row }) => <span className=\"font-mono text-sm text-muted-foreground\">{formatPercent(row.original.rate)}</span>,\n },\n {\n id: 'position',\n header: t('sales.documents.adjustments.position', 'Position'),\n cell: ({ row }) => <span className=\"text-sm text-muted-foreground\">{row.original.position}</span>,\n },\n ],\n [currencyCode, resolveKindLabel, t]\n )\n\n const showLoadingState = loading && rows.length === 0\n\n const renderRowActions = React.useCallback(\n (row: AdjustmentRow) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('ui.actions.edit', 'Edit'),\n onSelect: () => handleEdit(row),\n },\n {\n id: 'delete',\n label: t('ui.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n ),\n [handleDelete, handleEdit, t]\n )\n\n return (\n <div className=\"space-y-4\">\n {error ? (\n <ErrorMessage title={t('sales.documents.adjustments.errorLoad', 'Failed to load adjustments.')} description={error} onRetry={() => void loadAdjustments()} />\n ) : null}\n {showLoadingState ? (\n <LoadingMessage\n label={t('sales.documents.adjustments.loading', 'Loading adjustments\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n ) : (\n <DataTable<AdjustmentRow>\n data={rows}\n columns={columns}\n isLoading={loading && rows.length > 0}\n embedded\n onRowClick={handleEdit}\n rowActions={renderRowActions}\n emptyState={\n <TabEmptyState\n title={t('sales.documents.empty.adjustments.title', 'No adjustments yet.')}\n description={t('sales.documents.empty.adjustments.description', 'Add discounts, fees, or taxes to refine totals.')}\n actionLabel={t('sales.documents.adjustments.add', 'Add adjustment')}\n onAction={handleOpenCreate}\n />\n }\n />\n )}\n\n <AdjustmentDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n if (!open) {\n handleCloseDialog()\n } else {\n setDialogOpen(true)\n }\n }}\n kind={kind}\n currencyCode={currencyCode ?? null}\n kindOptions={kindOptions.length ? kindOptions : fallbackKindOptions}\n loadKindOptions={loadKindOptions}\n labels={{\n addTitle: t('sales.documents.adjustments.addTitle', 'Add adjustment'),\n editTitle: t('sales.documents.adjustments.editTitle', 'Edit adjustment'),\n submitCreate: t('sales.documents.adjustments.submitCreate', 'Add adjustment'),\n submitUpdate: t('sales.documents.adjustments.submitUpdate', 'Save changes'),\n }}\n initialAdjustment={activeAdjustment}\n onSubmit={handleFormSubmit}\n />\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// @ts-nocheck\n\n\"use client\"\n\nimport * as React from 'react'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { ErrorMessage, LoadingMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { createCrud, deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { handleSectionMutationError } from './optimisticLock'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { type DictionaryOption } from '@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect'\nimport {\n emitSalesDocumentTotalsRefresh,\n subscribeSalesDocumentTotalsRefresh,\n} from '@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents'\nimport type { SectionAction } from '@open-mercato/core/modules/customers/components/detail/types'\nimport type { SalesAdjustmentKind } from '../../data/entities'\nimport { PriceWithCurrency } from '../PriceWithCurrency'\nimport { AdjustmentDialog, type AdjustmentRowData, type AdjustmentSubmitPayload } from './AdjustmentDialog'\nimport { useT, useLocale } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { extractCustomFieldValues } from './customFieldHelpers'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\ntype AdjustmentRow = AdjustmentRowData\n\ntype SalesDocumentAdjustmentsSectionProps = {\n documentId: string\n kind: 'order' | 'quote'\n currencyCode: string | null | undefined\n documentUpdatedAt?: string | null\n organizationId?: string | null\n tenantId?: string | null\n onActionChange?: (action: SectionAction | null) => void\n onRowsChange?: (rows: AdjustmentRow[]) => void\n}\n\nconst FALLBACK_ADJUSTMENT_KIND_VALUES: SalesAdjustmentKind[] = [\n 'discount',\n 'tax',\n 'shipping',\n 'surcharge',\n 'custom',\n]\n\nfunction normalizeNumber(value: unknown, fallback = 0): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return fallback\n}\n\nexport function formatPercent(value: number | null | undefined, locale?: string): string {\n if (value === null || value === undefined) return '\u2014'\n const formatter = new Intl.NumberFormat(locale, { style: 'percent', maximumFractionDigits: 2 })\n return formatter.format(value / 100)\n}\n\nexport function SalesDocumentAdjustmentsSection({\n documentId,\n kind,\n currencyCode,\n documentUpdatedAt,\n organizationId: orgFromProps,\n tenantId: tenantFromProps,\n onActionChange,\n onRowsChange,\n}: SalesDocumentAdjustmentsSectionProps) {\n const t = useT()\n const locale = useLocale()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const resolvedOrganizationId = orgFromProps ?? organizationId ?? null\n const resolvedTenantId = tenantFromProps ?? tenantId ?? null\n const [rows, setRows] = React.useState<AdjustmentRow[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const [dialogOpen, setDialogOpen] = React.useState(false)\n const [activeAdjustment, setActiveAdjustment] = React.useState<AdjustmentRow | null>(null)\n const [kindOptions, setKindOptions] = React.useState<DictionaryOption[]>([])\n const kindLoadingRef = React.useRef(false)\n\n const apiResourcePath = React.useMemo(\n () => (kind === 'order' ? '/api/sales/order-adjustments' : '/api/sales/quote-adjustments'),\n [kind]\n )\n const crudResourcePath = React.useMemo(\n () => (kind === 'order' ? 'sales/order-adjustments' : 'sales/quote-adjustments'),\n [kind]\n )\n const documentKey = kind === 'order' ? 'orderId' : 'quoteId'\n const fallbackKindOptions = React.useMemo<DictionaryOption[]>(\n () =>\n FALLBACK_ADJUSTMENT_KIND_VALUES.map((value) => ({\n value,\n label: t(`sales.documents.adjustments.kindLabels.${value}`, value),\n color: null,\n icon: null,\n })),\n [t]\n )\n const kindOptionMap = React.useMemo(\n () =>\n kindOptions.reduce<Record<string, DictionaryOption>>((acc, entry) => {\n acc[entry.value] = entry\n return acc\n }, {}),\n [kindOptions]\n )\n const loadKindOptions = React.useCallback(async (): Promise<DictionaryOption[]> => {\n if (kindOptions.length) return kindOptions\n if (kindLoadingRef.current) return kindOptions.length ? kindOptions : fallbackKindOptions\n kindLoadingRef.current = true\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/adjustment-kinds?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const parsed = items\n .map((item) => {\n const value = typeof (item as any).value === 'string' ? (item as any).value.trim() : ''\n if (!value) return null\n const label =\n typeof (item as any).label === 'string' && (item as any).label.trim().length\n ? (item as any).label.trim()\n : value\n const color =\n typeof (item as any).color === 'string' && /^#([0-9a-fA-F]{6})$/.test((item as any).color)\n ? `#${(item as any).color.slice(1).toLowerCase()}`\n : null\n const icon =\n typeof (item as any).icon === 'string' && (item as any).icon.trim().length\n ? (item as any).icon.trim()\n : null\n return { value, label, color, icon }\n })\n .filter((entry): entry is DictionaryOption => Boolean(entry))\n const merged = new Map<string, DictionaryOption>()\n fallbackKindOptions.forEach((entry) => merged.set(entry.value, entry))\n parsed.forEach((entry) => merged.set(entry.value, entry))\n const options = Array.from(merged.values()).sort((a, b) =>\n a.label.localeCompare(b.label, undefined, { sensitivity: 'base' })\n )\n setKindOptions(options)\n kindLoadingRef.current = false\n return options\n } catch (err) {\n logger.error('sales.adjustment-kinds.fetch', { err })\n kindLoadingRef.current = false\n setKindOptions(fallbackKindOptions)\n return fallbackKindOptions\n }\n }, [fallbackKindOptions, kindOptions])\n\n React.useEffect(() => {\n loadKindOptions().catch(() => {})\n }, [loadKindOptions, resolvedOrganizationId, resolvedTenantId])\n\n const loadAdjustments = React.useCallback(async () => {\n setLoading(true)\n setError(null)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', [documentKey]: documentId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `${apiResourcePath}?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const mapped: AdjustmentRow[] = items\n .map((item) => {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const amountNet = normalizeNumber(\n (item as any).amount_net ?? (item as any).amountNet ?? (item as any).amount_net_amount,\n NaN\n )\n const amountGross = normalizeNumber(\n (item as any).amount_gross ?? (item as any).amountGross ?? (item as any).amount_gross_amount,\n NaN\n )\n const rateRaw = normalizeNumber((item as any).rate, NaN)\n const kindValue =\n typeof item.kind === 'string' && item.kind.trim().length\n ? (item.kind.trim() as SalesAdjustmentKind)\n : 'custom'\n const currency =\n typeof (item as any).currency_code === 'string'\n ? (item as any).currency_code\n : typeof (item as any).currencyCode === 'string'\n ? (item as any).currencyCode\n : currencyCode ?? null\n const customFields = extractCustomFieldValues(item as Record<string, unknown>)\n const customFieldSetId =\n typeof (item as any).custom_field_set_id === 'string'\n ? (item as any).custom_field_set_id\n : typeof (item as any).customFieldSetId === 'string'\n ? (item as any).customFieldSetId\n : null\n const metadata =\n typeof (item as any).metadata === 'object' && (item as any).metadata\n ? ((item as any).metadata as Record<string, unknown>)\n : null\n return {\n id,\n label: typeof item.label === 'string' ? item.label : null,\n code: typeof item.code === 'string' ? item.code : null,\n kind: kindValue,\n calculatorKey:\n typeof (item as any).calculator_key === 'string'\n ? (item as any).calculator_key\n : typeof (item as any).calculatorKey === 'string'\n ? (item as any).calculatorKey\n : null,\n rate: Number.isFinite(rateRaw) ? rateRaw : null,\n amountNet: Number.isFinite(amountNet) ? amountNet : null,\n amountGross: Number.isFinite(amountGross) ? amountGross : null,\n currencyCode: currency,\n position:\n typeof item.position === 'number'\n ? item.position\n : typeof (item as any).position === 'string'\n ? Number((item as any).position)\n : 0,\n customFields: Object.keys(customFields).length ? customFields : null,\n customFieldSetId,\n metadata,\n }\n })\n .filter((entry): entry is AdjustmentRow => Boolean(entry))\n const ordered = [...mapped].sort((a, b) => (a.position ?? 0) - (b.position ?? 0))\n setRows(ordered)\n if (onRowsChange) onRowsChange(ordered)\n } catch (err) {\n logger.error('sales.document.adjustments.load', { err })\n setError(t('sales.documents.adjustments.errorLoad', 'Failed to load adjustments.'))\n } finally {\n setLoading(false)\n }\n }, [apiResourcePath, currencyCode, documentId, documentKey, onRowsChange, t])\n\n React.useEffect(() => {\n void loadAdjustments()\n }, [loadAdjustments])\n\n React.useEffect(\n () =>\n subscribeSalesDocumentTotalsRefresh((detail) => {\n if (detail.documentId !== documentId) return\n if (detail.kind && detail.kind !== kind) return\n void loadAdjustments()\n }),\n [documentId, kind, loadAdjustments],\n )\n\n const resolveKindLabel = React.useCallback(\n (kindValue: SalesAdjustmentKind) => {\n const option = kindOptionMap[kindValue]\n if (option) return option.label\n return t(`sales.documents.adjustments.kindLabels.${kindValue}`, typeof kindValue === 'string' ? kindValue : String(kindValue))\n },\n [kindOptionMap, t]\n )\n\n const handleOpenCreate = React.useCallback(() => {\n setActiveAdjustment(null)\n setDialogOpen(true)\n }, [])\n\n const handleEdit = React.useCallback((row: AdjustmentRow) => {\n setActiveAdjustment(row)\n setDialogOpen(true)\n }, [])\n\n const handleCloseDialog = React.useCallback(() => {\n setDialogOpen(false)\n setActiveAdjustment(null)\n }, [])\n\n React.useEffect(() => {\n if (!onActionChange) return\n onActionChange({\n label: t('sales.documents.adjustments.add', 'Add adjustment'),\n onClick: handleOpenCreate,\n disabled: false,\n })\n return () => onActionChange(null)\n }, [handleOpenCreate, onActionChange, t])\n\n const handleFormSubmit = React.useCallback(\n async (values: AdjustmentSubmitPayload) => {\n if (!resolvedOrganizationId || !resolvedTenantId) {\n throw createCrudFormError(\n t('sales.documents.adjustments.errorScope', 'Organization and tenant are required.')\n )\n }\n const payload: Record<string, unknown> = {\n [documentKey]: String(documentId),\n organizationId: String(resolvedOrganizationId),\n tenantId: String(resolvedTenantId),\n scope: 'order',\n kind: values.kind ?? 'custom',\n code: values.code ?? undefined,\n label: values.label ?? undefined,\n calculatorKey: values.calculatorKey ?? undefined,\n rate: Number.isFinite(values.rate) ? values.rate : undefined,\n amountNet: Number.isFinite(values.amountNet) ? values.amountNet : undefined,\n amountGross: Number.isFinite(values.amountGross) ? values.amountGross : undefined,\n currencyCode: (values.currencyCode ?? currencyCode ?? '').toUpperCase(),\n position: Number.isFinite(values.position) ? values.position : undefined,\n customFields: values.customFields ?? undefined,\n metadata: values.metadata ?? undefined,\n }\n\n const action = values.id ? updateCrud : createCrud\n try {\n const result = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(documentUpdatedAt),\n () =>\n action(\n crudResourcePath,\n values.id ? { id: values.id, ...payload } : payload,\n {\n successMessage: values.id\n ? t('sales.documents.adjustments.updated', 'Adjustment updated.')\n : t('sales.documents.adjustments.created', 'Adjustment added.'),\n errorMessage: t('sales.documents.adjustments.errorSave', 'Failed to save adjustment.'),\n }\n )\n )\n if (result.ok) {\n await loadAdjustments()\n emitSalesDocumentTotalsRefresh({ documentId, kind })\n setDialogOpen(false)\n setActiveAdjustment(null)\n }\n } catch (err) {\n if (\n handleSectionMutationError(err, t, () => void loadAdjustments())\n ) {\n setDialogOpen(false)\n setActiveAdjustment(null)\n return\n }\n throw err\n }\n },\n [\n currencyCode,\n documentId,\n documentKey,\n documentUpdatedAt,\n kind,\n loadAdjustments,\n crudResourcePath,\n resolvedOrganizationId,\n resolvedTenantId,\n t,\n ]\n )\n\n const handleDelete = React.useCallback(\n async (row: AdjustmentRow) => {\n try {\n const result = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(documentUpdatedAt),\n () =>\n deleteCrud(crudResourcePath, {\n body: {\n id: row.id,\n [documentKey]: documentId,\n organizationId: resolvedOrganizationId ?? undefined,\n tenantId: resolvedTenantId ?? undefined,\n },\n errorMessage: t('sales.documents.adjustments.errorDelete', 'Failed to delete adjustment.'),\n })\n )\n if (result.ok) {\n await loadAdjustments()\n emitSalesDocumentTotalsRefresh({ documentId, kind })\n }\n } catch (err) {\n if (handleSectionMutationError(err, t, () => void loadAdjustments())) return\n logger.error('sales.document.adjustments.delete', { err })\n flash(t('sales.documents.adjustments.errorDelete', 'Failed to delete adjustment.'), 'error')\n }\n },\n [crudResourcePath, documentId, documentKey, documentUpdatedAt, kind, loadAdjustments, resolvedOrganizationId, resolvedTenantId, t]\n )\n\n const columns = React.useMemo<ColumnDef<AdjustmentRow>[]>(\n () => [\n {\n id: 'label',\n header: t('sales.documents.adjustments.label', 'Label'),\n cell: ({ row }) => (\n <div className=\"flex flex-col\">\n <span className=\"font-medium text-foreground\">{row.original.label ?? t('sales.documents.adjustments.untitled', 'Untitled')}</span>\n {row.original.code ? <span className=\"text-xs text-muted-foreground\">{row.original.code}</span> : null}\n </div>\n ),\n },\n {\n id: 'kind',\n header: t('sales.documents.adjustments.kindLabel', 'Kind'),\n cell: ({ row }) => <Badge variant=\"outline\">{resolveKindLabel(row.original.kind)}</Badge>,\n },\n {\n id: 'amountNet',\n header: t('sales.documents.adjustments.amountNet', 'Net amount'),\n cell: ({ row }) => (\n <PriceWithCurrency amount={row.original.amountNet} currency={row.original.currencyCode ?? currencyCode} className=\"font-mono text-sm\" />\n ),\n },\n {\n id: 'amountGross',\n header: t('sales.documents.adjustments.amountGross', 'Gross amount'),\n cell: ({ row }) => (\n <PriceWithCurrency amount={row.original.amountGross} currency={row.original.currencyCode ?? currencyCode} className=\"font-mono text-sm\" />\n ),\n },\n {\n id: 'rate',\n header: t('sales.documents.adjustments.rate', 'Rate'),\n cell: ({ row }) => <span className=\"font-mono text-sm text-muted-foreground\">{formatPercent(row.original.rate, locale)}</span>,\n },\n {\n id: 'position',\n header: t('sales.documents.adjustments.position', 'Position'),\n cell: ({ row }) => <span className=\"text-sm text-muted-foreground\">{row.original.position}</span>,\n },\n ],\n [currencyCode, locale, resolveKindLabel, t]\n )\n\n const showLoadingState = loading && rows.length === 0\n\n const renderRowActions = React.useCallback(\n (row: AdjustmentRow) => (\n <RowActions\n items={[\n {\n id: 'edit',\n label: t('ui.actions.edit', 'Edit'),\n onSelect: () => handleEdit(row),\n },\n {\n id: 'delete',\n label: t('ui.actions.delete', 'Delete'),\n destructive: true,\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n ),\n [handleDelete, handleEdit, t]\n )\n\n return (\n <div className=\"space-y-4\">\n {error ? (\n <ErrorMessage title={t('sales.documents.adjustments.errorLoad', 'Failed to load adjustments.')} description={error} onRetry={() => void loadAdjustments()} />\n ) : null}\n {showLoadingState ? (\n <LoadingMessage\n label={t('sales.documents.adjustments.loading', 'Loading adjustments\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n ) : (\n <DataTable<AdjustmentRow>\n data={rows}\n columns={columns}\n isLoading={loading && rows.length > 0}\n embedded\n onRowClick={handleEdit}\n rowActions={renderRowActions}\n emptyState={\n <TabEmptyState\n title={t('sales.documents.empty.adjustments.title', 'No adjustments yet.')}\n description={t('sales.documents.empty.adjustments.description', 'Add discounts, fees, or taxes to refine totals.')}\n actionLabel={t('sales.documents.adjustments.add', 'Add adjustment')}\n onAction={handleOpenCreate}\n />\n }\n />\n )}\n\n <AdjustmentDialog\n open={dialogOpen}\n onOpenChange={(open) => {\n if (!open) {\n handleCloseDialog()\n } else {\n setDialogOpen(true)\n }\n }}\n kind={kind}\n currencyCode={currencyCode ?? null}\n kindOptions={kindOptions.length ? kindOptions : fallbackKindOptions}\n loadKindOptions={loadKindOptions}\n labels={{\n addTitle: t('sales.documents.adjustments.addTitle', 'Add adjustment'),\n editTitle: t('sales.documents.adjustments.editTitle', 'Edit adjustment'),\n submitCreate: t('sales.documents.adjustments.submitCreate', 'Add adjustment'),\n submitUpdate: t('sales.documents.adjustments.submitUpdate', 'Save changes'),\n }}\n initialAdjustment={activeAdjustment}\n onSubmit={handleFormSubmit}\n />\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -15,7 +15,7 @@ import {
15
15
  createDictionaryMap,
16
16
  normalizeDictionaryEntries
17
17
  } from "@open-mercato/core/modules/dictionaries/components/dictionaryAppearance";
18
- import { useT } from "@open-mercato/shared/lib/i18n/context";
18
+ import { useT, useLocale } from "@open-mercato/shared/lib/i18n/context";
19
19
  import { useOrganizationScopeDetail } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
20
20
  import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
21
21
  import { emitSalesDocumentTotalsRefresh } from "@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents";
@@ -89,6 +89,7 @@ function SalesDocumentItemsSection({
89
89
  onItemsChange
90
90
  }) {
91
91
  const t = useT();
92
+ const locale = useLocale();
92
93
  const { organizationId, tenantId } = useOrganizationScopeDetail();
93
94
  const { confirm, ConfirmDialogElement } = useConfirmDialog();
94
95
  const resolvedOrganizationId = orgFromProps ?? organizationId ?? null;
@@ -552,7 +553,8 @@ function SalesDocumentItemsSection({
552
553
  /* @__PURE__ */ jsxs("span", { className: "font-mono text-sm", children: [
553
554
  formatMoney(
554
555
  item.unitPriceGross,
555
- item.currencyCode ?? currencyCode ?? void 0
556
+ item.currencyCode ?? currencyCode ?? void 0,
557
+ locale
556
558
  ),
557
559
  " ",
558
560
  /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t("sales.documents.items.table.gross", "gross") })
@@ -560,7 +562,8 @@ function SalesDocumentItemsSection({
560
562
  /* @__PURE__ */ jsxs("span", { className: "font-mono text-xs text-muted-foreground", children: [
561
563
  formatMoney(
562
564
  item.unitPriceNet,
563
- item.currencyCode ?? currencyCode ?? void 0
565
+ item.currencyCode ?? currencyCode ?? void 0,
566
+ locale
564
567
  ),
565
568
  " ",
566
569
  t("sales.documents.items.table.net", "net")
@@ -571,7 +574,8 @@ function SalesDocumentItemsSection({
571
574
  {
572
575
  value: formatMoney(
573
576
  unitPriceReference.grossPerReference,
574
- item.currencyCode ?? currencyCode ?? void 0
577
+ item.currencyCode ?? currencyCode ?? void 0,
578
+ locale
575
579
  ),
576
580
  unit: unitPriceReference.referenceUnitCode
577
581
  }
@@ -584,7 +588,8 @@ function SalesDocumentItemsSection({
584
588
  {
585
589
  value: formatMoney(
586
590
  discount.amount,
587
- item.currencyCode ?? currencyCode ?? void 0
591
+ item.currencyCode ?? currencyCode ?? void 0,
592
+ locale
588
593
  )
589
594
  }
590
595
  ) }) : null,
@@ -604,7 +609,8 @@ function SalesDocumentItemsSection({
604
609
  /* @__PURE__ */ jsxs("span", { children: [
605
610
  formatMoney(
606
611
  item.totalGross,
607
- item.currencyCode ?? currencyCode ?? void 0
612
+ item.currencyCode ?? currencyCode ?? void 0,
613
+ locale
608
614
  ),
609
615
  " ",
610
616
  /* @__PURE__ */ jsx("span", { className: "text-xs font-normal text-muted-foreground", children: t("sales.documents.items.table.gross", "gross") })
@@ -612,7 +618,8 @@ function SalesDocumentItemsSection({
612
618
  /* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-muted-foreground", children: [
613
619
  formatMoney(
614
620
  item.totalNet,
615
- item.currencyCode ?? currencyCode ?? void 0
621
+ item.currencyCode ?? currencyCode ?? void 0,
622
+ locale
616
623
  ),
617
624
  " ",
618
625
  t("sales.documents.items.table.net", "net")