@open-mercato/core 0.4.7-develop-d6331ed114 → 0.4.7-develop-1ac08bd793

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.
@@ -210,17 +210,13 @@ function SalesDocumentAdjustmentsSection({
210
210
  }, []);
211
211
  React.useEffect(() => {
212
212
  if (!onActionChange) return;
213
- if (!rows.length) {
214
- onActionChange(null);
215
- return () => onActionChange(null);
216
- }
217
213
  onActionChange({
218
214
  label: t("sales.documents.adjustments.add", "Add adjustment"),
219
215
  onClick: handleOpenCreate,
220
216
  disabled: false
221
217
  });
222
218
  return () => onActionChange(null);
223
- }, [handleOpenCreate, onActionChange, rows.length, t]);
219
+ }, [handleOpenCreate, onActionChange, t]);
224
220
  const handleFormSubmit = React.useCallback(
225
221
  async (values) => {
226
222
  if (!resolvedOrganizationId || !resolvedTenantId) {
@@ -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 { ColumnDef } from '@tanstack/react-table'\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 } from '@open-mercato/ui/backend/utils/apiCall'\nimport { createCrud, deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\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'\n\ntype AdjustmentRow = AdjustmentRowData\n\ntype SalesDocumentAdjustmentsSectionProps = {\n documentId: string\n kind: 'order' | 'quote'\n currencyCode: string | null | undefined\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 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 console.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 console.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 if (!rows.length) {\n onActionChange(null)\n return () => onActionChange(null)\n }\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, rows.length, 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 const result = await 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 if (result.ok) {\n await loadAdjustments()\n emitSalesDocumentTotalsRefresh({ documentId, kind })\n setDialogOpen(false)\n setActiveAdjustment(null)\n }\n },\n [\n currencyCode,\n documentId,\n documentKey,\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 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 if (result.ok) {\n await loadAdjustments()\n emitSalesDocumentTotalsRefresh({ documentId, kind })\n }\n } catch (err) {\n console.error('sales.document.adjustments.delete', err)\n flash(t('sales.documents.adjustments.errorDelete', 'Failed to delete adjustment.'), 'error')\n }\n },\n [crudResourcePath, documentId, documentKey, 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": ";AA+XU,SACE,KADF;AA3XV,YAAY,WAAW;AAEvB,SAAS,aAAa;AACtB,SAAS,iBAAiB;AAC1B,SAAS,cAAc,gBAAgB,qBAAqB;AAC5D,SAAS,aAAa;AACtB,SAAS,eAAe;AACxB,SAAS,YAAY,YAAY,kBAAkB;AACnD,SAAS,2BAA2B;AACpC,SAAS,kBAAkB;AAE3B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAGP,SAAS,yBAAyB;AAClC,SAAS,wBAA8E;AACvF,SAAS,YAAY;AACrB,SAAS,kCAAkC;AAC3C,SAAS,gCAAgC;AAczC,MAAM,kCAAyD;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,gBAAgB,OAAgB,WAAW,GAAW;AAC7D,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,QAAQ;AACpD,UAAM,SAAS,OAAO,KAAK;AAC3B,QAAI,CAAC,OAAO,MAAM,MAAM,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAA0C;AAC/D,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,QAAM,YAAY,IAAI,KAAK,aAAa,QAAW,EAAE,OAAO,WAAW,uBAAuB,EAAE,CAAC;AACjG,SAAO,UAAU,OAAO,QAAQ,GAAG;AACrC;AAEO,SAAS,gCAAgC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAyC;AACvC,QAAM,IAAI,KAAK;AACf,QAAM,EAAE,gBAAgB,SAAS,IAAI,2BAA2B;AAChE,QAAM,yBAAyB,gBAAgB,kBAAkB;AACjE,QAAM,mBAAmB,mBAAmB,YAAY;AACxD,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAA0B,CAAC,CAAC;AAC1D,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAwB,IAAI;AAC5D,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,KAAK;AACxD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAA+B,IAAI;AACzF,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAA6B,CAAC,CAAC;AAC3E,QAAM,iBAAiB,MAAM,OAAO,KAAK;AAEzC,QAAM,kBAAkB,MAAM;AAAA,IAC5B,MAAO,SAAS,UAAU,iCAAiC;AAAA,IAC3D,CAAC,IAAI;AAAA,EACP;AACA,QAAM,mBAAmB,MAAM;AAAA,IAC7B,MAAO,SAAS,UAAU,4BAA4B;AAAA,IACtD,CAAC,IAAI;AAAA,EACP;AACA,QAAM,cAAc,SAAS,UAAU,YAAY;AACnD,QAAM,sBAAsB,MAAM;AAAA,IAChC,MACE,gCAAgC,IAAI,CAAC,WAAW;AAAA,MAC9C;AAAA,MACA,OAAO,EAAE,0CAA0C,KAAK,IAAI,KAAK;AAAA,MACjE,OAAO;AAAA,MACP,MAAM;AAAA,IACR,EAAE;AAAA,IACJ,CAAC,CAAC;AAAA,EACJ;AACA,QAAM,gBAAgB,MAAM;AAAA,IAC1B,MACE,YAAY,OAAyC,CAAC,KAAK,UAAU;AACnE,UAAI,MAAM,KAAK,IAAI;AACnB,aAAO;AAAA,IACT,GAAG,CAAC,CAAC;AAAA,IACP,CAAC,WAAW;AAAA,EACd;AACA,QAAM,kBAAkB,MAAM,YAAY,YAAyC;AACjF,QAAI,YAAY,OAAQ,QAAO;AAC/B,QAAI,eAAe,QAAS,QAAO,YAAY,SAAS,cAAc;AACtE,mBAAe,UAAU;AACzB,QAAI;AACF,YAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,KAAK,UAAU,MAAM,CAAC;AACjE,YAAM,WAAW,MAAM;AAAA,QACrB,+BAA+B,OAAO,SAAS,CAAC;AAAA,QAChD;AAAA,QACA,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE;AAAA,MAC5B;AACA,YAAM,QAAQ,MAAM,QAAQ,SAAS,QAAQ,KAAK,IAAI,SAAS,OAAO,QAAQ,CAAC;AAC/E,YAAM,SAAS,MACZ,IAAI,CAAC,SAAS;AACb,cAAM,QAAQ,OAAQ,KAAa,UAAU,WAAY,KAAa,MAAM,KAAK,IAAI;AACrF,YAAI,CAAC,MAAO,QAAO;AACnB,cAAM,QACJ,OAAQ,KAAa,UAAU,YAAa,KAAa,MAAM,KAAK,EAAE,SACjE,KAAa,MAAM,KAAK,IACzB;AACN,cAAM,QACJ,OAAQ,KAAa,UAAU,YAAY,sBAAsB,KAAM,KAAa,KAAK,IACrF,IAAK,KAAa,MAAM,MAAM,CAAC,EAAE,YAAY,CAAC,KAC9C;AACN,cAAM,OACJ,OAAQ,KAAa,SAAS,YAAa,KAAa,KAAK,KAAK,EAAE,SAC/D,KAAa,KAAK,KAAK,IACxB;AACN,eAAO,EAAE,OAAO,OAAO,OAAO,KAAK;AAAA,MACrC,CAAC,EACA,OAAO,CAAC,UAAqC,QAAQ,KAAK,CAAC;AAC9D,YAAM,SAAS,oBAAI,IAA8B;AACjD,0BAAoB,QAAQ,CAAC,UAAU,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC;AACrE,aAAO,QAAQ,CAAC,UAAU,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC;AACxD,YAAM,UAAU,MAAM,KAAK,OAAO,OAAO,CAAC,EAAE;AAAA,QAAK,CAAC,GAAG,MACnD,EAAE,MAAM,cAAc,EAAE,OAAO,QAAW,EAAE,aAAa,OAAO,CAAC;AAAA,MACnE;AACA,qBAAe,OAAO;AACtB,qBAAe,UAAU;AACzB,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,gCAAgC,GAAG;AACjD,qBAAe,UAAU;AACzB,qBAAe,mBAAmB;AAClC,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,qBAAqB,WAAW,CAAC;AAErC,QAAM,UAAU,MAAM;AACpB,oBAAgB,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAClC,GAAG,CAAC,iBAAiB,wBAAwB,gBAAgB,CAAC;AAE9D,QAAM,kBAAkB,MAAM,YAAY,YAAY;AACpD,eAAW,IAAI;AACf,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,KAAK,UAAU,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;AAC5F,YAAM,WAAW,MAAM;AAAA,QACrB,GAAG,eAAe,IAAI,OAAO,SAAS,CAAC;AAAA,QACvC;AAAA,QACA,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE;AAAA,MAC5B;AACA,YAAM,QAAQ,MAAM,QAAQ,SAAS,QAAQ,KAAK,IAAI,SAAS,OAAO,QAAQ,CAAC;AAC/E,YAAM,SAA0B,MAC7B,IAAI,CAAC,SAAS;AACb,cAAM,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACnD,YAAI,CAAC,GAAI,QAAO;AAChB,cAAM,YAAY;AAAA,UACf,KAAa,cAAe,KAAa,aAAc,KAAa;AAAA,UACrE;AAAA,QACF;AACA,cAAM,cAAc;AAAA,UACjB,KAAa,gBAAiB,KAAa,eAAgB,KAAa;AAAA,UACzE;AAAA,QACF;AACA,cAAM,UAAU,gBAAiB,KAAa,MAAM,GAAG;AACvD,cAAM,YACJ,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,KAAK,EAAE,SAC7C,KAAK,KAAK,KAAK,IAChB;AACN,cAAM,WACJ,OAAQ,KAAa,kBAAkB,WAClC,KAAa,gBACd,OAAQ,KAAa,iBAAiB,WACnC,KAAa,eACd,gBAAgB;AACxB,cAAM,eAAe,yBAAyB,IAA+B;AAC7E,cAAM,mBACJ,OAAQ,KAAa,wBAAwB,WACxC,KAAa,sBACd,OAAQ,KAAa,qBAAqB,WACvC,KAAa,mBACd;AACR,cAAM,WACJ,OAAQ,KAAa,aAAa,YAAa,KAAa,WACtD,KAAa,WACf;AACN,eAAO;AAAA,UACL;AAAA,UACA,OAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,UACrD,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AAAA,UAClD,MAAM;AAAA,UACN,eACE,OAAQ,KAAa,mBAAmB,WACnC,KAAa,iBACd,OAAQ,KAAa,kBAAkB,WACpC,KAAa,gBACd;AAAA,UACR,MAAM,OAAO,SAAS,OAAO,IAAI,UAAU;AAAA,UAC3C,WAAW,OAAO,SAAS,SAAS,IAAI,YAAY;AAAA,UACpD,aAAa,OAAO,SAAS,WAAW,IAAI,cAAc;AAAA,UAC1D,cAAc;AAAA,UACd,UACE,OAAO,KAAK,aAAa,WACrB,KAAK,WACL,OAAQ,KAAa,aAAa,WAChC,OAAQ,KAAa,QAAQ,IAC7B;AAAA,UACR,cAAc,OAAO,KAAK,YAAY,EAAE,SAAS,eAAe;AAAA,UAChE;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC,EACA,OAAO,CAAC,UAAkC,QAAQ,KAAK,CAAC;AAC3D,YAAM,UAAU,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,YAAY,EAAE;AAChF,cAAQ,OAAO;AACf,UAAI,aAAc,cAAa,OAAO;AAAA,IACxC,SAAS,KAAK;AACZ,cAAQ,MAAM,mCAAmC,GAAG;AACpD,eAAS,EAAE,yCAAyC,6BAA6B,CAAC;AAAA,IACpF,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,iBAAiB,cAAc,YAAY,aAAa,cAAc,CAAC,CAAC;AAE5E,QAAM,UAAU,MAAM;AACpB,SAAK,gBAAgB;AAAA,EACvB,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM;AAAA,IACJ,MACE,oCAAoC,CAAC,WAAW;AAC9C,UAAI,OAAO,eAAe,WAAY;AACtC,UAAI,OAAO,QAAQ,OAAO,SAAS,KAAM;AACzC,WAAK,gBAAgB;AAAA,IACvB,CAAC;AAAA,IACH,CAAC,YAAY,MAAM,eAAe;AAAA,EACpC;AAEA,QAAM,mBAAmB,MAAM;AAAA,IAC7B,CAAC,cAAmC;AAClC,YAAM,SAAS,cAAc,SAAS;AACtC,UAAI,OAAQ,QAAO,OAAO;AAC1B,aAAO,EAAE,0CAA0C,SAAS,IAAI,OAAO,cAAc,WAAW,YAAY,OAAO,SAAS,CAAC;AAAA,IAC/H;AAAA,IACA,CAAC,eAAe,CAAC;AAAA,EACnB;AAEA,QAAM,mBAAmB,MAAM,YAAY,MAAM;AAC/C,wBAAoB,IAAI;AACxB,kBAAc,IAAI;AAAA,EACpB,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,MAAM,YAAY,CAAC,QAAuB;AAC3D,wBAAoB,GAAG;AACvB,kBAAc,IAAI;AAAA,EACpB,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB,MAAM,YAAY,MAAM;AAChD,kBAAc,KAAK;AACnB,wBAAoB,IAAI;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,eAAgB;AACrB,QAAI,CAAC,KAAK,QAAQ;AAChB,qBAAe,IAAI;AACnB,aAAO,MAAM,eAAe,IAAI;AAAA,IAClC;AACA,mBAAe;AAAA,MACb,OAAO,EAAE,mCAAmC,gBAAgB;AAAA,MAC5D,SAAS;AAAA,MACT,UAAU;AAAA,IACZ,CAAC;AACD,WAAO,MAAM,eAAe,IAAI;AAAA,EAClC,GAAG,CAAC,kBAAkB,gBAAgB,KAAK,QAAQ,CAAC,CAAC;AAErD,QAAM,mBAAmB,MAAM;AAAA,IAC7B,OAAO,WAAoC;AACzC,UAAI,CAAC,0BAA0B,CAAC,kBAAkB;AAChD,cAAM;AAAA,UACJ,EAAE,0CAA0C,uCAAuC;AAAA,QACrF;AAAA,MACF;AACA,YAAM,UAAmC;AAAA,QACvC,CAAC,WAAW,GAAG,OAAO,UAAU;AAAA,QAChC,gBAAgB,OAAO,sBAAsB;AAAA,QAC7C,UAAU,OAAO,gBAAgB;AAAA,QACjC,OAAO;AAAA,QACP,MAAM,OAAO,QAAQ;AAAA,QACrB,MAAM,OAAO,QAAQ;AAAA,QACrB,OAAO,OAAO,SAAS;AAAA,QACvB,eAAe,OAAO,iBAAiB;AAAA,QACvC,MAAM,OAAO,SAAS,OAAO,IAAI,IAAI,OAAO,OAAO;AAAA,QACnD,WAAW,OAAO,SAAS,OAAO,SAAS,IAAI,OAAO,YAAY;AAAA,QAClE,aAAa,OAAO,SAAS,OAAO,WAAW,IAAI,OAAO,cAAc;AAAA,QACxE,eAAe,OAAO,gBAAgB,gBAAgB,IAAI,YAAY;AAAA,QACtE,UAAU,OAAO,SAAS,OAAO,QAAQ,IAAI,OAAO,WAAW;AAAA,QAC/D,cAAc,OAAO,gBAAgB;AAAA,QACrC,UAAU,OAAO,YAAY;AAAA,MAC/B;AAEA,YAAM,SAAS,OAAO,KAAK,aAAa;AACxC,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA,OAAO,KAAK,EAAE,IAAI,OAAO,IAAI,GAAG,QAAQ,IAAI;AAAA,QAC5C;AAAA,UACE,gBAAgB,OAAO,KACnB,EAAE,uCAAuC,qBAAqB,IAC9D,EAAE,uCAAuC,mBAAmB;AAAA,UAChE,cAAc,EAAE,yCAAyC,4BAA4B;AAAA,QACvF;AAAA,MACF;AACA,UAAI,OAAO,IAAI;AACb,cAAM,gBAAgB;AACtB,uCAA+B,EAAE,YAAY,KAAK,CAAC;AACnD,sBAAc,KAAK;AACnB,4BAAoB,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB,OAAO,QAAuB;AAC5B,UAAI;AACF,cAAM,SAAS,MAAM,WAAW,kBAAkB;AAAA,UAChD,MAAM;AAAA,YACJ,IAAI,IAAI;AAAA,YACR,CAAC,WAAW,GAAG;AAAA,YACf,gBAAgB,0BAA0B;AAAA,YAC1C,UAAU,oBAAoB;AAAA,UAChC;AAAA,UACA,cAAc,EAAE,2CAA2C,8BAA8B;AAAA,QAC3F,CAAC;AACD,YAAI,OAAO,IAAI;AACb,gBAAM,gBAAgB;AACtB,yCAA+B,EAAE,YAAY,KAAK,CAAC;AAAA,QACrD;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,qCAAqC,GAAG;AACtD,cAAM,EAAE,2CAA2C,8BAA8B,GAAG,OAAO;AAAA,MAC7F;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,YAAY,aAAa,MAAM,iBAAiB,wBAAwB,kBAAkB,CAAC;AAAA,EAChH;AAEA,QAAM,UAAU,MAAM;AAAA,IACpB,MAAM;AAAA,MACJ;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,qCAAqC,OAAO;AAAA,QACtD,MAAM,CAAC,EAAE,IAAI,MACX,qBAAC,SAAI,WAAU,iBACb;AAAA,8BAAC,UAAK,WAAU,+BAA+B,cAAI,SAAS,SAAS,EAAE,wCAAwC,UAAU,GAAE;AAAA,UAC1H,IAAI,SAAS,OAAO,oBAAC,UAAK,WAAU,iCAAiC,cAAI,SAAS,MAAK,IAAU;AAAA,WACpG;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,yCAAyC,MAAM;AAAA,QACzD,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,SAAM,SAAQ,WAAW,2BAAiB,IAAI,SAAS,IAAI,GAAE;AAAA,MACnF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,yCAAyC,YAAY;AAAA,QAC/D,MAAM,CAAC,EAAE,IAAI,MACX,oBAAC,qBAAkB,QAAQ,IAAI,SAAS,WAAW,UAAU,IAAI,SAAS,gBAAgB,cAAc,WAAU,qBAAoB;AAAA,MAE1I;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,2CAA2C,cAAc;AAAA,QACnE,MAAM,CAAC,EAAE,IAAI,MACX,oBAAC,qBAAkB,QAAQ,IAAI,SAAS,aAAa,UAAU,IAAI,SAAS,gBAAgB,cAAc,WAAU,qBAAoB;AAAA,MAE5I;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,oCAAoC,MAAM;AAAA,QACpD,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,UAAK,WAAU,2CAA2C,wBAAc,IAAI,SAAS,IAAI,GAAE;AAAA,MACjH;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,wCAAwC,UAAU;AAAA,QAC5D,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,UAAK,WAAU,iCAAiC,cAAI,SAAS,UAAS;AAAA,MAC5F;AAAA,IACF;AAAA,IACA,CAAC,cAAc,kBAAkB,CAAC;AAAA,EACpC;AAEA,QAAM,mBAAmB,WAAW,KAAK,WAAW;AAEpD,QAAM,mBAAmB,MAAM;AAAA,IAC7B,CAAC,QACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL;AAAA,YACE,IAAI;AAAA,YACJ,OAAO,EAAE,mBAAmB,MAAM;AAAA,YAClC,UAAU,MAAM,WAAW,GAAG;AAAA,UAChC;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO,EAAE,qBAAqB,QAAQ;AAAA,YACtC,aAAa;AAAA,YACb,UAAU,MAAM,aAAa,GAAG;AAAA,UAClC;AAAA,QACF;AAAA;AAAA,IACF;AAAA,IAEF,CAAC,cAAc,YAAY,CAAC;AAAA,EAC9B;AAEA,SACE,qBAAC,SAAI,WAAU,aACZ;AAAA,YACC,oBAAC,gBAAa,OAAO,EAAE,yCAAyC,6BAA6B,GAAG,aAAa,OAAO,SAAS,MAAM,KAAK,gBAAgB,GAAG,IACzJ;AAAA,IACH,mBACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,uCAAuC,2BAAsB;AAAA,QACtE,WAAU;AAAA;AAAA,IACZ,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN;AAAA,QACA,WAAW,WAAW,KAAK,SAAS;AAAA,QACpC,UAAQ;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YACE;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,EAAE,2CAA2C,qBAAqB;AAAA,YACzE,aAAa,EAAE,iDAAiD,iDAAiD;AAAA,YACjH,aAAa,EAAE,mCAAmC,gBAAgB;AAAA,YAClE,UAAU;AAAA;AAAA,QACZ;AAAA;AAAA,IAEJ;AAAA,IAGF;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,cAAc,CAAC,SAAS;AACtB,cAAI,CAAC,MAAM;AACT,8BAAkB;AAAA,UACpB,OAAO;AACL,0BAAc,IAAI;AAAA,UACpB;AAAA,QACF;AAAA,QACA;AAAA,QACA,cAAc,gBAAgB;AAAA,QAC9B,aAAa,YAAY,SAAS,cAAc;AAAA,QAChD;AAAA,QACA,QAAQ;AAAA,UACN,UAAU,EAAE,wCAAwC,gBAAgB;AAAA,UACpE,WAAW,EAAE,yCAAyC,iBAAiB;AAAA,UACvE,cAAc,EAAE,4CAA4C,gBAAgB;AAAA,UAC5E,cAAc,EAAE,4CAA4C,cAAc;AAAA,QAC5E;AAAA,QACA,mBAAmB;AAAA,QACnB,UAAU;AAAA;AAAA,IACZ;AAAA,KACF;AAEJ;",
4
+ "sourcesContent": ["// @ts-nocheck\n\n\"use client\"\n\nimport * as React from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\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 } from '@open-mercato/ui/backend/utils/apiCall'\nimport { createCrud, deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\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'\n\ntype AdjustmentRow = AdjustmentRowData\n\ntype SalesDocumentAdjustmentsSectionProps = {\n documentId: string\n kind: 'order' | 'quote'\n currencyCode: string | null | undefined\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 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 console.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 console.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 const result = await 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 if (result.ok) {\n await loadAdjustments()\n emitSalesDocumentTotalsRefresh({ documentId, kind })\n setDialogOpen(false)\n setActiveAdjustment(null)\n }\n },\n [\n currencyCode,\n documentId,\n documentKey,\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 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 if (result.ok) {\n await loadAdjustments()\n emitSalesDocumentTotalsRefresh({ documentId, kind })\n }\n } catch (err) {\n console.error('sales.document.adjustments.delete', err)\n flash(t('sales.documents.adjustments.errorDelete', 'Failed to delete adjustment.'), 'error')\n }\n },\n [crudResourcePath, documentId, documentKey, 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": ";AA2XU,SACE,KADF;AAvXV,YAAY,WAAW;AAEvB,SAAS,aAAa;AACtB,SAAS,iBAAiB;AAC1B,SAAS,cAAc,gBAAgB,qBAAqB;AAC5D,SAAS,aAAa;AACtB,SAAS,eAAe;AACxB,SAAS,YAAY,YAAY,kBAAkB;AACnD,SAAS,2BAA2B;AACpC,SAAS,kBAAkB;AAE3B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAGP,SAAS,yBAAyB;AAClC,SAAS,wBAA8E;AACvF,SAAS,YAAY;AACrB,SAAS,kCAAkC;AAC3C,SAAS,gCAAgC;AAczC,MAAM,kCAAyD;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,gBAAgB,OAAgB,WAAW,GAAW;AAC7D,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,QAAQ;AACpD,UAAM,SAAS,OAAO,KAAK;AAC3B,QAAI,CAAC,OAAO,MAAM,MAAM,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAA0C;AAC/D,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,QAAM,YAAY,IAAI,KAAK,aAAa,QAAW,EAAE,OAAO,WAAW,uBAAuB,EAAE,CAAC;AACjG,SAAO,UAAU,OAAO,QAAQ,GAAG;AACrC;AAEO,SAAS,gCAAgC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAyC;AACvC,QAAM,IAAI,KAAK;AACf,QAAM,EAAE,gBAAgB,SAAS,IAAI,2BAA2B;AAChE,QAAM,yBAAyB,gBAAgB,kBAAkB;AACjE,QAAM,mBAAmB,mBAAmB,YAAY;AACxD,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAA0B,CAAC,CAAC;AAC1D,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAwB,IAAI;AAC5D,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,KAAK;AACxD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAA+B,IAAI;AACzF,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAA6B,CAAC,CAAC;AAC3E,QAAM,iBAAiB,MAAM,OAAO,KAAK;AAEzC,QAAM,kBAAkB,MAAM;AAAA,IAC5B,MAAO,SAAS,UAAU,iCAAiC;AAAA,IAC3D,CAAC,IAAI;AAAA,EACP;AACA,QAAM,mBAAmB,MAAM;AAAA,IAC7B,MAAO,SAAS,UAAU,4BAA4B;AAAA,IACtD,CAAC,IAAI;AAAA,EACP;AACA,QAAM,cAAc,SAAS,UAAU,YAAY;AACnD,QAAM,sBAAsB,MAAM;AAAA,IAChC,MACE,gCAAgC,IAAI,CAAC,WAAW;AAAA,MAC9C;AAAA,MACA,OAAO,EAAE,0CAA0C,KAAK,IAAI,KAAK;AAAA,MACjE,OAAO;AAAA,MACP,MAAM;AAAA,IACR,EAAE;AAAA,IACJ,CAAC,CAAC;AAAA,EACJ;AACA,QAAM,gBAAgB,MAAM;AAAA,IAC1B,MACE,YAAY,OAAyC,CAAC,KAAK,UAAU;AACnE,UAAI,MAAM,KAAK,IAAI;AACnB,aAAO;AAAA,IACT,GAAG,CAAC,CAAC;AAAA,IACP,CAAC,WAAW;AAAA,EACd;AACA,QAAM,kBAAkB,MAAM,YAAY,YAAyC;AACjF,QAAI,YAAY,OAAQ,QAAO;AAC/B,QAAI,eAAe,QAAS,QAAO,YAAY,SAAS,cAAc;AACtE,mBAAe,UAAU;AACzB,QAAI;AACF,YAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,KAAK,UAAU,MAAM,CAAC;AACjE,YAAM,WAAW,MAAM;AAAA,QACrB,+BAA+B,OAAO,SAAS,CAAC;AAAA,QAChD;AAAA,QACA,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE;AAAA,MAC5B;AACA,YAAM,QAAQ,MAAM,QAAQ,SAAS,QAAQ,KAAK,IAAI,SAAS,OAAO,QAAQ,CAAC;AAC/E,YAAM,SAAS,MACZ,IAAI,CAAC,SAAS;AACb,cAAM,QAAQ,OAAQ,KAAa,UAAU,WAAY,KAAa,MAAM,KAAK,IAAI;AACrF,YAAI,CAAC,MAAO,QAAO;AACnB,cAAM,QACJ,OAAQ,KAAa,UAAU,YAAa,KAAa,MAAM,KAAK,EAAE,SACjE,KAAa,MAAM,KAAK,IACzB;AACN,cAAM,QACJ,OAAQ,KAAa,UAAU,YAAY,sBAAsB,KAAM,KAAa,KAAK,IACrF,IAAK,KAAa,MAAM,MAAM,CAAC,EAAE,YAAY,CAAC,KAC9C;AACN,cAAM,OACJ,OAAQ,KAAa,SAAS,YAAa,KAAa,KAAK,KAAK,EAAE,SAC/D,KAAa,KAAK,KAAK,IACxB;AACN,eAAO,EAAE,OAAO,OAAO,OAAO,KAAK;AAAA,MACrC,CAAC,EACA,OAAO,CAAC,UAAqC,QAAQ,KAAK,CAAC;AAC9D,YAAM,SAAS,oBAAI,IAA8B;AACjD,0BAAoB,QAAQ,CAAC,UAAU,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC;AACrE,aAAO,QAAQ,CAAC,UAAU,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC;AACxD,YAAM,UAAU,MAAM,KAAK,OAAO,OAAO,CAAC,EAAE;AAAA,QAAK,CAAC,GAAG,MACnD,EAAE,MAAM,cAAc,EAAE,OAAO,QAAW,EAAE,aAAa,OAAO,CAAC;AAAA,MACnE;AACA,qBAAe,OAAO;AACtB,qBAAe,UAAU;AACzB,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,gCAAgC,GAAG;AACjD,qBAAe,UAAU;AACzB,qBAAe,mBAAmB;AAClC,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,qBAAqB,WAAW,CAAC;AAErC,QAAM,UAAU,MAAM;AACpB,oBAAgB,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAClC,GAAG,CAAC,iBAAiB,wBAAwB,gBAAgB,CAAC;AAE9D,QAAM,kBAAkB,MAAM,YAAY,YAAY;AACpD,eAAW,IAAI;AACf,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,KAAK,UAAU,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;AAC5F,YAAM,WAAW,MAAM;AAAA,QACrB,GAAG,eAAe,IAAI,OAAO,SAAS,CAAC;AAAA,QACvC;AAAA,QACA,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE;AAAA,MAC5B;AACA,YAAM,QAAQ,MAAM,QAAQ,SAAS,QAAQ,KAAK,IAAI,SAAS,OAAO,QAAQ,CAAC;AAC/E,YAAM,SAA0B,MAC7B,IAAI,CAAC,SAAS;AACb,cAAM,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACnD,YAAI,CAAC,GAAI,QAAO;AAChB,cAAM,YAAY;AAAA,UACf,KAAa,cAAe,KAAa,aAAc,KAAa;AAAA,UACrE;AAAA,QACF;AACA,cAAM,cAAc;AAAA,UACjB,KAAa,gBAAiB,KAAa,eAAgB,KAAa;AAAA,UACzE;AAAA,QACF;AACA,cAAM,UAAU,gBAAiB,KAAa,MAAM,GAAG;AACvD,cAAM,YACJ,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,KAAK,EAAE,SAC7C,KAAK,KAAK,KAAK,IAChB;AACN,cAAM,WACJ,OAAQ,KAAa,kBAAkB,WAClC,KAAa,gBACd,OAAQ,KAAa,iBAAiB,WACnC,KAAa,eACd,gBAAgB;AACxB,cAAM,eAAe,yBAAyB,IAA+B;AAC7E,cAAM,mBACJ,OAAQ,KAAa,wBAAwB,WACxC,KAAa,sBACd,OAAQ,KAAa,qBAAqB,WACvC,KAAa,mBACd;AACR,cAAM,WACJ,OAAQ,KAAa,aAAa,YAAa,KAAa,WACtD,KAAa,WACf;AACN,eAAO;AAAA,UACL;AAAA,UACA,OAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,UACrD,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AAAA,UAClD,MAAM;AAAA,UACN,eACE,OAAQ,KAAa,mBAAmB,WACnC,KAAa,iBACd,OAAQ,KAAa,kBAAkB,WACpC,KAAa,gBACd;AAAA,UACR,MAAM,OAAO,SAAS,OAAO,IAAI,UAAU;AAAA,UAC3C,WAAW,OAAO,SAAS,SAAS,IAAI,YAAY;AAAA,UACpD,aAAa,OAAO,SAAS,WAAW,IAAI,cAAc;AAAA,UAC1D,cAAc;AAAA,UACd,UACE,OAAO,KAAK,aAAa,WACrB,KAAK,WACL,OAAQ,KAAa,aAAa,WAChC,OAAQ,KAAa,QAAQ,IAC7B;AAAA,UACR,cAAc,OAAO,KAAK,YAAY,EAAE,SAAS,eAAe;AAAA,UAChE;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC,EACA,OAAO,CAAC,UAAkC,QAAQ,KAAK,CAAC;AAC3D,YAAM,UAAU,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,YAAY,EAAE;AAChF,cAAQ,OAAO;AACf,UAAI,aAAc,cAAa,OAAO;AAAA,IACxC,SAAS,KAAK;AACZ,cAAQ,MAAM,mCAAmC,GAAG;AACpD,eAAS,EAAE,yCAAyC,6BAA6B,CAAC;AAAA,IACpF,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,iBAAiB,cAAc,YAAY,aAAa,cAAc,CAAC,CAAC;AAE5E,QAAM,UAAU,MAAM;AACpB,SAAK,gBAAgB;AAAA,EACvB,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM;AAAA,IACJ,MACE,oCAAoC,CAAC,WAAW;AAC9C,UAAI,OAAO,eAAe,WAAY;AACtC,UAAI,OAAO,QAAQ,OAAO,SAAS,KAAM;AACzC,WAAK,gBAAgB;AAAA,IACvB,CAAC;AAAA,IACH,CAAC,YAAY,MAAM,eAAe;AAAA,EACpC;AAEA,QAAM,mBAAmB,MAAM;AAAA,IAC7B,CAAC,cAAmC;AAClC,YAAM,SAAS,cAAc,SAAS;AACtC,UAAI,OAAQ,QAAO,OAAO;AAC1B,aAAO,EAAE,0CAA0C,SAAS,IAAI,OAAO,cAAc,WAAW,YAAY,OAAO,SAAS,CAAC;AAAA,IAC/H;AAAA,IACA,CAAC,eAAe,CAAC;AAAA,EACnB;AAEA,QAAM,mBAAmB,MAAM,YAAY,MAAM;AAC/C,wBAAoB,IAAI;AACxB,kBAAc,IAAI;AAAA,EACpB,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,MAAM,YAAY,CAAC,QAAuB;AAC3D,wBAAoB,GAAG;AACvB,kBAAc,IAAI;AAAA,EACpB,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB,MAAM,YAAY,MAAM;AAChD,kBAAc,KAAK;AACnB,wBAAoB,IAAI;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,eAAgB;AACrB,mBAAe;AAAA,MACb,OAAO,EAAE,mCAAmC,gBAAgB;AAAA,MAC5D,SAAS;AAAA,MACT,UAAU;AAAA,IACZ,CAAC;AACD,WAAO,MAAM,eAAe,IAAI;AAAA,EAClC,GAAG,CAAC,kBAAkB,gBAAgB,CAAC,CAAC;AAExC,QAAM,mBAAmB,MAAM;AAAA,IAC7B,OAAO,WAAoC;AACzC,UAAI,CAAC,0BAA0B,CAAC,kBAAkB;AAChD,cAAM;AAAA,UACJ,EAAE,0CAA0C,uCAAuC;AAAA,QACrF;AAAA,MACF;AACA,YAAM,UAAmC;AAAA,QACvC,CAAC,WAAW,GAAG,OAAO,UAAU;AAAA,QAChC,gBAAgB,OAAO,sBAAsB;AAAA,QAC7C,UAAU,OAAO,gBAAgB;AAAA,QACjC,OAAO;AAAA,QACP,MAAM,OAAO,QAAQ;AAAA,QACrB,MAAM,OAAO,QAAQ;AAAA,QACrB,OAAO,OAAO,SAAS;AAAA,QACvB,eAAe,OAAO,iBAAiB;AAAA,QACvC,MAAM,OAAO,SAAS,OAAO,IAAI,IAAI,OAAO,OAAO;AAAA,QACnD,WAAW,OAAO,SAAS,OAAO,SAAS,IAAI,OAAO,YAAY;AAAA,QAClE,aAAa,OAAO,SAAS,OAAO,WAAW,IAAI,OAAO,cAAc;AAAA,QACxE,eAAe,OAAO,gBAAgB,gBAAgB,IAAI,YAAY;AAAA,QACtE,UAAU,OAAO,SAAS,OAAO,QAAQ,IAAI,OAAO,WAAW;AAAA,QAC/D,cAAc,OAAO,gBAAgB;AAAA,QACrC,UAAU,OAAO,YAAY;AAAA,MAC/B;AAEA,YAAM,SAAS,OAAO,KAAK,aAAa;AACxC,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA,OAAO,KAAK,EAAE,IAAI,OAAO,IAAI,GAAG,QAAQ,IAAI;AAAA,QAC5C;AAAA,UACE,gBAAgB,OAAO,KACnB,EAAE,uCAAuC,qBAAqB,IAC9D,EAAE,uCAAuC,mBAAmB;AAAA,UAChE,cAAc,EAAE,yCAAyC,4BAA4B;AAAA,QACvF;AAAA,MACF;AACA,UAAI,OAAO,IAAI;AACb,cAAM,gBAAgB;AACtB,uCAA+B,EAAE,YAAY,KAAK,CAAC;AACnD,sBAAc,KAAK;AACnB,4BAAoB,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB,OAAO,QAAuB;AAC5B,UAAI;AACF,cAAM,SAAS,MAAM,WAAW,kBAAkB;AAAA,UAChD,MAAM;AAAA,YACJ,IAAI,IAAI;AAAA,YACR,CAAC,WAAW,GAAG;AAAA,YACf,gBAAgB,0BAA0B;AAAA,YAC1C,UAAU,oBAAoB;AAAA,UAChC;AAAA,UACA,cAAc,EAAE,2CAA2C,8BAA8B;AAAA,QAC3F,CAAC;AACD,YAAI,OAAO,IAAI;AACb,gBAAM,gBAAgB;AACtB,yCAA+B,EAAE,YAAY,KAAK,CAAC;AAAA,QACrD;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,qCAAqC,GAAG;AACtD,cAAM,EAAE,2CAA2C,8BAA8B,GAAG,OAAO;AAAA,MAC7F;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,YAAY,aAAa,MAAM,iBAAiB,wBAAwB,kBAAkB,CAAC;AAAA,EAChH;AAEA,QAAM,UAAU,MAAM;AAAA,IACpB,MAAM;AAAA,MACJ;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,qCAAqC,OAAO;AAAA,QACtD,MAAM,CAAC,EAAE,IAAI,MACX,qBAAC,SAAI,WAAU,iBACb;AAAA,8BAAC,UAAK,WAAU,+BAA+B,cAAI,SAAS,SAAS,EAAE,wCAAwC,UAAU,GAAE;AAAA,UAC1H,IAAI,SAAS,OAAO,oBAAC,UAAK,WAAU,iCAAiC,cAAI,SAAS,MAAK,IAAU;AAAA,WACpG;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,yCAAyC,MAAM;AAAA,QACzD,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,SAAM,SAAQ,WAAW,2BAAiB,IAAI,SAAS,IAAI,GAAE;AAAA,MACnF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,yCAAyC,YAAY;AAAA,QAC/D,MAAM,CAAC,EAAE,IAAI,MACX,oBAAC,qBAAkB,QAAQ,IAAI,SAAS,WAAW,UAAU,IAAI,SAAS,gBAAgB,cAAc,WAAU,qBAAoB;AAAA,MAE1I;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,2CAA2C,cAAc;AAAA,QACnE,MAAM,CAAC,EAAE,IAAI,MACX,oBAAC,qBAAkB,QAAQ,IAAI,SAAS,aAAa,UAAU,IAAI,SAAS,gBAAgB,cAAc,WAAU,qBAAoB;AAAA,MAE5I;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,oCAAoC,MAAM;AAAA,QACpD,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,UAAK,WAAU,2CAA2C,wBAAc,IAAI,SAAS,IAAI,GAAE;AAAA,MACjH;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,wCAAwC,UAAU;AAAA,QAC5D,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,UAAK,WAAU,iCAAiC,cAAI,SAAS,UAAS;AAAA,MAC5F;AAAA,IACF;AAAA,IACA,CAAC,cAAc,kBAAkB,CAAC;AAAA,EACpC;AAEA,QAAM,mBAAmB,WAAW,KAAK,WAAW;AAEpD,QAAM,mBAAmB,MAAM;AAAA,IAC7B,CAAC,QACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL;AAAA,YACE,IAAI;AAAA,YACJ,OAAO,EAAE,mBAAmB,MAAM;AAAA,YAClC,UAAU,MAAM,WAAW,GAAG;AAAA,UAChC;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO,EAAE,qBAAqB,QAAQ;AAAA,YACtC,aAAa;AAAA,YACb,UAAU,MAAM,aAAa,GAAG;AAAA,UAClC;AAAA,QACF;AAAA;AAAA,IACF;AAAA,IAEF,CAAC,cAAc,YAAY,CAAC;AAAA,EAC9B;AAEA,SACE,qBAAC,SAAI,WAAU,aACZ;AAAA,YACC,oBAAC,gBAAa,OAAO,EAAE,yCAAyC,6BAA6B,GAAG,aAAa,OAAO,SAAS,MAAM,KAAK,gBAAgB,GAAG,IACzJ;AAAA,IACH,mBACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,uCAAuC,2BAAsB;AAAA,QACtE,WAAU;AAAA;AAAA,IACZ,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN;AAAA,QACA,WAAW,WAAW,KAAK,SAAS;AAAA,QACpC,UAAQ;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YACE;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,EAAE,2CAA2C,qBAAqB;AAAA,YACzE,aAAa,EAAE,iDAAiD,iDAAiD;AAAA,YACjH,aAAa,EAAE,mCAAmC,gBAAgB;AAAA,YAClE,UAAU;AAAA;AAAA,QACZ;AAAA;AAAA,IAEJ;AAAA,IAGF;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,cAAc,CAAC,SAAS;AACtB,cAAI,CAAC,MAAM;AACT,8BAAkB;AAAA,UACpB,OAAO;AACL,0BAAc,IAAI;AAAA,UACpB;AAAA,QACF;AAAA,QACA;AAAA,QACA,cAAc,gBAAgB;AAAA,QAC9B,aAAa,YAAY,SAAS,cAAc;AAAA,QAChD;AAAA,QACA,QAAQ;AAAA,UACN,UAAU,EAAE,wCAAwC,gBAAgB;AAAA,UACpE,WAAW,EAAE,yCAAyC,iBAAiB;AAAA,UACvE,cAAc,EAAE,4CAA4C,gBAAgB;AAAA,UAC5E,cAAc,EAAE,4CAA4C,cAAc;AAAA,QAC5E;AAAA,QACA,mBAAmB;AAAA,QACnB,UAAU;AAAA;AAAA,IACZ;AAAA,KACF;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -266,17 +266,13 @@ function SalesDocumentItemsSection({
266
266
  }, []);
267
267
  React.useEffect(() => {
268
268
  if (!onActionChange) return;
269
- if (items.length === 0) {
270
- onActionChange(null);
271
- return;
272
- }
273
269
  onActionChange({
274
270
  label: t("sales.documents.items.add", "Add item"),
275
271
  onClick: openCreate,
276
272
  disabled: false
277
273
  });
278
274
  return () => onActionChange(null);
279
- }, [items.length, onActionChange, openCreate, t]);
275
+ }, [onActionChange, openCreate, t]);
280
276
  const handleEdit = React.useCallback((line) => {
281
277
  setLineForEdit(line);
282
278
  setDialogOpen(true);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/sales/components/documents/ItemsSection.tsx"],
4
- "sourcesContent": ["\"use client\";\n\nimport * as React from \"react\";\nimport { apiCall } from \"@open-mercato/ui/backend/utils/apiCall\";\nimport { deleteCrud } from \"@open-mercato/ui/backend/utils/crud\";\nimport { normalizeCrudServerError } from \"@open-mercato/ui/backend/utils/serverErrors\";\nimport { LoadingMessage, TabEmptyState } from \"@open-mercato/ui/backend/detail\";\nimport { Button } from \"@open-mercato/ui/primitives/button\";\nimport { flash } from \"@open-mercato/ui/backend/FlashMessages\";\nimport { Pencil, Trash2 } from \"lucide-react\";\nimport {\n DictionaryValue,\n type DictionaryMap,\n createDictionaryMap,\n normalizeDictionaryEntries,\n} from \"@open-mercato/core/modules/dictionaries/components/dictionaryAppearance\";\nimport { useT } from \"@open-mercato/shared/lib/i18n/context\";\nimport { useOrganizationScopeDetail } from \"@open-mercato/shared/lib/frontend/useOrganizationScope\";\nimport { useConfirmDialog } from \"@open-mercato/ui/backend/confirm-dialog\";\nimport { emitSalesDocumentTotalsRefresh } from \"@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents\";\nimport { LineItemDialog } from \"./LineItemDialog\";\nimport type { SalesLineRecord } from \"./lineItemTypes\";\nimport { formatMoney, normalizeNumber } from \"./lineItemUtils\";\nimport type { SectionAction } from \"@open-mercato/ui/backend/detail\";\nimport { extractCustomFieldValues } from \"./customFieldHelpers\";\nimport { canonicalizeUnitCode } from \"@open-mercato/shared/lib/units/unitCodes\";\nimport type { SalesLineUomSnapshot } from \"../../lib/types\";\n\ntype ResolvedUnitPriceReference = {\n grossPerReference: number;\n referenceUnitCode: string;\n};\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isSalesLineUomSnapshot(\n value: unknown,\n): value is SalesLineUomSnapshot {\n if (!isPlainObject(value)) return false;\n return (\n value.version === 1 &&\n typeof value.enteredQuantity === \"string\" &&\n typeof value.toBaseFactor === \"string\" &&\n typeof value.normalizedQuantity === \"string\"\n );\n}\n\nfunction extractUomSnapshot(\n item: Record<string, unknown>,\n): SalesLineUomSnapshot | null {\n const raw = item.uom_snapshot ?? item.uomSnapshot;\n if (isSalesLineUomSnapshot(raw)) return raw;\n return null;\n}\n\nfunction resolveUnitPriceReference(\n snapshot: SalesLineUomSnapshot | Record<string, unknown> | null,\n): ResolvedUnitPriceReference | null {\n if (!snapshot) return null;\n\n const ref = isSalesLineUomSnapshot(snapshot)\n ? snapshot.unitPriceReference\n : isPlainObject(snapshot)\n ? isPlainObject(snapshot.unitPriceReference)\n ? snapshot.unitPriceReference\n : isPlainObject(snapshot.unit_price_reference)\n ? snapshot.unit_price_reference\n : null\n : null;\n\n if (!ref || !isPlainObject(ref)) return null;\n\n const refRecord = ref as Record<string, unknown>;\n const grossPerReference = normalizeNumber(\n refRecord.grossPerReference ?? refRecord.gross_per_reference,\n Number.NaN,\n );\n if (!Number.isFinite(grossPerReference)) return null;\n\n const referenceUnitCode =\n typeof refRecord.referenceUnitCode === \"string\"\n ? refRecord.referenceUnitCode\n : typeof refRecord.reference_unit_code === \"string\"\n ? refRecord.reference_unit_code\n : typeof refRecord.referenceUnit === \"string\"\n ? refRecord.referenceUnit\n : null;\n if (!referenceUnitCode) return null;\n\n return { grossPerReference, referenceUnitCode };\n}\n\nfunction getUomFields(item: Record<string, unknown>) {\n const uomSnapshot = extractUomSnapshot(item);\n return {\n normalizedQuantity: (item.normalized_quantity ?? item.normalizedQuantity ?? null) as\n | number\n | string\n | null,\n normalizedUnit: (item.normalized_unit ?? item.normalizedUnit ?? null) as string | null,\n quantityUnit: (item.quantity_unit ?? item.quantityUnit ?? null) as string | null,\n uomSnapshot,\n };\n}\n\ntype SalesDocumentItemsSectionProps = {\n documentId: string;\n kind: \"order\" | \"quote\";\n currencyCode: string | null | undefined;\n organizationId?: string | null;\n tenantId?: string | null;\n onActionChange?: (action: SectionAction | null) => void;\n onItemsChange?: (items: SalesLineRecord[]) => void;\n};\n\nexport function SalesDocumentItemsSection({\n documentId,\n kind,\n currencyCode,\n organizationId: orgFromProps,\n tenantId: tenantFromProps,\n onActionChange,\n onItemsChange,\n}: SalesDocumentItemsSectionProps) {\n const t = useT();\n const { organizationId, tenantId } = useOrganizationScopeDetail();\n const { confirm, ConfirmDialogElement } = useConfirmDialog();\n const resolvedOrganizationId = orgFromProps ?? organizationId ?? null;\n const resolvedTenantId = tenantFromProps ?? tenantId ?? null;\n const [items, setItems] = React.useState<SalesLineRecord[]>([]);\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 [lineForEdit, setLineForEdit] = React.useState<SalesLineRecord | null>(\n null,\n );\n const [lineStatusMap, setLineStatusMap] = React.useState<DictionaryMap>({});\n const [shippedTotals, setShippedTotals] = React.useState<Map<string, number>>(\n new Map(),\n );\n\n const resourcePath = React.useMemo(\n () => (kind === \"order\" ? \"sales/order-lines\" : \"sales/quote-lines\"),\n [kind],\n );\n const documentKey = kind === \"order\" ? \"orderId\" : \"quoteId\";\n const lineStatusesLoaded = React.useRef(false);\n const itemsLoadedForDocument = React.useRef<string | null>(null);\n const shipmentsLoadedForDocument = React.useRef<string | null>(null);\n const loadLineStatuses = React.useCallback(async () => {\n try {\n const params = new URLSearchParams({ page: \"1\", pageSize: \"100\" });\n const response = await apiCall<{\n items?: Array<Record<string, unknown>>;\n }>(`/api/sales/order-line-statuses?${params.toString()}`, undefined, {\n fallback: { items: [] },\n });\n const entries = normalizeDictionaryEntries(response.result?.items ?? []);\n setLineStatusMap(createDictionaryMap(entries));\n } catch (err) {\n console.error(\"sales.document.line-statuses.load\", err);\n setLineStatusMap({});\n }\n }, []);\n\n const loadItems = React.useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const params = new URLSearchParams({\n page: \"1\",\n pageSize: \"100\",\n [documentKey]: documentId,\n });\n const response = await apiCall<{\n items?: Array<Record<string, unknown>>;\n }>(`/api/${resourcePath}?${params.toString()}`, undefined, {\n fallback: { items: [] },\n });\n if (response.ok && Array.isArray(response.result?.items)) {\n const mapped = response.result.items.flatMap<SalesLineRecord>(\n (item) => {\n const id = typeof item.id === \"string\" ? item.id : null;\n if (!id) return [];\n const taxRate = normalizeNumber(\n item.tax_rate ?? item.taxRate,\n 0,\n );\n const customFields = extractCustomFieldValues(\n item as Record<string, unknown>,\n );\n const name =\n typeof item.name === \"string\"\n ? item.name\n : typeof item.catalog_snapshot === \"object\" &&\n item.catalog_snapshot &&\n typeof (item.catalog_snapshot as Record<string, unknown>).name === \"string\"\n ? (item.catalog_snapshot as Record<string, unknown>).name as string\n : null;\n const quantity = normalizeNumber(item.quantity, 0);\n const uomFields = getUomFields(item);\n const quantityUnit = canonicalizeUnitCode(uomFields.quantityUnit);\n const normalizedQuantity = normalizeNumber(\n uomFields.normalizedQuantity,\n quantity,\n );\n const normalizedUnit =\n canonicalizeUnitCode(uomFields.normalizedUnit) ?? quantityUnit;\n const uomSnapshot = uomFields.uomSnapshot;\n const unitPriceNetRaw = normalizeNumber(\n item.unit_price_net ?? item.unitPriceNet,\n Number.NaN,\n );\n const unitPriceGrossRaw = normalizeNumber(\n item.unit_price_gross ?? item.unitPriceGross,\n Number.NaN,\n );\n const unitPriceNet = Number.isFinite(unitPriceNetRaw)\n ? unitPriceNetRaw\n : Number.isFinite(unitPriceGrossRaw)\n ? unitPriceGrossRaw / (1 + taxRate / 100)\n : 0;\n const unitPriceGross = Number.isFinite(unitPriceGrossRaw)\n ? unitPriceGrossRaw\n : Number.isFinite(unitPriceNetRaw)\n ? unitPriceNetRaw * (1 + taxRate / 100)\n : 0;\n const totalNetRaw = normalizeNumber(\n item.total_net_amount ?? item.totalNetAmount,\n Number.NaN,\n );\n const totalGrossRaw = normalizeNumber(\n item.total_gross_amount ?? item.totalGrossAmount,\n Number.NaN,\n );\n const totalNet = Number.isFinite(totalNetRaw)\n ? totalNetRaw\n : unitPriceNet * quantity;\n const totalGross = Number.isFinite(totalGrossRaw)\n ? totalGrossRaw\n : unitPriceGross * quantity;\n const priceModeRaw =\n item.metadata &&\n typeof item.metadata === \"object\"\n ? (item.metadata as Record<string, unknown>).priceMode\n : null;\n const priceMode = priceModeRaw === \"net\" ? \"net\" : \"gross\";\n const customFieldSetId =\n typeof item.custom_field_set_id === \"string\"\n ? item.custom_field_set_id\n : typeof item.customFieldSetId === \"string\"\n ? item.customFieldSetId\n : null;\n const statusEntryId =\n typeof item.status_entry_id === \"string\"\n ? item.status_entry_id\n : typeof item.statusEntryId === \"string\"\n ? item.statusEntryId\n : null;\n const status = typeof item.status === \"string\" ? item.status : null;\n const record: SalesLineRecord = {\n id,\n name,\n productId:\n typeof item.product_id === \"string\" ? item.product_id : null,\n productVariantId:\n typeof item.product_variant_id === \"string\"\n ? item.product_variant_id\n : null,\n quantity,\n quantityUnit,\n normalizedQuantity,\n normalizedUnit,\n currencyCode:\n typeof item.currency_code === \"string\"\n ? item.currency_code\n : typeof currencyCode === \"string\"\n ? currencyCode\n : null,\n unitPriceNet,\n unitPriceGross,\n taxRate,\n totalNet,\n totalGross,\n priceMode,\n uomSnapshot,\n metadata:\n (item.metadata as Record<string, unknown> | null | undefined) ??\n null,\n catalogSnapshot:\n (item.catalog_snapshot as\n | Record<string, unknown>\n | null\n | undefined) ?? null,\n customFieldSetId,\n customFields: Object.keys(customFields).length\n ? customFields\n : null,\n status,\n statusEntryId,\n };\n return [record];\n },\n );\n setItems(mapped);\n if (onItemsChange) onItemsChange(mapped);\n } else {\n setItems([]);\n if (onItemsChange) onItemsChange([]);\n }\n } catch (err) {\n console.error(\"sales.document.items.load\", err);\n setError(t(\"sales.documents.items.errorLoad\", \"Failed to load items.\"));\n if (onItemsChange) onItemsChange([]);\n } finally {\n setLoading(false);\n }\n }, [currencyCode, documentId, documentKey, onItemsChange, resourcePath, t]);\n\n const loadShippedTotals = React.useCallback(async () => {\n if (kind !== \"order\") {\n setShippedTotals(new Map());\n return;\n }\n try {\n const params = new URLSearchParams({\n page: \"1\",\n pageSize: \"100\",\n orderId: documentId,\n });\n const response = await apiCall<{\n items?: Array<Record<string, unknown>>;\n }>(`/api/sales/shipments?${params.toString()}`, undefined, {\n fallback: { items: [] },\n });\n if (response.ok && Array.isArray(response.result?.items)) {\n const totals = new Map<string, number>();\n response.result.items.forEach((shipment) => {\n const entries = Array.isArray(shipment.items)\n ? (shipment.items as Array<Record<string, unknown>>)\n : [];\n entries.forEach((entry) => {\n const lineId =\n typeof entry.orderLineId === \"string\"\n ? entry.orderLineId\n : typeof entry.order_line_id === \"string\"\n ? entry.order_line_id\n : null;\n if (!lineId) return;\n const quantity = normalizeNumber(entry.quantity, 0);\n if (!Number.isFinite(quantity) || quantity <= 0) return;\n const current = totals.get(lineId) ?? 0;\n totals.set(lineId, current + quantity);\n });\n });\n setShippedTotals(totals);\n } else {\n setShippedTotals(new Map());\n }\n } catch (err) {\n console.error(\"sales.document.shipments.load\", err);\n setShippedTotals(new Map());\n }\n }, [documentId, kind]);\n\n React.useEffect(() => {\n if (lineStatusesLoaded.current) return;\n lineStatusesLoaded.current = true;\n void loadLineStatuses();\n }, [loadLineStatuses]);\n\n React.useEffect(() => {\n if (!documentId) return;\n if (itemsLoadedForDocument.current === documentId) return;\n itemsLoadedForDocument.current = documentId;\n void loadItems();\n }, [documentId, loadItems]);\n\n React.useEffect(() => {\n if (kind !== \"order\") {\n shipmentsLoadedForDocument.current = null;\n setShippedTotals(new Map());\n return;\n }\n const key = `${kind}:${documentId}`;\n if (shipmentsLoadedForDocument.current === key) return;\n shipmentsLoadedForDocument.current = key;\n void loadShippedTotals();\n }, [documentId, kind, loadShippedTotals]);\n\n const openCreate = React.useCallback(() => {\n setLineForEdit(null);\n setDialogOpen(true);\n }, []);\n\n React.useEffect(() => {\n if (!onActionChange) return;\n if (items.length === 0) {\n onActionChange(null);\n return;\n }\n onActionChange({\n label: t(\"sales.documents.items.add\", \"Add item\"),\n onClick: openCreate,\n disabled: false,\n });\n return () => onActionChange(null);\n }, [items.length, onActionChange, openCreate, t]);\n\n const handleEdit = React.useCallback((line: SalesLineRecord) => {\n setLineForEdit(line);\n setDialogOpen(true);\n }, []);\n\n const resolveVariantInfo = React.useCallback((record: SalesLineRecord) => {\n const meta =\n (record.metadata as Record<string, unknown> | null | undefined) ?? null;\n const snapshot =\n (record.catalogSnapshot as Record<string, unknown> | null | undefined) ??\n null;\n const variantSnapshot =\n snapshot &&\n typeof snapshot.variant === \"object\" &&\n snapshot.variant\n ? (snapshot.variant as Record<string, unknown>)\n : null;\n const variantTitle =\n meta && typeof meta.variantTitle === \"string\"\n ? meta.variantTitle\n : variantSnapshot && typeof variantSnapshot.name === \"string\"\n ? variantSnapshot.name\n : null;\n const variantSku =\n meta && typeof meta.variantSku === \"string\"\n ? meta.variantSku\n : variantSnapshot && typeof variantSnapshot.sku === \"string\"\n ? variantSnapshot.sku\n : null;\n\n return { variantTitle, variantSku };\n }, []);\n\n const handleDelete = React.useCallback(\n async (line: SalesLineRecord) => {\n const confirmed = await confirm({\n title: t(\n \"sales.documents.items.deleteConfirm\",\n \"Delete this line item?\",\n ),\n variant: \"destructive\",\n });\n if (!confirmed) return;\n try {\n const result = await deleteCrud(resourcePath, {\n body: {\n id: line.id,\n [documentKey]: documentId,\n organizationId: resolvedOrganizationId ?? undefined,\n tenantId: resolvedTenantId ?? undefined,\n },\n errorMessage: t(\n \"sales.documents.items.errorDelete\",\n \"Failed to delete line.\",\n ),\n });\n if (result.ok) {\n flash(t(\"sales.documents.items.deleted\", \"Line removed.\"), \"success\");\n await loadItems();\n emitSalesDocumentTotalsRefresh({ documentId, kind });\n }\n } catch (err) {\n console.error(\"sales.document.items.delete\", err);\n const normalized = normalizeCrudServerError(err);\n const fallback = t(\n \"sales.documents.items.errorDelete\",\n \"Failed to delete line.\",\n );\n flash(normalized.message || fallback, \"error\");\n }\n },\n [\n confirm,\n documentId,\n documentKey,\n kind,\n loadItems,\n resolvedOrganizationId,\n resourcePath,\n t,\n resolvedTenantId,\n ],\n );\n\n const renderStatus = React.useCallback(\n (line: SalesLineRecord) => {\n const value = line.status ?? null;\n if (!value) {\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"sales.documents.items.table.statusEmpty\", \"No status\")}\n </span>\n );\n }\n return (\n <DictionaryValue\n value={value}\n map={lineStatusMap}\n fallback={<span className=\"text-xs font-medium\">{value}</span>}\n className=\"text-xs font-medium\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded bg-muted text-muted-foreground\"\n iconClassName=\"h-3.5 w-3.5\"\n colorClassName=\"h-4 w-4 rounded-full border border-border/70\"\n />\n );\n },\n [lineStatusMap, t],\n );\n\n const renderImage = (record: SalesLineRecord) => {\n const meta =\n (record.metadata as Record<string, unknown> | null | undefined) ?? {};\n const snapshot =\n (record.catalogSnapshot as Record<string, unknown> | null | undefined) ??\n {};\n const productSnapshot: Record<string, unknown> =\n typeof snapshot === \"object\" && snapshot\n ? ((snapshot.product as Record<string, unknown>) ?? {})\n : {};\n const variantSnapshot: Record<string, unknown> =\n typeof snapshot === \"object\" && snapshot\n ? ((snapshot.variant as Record<string, unknown>) ?? {})\n : {};\n const productThumb =\n (meta &&\n typeof meta.productThumbnail === \"string\" &&\n meta.productThumbnail) ||\n (productSnapshot &&\n typeof productSnapshot.thumbnailUrl === \"string\" &&\n productSnapshot.thumbnailUrl) ||\n null;\n const variantThumb =\n (meta &&\n typeof meta.variantThumbnail === \"string\" &&\n meta.variantThumbnail) ||\n (variantSnapshot &&\n typeof variantSnapshot.thumbnailUrl === \"string\" &&\n variantSnapshot.thumbnailUrl) ||\n null;\n const thumbnail = variantThumb ?? productThumb;\n if (thumbnail) {\n return (\n <img\n src={thumbnail}\n alt={record.name ?? record.id}\n className=\"h-10 w-10 rounded border object-cover\"\n />\n );\n }\n return (\n <div className=\"flex h-10 w-10 items-center justify-center rounded border bg-muted text-xs text-muted-foreground\">\n N/A\n </div>\n );\n };\n\n return (\n <div className=\"space-y-4\">\n {loading ? (\n <LoadingMessage\n label={t(\"sales.documents.items.loading\", \"Loading items\u2026\")}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n ) : error ? (\n <p className=\"text-sm text-destructive\">{error}</p>\n ) : items.length === 0 ? (\n <TabEmptyState\n title={t(\"sales.documents.items.empty\", \"No items yet.\")}\n description={t(\n \"sales.documents.items.subtitle\",\n \"Add products and configure pricing for this document.\",\n )}\n action={{\n label: t(\"sales.documents.items.add\", \"Add item\"),\n onClick: openCreate,\n }}\n />\n ) : (\n <div className=\"overflow-hidden rounded border\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-muted\">\n <tr className=\"text-left\">\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.product\", \"Product\")}\n </th>\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.status\", \"Status\")}\n </th>\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.quantity\", \"Qty\")}\n </th>\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.unit\", \"Unit price\")}\n </th>\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.total\", \"Total\")}\n </th>\n <th className=\"px-3 py-2 font-medium sr-only\">\n {t(\"sales.documents.items.table.actions\", \"Actions\")}\n </th>\n </tr>\n </thead>\n <tbody>\n {items.map((item) => {\n const meta =\n (item.metadata as\n | Record<string, unknown>\n | null\n | undefined) ?? null;\n const { variantTitle, variantSku } = resolveVariantInfo(item);\n const productSku =\n meta && typeof meta.productSku === \"string\"\n ? meta.productSku\n : null;\n const variantLabel = variantTitle ?? variantSku;\n const variantSuffix =\n variantSku && variantLabel && variantSku !== variantLabel\n ? ` \u2022 ${variantSku}`\n : \"\";\n const showProductSku =\n productSku && productSku !== variantSku ? productSku : null;\n const shippedQuantity = Math.max(\n 0,\n shippedTotals.get(item.id) ?? 0,\n );\n const quantityLabel = item.quantityUnit\n ? `${item.quantity} ${item.quantityUnit}`\n : String(item.quantity);\n const showNormalized =\n Number.isFinite(item.normalizedQuantity) &&\n item.normalizedQuantity > 0 &&\n (item.normalizedUnit ?? null) &&\n (Math.abs(item.normalizedQuantity - item.quantity) >\n 0.000001 ||\n (item.normalizedUnit ?? null) !==\n (item.quantityUnit ?? null));\n const unitPriceReference = resolveUnitPriceReference(\n item.uomSnapshot,\n );\n\n return (\n <tr\n key={item.id}\n className=\"border-t hover:bg-muted/50 cursor-pointer transition-colors\"\n onClick={() => handleEdit(item)}\n >\n <td className=\"px-3 py-3\">\n <div className=\"flex items-center gap-3\">\n {renderImage(item)}\n <div className=\"min-w-0\">\n <div className=\"truncate font-medium\">\n {item.name ??\n t(\"sales.documents.items.untitled\", \"Untitled\")}\n </div>\n {variantLabel ? (\n <div className=\"text-xs text-muted-foreground truncate\">\n {variantLabel}\n {variantSuffix}\n </div>\n ) : null}\n {showProductSku ? (\n <div className=\"text-xs text-muted-foreground truncate\">\n {showProductSku}\n </div>\n ) : null}\n </div>\n </div>\n </td>\n <td className=\"px-3 py-3\">\n <div className=\"flex items-center\">\n {renderStatus(item)}\n </div>\n </td>\n <td className=\"px-3 py-3\">\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"font-medium\">{quantityLabel}</span>\n {showNormalized ? (\n <span className=\"text-xs text-muted-foreground\">\n {item.normalizedQuantity} {item.normalizedUnit}\n </span>\n ) : null}\n {shippedQuantity > 0 ? (\n <span className=\"text-xs text-muted-foreground\">\n {t(\n \"sales.documents.items.table.shipped\",\n \"{{shipped}} / {{total}} shipped\",\n {\n shipped: shippedQuantity,\n total: item.quantity,\n },\n )}\n </span>\n ) : null}\n </div>\n </td>\n <td className=\"px-3 py-3\">\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"font-mono text-sm\">\n {formatMoney(\n item.unitPriceGross,\n item.currencyCode ?? currencyCode ?? undefined,\n )}{\" \"}\n <span className=\"text-xs text-muted-foreground\">\n {t(\"sales.documents.items.table.gross\", \"gross\")}\n </span>\n </span>\n <span className=\"font-mono text-xs text-muted-foreground\">\n {formatMoney(\n item.unitPriceNet,\n item.currencyCode ?? currencyCode ?? undefined,\n )}{\" \"}\n {t(\"sales.documents.items.table.net\", \"net\")}\n </span>\n {unitPriceReference ? (\n <span className=\"text-xs text-muted-foreground\">\n {t(\n \"sales.documents.items.table.unitPriceReference\",\n \"{{value}} per 1 {{unit}}\",\n {\n value: formatMoney(\n unitPriceReference.grossPerReference,\n item.currencyCode ??\n currencyCode ??\n undefined,\n ),\n unit: unitPriceReference.referenceUnitCode,\n },\n )}\n </span>\n ) : null}\n </div>\n </td>\n <td className=\"px-3 py-3 font-semibold\">\n <div className=\"flex flex-col gap-0.5\">\n <span>\n {formatMoney(\n item.totalGross,\n item.currencyCode ?? currencyCode ?? undefined,\n )}{\" \"}\n <span className=\"text-xs font-normal text-muted-foreground\">\n {t(\"sales.documents.items.table.gross\", \"gross\")}\n </span>\n </span>\n <span className=\"text-xs font-medium text-muted-foreground\">\n {formatMoney(\n item.totalNet,\n item.currencyCode ?? currencyCode ?? undefined,\n )}{\" \"}\n {t(\"sales.documents.items.table.net\", \"net\")}\n </span>\n </div>\n </td>\n <td className=\"px-3 py-3\">\n <div className=\"flex items-center gap-2 justify-end\">\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-8 w-8\"\n onClick={(event) => {\n event.stopPropagation();\n handleEdit(item);\n }}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-8 w-8 text-destructive\"\n onClick={(event) => {\n event.stopPropagation();\n void handleDelete(item);\n }}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n\n <LineItemDialog\n open={dialogOpen}\n onOpenChange={(next) => {\n setDialogOpen(next);\n if (!next) setLineForEdit(null);\n }}\n kind={kind}\n documentId={documentId}\n currencyCode={currencyCode}\n organizationId={resolvedOrganizationId}\n tenantId={resolvedTenantId}\n initialLine={lineForEdit}\n onSaved={async () => {\n await loadItems();\n emitSalesDocumentTotalsRefresh({ documentId, kind });\n }}\n />\n {ConfirmDialogElement}\n </div>\n );\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\";\n\nimport * as React from \"react\";\nimport { apiCall } from \"@open-mercato/ui/backend/utils/apiCall\";\nimport { deleteCrud } from \"@open-mercato/ui/backend/utils/crud\";\nimport { normalizeCrudServerError } from \"@open-mercato/ui/backend/utils/serverErrors\";\nimport { LoadingMessage, TabEmptyState } from \"@open-mercato/ui/backend/detail\";\nimport { Button } from \"@open-mercato/ui/primitives/button\";\nimport { flash } from \"@open-mercato/ui/backend/FlashMessages\";\nimport { Pencil, Trash2 } from \"lucide-react\";\nimport {\n DictionaryValue,\n type DictionaryMap,\n createDictionaryMap,\n normalizeDictionaryEntries,\n} from \"@open-mercato/core/modules/dictionaries/components/dictionaryAppearance\";\nimport { useT } from \"@open-mercato/shared/lib/i18n/context\";\nimport { useOrganizationScopeDetail } from \"@open-mercato/shared/lib/frontend/useOrganizationScope\";\nimport { useConfirmDialog } from \"@open-mercato/ui/backend/confirm-dialog\";\nimport { emitSalesDocumentTotalsRefresh } from \"@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents\";\nimport { LineItemDialog } from \"./LineItemDialog\";\nimport type { SalesLineRecord } from \"./lineItemTypes\";\nimport { formatMoney, normalizeNumber } from \"./lineItemUtils\";\nimport type { SectionAction } from \"@open-mercato/ui/backend/detail\";\nimport { extractCustomFieldValues } from \"./customFieldHelpers\";\nimport { canonicalizeUnitCode } from \"@open-mercato/shared/lib/units/unitCodes\";\nimport type { SalesLineUomSnapshot } from \"../../lib/types\";\n\ntype ResolvedUnitPriceReference = {\n grossPerReference: number;\n referenceUnitCode: string;\n};\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isSalesLineUomSnapshot(\n value: unknown,\n): value is SalesLineUomSnapshot {\n if (!isPlainObject(value)) return false;\n return (\n value.version === 1 &&\n typeof value.enteredQuantity === \"string\" &&\n typeof value.toBaseFactor === \"string\" &&\n typeof value.normalizedQuantity === \"string\"\n );\n}\n\nfunction extractUomSnapshot(\n item: Record<string, unknown>,\n): SalesLineUomSnapshot | null {\n const raw = item.uom_snapshot ?? item.uomSnapshot;\n if (isSalesLineUomSnapshot(raw)) return raw;\n return null;\n}\n\nfunction resolveUnitPriceReference(\n snapshot: SalesLineUomSnapshot | Record<string, unknown> | null,\n): ResolvedUnitPriceReference | null {\n if (!snapshot) return null;\n\n const ref = isSalesLineUomSnapshot(snapshot)\n ? snapshot.unitPriceReference\n : isPlainObject(snapshot)\n ? isPlainObject(snapshot.unitPriceReference)\n ? snapshot.unitPriceReference\n : isPlainObject(snapshot.unit_price_reference)\n ? snapshot.unit_price_reference\n : null\n : null;\n\n if (!ref || !isPlainObject(ref)) return null;\n\n const refRecord = ref as Record<string, unknown>;\n const grossPerReference = normalizeNumber(\n refRecord.grossPerReference ?? refRecord.gross_per_reference,\n Number.NaN,\n );\n if (!Number.isFinite(grossPerReference)) return null;\n\n const referenceUnitCode =\n typeof refRecord.referenceUnitCode === \"string\"\n ? refRecord.referenceUnitCode\n : typeof refRecord.reference_unit_code === \"string\"\n ? refRecord.reference_unit_code\n : typeof refRecord.referenceUnit === \"string\"\n ? refRecord.referenceUnit\n : null;\n if (!referenceUnitCode) return null;\n\n return { grossPerReference, referenceUnitCode };\n}\n\nfunction getUomFields(item: Record<string, unknown>) {\n const uomSnapshot = extractUomSnapshot(item);\n return {\n normalizedQuantity: (item.normalized_quantity ?? item.normalizedQuantity ?? null) as\n | number\n | string\n | null,\n normalizedUnit: (item.normalized_unit ?? item.normalizedUnit ?? null) as string | null,\n quantityUnit: (item.quantity_unit ?? item.quantityUnit ?? null) as string | null,\n uomSnapshot,\n };\n}\n\ntype SalesDocumentItemsSectionProps = {\n documentId: string;\n kind: \"order\" | \"quote\";\n currencyCode: string | null | undefined;\n organizationId?: string | null;\n tenantId?: string | null;\n onActionChange?: (action: SectionAction | null) => void;\n onItemsChange?: (items: SalesLineRecord[]) => void;\n};\n\nexport function SalesDocumentItemsSection({\n documentId,\n kind,\n currencyCode,\n organizationId: orgFromProps,\n tenantId: tenantFromProps,\n onActionChange,\n onItemsChange,\n}: SalesDocumentItemsSectionProps) {\n const t = useT();\n const { organizationId, tenantId } = useOrganizationScopeDetail();\n const { confirm, ConfirmDialogElement } = useConfirmDialog();\n const resolvedOrganizationId = orgFromProps ?? organizationId ?? null;\n const resolvedTenantId = tenantFromProps ?? tenantId ?? null;\n const [items, setItems] = React.useState<SalesLineRecord[]>([]);\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 [lineForEdit, setLineForEdit] = React.useState<SalesLineRecord | null>(\n null,\n );\n const [lineStatusMap, setLineStatusMap] = React.useState<DictionaryMap>({});\n const [shippedTotals, setShippedTotals] = React.useState<Map<string, number>>(\n new Map(),\n );\n\n const resourcePath = React.useMemo(\n () => (kind === \"order\" ? \"sales/order-lines\" : \"sales/quote-lines\"),\n [kind],\n );\n const documentKey = kind === \"order\" ? \"orderId\" : \"quoteId\";\n const lineStatusesLoaded = React.useRef(false);\n const itemsLoadedForDocument = React.useRef<string | null>(null);\n const shipmentsLoadedForDocument = React.useRef<string | null>(null);\n const loadLineStatuses = React.useCallback(async () => {\n try {\n const params = new URLSearchParams({ page: \"1\", pageSize: \"100\" });\n const response = await apiCall<{\n items?: Array<Record<string, unknown>>;\n }>(`/api/sales/order-line-statuses?${params.toString()}`, undefined, {\n fallback: { items: [] },\n });\n const entries = normalizeDictionaryEntries(response.result?.items ?? []);\n setLineStatusMap(createDictionaryMap(entries));\n } catch (err) {\n console.error(\"sales.document.line-statuses.load\", err);\n setLineStatusMap({});\n }\n }, []);\n\n const loadItems = React.useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const params = new URLSearchParams({\n page: \"1\",\n pageSize: \"100\",\n [documentKey]: documentId,\n });\n const response = await apiCall<{\n items?: Array<Record<string, unknown>>;\n }>(`/api/${resourcePath}?${params.toString()}`, undefined, {\n fallback: { items: [] },\n });\n if (response.ok && Array.isArray(response.result?.items)) {\n const mapped = response.result.items.flatMap<SalesLineRecord>(\n (item) => {\n const id = typeof item.id === \"string\" ? item.id : null;\n if (!id) return [];\n const taxRate = normalizeNumber(\n item.tax_rate ?? item.taxRate,\n 0,\n );\n const customFields = extractCustomFieldValues(\n item as Record<string, unknown>,\n );\n const name =\n typeof item.name === \"string\"\n ? item.name\n : typeof item.catalog_snapshot === \"object\" &&\n item.catalog_snapshot &&\n typeof (item.catalog_snapshot as Record<string, unknown>).name === \"string\"\n ? (item.catalog_snapshot as Record<string, unknown>).name as string\n : null;\n const quantity = normalizeNumber(item.quantity, 0);\n const uomFields = getUomFields(item);\n const quantityUnit = canonicalizeUnitCode(uomFields.quantityUnit);\n const normalizedQuantity = normalizeNumber(\n uomFields.normalizedQuantity,\n quantity,\n );\n const normalizedUnit =\n canonicalizeUnitCode(uomFields.normalizedUnit) ?? quantityUnit;\n const uomSnapshot = uomFields.uomSnapshot;\n const unitPriceNetRaw = normalizeNumber(\n item.unit_price_net ?? item.unitPriceNet,\n Number.NaN,\n );\n const unitPriceGrossRaw = normalizeNumber(\n item.unit_price_gross ?? item.unitPriceGross,\n Number.NaN,\n );\n const unitPriceNet = Number.isFinite(unitPriceNetRaw)\n ? unitPriceNetRaw\n : Number.isFinite(unitPriceGrossRaw)\n ? unitPriceGrossRaw / (1 + taxRate / 100)\n : 0;\n const unitPriceGross = Number.isFinite(unitPriceGrossRaw)\n ? unitPriceGrossRaw\n : Number.isFinite(unitPriceNetRaw)\n ? unitPriceNetRaw * (1 + taxRate / 100)\n : 0;\n const totalNetRaw = normalizeNumber(\n item.total_net_amount ?? item.totalNetAmount,\n Number.NaN,\n );\n const totalGrossRaw = normalizeNumber(\n item.total_gross_amount ?? item.totalGrossAmount,\n Number.NaN,\n );\n const totalNet = Number.isFinite(totalNetRaw)\n ? totalNetRaw\n : unitPriceNet * quantity;\n const totalGross = Number.isFinite(totalGrossRaw)\n ? totalGrossRaw\n : unitPriceGross * quantity;\n const priceModeRaw =\n item.metadata &&\n typeof item.metadata === \"object\"\n ? (item.metadata as Record<string, unknown>).priceMode\n : null;\n const priceMode = priceModeRaw === \"net\" ? \"net\" : \"gross\";\n const customFieldSetId =\n typeof item.custom_field_set_id === \"string\"\n ? item.custom_field_set_id\n : typeof item.customFieldSetId === \"string\"\n ? item.customFieldSetId\n : null;\n const statusEntryId =\n typeof item.status_entry_id === \"string\"\n ? item.status_entry_id\n : typeof item.statusEntryId === \"string\"\n ? item.statusEntryId\n : null;\n const status = typeof item.status === \"string\" ? item.status : null;\n const record: SalesLineRecord = {\n id,\n name,\n productId:\n typeof item.product_id === \"string\" ? item.product_id : null,\n productVariantId:\n typeof item.product_variant_id === \"string\"\n ? item.product_variant_id\n : null,\n quantity,\n quantityUnit,\n normalizedQuantity,\n normalizedUnit,\n currencyCode:\n typeof item.currency_code === \"string\"\n ? item.currency_code\n : typeof currencyCode === \"string\"\n ? currencyCode\n : null,\n unitPriceNet,\n unitPriceGross,\n taxRate,\n totalNet,\n totalGross,\n priceMode,\n uomSnapshot,\n metadata:\n (item.metadata as Record<string, unknown> | null | undefined) ??\n null,\n catalogSnapshot:\n (item.catalog_snapshot as\n | Record<string, unknown>\n | null\n | undefined) ?? null,\n customFieldSetId,\n customFields: Object.keys(customFields).length\n ? customFields\n : null,\n status,\n statusEntryId,\n };\n return [record];\n },\n );\n setItems(mapped);\n if (onItemsChange) onItemsChange(mapped);\n } else {\n setItems([]);\n if (onItemsChange) onItemsChange([]);\n }\n } catch (err) {\n console.error(\"sales.document.items.load\", err);\n setError(t(\"sales.documents.items.errorLoad\", \"Failed to load items.\"));\n if (onItemsChange) onItemsChange([]);\n } finally {\n setLoading(false);\n }\n }, [currencyCode, documentId, documentKey, onItemsChange, resourcePath, t]);\n\n const loadShippedTotals = React.useCallback(async () => {\n if (kind !== \"order\") {\n setShippedTotals(new Map());\n return;\n }\n try {\n const params = new URLSearchParams({\n page: \"1\",\n pageSize: \"100\",\n orderId: documentId,\n });\n const response = await apiCall<{\n items?: Array<Record<string, unknown>>;\n }>(`/api/sales/shipments?${params.toString()}`, undefined, {\n fallback: { items: [] },\n });\n if (response.ok && Array.isArray(response.result?.items)) {\n const totals = new Map<string, number>();\n response.result.items.forEach((shipment) => {\n const entries = Array.isArray(shipment.items)\n ? (shipment.items as Array<Record<string, unknown>>)\n : [];\n entries.forEach((entry) => {\n const lineId =\n typeof entry.orderLineId === \"string\"\n ? entry.orderLineId\n : typeof entry.order_line_id === \"string\"\n ? entry.order_line_id\n : null;\n if (!lineId) return;\n const quantity = normalizeNumber(entry.quantity, 0);\n if (!Number.isFinite(quantity) || quantity <= 0) return;\n const current = totals.get(lineId) ?? 0;\n totals.set(lineId, current + quantity);\n });\n });\n setShippedTotals(totals);\n } else {\n setShippedTotals(new Map());\n }\n } catch (err) {\n console.error(\"sales.document.shipments.load\", err);\n setShippedTotals(new Map());\n }\n }, [documentId, kind]);\n\n React.useEffect(() => {\n if (lineStatusesLoaded.current) return;\n lineStatusesLoaded.current = true;\n void loadLineStatuses();\n }, [loadLineStatuses]);\n\n React.useEffect(() => {\n if (!documentId) return;\n if (itemsLoadedForDocument.current === documentId) return;\n itemsLoadedForDocument.current = documentId;\n void loadItems();\n }, [documentId, loadItems]);\n\n React.useEffect(() => {\n if (kind !== \"order\") {\n shipmentsLoadedForDocument.current = null;\n setShippedTotals(new Map());\n return;\n }\n const key = `${kind}:${documentId}`;\n if (shipmentsLoadedForDocument.current === key) return;\n shipmentsLoadedForDocument.current = key;\n void loadShippedTotals();\n }, [documentId, kind, loadShippedTotals]);\n\n const openCreate = React.useCallback(() => {\n setLineForEdit(null);\n setDialogOpen(true);\n }, []);\n\n React.useEffect(() => {\n if (!onActionChange) return;\n onActionChange({\n label: t(\"sales.documents.items.add\", \"Add item\"),\n onClick: openCreate,\n disabled: false,\n });\n return () => onActionChange(null);\n }, [onActionChange, openCreate, t]);\n\n const handleEdit = React.useCallback((line: SalesLineRecord) => {\n setLineForEdit(line);\n setDialogOpen(true);\n }, []);\n\n const resolveVariantInfo = React.useCallback((record: SalesLineRecord) => {\n const meta =\n (record.metadata as Record<string, unknown> | null | undefined) ?? null;\n const snapshot =\n (record.catalogSnapshot as Record<string, unknown> | null | undefined) ??\n null;\n const variantSnapshot =\n snapshot &&\n typeof snapshot.variant === \"object\" &&\n snapshot.variant\n ? (snapshot.variant as Record<string, unknown>)\n : null;\n const variantTitle =\n meta && typeof meta.variantTitle === \"string\"\n ? meta.variantTitle\n : variantSnapshot && typeof variantSnapshot.name === \"string\"\n ? variantSnapshot.name\n : null;\n const variantSku =\n meta && typeof meta.variantSku === \"string\"\n ? meta.variantSku\n : variantSnapshot && typeof variantSnapshot.sku === \"string\"\n ? variantSnapshot.sku\n : null;\n\n return { variantTitle, variantSku };\n }, []);\n\n const handleDelete = React.useCallback(\n async (line: SalesLineRecord) => {\n const confirmed = await confirm({\n title: t(\n \"sales.documents.items.deleteConfirm\",\n \"Delete this line item?\",\n ),\n variant: \"destructive\",\n });\n if (!confirmed) return;\n try {\n const result = await deleteCrud(resourcePath, {\n body: {\n id: line.id,\n [documentKey]: documentId,\n organizationId: resolvedOrganizationId ?? undefined,\n tenantId: resolvedTenantId ?? undefined,\n },\n errorMessage: t(\n \"sales.documents.items.errorDelete\",\n \"Failed to delete line.\",\n ),\n });\n if (result.ok) {\n flash(t(\"sales.documents.items.deleted\", \"Line removed.\"), \"success\");\n await loadItems();\n emitSalesDocumentTotalsRefresh({ documentId, kind });\n }\n } catch (err) {\n console.error(\"sales.document.items.delete\", err);\n const normalized = normalizeCrudServerError(err);\n const fallback = t(\n \"sales.documents.items.errorDelete\",\n \"Failed to delete line.\",\n );\n flash(normalized.message || fallback, \"error\");\n }\n },\n [\n confirm,\n documentId,\n documentKey,\n kind,\n loadItems,\n resolvedOrganizationId,\n resourcePath,\n t,\n resolvedTenantId,\n ],\n );\n\n const renderStatus = React.useCallback(\n (line: SalesLineRecord) => {\n const value = line.status ?? null;\n if (!value) {\n return (\n <span className=\"text-xs text-muted-foreground\">\n {t(\"sales.documents.items.table.statusEmpty\", \"No status\")}\n </span>\n );\n }\n return (\n <DictionaryValue\n value={value}\n map={lineStatusMap}\n fallback={<span className=\"text-xs font-medium\">{value}</span>}\n className=\"text-xs font-medium\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded bg-muted text-muted-foreground\"\n iconClassName=\"h-3.5 w-3.5\"\n colorClassName=\"h-4 w-4 rounded-full border border-border/70\"\n />\n );\n },\n [lineStatusMap, t],\n );\n\n const renderImage = (record: SalesLineRecord) => {\n const meta =\n (record.metadata as Record<string, unknown> | null | undefined) ?? {};\n const snapshot =\n (record.catalogSnapshot as Record<string, unknown> | null | undefined) ??\n {};\n const productSnapshot: Record<string, unknown> =\n typeof snapshot === \"object\" && snapshot\n ? ((snapshot.product as Record<string, unknown>) ?? {})\n : {};\n const variantSnapshot: Record<string, unknown> =\n typeof snapshot === \"object\" && snapshot\n ? ((snapshot.variant as Record<string, unknown>) ?? {})\n : {};\n const productThumb =\n (meta &&\n typeof meta.productThumbnail === \"string\" &&\n meta.productThumbnail) ||\n (productSnapshot &&\n typeof productSnapshot.thumbnailUrl === \"string\" &&\n productSnapshot.thumbnailUrl) ||\n null;\n const variantThumb =\n (meta &&\n typeof meta.variantThumbnail === \"string\" &&\n meta.variantThumbnail) ||\n (variantSnapshot &&\n typeof variantSnapshot.thumbnailUrl === \"string\" &&\n variantSnapshot.thumbnailUrl) ||\n null;\n const thumbnail = variantThumb ?? productThumb;\n if (thumbnail) {\n return (\n <img\n src={thumbnail}\n alt={record.name ?? record.id}\n className=\"h-10 w-10 rounded border object-cover\"\n />\n );\n }\n return (\n <div className=\"flex h-10 w-10 items-center justify-center rounded border bg-muted text-xs text-muted-foreground\">\n N/A\n </div>\n );\n };\n\n return (\n <div className=\"space-y-4\">\n {loading ? (\n <LoadingMessage\n label={t(\"sales.documents.items.loading\", \"Loading items\u2026\")}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n ) : error ? (\n <p className=\"text-sm text-destructive\">{error}</p>\n ) : items.length === 0 ? (\n <TabEmptyState\n title={t(\"sales.documents.items.empty\", \"No items yet.\")}\n description={t(\n \"sales.documents.items.subtitle\",\n \"Add products and configure pricing for this document.\",\n )}\n action={{\n label: t(\"sales.documents.items.add\", \"Add item\"),\n onClick: openCreate,\n }}\n />\n ) : (\n <div className=\"overflow-hidden rounded border\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-muted\">\n <tr className=\"text-left\">\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.product\", \"Product\")}\n </th>\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.status\", \"Status\")}\n </th>\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.quantity\", \"Qty\")}\n </th>\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.unit\", \"Unit price\")}\n </th>\n <th className=\"px-3 py-2 font-medium\">\n {t(\"sales.documents.items.table.total\", \"Total\")}\n </th>\n <th className=\"px-3 py-2 font-medium sr-only\">\n {t(\"sales.documents.items.table.actions\", \"Actions\")}\n </th>\n </tr>\n </thead>\n <tbody>\n {items.map((item) => {\n const meta =\n (item.metadata as\n | Record<string, unknown>\n | null\n | undefined) ?? null;\n const { variantTitle, variantSku } = resolveVariantInfo(item);\n const productSku =\n meta && typeof meta.productSku === \"string\"\n ? meta.productSku\n : null;\n const variantLabel = variantTitle ?? variantSku;\n const variantSuffix =\n variantSku && variantLabel && variantSku !== variantLabel\n ? ` \u2022 ${variantSku}`\n : \"\";\n const showProductSku =\n productSku && productSku !== variantSku ? productSku : null;\n const shippedQuantity = Math.max(\n 0,\n shippedTotals.get(item.id) ?? 0,\n );\n const quantityLabel = item.quantityUnit\n ? `${item.quantity} ${item.quantityUnit}`\n : String(item.quantity);\n const showNormalized =\n Number.isFinite(item.normalizedQuantity) &&\n item.normalizedQuantity > 0 &&\n (item.normalizedUnit ?? null) &&\n (Math.abs(item.normalizedQuantity - item.quantity) >\n 0.000001 ||\n (item.normalizedUnit ?? null) !==\n (item.quantityUnit ?? null));\n const unitPriceReference = resolveUnitPriceReference(\n item.uomSnapshot,\n );\n\n return (\n <tr\n key={item.id}\n className=\"border-t hover:bg-muted/50 cursor-pointer transition-colors\"\n onClick={() => handleEdit(item)}\n >\n <td className=\"px-3 py-3\">\n <div className=\"flex items-center gap-3\">\n {renderImage(item)}\n <div className=\"min-w-0\">\n <div className=\"truncate font-medium\">\n {item.name ??\n t(\"sales.documents.items.untitled\", \"Untitled\")}\n </div>\n {variantLabel ? (\n <div className=\"text-xs text-muted-foreground truncate\">\n {variantLabel}\n {variantSuffix}\n </div>\n ) : null}\n {showProductSku ? (\n <div className=\"text-xs text-muted-foreground truncate\">\n {showProductSku}\n </div>\n ) : null}\n </div>\n </div>\n </td>\n <td className=\"px-3 py-3\">\n <div className=\"flex items-center\">\n {renderStatus(item)}\n </div>\n </td>\n <td className=\"px-3 py-3\">\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"font-medium\">{quantityLabel}</span>\n {showNormalized ? (\n <span className=\"text-xs text-muted-foreground\">\n {item.normalizedQuantity} {item.normalizedUnit}\n </span>\n ) : null}\n {shippedQuantity > 0 ? (\n <span className=\"text-xs text-muted-foreground\">\n {t(\n \"sales.documents.items.table.shipped\",\n \"{{shipped}} / {{total}} shipped\",\n {\n shipped: shippedQuantity,\n total: item.quantity,\n },\n )}\n </span>\n ) : null}\n </div>\n </td>\n <td className=\"px-3 py-3\">\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"font-mono text-sm\">\n {formatMoney(\n item.unitPriceGross,\n item.currencyCode ?? currencyCode ?? undefined,\n )}{\" \"}\n <span className=\"text-xs text-muted-foreground\">\n {t(\"sales.documents.items.table.gross\", \"gross\")}\n </span>\n </span>\n <span className=\"font-mono text-xs text-muted-foreground\">\n {formatMoney(\n item.unitPriceNet,\n item.currencyCode ?? currencyCode ?? undefined,\n )}{\" \"}\n {t(\"sales.documents.items.table.net\", \"net\")}\n </span>\n {unitPriceReference ? (\n <span className=\"text-xs text-muted-foreground\">\n {t(\n \"sales.documents.items.table.unitPriceReference\",\n \"{{value}} per 1 {{unit}}\",\n {\n value: formatMoney(\n unitPriceReference.grossPerReference,\n item.currencyCode ??\n currencyCode ??\n undefined,\n ),\n unit: unitPriceReference.referenceUnitCode,\n },\n )}\n </span>\n ) : null}\n </div>\n </td>\n <td className=\"px-3 py-3 font-semibold\">\n <div className=\"flex flex-col gap-0.5\">\n <span>\n {formatMoney(\n item.totalGross,\n item.currencyCode ?? currencyCode ?? undefined,\n )}{\" \"}\n <span className=\"text-xs font-normal text-muted-foreground\">\n {t(\"sales.documents.items.table.gross\", \"gross\")}\n </span>\n </span>\n <span className=\"text-xs font-medium text-muted-foreground\">\n {formatMoney(\n item.totalNet,\n item.currencyCode ?? currencyCode ?? undefined,\n )}{\" \"}\n {t(\"sales.documents.items.table.net\", \"net\")}\n </span>\n </div>\n </td>\n <td className=\"px-3 py-3\">\n <div className=\"flex items-center gap-2 justify-end\">\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-8 w-8\"\n onClick={(event) => {\n event.stopPropagation();\n handleEdit(item);\n }}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-8 w-8 text-destructive\"\n onClick={(event) => {\n event.stopPropagation();\n void handleDelete(item);\n }}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n\n <LineItemDialog\n open={dialogOpen}\n onOpenChange={(next) => {\n setDialogOpen(next);\n if (!next) setLineForEdit(null);\n }}\n kind={kind}\n documentId={documentId}\n currencyCode={currencyCode}\n organizationId={resolvedOrganizationId}\n tenantId={resolvedTenantId}\n initialLine={lineForEdit}\n onSaved={async () => {\n await loadItems();\n emitSalesDocumentTotalsRefresh({ documentId, kind });\n }}\n />\n {ConfirmDialogElement}\n </div>\n );\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -166,17 +166,13 @@ function SalesDocumentPaymentsSection({
166
166
  );
167
167
  React.useEffect(() => {
168
168
  if (!onActionChange) return;
169
- if (payments.length === 0) {
170
- onActionChange(null);
171
- return;
172
- }
173
169
  onActionChange({
174
170
  label: addActionLabel,
175
171
  onClick: openCreate,
176
- disabled: loading
172
+ disabled: false
177
173
  });
178
174
  return () => onActionChange(null);
179
- }, [addActionLabel, loading, onActionChange, openCreate, payments.length]);
175
+ }, [addActionLabel, onActionChange, openCreate]);
180
176
  const columns = React.useMemo(
181
177
  () => [
182
178
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/sales/components/documents/PaymentsSection.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { LoadingMessage, ErrorMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport type { SectionAction } from '@open-mercato/ui/backend/detail'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { emitSalesDocumentTotalsRefresh } from '@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents'\nimport { PaymentDialog, type PaymentFormData, type PaymentTotals } from './PaymentDialog'\nimport { extractCustomFieldValues } from './customFieldHelpers'\nimport { Plus } from 'lucide-react'\n\ntype PaymentRow = {\n id: string\n paymentReference: string | null\n paymentMethodId: string | null\n paymentMethodName: string | null\n status: string | null\n statusEntryId: string | null\n statusLabel: string | null\n amount: number\n currencyCode: string | null\n receivedAt: string | null\n createdAt: string | null\n customValues?: Record<string, unknown> | null\n customFieldSetId?: string | null\n}\n\ntype SalesDocumentPaymentsSectionProps = {\n orderId: string\n currencyCode: string | null | undefined\n organizationId?: string | null\n tenantId?: string | null\n onActionChange?: (action: SectionAction | null) => void\n onTotalsChange?: () => void\n onPaymentsChange?: (payments: PaymentRow[]) => void\n}\n\nfunction normalizeNumber(value: unknown): 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 0\n}\n\nfunction formatMoney(value: number, currency: string | null | undefined): string {\n if (!currency || currency.trim().length !== 3) return value.toFixed(2)\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return `${currency.toUpperCase()} ${value.toFixed(2)}`\n }\n}\n\nexport function SalesDocumentPaymentsSection({\n orderId,\n currencyCode,\n organizationId: orgFromProps,\n tenantId: tenantFromProps,\n onActionChange,\n onTotalsChange,\n onPaymentsChange,\n}: SalesDocumentPaymentsSectionProps) {\n const t = useT()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const resolvedOrganizationId = orgFromProps ?? organizationId ?? null\n const resolvedTenantId = tenantFromProps ?? tenantId ?? null\n const [payments, setPayments] = React.useState<PaymentRow[]>([])\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 [editingPayment, setEditingPayment] = React.useState<PaymentFormData | null>(null)\n const onPaymentsChangeRef = React.useRef<typeof onPaymentsChange>(onPaymentsChange)\n\n React.useEffect(() => {\n onPaymentsChangeRef.current = onPaymentsChange\n }, [onPaymentsChange])\n\n const addActionLabel = t('sales.documents.payments.add', 'Add payment')\n const editActionLabel = t('sales.documents.payments.edit', 'Edit payment')\n const deleteActionLabel = t('sales.documents.payments.delete', 'Delete payment')\n\n const loadPayments = React.useCallback(async () => {\n setLoading(true)\n setError(null)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/payments?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n if (response.ok && Array.isArray(response.result?.items)) {\n const mapped = response.result.items.flatMap<PaymentRow>((item) => {\n if (typeof item.id !== 'string') return []\n const customValues =\n item && typeof item === 'object'\n ? extractCustomFieldValues(item as Record<string, unknown>)\n : {}\n const record: PaymentRow = {\n id: item.id,\n paymentReference: typeof item.payment_reference === 'string' ? item.payment_reference : null,\n paymentMethodId: typeof item.payment_method_id === 'string' ? item.payment_method_id : null,\n paymentMethodName:\n typeof item.payment_method_name === 'string'\n ? item.payment_method_name\n : typeof item.payment_method_code === 'string'\n ? item.payment_method_code\n : null,\n status: typeof item.status === 'string' ? item.status : null,\n statusEntryId:\n typeof (item as any).status_entry_id === 'string'\n ? (item as any).status_entry_id\n : typeof (item as any).statusEntryId === 'string'\n ? (item as any).statusEntryId\n : null,\n statusLabel:\n typeof (item as any).status_label === 'string'\n ? (item as any).status_label\n : typeof (item as any).statusLabel === 'string'\n ? (item as any).statusLabel\n : null,\n amount: normalizeNumber(item.amount),\n currencyCode:\n typeof item.currency_code === 'string'\n ? item.currency_code\n : typeof currencyCode === 'string'\n ? currencyCode\n : null,\n receivedAt: typeof item.received_at === 'string' ? item.received_at : null,\n createdAt: typeof item.created_at === 'string' ? item.created_at : null,\n customValues: Object.keys(customValues).length ? customValues : null,\n 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 }\n return [record]\n })\n setPayments(mapped)\n onPaymentsChangeRef.current?.(mapped)\n } else {\n setPayments([])\n onPaymentsChangeRef.current?.([])\n }\n } catch (err) {\n console.error('sales.payments.list', err)\n setError(t('sales.documents.payments.errorLoad', 'Failed to load payments.'))\n onPaymentsChangeRef.current?.([])\n } finally {\n setLoading(false)\n }\n }, [currencyCode, orderId, t])\n\n React.useEffect(() => {\n void loadPayments()\n }, [loadPayments])\n\n const openCreate = React.useCallback(() => {\n setEditingPayment(null)\n setDialogOpen(true)\n }, [])\n\n const handleDialogChange = React.useCallback((nextOpen: boolean) => {\n setDialogOpen(nextOpen)\n if (!nextOpen) {\n setEditingPayment(null)\n }\n }, [])\n\n const openEditPayment = React.useCallback(\n (record: PaymentRow) => {\n setEditingPayment({\n id: record.id,\n amount: record.amount ?? '',\n paymentMethodId: record.paymentMethodId ?? '',\n paymentReference: record.paymentReference ?? '',\n receivedAt: record.receivedAt ? record.receivedAt.slice(0, 10) : '',\n currencyCode: record.currencyCode ?? currencyCode ?? null,\n statusEntryId: record.statusEntryId ?? null,\n customValues: record.customValues ?? null,\n customFieldSetId: record.customFieldSetId ?? null,\n })\n setDialogOpen(true)\n },\n [currencyCode]\n )\n\n const handlePaymentSaved = React.useCallback(\n async (_totals?: PaymentTotals | null) => {\n onTotalsChange?.()\n await loadPayments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n handleDialogChange(false)\n },\n [handleDialogChange, loadPayments, onTotalsChange, orderId]\n )\n\n const handleDelete = React.useCallback(\n async (row: PaymentRow) => {\n try {\n const result = await deleteCrud<{ orderTotals?: PaymentTotals | null }>('sales/payments', {\n body: {\n id: row.id,\n orderId,\n organizationId: resolvedOrganizationId ?? undefined,\n tenantId: resolvedTenantId ?? undefined,\n },\n errorMessage: t('sales.documents.payments.errorDelete', 'Failed to delete payment.'),\n })\n if (result.ok) {\n onTotalsChange?.()\n flash(t('sales.documents.payments.deleted', 'Payment deleted.'), 'success')\n await loadPayments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n }\n } catch (err) {\n console.error('sales.payments.delete', err)\n flash(t('sales.documents.payments.errorDelete', 'Failed to delete payment.'), 'error')\n }\n },\n [loadPayments, onTotalsChange, orderId, resolvedOrganizationId, resolvedTenantId, t]\n )\n\n React.useEffect(() => {\n if (!onActionChange) return\n if (payments.length === 0) {\n onActionChange(null)\n return\n }\n onActionChange({\n label: addActionLabel,\n onClick: openCreate,\n disabled: loading,\n })\n return () => onActionChange(null)\n }, [addActionLabel, loading, onActionChange, openCreate, payments.length])\n\n const columns = React.useMemo<ColumnDef<PaymentRow>[]>(\n () => [\n {\n accessorKey: 'paymentReference',\n header: t('sales.documents.payments.reference', 'Reference'),\n cell: ({ row }) => row.original.paymentReference || '\u2014',\n },\n {\n accessorKey: 'paymentMethodName',\n header: t('sales.documents.payments.method', 'Method'),\n cell: ({ row }) => row.original.paymentMethodName ?? '\u2014',\n },\n {\n accessorKey: 'status',\n header: t('sales.documents.payments.status', 'Status'),\n cell: ({ row }) => row.original.statusLabel ?? row.original.status ?? '\u2014',\n },\n {\n accessorKey: 'amount',\n header: t('sales.documents.payments.amount', 'Amount'),\n cell: ({ row }) => formatMoney(row.original.amount, row.original.currencyCode ?? currencyCode),\n },\n {\n accessorKey: 'receivedAt',\n header: t('sales.documents.payments.receivedAt', 'Received'),\n cell: ({ row }) =>\n row.original.receivedAt\n ? new Date(row.original.receivedAt).toLocaleDateString()\n : '\u2014',\n },\n {\n accessorKey: 'createdAt',\n header: t('sales.documents.payments.createdAt', 'Created'),\n cell: ({ row }) =>\n row.original.createdAt ? new Date(row.original.createdAt).toLocaleString() : '\u2014',\n meta: {\n tooltipContent: (row: PaymentRow) =>\n row.createdAt ? new Date(row.createdAt).toLocaleString() : undefined,\n },\n },\n {\n id: 'actions',\n header: '',\n cell: ({ row }) => {\n return (\n <RowActions\n items={[\n { id: 'edit', label: editActionLabel, onSelect: () => openEditPayment(row.original) },\n {\n id: 'delete',\n label: deleteActionLabel,\n destructive: true,\n onSelect: () => void handleDelete(row.original),\n },\n ]}\n />\n )\n },\n },\n ],\n [currencyCode, deleteActionLabel, editActionLabel, handleDelete, openEditPayment, t]\n )\n\n if (loading) {\n return (\n <LoadingMessage\n label={t('sales.documents.payments.loading', 'Loading payments\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n )\n }\n\n if (error) {\n return (\n <ErrorMessage\n label={error}\n action={\n <Button variant=\"outline\" size=\"sm\" onClick={() => void loadPayments()}>\n {t('sales.documents.payments.retry', 'Retry')}\n </Button>\n }\n />\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {payments.length ? (\n <DataTable<PaymentRow> columns={columns} data={payments} onRowClick={openEditPayment} />\n ) : (\n <TabEmptyState\n title={t('sales.documents.payments.emptyTitle', 'No payments yet.')}\n description={t(\n 'sales.documents.payments.emptyDescription',\n 'Track received payments to keep outstanding balances up to date.'\n )}\n action={{\n label: addActionLabel,\n onClick: openCreate,\n icon: <Plus className=\"h-4 w-4\" aria-hidden />,\n disabled: loading,\n }}\n />\n )}\n\n <PaymentDialog\n open={dialogOpen}\n onOpenChange={handleDialogChange}\n mode={editingPayment ? 'edit' : 'create'}\n payment={editingPayment}\n currencyCode={editingPayment?.currencyCode ?? currencyCode}\n orderId={orderId}\n organizationId={resolvedOrganizationId}\n tenantId={resolvedTenantId}\n onSaved={handlePaymentSaved}\n />\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { LoadingMessage, ErrorMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport type { SectionAction } from '@open-mercato/ui/backend/detail'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { emitSalesDocumentTotalsRefresh } from '@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents'\nimport { PaymentDialog, type PaymentFormData, type PaymentTotals } from './PaymentDialog'\nimport { extractCustomFieldValues } from './customFieldHelpers'\nimport { Plus } from 'lucide-react'\n\ntype PaymentRow = {\n id: string\n paymentReference: string | null\n paymentMethodId: string | null\n paymentMethodName: string | null\n status: string | null\n statusEntryId: string | null\n statusLabel: string | null\n amount: number\n currencyCode: string | null\n receivedAt: string | null\n createdAt: string | null\n customValues?: Record<string, unknown> | null\n customFieldSetId?: string | null\n}\n\ntype SalesDocumentPaymentsSectionProps = {\n orderId: string\n currencyCode: string | null | undefined\n organizationId?: string | null\n tenantId?: string | null\n onActionChange?: (action: SectionAction | null) => void\n onTotalsChange?: () => void\n onPaymentsChange?: (payments: PaymentRow[]) => void\n}\n\nfunction normalizeNumber(value: unknown): 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 0\n}\n\nfunction formatMoney(value: number, currency: string | null | undefined): string {\n if (!currency || currency.trim().length !== 3) return value.toFixed(2)\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return `${currency.toUpperCase()} ${value.toFixed(2)}`\n }\n}\n\nexport function SalesDocumentPaymentsSection({\n orderId,\n currencyCode,\n organizationId: orgFromProps,\n tenantId: tenantFromProps,\n onActionChange,\n onTotalsChange,\n onPaymentsChange,\n}: SalesDocumentPaymentsSectionProps) {\n const t = useT()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const resolvedOrganizationId = orgFromProps ?? organizationId ?? null\n const resolvedTenantId = tenantFromProps ?? tenantId ?? null\n const [payments, setPayments] = React.useState<PaymentRow[]>([])\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 [editingPayment, setEditingPayment] = React.useState<PaymentFormData | null>(null)\n const onPaymentsChangeRef = React.useRef<typeof onPaymentsChange>(onPaymentsChange)\n\n React.useEffect(() => {\n onPaymentsChangeRef.current = onPaymentsChange\n }, [onPaymentsChange])\n\n const addActionLabel = t('sales.documents.payments.add', 'Add payment')\n const editActionLabel = t('sales.documents.payments.edit', 'Edit payment')\n const deleteActionLabel = t('sales.documents.payments.delete', 'Delete payment')\n\n const loadPayments = React.useCallback(async () => {\n setLoading(true)\n setError(null)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/payments?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n if (response.ok && Array.isArray(response.result?.items)) {\n const mapped = response.result.items.flatMap<PaymentRow>((item) => {\n if (typeof item.id !== 'string') return []\n const customValues =\n item && typeof item === 'object'\n ? extractCustomFieldValues(item as Record<string, unknown>)\n : {}\n const record: PaymentRow = {\n id: item.id,\n paymentReference: typeof item.payment_reference === 'string' ? item.payment_reference : null,\n paymentMethodId: typeof item.payment_method_id === 'string' ? item.payment_method_id : null,\n paymentMethodName:\n typeof item.payment_method_name === 'string'\n ? item.payment_method_name\n : typeof item.payment_method_code === 'string'\n ? item.payment_method_code\n : null,\n status: typeof item.status === 'string' ? item.status : null,\n statusEntryId:\n typeof (item as any).status_entry_id === 'string'\n ? (item as any).status_entry_id\n : typeof (item as any).statusEntryId === 'string'\n ? (item as any).statusEntryId\n : null,\n statusLabel:\n typeof (item as any).status_label === 'string'\n ? (item as any).status_label\n : typeof (item as any).statusLabel === 'string'\n ? (item as any).statusLabel\n : null,\n amount: normalizeNumber(item.amount),\n currencyCode:\n typeof item.currency_code === 'string'\n ? item.currency_code\n : typeof currencyCode === 'string'\n ? currencyCode\n : null,\n receivedAt: typeof item.received_at === 'string' ? item.received_at : null,\n createdAt: typeof item.created_at === 'string' ? item.created_at : null,\n customValues: Object.keys(customValues).length ? customValues : null,\n 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 }\n return [record]\n })\n setPayments(mapped)\n onPaymentsChangeRef.current?.(mapped)\n } else {\n setPayments([])\n onPaymentsChangeRef.current?.([])\n }\n } catch (err) {\n console.error('sales.payments.list', err)\n setError(t('sales.documents.payments.errorLoad', 'Failed to load payments.'))\n onPaymentsChangeRef.current?.([])\n } finally {\n setLoading(false)\n }\n }, [currencyCode, orderId, t])\n\n React.useEffect(() => {\n void loadPayments()\n }, [loadPayments])\n\n const openCreate = React.useCallback(() => {\n setEditingPayment(null)\n setDialogOpen(true)\n }, [])\n\n const handleDialogChange = React.useCallback((nextOpen: boolean) => {\n setDialogOpen(nextOpen)\n if (!nextOpen) {\n setEditingPayment(null)\n }\n }, [])\n\n const openEditPayment = React.useCallback(\n (record: PaymentRow) => {\n setEditingPayment({\n id: record.id,\n amount: record.amount ?? '',\n paymentMethodId: record.paymentMethodId ?? '',\n paymentReference: record.paymentReference ?? '',\n receivedAt: record.receivedAt ? record.receivedAt.slice(0, 10) : '',\n currencyCode: record.currencyCode ?? currencyCode ?? null,\n statusEntryId: record.statusEntryId ?? null,\n customValues: record.customValues ?? null,\n customFieldSetId: record.customFieldSetId ?? null,\n })\n setDialogOpen(true)\n },\n [currencyCode]\n )\n\n const handlePaymentSaved = React.useCallback(\n async (_totals?: PaymentTotals | null) => {\n onTotalsChange?.()\n await loadPayments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n handleDialogChange(false)\n },\n [handleDialogChange, loadPayments, onTotalsChange, orderId]\n )\n\n const handleDelete = React.useCallback(\n async (row: PaymentRow) => {\n try {\n const result = await deleteCrud<{ orderTotals?: PaymentTotals | null }>('sales/payments', {\n body: {\n id: row.id,\n orderId,\n organizationId: resolvedOrganizationId ?? undefined,\n tenantId: resolvedTenantId ?? undefined,\n },\n errorMessage: t('sales.documents.payments.errorDelete', 'Failed to delete payment.'),\n })\n if (result.ok) {\n onTotalsChange?.()\n flash(t('sales.documents.payments.deleted', 'Payment deleted.'), 'success')\n await loadPayments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n }\n } catch (err) {\n console.error('sales.payments.delete', err)\n flash(t('sales.documents.payments.errorDelete', 'Failed to delete payment.'), 'error')\n }\n },\n [loadPayments, onTotalsChange, orderId, resolvedOrganizationId, resolvedTenantId, t]\n )\n\n React.useEffect(() => {\n if (!onActionChange) return\n onActionChange({\n label: addActionLabel,\n onClick: openCreate,\n disabled: false,\n })\n return () => onActionChange(null)\n }, [addActionLabel, onActionChange, openCreate])\n\n const columns = React.useMemo<ColumnDef<PaymentRow>[]>(\n () => [\n {\n accessorKey: 'paymentReference',\n header: t('sales.documents.payments.reference', 'Reference'),\n cell: ({ row }) => row.original.paymentReference || '\u2014',\n },\n {\n accessorKey: 'paymentMethodName',\n header: t('sales.documents.payments.method', 'Method'),\n cell: ({ row }) => row.original.paymentMethodName ?? '\u2014',\n },\n {\n accessorKey: 'status',\n header: t('sales.documents.payments.status', 'Status'),\n cell: ({ row }) => row.original.statusLabel ?? row.original.status ?? '\u2014',\n },\n {\n accessorKey: 'amount',\n header: t('sales.documents.payments.amount', 'Amount'),\n cell: ({ row }) => formatMoney(row.original.amount, row.original.currencyCode ?? currencyCode),\n },\n {\n accessorKey: 'receivedAt',\n header: t('sales.documents.payments.receivedAt', 'Received'),\n cell: ({ row }) =>\n row.original.receivedAt\n ? new Date(row.original.receivedAt).toLocaleDateString()\n : '\u2014',\n },\n {\n accessorKey: 'createdAt',\n header: t('sales.documents.payments.createdAt', 'Created'),\n cell: ({ row }) =>\n row.original.createdAt ? new Date(row.original.createdAt).toLocaleString() : '\u2014',\n meta: {\n tooltipContent: (row: PaymentRow) =>\n row.createdAt ? new Date(row.createdAt).toLocaleString() : undefined,\n },\n },\n {\n id: 'actions',\n header: '',\n cell: ({ row }) => {\n return (\n <RowActions\n items={[\n { id: 'edit', label: editActionLabel, onSelect: () => openEditPayment(row.original) },\n {\n id: 'delete',\n label: deleteActionLabel,\n destructive: true,\n onSelect: () => void handleDelete(row.original),\n },\n ]}\n />\n )\n },\n },\n ],\n [currencyCode, deleteActionLabel, editActionLabel, handleDelete, openEditPayment, t]\n )\n\n if (loading) {\n return (\n <LoadingMessage\n label={t('sales.documents.payments.loading', 'Loading payments\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n )\n }\n\n if (error) {\n return (\n <ErrorMessage\n label={error}\n action={\n <Button variant=\"outline\" size=\"sm\" onClick={() => void loadPayments()}>\n {t('sales.documents.payments.retry', 'Retry')}\n </Button>\n }\n />\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {payments.length ? (\n <DataTable<PaymentRow> columns={columns} data={payments} onRowClick={openEditPayment} />\n ) : (\n <TabEmptyState\n title={t('sales.documents.payments.emptyTitle', 'No payments yet.')}\n description={t(\n 'sales.documents.payments.emptyDescription',\n 'Track received payments to keep outstanding balances up to date.'\n )}\n action={{\n label: addActionLabel,\n onClick: openCreate,\n icon: <Plus className=\"h-4 w-4\" aria-hidden />,\n disabled: loading,\n }}\n />\n )}\n\n <PaymentDialog\n open={dialogOpen}\n onOpenChange={handleDialogChange}\n mode={editingPayment ? 'edit' : 'create'}\n payment={editingPayment}\n currencyCode={editingPayment?.currencyCode ?? currencyCode}\n orderId={orderId}\n organizationId={resolvedOrganizationId}\n tenantId={resolvedTenantId}\n onSaved={handlePaymentSaved}\n />\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -224,17 +224,13 @@ function SalesShipmentsSection({
224
224
  }, []);
225
225
  React.useEffect(() => {
226
226
  if (!onActionChange) return;
227
- if (shipments.length === 0) {
228
- onActionChange(null);
229
- return;
230
- }
231
227
  onActionChange({
232
228
  label: addShipmentLabel,
233
229
  onClick: handleOpenCreate,
234
- disabled: loading
230
+ disabled: false
235
231
  });
236
232
  return () => onActionChange(null);
237
- }, [addShipmentLabel, handleOpenCreate, loading, onActionChange, shipments.length]);
233
+ }, [addShipmentLabel, handleOpenCreate, onActionChange]);
238
234
  const handleEdit = React.useCallback((shipment) => {
239
235
  setDialogState({ mode: "edit", shipment });
240
236
  }, []);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/sales/components/documents/ShipmentsSection.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Pencil, Plus, Trash2, Truck } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { ErrorMessage, LoadingMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\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 { generateTempId } from '@open-mercato/core/modules/customers/lib/detailHelpers'\nimport { formatAddressString, type AddressValue } from '@open-mercato/core/modules/customers/utils/addressFormat'\nimport { ShipmentDialog } from './ShipmentDialog'\nimport { extractCustomFieldValues } from './customFieldHelpers'\nimport type { OrderLine, ShipmentRow, ShipmentItem } from './shipmentTypes'\n\nconst ADDRESS_SNAPSHOT_KEY = 'shipmentAddressSnapshot'\nconst ADDRESS_FORMAT: 'line_first' = 'line_first'\n\ntype SalesShipmentsSectionProps = {\n orderId: string\n currencyCode?: string | null\n shippingAddressSnapshot?: Record<string, unknown> | null\n organizationId?: string | null\n tenantId?: string | null\n onActionChange?: (action: SectionAction | null) => void\n onAddComment?: (body: string) => Promise<void>\n}\n\nfunction formatDisplayDate(value: string | null | undefined): string | null {\n if (!value) return null\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return null\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium' }).format(date)\n}\n\nconst formatShipmentAddress = (metadata?: Record<string, unknown> | null): string | null => {\n if (!metadata || typeof metadata !== 'object') return null\n const snapshot = (metadata as any)[ADDRESS_SNAPSHOT_KEY]\n if (!snapshot || typeof snapshot !== 'object' || Array.isArray(snapshot)) return null\n const read = (key: string): string | null => {\n const value = (snapshot as any)[key]\n return typeof value === 'string' && value.trim().length ? value.trim() : null\n }\n const addressValue: AddressValue = {\n addressLine1: read('addressLine1') ?? read('address_line1'),\n addressLine2: read('addressLine2') ?? read('address_line2'),\n buildingNumber: read('buildingNumber') ?? read('building_number'),\n flatNumber: read('flatNumber') ?? read('flat_number'),\n city: read('city'),\n region: read('region'),\n postalCode: read('postalCode') ?? read('postal_code'),\n country: read('country'),\n companyName: read('companyName') ?? read('company_name'),\n }\n const summary = formatAddressString(addressValue, ADDRESS_FORMAT)\n return summary && summary.trim().length ? summary : null\n}\n\nconst resolveLineThumbnail = (item: Record<string, unknown>): string | null => {\n const pickThumbnail = (...candidates: Array<unknown>): string | null => {\n const found = candidates.find(\n (candidate): candidate is string =>\n typeof candidate === 'string' && candidate.trim().length > 0,\n )\n return found ?? null\n }\n\n const metadata =\n typeof (item as any).metadata === 'object' && (item as any).metadata !== null\n ? ((item as any).metadata as Record<string, unknown>)\n : null\n const snapshot =\n typeof (item as any).catalog_snapshot === 'object' && (item as any).catalog_snapshot !== null\n ? ((item as any).catalog_snapshot as Record<string, unknown>)\n : null\n const productSnapshot =\n snapshot && typeof (snapshot as any).product === 'object' ? ((snapshot as any).product as Record<string, unknown>) : null\n const variantSnapshot =\n snapshot && typeof (snapshot as any).variant === 'object' ? ((snapshot as any).variant as Record<string, unknown>) : null\n\n const productThumb = pickThumbnail(\n metadata ? (metadata as any).productThumbnail : null,\n productSnapshot ? (productSnapshot as any).thumbnailUrl : null,\n productSnapshot ? (productSnapshot as any).thumbnail_url : null,\n )\n const variantThumb = pickThumbnail(\n metadata ? (metadata as any).variantThumbnail : null,\n variantSnapshot ? (variantSnapshot as any).thumbnailUrl : null,\n variantSnapshot ? (variantSnapshot as any).thumbnail_url : null,\n )\n\n const snapshotThumb = pickThumbnail(\n snapshot ? (snapshot as any).thumbnailUrl : null,\n snapshot ? (snapshot as any).thumbnail_url : null,\n )\n\n return variantThumb ?? productThumb ?? snapshotThumb ?? null\n}\n\nexport function SalesShipmentsSection({\n orderId,\n currencyCode,\n shippingAddressSnapshot,\n organizationId: organizationIdProp,\n tenantId: tenantIdProp,\n onActionChange,\n onAddComment,\n}: SalesShipmentsSectionProps) {\n const t = useT()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const resolvedOrganizationId = organizationIdProp ?? organizationId ?? null\n const resolvedTenantId = tenantIdProp ?? tenantId ?? null\n const addShipmentLabel = React.useMemo(\n () => t('sales.documents.shipments.add', 'Add shipment'),\n [t]\n )\n const [shipments, setShipments] = React.useState<ShipmentRow[]>([])\n const [lines, setLines] = React.useState<OrderLine[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const [dialogState, setDialogState] = React.useState<{ mode: 'create' | 'edit'; shipment: ShipmentRow | null } | null>(null)\n\n const lineMap = React.useMemo(() => new Map(lines.map((line) => [line.id, line])), [lines])\n\n const shippedTotals = React.useMemo(() => {\n const totals = new Map<string, number>()\n shipments.forEach((shipment) => {\n shipment.items.forEach((item) => {\n const current = totals.get(item.orderLineId) ?? 0\n totals.set(item.orderLineId, current + (Number.isFinite(item.quantity) ? item.quantity : 0))\n })\n })\n return totals\n }, [shipments])\n\n const computeAvailable = React.useCallback(\n (lineId: string, excludeShipmentId?: string | null) => {\n const line = lineMap.get(lineId)\n if (!line) return 0\n const shipped = shippedTotals.get(lineId) ?? 0\n const editingShipment = excludeShipmentId ? shipments.find((entry) => entry.id === excludeShipmentId) : null\n const editingQty =\n editingShipment?.items\n .filter((item) => item.orderLineId === lineId)\n .reduce((acc, item) => acc + (Number.isFinite(item.quantity) ? item.quantity : 0), 0) ?? 0\n const remaining = line.quantity - (shipped - editingQty)\n return remaining < 0 ? 0 : remaining\n },\n [lineMap, shipments, shippedTotals]\n )\n\n const loadLines = React.useCallback(async () => {\n const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/order-lines?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result?.items ?? [] : []\n const mapped: OrderLine[] = items\n .map((item) => {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const name =\n typeof item.name === 'string'\n ? item.name\n : typeof (item as any).catalog_snapshot === 'object' &&\n (item as any).catalog_snapshot &&\n typeof (item as any).catalog_snapshot.name === 'string'\n ? (item as any).catalog_snapshot.name\n : null\n const lineNumber =\n typeof (item as any).line_number === 'number'\n ? (item as any).line_number\n : typeof (item as any).lineNumber === 'number'\n ? (item as any).lineNumber\n : null\n const quantity =\n typeof item.quantity === 'number'\n ? item.quantity\n : typeof (item as any).quantity === 'string'\n ? Number((item as any).quantity)\n : 0\n return {\n id,\n title: name ?? id,\n lineNumber,\n quantity: Number.isFinite(quantity) ? quantity : 0,\n thumbnail: resolveLineThumbnail(item as Record<string, unknown>),\n }\n })\n .filter((entry): entry is OrderLine => Boolean(entry?.id))\n setLines(mapped)\n }, [orderId])\n\n const loadShipments = React.useCallback(async () => {\n setLoading(true)\n setError(null)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/shipments?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result?.items ?? [] : []\n const mapped: ShipmentRow[] = items\n .map((item) => {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const snapshotItemsRaw = Array.isArray((item as any).items_snapshot)\n ? ((item as any).items_snapshot as Array<Record<string, unknown>>)\n : []\n const responseItems = Array.isArray((item as any).items)\n ? ((item as any).items as Array<Record<string, unknown>>)\n : []\n const itemsRaw = responseItems.length ? responseItems : snapshotItemsRaw\n const shipmentItems: ShipmentItem[] = itemsRaw\n .map((entry) => {\n const lineId =\n typeof entry.orderLineId === 'string'\n ? entry.orderLineId\n : typeof (entry as any).order_line_id === 'string'\n ? (entry as any).order_line_id\n : null\n if (!lineId) return null\n const quantity =\n typeof entry.quantity === 'number'\n ? entry.quantity\n : typeof (entry as any).quantity === 'string'\n ? Number((entry as any).quantity)\n : 0\n return {\n id: typeof entry.id === 'string' ? entry.id : generateTempId(),\n orderLineId: lineId,\n orderLineName:\n typeof entry.orderLineName === 'string'\n ? entry.orderLineName\n : typeof (entry as any).order_line_name === 'string'\n ? (entry as any).order_line_name\n : null,\n orderLineNumber:\n typeof entry.orderLineNumber === 'number'\n ? entry.orderLineNumber\n : typeof (entry as any).order_line_number === 'number'\n ? (entry as any).order_line_number\n : null,\n quantity: Number.isFinite(quantity) ? quantity : 0,\n metadata: (entry.metadata as Record<string, unknown> | undefined | null) ?? null,\n }\n })\n .filter((entry): entry is ShipmentItem => Boolean(entry))\n const tracking =\n Array.isArray((item as any).tracking_numbers) && (item as any).tracking_numbers.length\n ? ((item as any).tracking_numbers as string[])\n : []\n const customValues = extractCustomFieldValues(item as Record<string, unknown>)\n return {\n id,\n shipmentNumber:\n typeof (item as any).shipment_number === 'string'\n ? (item as any).shipment_number\n : typeof (item as any).shipmentNumber === 'string'\n ? (item as any).shipmentNumber\n : null,\n shippingMethodId:\n typeof (item as any).shipping_method_id === 'string'\n ? (item as any).shipping_method_id\n : typeof (item as any).shippingMethodId === 'string'\n ? (item as any).shippingMethodId\n : null,\n shippingMethodCode:\n typeof (item as any).shipping_method_code === 'string'\n ? (item as any).shipping_method_code\n : typeof (item as any).shippingMethodCode === 'string'\n ? (item as any).shippingMethodCode\n : null,\n shippingMethodName:\n typeof (item as any).shipping_method_name === 'string'\n ? (item as any).shipping_method_name\n : typeof (item as any).shippingMethodName === 'string'\n ? (item as any).shippingMethodName\n : null,\n status:\n typeof item.status === 'string'\n ? item.status\n : typeof (item as any).status === 'string'\n ? (item as any).status\n : null,\n statusLabel:\n typeof (item as any).status_label === 'string'\n ? (item as any).status_label\n : typeof (item as any).statusLabel === 'string'\n ? (item as any).statusLabel\n : null,\n statusEntryId:\n typeof (item as any).status_entry_id === 'string'\n ? (item as any).status_entry_id\n : typeof (item as any).statusEntryId === 'string'\n ? (item as any).statusEntryId\n : null,\n carrierName:\n typeof (item as any).carrier_name === 'string'\n ? (item as any).carrier_name\n : typeof (item as any).carrierName === 'string'\n ? (item as any).carrierName\n : null,\n trackingNumbers: tracking,\n shippedAt:\n typeof (item as any).shipped_at === 'string'\n ? (item as any).shipped_at\n : typeof (item as any).shippedAt === 'string'\n ? (item as any).shippedAt\n : null,\n deliveredAt:\n typeof (item as any).delivered_at === 'string'\n ? (item as any).delivered_at\n : typeof (item as any).deliveredAt === 'string'\n ? (item as any).deliveredAt\n : null,\n notes:\n typeof (item as any).notes === 'string'\n ? (item as any).notes\n : typeof (item as any).notesText === 'string'\n ? (item as any).notesText\n : null,\n metadata: (item as Record<string, unknown> | null | undefined)?.metadata ?? null,\n customValues: Object.keys(customValues).length ? customValues : null,\n items: shipmentItems,\n createdAt:\n typeof (item as any).created_at === 'string'\n ? (item as any).created_at\n : typeof (item as any).createdAt === 'string'\n ? (item as any).createdAt\n : null,\n }\n })\n .filter((entry): entry is ShipmentRow => Boolean(entry))\n setShipments(mapped)\n } catch (err) {\n console.error('sales.shipments.load', err)\n setError(t('sales.documents.shipments.errorLoad', 'Failed to load shipments.'))\n } finally {\n setLoading(false)\n }\n }, [orderId, t])\n\n React.useEffect(() => {\n void loadLines()\n void loadShipments()\n }, [loadLines, loadShipments])\n\n React.useEffect(\n () =>\n subscribeSalesDocumentTotalsRefresh((detail) => {\n if (detail.documentId !== orderId) return\n if (detail.kind && detail.kind !== 'order') return\n void loadLines()\n void loadShipments()\n }),\n [loadLines, loadShipments, orderId],\n )\n\n const handleOpenCreate = React.useCallback(() => {\n setDialogState({ mode: 'create', shipment: null })\n }, [])\n\n React.useEffect(() => {\n if (!onActionChange) return\n if (shipments.length === 0) {\n onActionChange(null)\n return\n }\n onActionChange({\n label: addShipmentLabel,\n onClick: handleOpenCreate,\n disabled: loading,\n })\n return () => onActionChange(null)\n }, [addShipmentLabel, handleOpenCreate, loading, onActionChange, shipments.length])\n\n const handleEdit = React.useCallback((shipment: ShipmentRow) => {\n setDialogState({ mode: 'edit', shipment })\n }, [])\n\n const handleDelete = React.useCallback(\n async (shipment: ShipmentRow) => {\n const confirmed = await confirm({\n title: t('sales.documents.shipments.confirmDelete', 'Delete this shipment?'),\n variant: 'default',\n })\n if (!confirmed) return\n try {\n const result = await deleteCrud('sales/shipments', {\n body: {\n id: shipment.id,\n orderId,\n organizationId: resolvedOrganizationId,\n tenantId: resolvedTenantId,\n },\n errorMessage: t('sales.documents.shipments.errorDelete', 'Failed to delete shipment.'),\n })\n if (result.ok) {\n await loadShipments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n }\n } catch (err) {\n console.error('sales.shipments.delete', err)\n flash(t('sales.documents.shipments.errorDelete', 'Failed to delete shipment.'), 'error')\n }\n },\n [confirm, loadShipments, orderId, resolvedOrganizationId, resolvedTenantId, t]\n )\n\n const renderItemList = (items: ShipmentItem[]) => (\n <ul className=\"space-y-1 text-sm text-muted-foreground\">\n {items.map((item) => {\n const label = item.orderLineNumber ? `#${item.orderLineNumber}` : ''\n return (\n <li key={item.id} className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate\">\n {label ? `${label} \u00B7 ` : null}\n {item.orderLineName ?? item.orderLineId}\n </span>\n <Badge variant=\"secondary\">{item.quantity}</Badge>\n </li>\n )\n })}\n </ul>\n )\n\n if (loading) {\n return (\n <LoadingMessage\n label={t('sales.documents.shipments.loading', 'Loading shipments\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n )\n }\n\n if (error) {\n return <ErrorMessage label={error} />\n }\n\n const empty = !shipments.length\n\n return (\n <div className=\"space-y-4\">\n {empty ? (\n <TabEmptyState\n title={t('sales.documents.shipments.empty.title', 'No shipments yet.')}\n description={t(\n 'sales.documents.shipments.empty.description',\n 'Add shipments for this document to let the user track the order.'\n )}\n action={{\n label: addShipmentLabel,\n onClick: handleOpenCreate,\n icon: <Plus className=\"h-4 w-4\" aria-hidden />,\n disabled: loading,\n }}\n />\n ) : (\n <div className=\"grid gap-3 md:grid-cols-2\">\n {shipments.map((shipment) => {\n const shippedAt = formatDisplayDate(shipment.shippedAt)\n const deliveredAt = formatDisplayDate(shipment.deliveredAt)\n const addressSummary = formatShipmentAddress(shipment.metadata)\n const statusLabel =\n shipment.statusLabel ??\n shipment.status ??\n t('sales.documents.shipments.statusMissing', 'Status pending')\n return (\n <div key={shipment.id} className=\"rounded-lg border bg-card p-4 shadow-sm\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Truck className=\"h-5 w-5\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold\">\n {shipment.shipmentNumber\n ? t('sales.documents.shipments.numberLabel', 'Shipment {{number}}', {\n number: shipment.shipmentNumber,\n })\n : t('sales.documents.shipments.fallbackNumber', 'Shipment {{id}}', {\n id: shipment.id.slice(0, 6),\n })}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {statusLabel}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => handleEdit(shipment)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive\"\n onClick={() => void handleDelete(shipment)}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n <div className=\"mt-3 space-y-2 text-sm\">\n <div className=\"flex flex-wrap items-center gap-2 text-muted-foreground\">\n {shipment.carrierName ? (\n <Badge variant=\"outline\">{shipment.carrierName}</Badge>\n ) : null}\n {shipment.trackingNumbers.length ? (\n <span className=\"truncate\">\n {t('sales.documents.shipments.tracking', 'Tracking')}: {shipment.trackingNumbers.join(', ')}\n </span>\n ) : null}\n </div>\n {shippedAt ? (\n <p className=\"text-muted-foreground\">\n {t('sales.documents.shipments.shippedOn', 'Shipped on {{date}}', { date: shippedAt })}\n </p>\n ) : null}\n {deliveredAt ? (\n <p className=\"text-muted-foreground\">\n {t('sales.documents.shipments.deliveredOn', 'Delivered on {{date}}', { date: deliveredAt })}\n </p>\n ) : null}\n {addressSummary ? (\n <p className=\"text-xs text-muted-foreground\">{addressSummary}</p>\n ) : null}\n {shipment.notes ? (\n <p className=\"rounded-md bg-muted px-3 py-2 text-muted-foreground\">\n {shipment.notes}\n </p>\n ) : null}\n {renderItemList(shipment.items)}\n </div>\n </div>\n )\n })}\n </div>\n )}\n\n <ShipmentDialog\n open={dialogState !== null}\n mode={dialogState?.mode ?? 'create'}\n shipment={dialogState?.shipment ?? null}\n lines={lines}\n orderId={orderId}\n currencyCode={currencyCode}\n organizationId={resolvedOrganizationId}\n tenantId={resolvedTenantId}\n computeAvailable={computeAvailable}\n shippingAddressSnapshot={shippingAddressSnapshot}\n onClose={() => setDialogState(null)}\n onSaved={async () => {\n await loadShipments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n setDialogState(null)\n }}\n onAddComment={onAddComment}\n />\n {ConfirmDialogElement}\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Pencil, Plus, Trash2, Truck } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { ErrorMessage, LoadingMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\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 { generateTempId } from '@open-mercato/core/modules/customers/lib/detailHelpers'\nimport { formatAddressString, type AddressValue } from '@open-mercato/core/modules/customers/utils/addressFormat'\nimport { ShipmentDialog } from './ShipmentDialog'\nimport { extractCustomFieldValues } from './customFieldHelpers'\nimport type { OrderLine, ShipmentRow, ShipmentItem } from './shipmentTypes'\n\nconst ADDRESS_SNAPSHOT_KEY = 'shipmentAddressSnapshot'\nconst ADDRESS_FORMAT: 'line_first' = 'line_first'\n\ntype SalesShipmentsSectionProps = {\n orderId: string\n currencyCode?: string | null\n shippingAddressSnapshot?: Record<string, unknown> | null\n organizationId?: string | null\n tenantId?: string | null\n onActionChange?: (action: SectionAction | null) => void\n onAddComment?: (body: string) => Promise<void>\n}\n\nfunction formatDisplayDate(value: string | null | undefined): string | null {\n if (!value) return null\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return null\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium' }).format(date)\n}\n\nconst formatShipmentAddress = (metadata?: Record<string, unknown> | null): string | null => {\n if (!metadata || typeof metadata !== 'object') return null\n const snapshot = (metadata as any)[ADDRESS_SNAPSHOT_KEY]\n if (!snapshot || typeof snapshot !== 'object' || Array.isArray(snapshot)) return null\n const read = (key: string): string | null => {\n const value = (snapshot as any)[key]\n return typeof value === 'string' && value.trim().length ? value.trim() : null\n }\n const addressValue: AddressValue = {\n addressLine1: read('addressLine1') ?? read('address_line1'),\n addressLine2: read('addressLine2') ?? read('address_line2'),\n buildingNumber: read('buildingNumber') ?? read('building_number'),\n flatNumber: read('flatNumber') ?? read('flat_number'),\n city: read('city'),\n region: read('region'),\n postalCode: read('postalCode') ?? read('postal_code'),\n country: read('country'),\n companyName: read('companyName') ?? read('company_name'),\n }\n const summary = formatAddressString(addressValue, ADDRESS_FORMAT)\n return summary && summary.trim().length ? summary : null\n}\n\nconst resolveLineThumbnail = (item: Record<string, unknown>): string | null => {\n const pickThumbnail = (...candidates: Array<unknown>): string | null => {\n const found = candidates.find(\n (candidate): candidate is string =>\n typeof candidate === 'string' && candidate.trim().length > 0,\n )\n return found ?? null\n }\n\n const metadata =\n typeof (item as any).metadata === 'object' && (item as any).metadata !== null\n ? ((item as any).metadata as Record<string, unknown>)\n : null\n const snapshot =\n typeof (item as any).catalog_snapshot === 'object' && (item as any).catalog_snapshot !== null\n ? ((item as any).catalog_snapshot as Record<string, unknown>)\n : null\n const productSnapshot =\n snapshot && typeof (snapshot as any).product === 'object' ? ((snapshot as any).product as Record<string, unknown>) : null\n const variantSnapshot =\n snapshot && typeof (snapshot as any).variant === 'object' ? ((snapshot as any).variant as Record<string, unknown>) : null\n\n const productThumb = pickThumbnail(\n metadata ? (metadata as any).productThumbnail : null,\n productSnapshot ? (productSnapshot as any).thumbnailUrl : null,\n productSnapshot ? (productSnapshot as any).thumbnail_url : null,\n )\n const variantThumb = pickThumbnail(\n metadata ? (metadata as any).variantThumbnail : null,\n variantSnapshot ? (variantSnapshot as any).thumbnailUrl : null,\n variantSnapshot ? (variantSnapshot as any).thumbnail_url : null,\n )\n\n const snapshotThumb = pickThumbnail(\n snapshot ? (snapshot as any).thumbnailUrl : null,\n snapshot ? (snapshot as any).thumbnail_url : null,\n )\n\n return variantThumb ?? productThumb ?? snapshotThumb ?? null\n}\n\nexport function SalesShipmentsSection({\n orderId,\n currencyCode,\n shippingAddressSnapshot,\n organizationId: organizationIdProp,\n tenantId: tenantIdProp,\n onActionChange,\n onAddComment,\n}: SalesShipmentsSectionProps) {\n const t = useT()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const resolvedOrganizationId = organizationIdProp ?? organizationId ?? null\n const resolvedTenantId = tenantIdProp ?? tenantId ?? null\n const addShipmentLabel = React.useMemo(\n () => t('sales.documents.shipments.add', 'Add shipment'),\n [t]\n )\n const [shipments, setShipments] = React.useState<ShipmentRow[]>([])\n const [lines, setLines] = React.useState<OrderLine[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const [dialogState, setDialogState] = React.useState<{ mode: 'create' | 'edit'; shipment: ShipmentRow | null } | null>(null)\n\n const lineMap = React.useMemo(() => new Map(lines.map((line) => [line.id, line])), [lines])\n\n const shippedTotals = React.useMemo(() => {\n const totals = new Map<string, number>()\n shipments.forEach((shipment) => {\n shipment.items.forEach((item) => {\n const current = totals.get(item.orderLineId) ?? 0\n totals.set(item.orderLineId, current + (Number.isFinite(item.quantity) ? item.quantity : 0))\n })\n })\n return totals\n }, [shipments])\n\n const computeAvailable = React.useCallback(\n (lineId: string, excludeShipmentId?: string | null) => {\n const line = lineMap.get(lineId)\n if (!line) return 0\n const shipped = shippedTotals.get(lineId) ?? 0\n const editingShipment = excludeShipmentId ? shipments.find((entry) => entry.id === excludeShipmentId) : null\n const editingQty =\n editingShipment?.items\n .filter((item) => item.orderLineId === lineId)\n .reduce((acc, item) => acc + (Number.isFinite(item.quantity) ? item.quantity : 0), 0) ?? 0\n const remaining = line.quantity - (shipped - editingQty)\n return remaining < 0 ? 0 : remaining\n },\n [lineMap, shipments, shippedTotals]\n )\n\n const loadLines = React.useCallback(async () => {\n const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/order-lines?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result?.items ?? [] : []\n const mapped: OrderLine[] = items\n .map((item) => {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const name =\n typeof item.name === 'string'\n ? item.name\n : typeof (item as any).catalog_snapshot === 'object' &&\n (item as any).catalog_snapshot &&\n typeof (item as any).catalog_snapshot.name === 'string'\n ? (item as any).catalog_snapshot.name\n : null\n const lineNumber =\n typeof (item as any).line_number === 'number'\n ? (item as any).line_number\n : typeof (item as any).lineNumber === 'number'\n ? (item as any).lineNumber\n : null\n const quantity =\n typeof item.quantity === 'number'\n ? item.quantity\n : typeof (item as any).quantity === 'string'\n ? Number((item as any).quantity)\n : 0\n return {\n id,\n title: name ?? id,\n lineNumber,\n quantity: Number.isFinite(quantity) ? quantity : 0,\n thumbnail: resolveLineThumbnail(item as Record<string, unknown>),\n }\n })\n .filter((entry): entry is OrderLine => Boolean(entry?.id))\n setLines(mapped)\n }, [orderId])\n\n const loadShipments = React.useCallback(async () => {\n setLoading(true)\n setError(null)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/shipments?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result?.items ?? [] : []\n const mapped: ShipmentRow[] = items\n .map((item) => {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const snapshotItemsRaw = Array.isArray((item as any).items_snapshot)\n ? ((item as any).items_snapshot as Array<Record<string, unknown>>)\n : []\n const responseItems = Array.isArray((item as any).items)\n ? ((item as any).items as Array<Record<string, unknown>>)\n : []\n const itemsRaw = responseItems.length ? responseItems : snapshotItemsRaw\n const shipmentItems: ShipmentItem[] = itemsRaw\n .map((entry) => {\n const lineId =\n typeof entry.orderLineId === 'string'\n ? entry.orderLineId\n : typeof (entry as any).order_line_id === 'string'\n ? (entry as any).order_line_id\n : null\n if (!lineId) return null\n const quantity =\n typeof entry.quantity === 'number'\n ? entry.quantity\n : typeof (entry as any).quantity === 'string'\n ? Number((entry as any).quantity)\n : 0\n return {\n id: typeof entry.id === 'string' ? entry.id : generateTempId(),\n orderLineId: lineId,\n orderLineName:\n typeof entry.orderLineName === 'string'\n ? entry.orderLineName\n : typeof (entry as any).order_line_name === 'string'\n ? (entry as any).order_line_name\n : null,\n orderLineNumber:\n typeof entry.orderLineNumber === 'number'\n ? entry.orderLineNumber\n : typeof (entry as any).order_line_number === 'number'\n ? (entry as any).order_line_number\n : null,\n quantity: Number.isFinite(quantity) ? quantity : 0,\n metadata: (entry.metadata as Record<string, unknown> | undefined | null) ?? null,\n }\n })\n .filter((entry): entry is ShipmentItem => Boolean(entry))\n const tracking =\n Array.isArray((item as any).tracking_numbers) && (item as any).tracking_numbers.length\n ? ((item as any).tracking_numbers as string[])\n : []\n const customValues = extractCustomFieldValues(item as Record<string, unknown>)\n return {\n id,\n shipmentNumber:\n typeof (item as any).shipment_number === 'string'\n ? (item as any).shipment_number\n : typeof (item as any).shipmentNumber === 'string'\n ? (item as any).shipmentNumber\n : null,\n shippingMethodId:\n typeof (item as any).shipping_method_id === 'string'\n ? (item as any).shipping_method_id\n : typeof (item as any).shippingMethodId === 'string'\n ? (item as any).shippingMethodId\n : null,\n shippingMethodCode:\n typeof (item as any).shipping_method_code === 'string'\n ? (item as any).shipping_method_code\n : typeof (item as any).shippingMethodCode === 'string'\n ? (item as any).shippingMethodCode\n : null,\n shippingMethodName:\n typeof (item as any).shipping_method_name === 'string'\n ? (item as any).shipping_method_name\n : typeof (item as any).shippingMethodName === 'string'\n ? (item as any).shippingMethodName\n : null,\n status:\n typeof item.status === 'string'\n ? item.status\n : typeof (item as any).status === 'string'\n ? (item as any).status\n : null,\n statusLabel:\n typeof (item as any).status_label === 'string'\n ? (item as any).status_label\n : typeof (item as any).statusLabel === 'string'\n ? (item as any).statusLabel\n : null,\n statusEntryId:\n typeof (item as any).status_entry_id === 'string'\n ? (item as any).status_entry_id\n : typeof (item as any).statusEntryId === 'string'\n ? (item as any).statusEntryId\n : null,\n carrierName:\n typeof (item as any).carrier_name === 'string'\n ? (item as any).carrier_name\n : typeof (item as any).carrierName === 'string'\n ? (item as any).carrierName\n : null,\n trackingNumbers: tracking,\n shippedAt:\n typeof (item as any).shipped_at === 'string'\n ? (item as any).shipped_at\n : typeof (item as any).shippedAt === 'string'\n ? (item as any).shippedAt\n : null,\n deliveredAt:\n typeof (item as any).delivered_at === 'string'\n ? (item as any).delivered_at\n : typeof (item as any).deliveredAt === 'string'\n ? (item as any).deliveredAt\n : null,\n notes:\n typeof (item as any).notes === 'string'\n ? (item as any).notes\n : typeof (item as any).notesText === 'string'\n ? (item as any).notesText\n : null,\n metadata: (item as Record<string, unknown> | null | undefined)?.metadata ?? null,\n customValues: Object.keys(customValues).length ? customValues : null,\n items: shipmentItems,\n createdAt:\n typeof (item as any).created_at === 'string'\n ? (item as any).created_at\n : typeof (item as any).createdAt === 'string'\n ? (item as any).createdAt\n : null,\n }\n })\n .filter((entry): entry is ShipmentRow => Boolean(entry))\n setShipments(mapped)\n } catch (err) {\n console.error('sales.shipments.load', err)\n setError(t('sales.documents.shipments.errorLoad', 'Failed to load shipments.'))\n } finally {\n setLoading(false)\n }\n }, [orderId, t])\n\n React.useEffect(() => {\n void loadLines()\n void loadShipments()\n }, [loadLines, loadShipments])\n\n React.useEffect(\n () =>\n subscribeSalesDocumentTotalsRefresh((detail) => {\n if (detail.documentId !== orderId) return\n if (detail.kind && detail.kind !== 'order') return\n void loadLines()\n void loadShipments()\n }),\n [loadLines, loadShipments, orderId],\n )\n\n const handleOpenCreate = React.useCallback(() => {\n setDialogState({ mode: 'create', shipment: null })\n }, [])\n\n React.useEffect(() => {\n if (!onActionChange) return\n onActionChange({\n label: addShipmentLabel,\n onClick: handleOpenCreate,\n disabled: false,\n })\n return () => onActionChange(null)\n }, [addShipmentLabel, handleOpenCreate, onActionChange])\n\n const handleEdit = React.useCallback((shipment: ShipmentRow) => {\n setDialogState({ mode: 'edit', shipment })\n }, [])\n\n const handleDelete = React.useCallback(\n async (shipment: ShipmentRow) => {\n const confirmed = await confirm({\n title: t('sales.documents.shipments.confirmDelete', 'Delete this shipment?'),\n variant: 'default',\n })\n if (!confirmed) return\n try {\n const result = await deleteCrud('sales/shipments', {\n body: {\n id: shipment.id,\n orderId,\n organizationId: resolvedOrganizationId,\n tenantId: resolvedTenantId,\n },\n errorMessage: t('sales.documents.shipments.errorDelete', 'Failed to delete shipment.'),\n })\n if (result.ok) {\n await loadShipments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n }\n } catch (err) {\n console.error('sales.shipments.delete', err)\n flash(t('sales.documents.shipments.errorDelete', 'Failed to delete shipment.'), 'error')\n }\n },\n [confirm, loadShipments, orderId, resolvedOrganizationId, resolvedTenantId, t]\n )\n\n const renderItemList = (items: ShipmentItem[]) => (\n <ul className=\"space-y-1 text-sm text-muted-foreground\">\n {items.map((item) => {\n const label = item.orderLineNumber ? `#${item.orderLineNumber}` : ''\n return (\n <li key={item.id} className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate\">\n {label ? `${label} \u00B7 ` : null}\n {item.orderLineName ?? item.orderLineId}\n </span>\n <Badge variant=\"secondary\">{item.quantity}</Badge>\n </li>\n )\n })}\n </ul>\n )\n\n if (loading) {\n return (\n <LoadingMessage\n label={t('sales.documents.shipments.loading', 'Loading shipments\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n )\n }\n\n if (error) {\n return <ErrorMessage label={error} />\n }\n\n const empty = !shipments.length\n\n return (\n <div className=\"space-y-4\">\n {empty ? (\n <TabEmptyState\n title={t('sales.documents.shipments.empty.title', 'No shipments yet.')}\n description={t(\n 'sales.documents.shipments.empty.description',\n 'Add shipments for this document to let the user track the order.'\n )}\n action={{\n label: addShipmentLabel,\n onClick: handleOpenCreate,\n icon: <Plus className=\"h-4 w-4\" aria-hidden />,\n disabled: loading,\n }}\n />\n ) : (\n <div className=\"grid gap-3 md:grid-cols-2\">\n {shipments.map((shipment) => {\n const shippedAt = formatDisplayDate(shipment.shippedAt)\n const deliveredAt = formatDisplayDate(shipment.deliveredAt)\n const addressSummary = formatShipmentAddress(shipment.metadata)\n const statusLabel =\n shipment.statusLabel ??\n shipment.status ??\n t('sales.documents.shipments.statusMissing', 'Status pending')\n return (\n <div key={shipment.id} className=\"rounded-lg border bg-card p-4 shadow-sm\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Truck className=\"h-5 w-5\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold\">\n {shipment.shipmentNumber\n ? t('sales.documents.shipments.numberLabel', 'Shipment {{number}}', {\n number: shipment.shipmentNumber,\n })\n : t('sales.documents.shipments.fallbackNumber', 'Shipment {{id}}', {\n id: shipment.id.slice(0, 6),\n })}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {statusLabel}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => handleEdit(shipment)}\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive\"\n onClick={() => void handleDelete(shipment)}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n <div className=\"mt-3 space-y-2 text-sm\">\n <div className=\"flex flex-wrap items-center gap-2 text-muted-foreground\">\n {shipment.carrierName ? (\n <Badge variant=\"outline\">{shipment.carrierName}</Badge>\n ) : null}\n {shipment.trackingNumbers.length ? (\n <span className=\"truncate\">\n {t('sales.documents.shipments.tracking', 'Tracking')}: {shipment.trackingNumbers.join(', ')}\n </span>\n ) : null}\n </div>\n {shippedAt ? (\n <p className=\"text-muted-foreground\">\n {t('sales.documents.shipments.shippedOn', 'Shipped on {{date}}', { date: shippedAt })}\n </p>\n ) : null}\n {deliveredAt ? (\n <p className=\"text-muted-foreground\">\n {t('sales.documents.shipments.deliveredOn', 'Delivered on {{date}}', { date: deliveredAt })}\n </p>\n ) : null}\n {addressSummary ? (\n <p className=\"text-xs text-muted-foreground\">{addressSummary}</p>\n ) : null}\n {shipment.notes ? (\n <p className=\"rounded-md bg-muted px-3 py-2 text-muted-foreground\">\n {shipment.notes}\n </p>\n ) : null}\n {renderItemList(shipment.items)}\n </div>\n </div>\n )\n })}\n </div>\n )}\n\n <ShipmentDialog\n open={dialogState !== null}\n mode={dialogState?.mode ?? 'create'}\n shipment={dialogState?.shipment ?? null}\n lines={lines}\n orderId={orderId}\n currencyCode={currencyCode}\n organizationId={resolvedOrganizationId}\n tenantId={resolvedTenantId}\n computeAvailable={computeAvailable}\n shippingAddressSnapshot={shippingAddressSnapshot}\n onClose={() => setDialogState(null)}\n onSaved={async () => {\n await loadShipments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n setDialogState(null)\n }}\n onAddComment={onAddComment}\n />\n {ConfirmDialogElement}\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.4.7-develop-d6331ed114",
3
+ "version": "0.4.7-develop-1ac08bd793",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -217,10 +217,10 @@
217
217
  "semver": "^7.6.3"
218
218
  },
219
219
  "peerDependencies": {
220
- "@open-mercato/shared": "0.4.7-develop-d6331ed114"
220
+ "@open-mercato/shared": "0.4.7-develop-1ac08bd793"
221
221
  },
222
222
  "devDependencies": {
223
- "@open-mercato/shared": "0.4.7-develop-d6331ed114",
223
+ "@open-mercato/shared": "0.4.7-develop-1ac08bd793",
224
224
  "@testing-library/dom": "^10.4.1",
225
225
  "@testing-library/jest-dom": "^6.9.1",
226
226
  "@testing-library/react": "^16.3.1",
@@ -283,17 +283,13 @@ export function SalesDocumentAdjustmentsSection({
283
283
 
284
284
  React.useEffect(() => {
285
285
  if (!onActionChange) return
286
- if (!rows.length) {
287
- onActionChange(null)
288
- return () => onActionChange(null)
289
- }
290
286
  onActionChange({
291
287
  label: t('sales.documents.adjustments.add', 'Add adjustment'),
292
288
  onClick: handleOpenCreate,
293
289
  disabled: false,
294
290
  })
295
291
  return () => onActionChange(null)
296
- }, [handleOpenCreate, onActionChange, rows.length, t])
292
+ }, [handleOpenCreate, onActionChange, t])
297
293
 
298
294
  const handleFormSubmit = React.useCallback(
299
295
  async (values: AdjustmentSubmitPayload) => {
@@ -397,17 +397,13 @@ export function SalesDocumentItemsSection({
397
397
 
398
398
  React.useEffect(() => {
399
399
  if (!onActionChange) return;
400
- if (items.length === 0) {
401
- onActionChange(null);
402
- return;
403
- }
404
400
  onActionChange({
405
401
  label: t("sales.documents.items.add", "Add item"),
406
402
  onClick: openCreate,
407
403
  disabled: false,
408
404
  });
409
405
  return () => onActionChange(null);
410
- }, [items.length, onActionChange, openCreate, t]);
406
+ }, [onActionChange, openCreate, t]);
411
407
 
412
408
  const handleEdit = React.useCallback((line: SalesLineRecord) => {
413
409
  setLineForEdit(line);
@@ -235,17 +235,13 @@ export function SalesDocumentPaymentsSection({
235
235
 
236
236
  React.useEffect(() => {
237
237
  if (!onActionChange) return
238
- if (payments.length === 0) {
239
- onActionChange(null)
240
- return
241
- }
242
238
  onActionChange({
243
239
  label: addActionLabel,
244
240
  onClick: openCreate,
245
- disabled: loading,
241
+ disabled: false,
246
242
  })
247
243
  return () => onActionChange(null)
248
- }, [addActionLabel, loading, onActionChange, openCreate, payments.length])
244
+ }, [addActionLabel, onActionChange, openCreate])
249
245
 
250
246
  const columns = React.useMemo<ColumnDef<PaymentRow>[]>(
251
247
  () => [
@@ -377,17 +377,13 @@ export function SalesShipmentsSection({
377
377
 
378
378
  React.useEffect(() => {
379
379
  if (!onActionChange) return
380
- if (shipments.length === 0) {
381
- onActionChange(null)
382
- return
383
- }
384
380
  onActionChange({
385
381
  label: addShipmentLabel,
386
382
  onClick: handleOpenCreate,
387
- disabled: loading,
383
+ disabled: false,
388
384
  })
389
385
  return () => onActionChange(null)
390
- }, [addShipmentLabel, handleOpenCreate, loading, onActionChange, shipments.length])
386
+ }, [addShipmentLabel, handleOpenCreate, onActionChange])
391
387
 
392
388
  const handleEdit = React.useCallback((shipment: ShipmentRow) => {
393
389
  setDialogState({ mode: 'edit', shipment })