@open-mercato/core 0.7.1-develop.7195.1.b5efd1d51a → 0.7.1-develop.7201.1.9bd6c88e3d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/modules/auth/lib/setup-app.js +1 -0
  2. package/dist/modules/auth/lib/setup-app.js.map +2 -2
  3. package/dist/modules/catalog/components/products/ProductUomSection.js +27 -22
  4. package/dist/modules/catalog/components/products/ProductUomSection.js.map +2 -2
  5. package/dist/modules/entities/lib/field-definitions.js +9 -0
  6. package/dist/modules/entities/lib/field-definitions.js.map +2 -2
  7. package/dist/modules/entities/lib/install-from-ce.js +1 -0
  8. package/dist/modules/entities/lib/install-from-ce.js.map +2 -2
  9. package/dist/modules/eudr/search.js +3 -5
  10. package/dist/modules/eudr/search.js.map +2 -2
  11. package/dist/modules/sales/components/documents/PaymentDialog.js +14 -11
  12. package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
  13. package/dist/modules/sales/lib/lineSnapshots.js +3 -0
  14. package/dist/modules/sales/lib/lineSnapshots.js.map +2 -2
  15. package/dist/modules/wms/components/backend/AdjustInventoryDialog.js +8 -6
  16. package/dist/modules/wms/components/backend/AdjustInventoryDialog.js.map +2 -2
  17. package/dist/modules/wms/search.js +4 -4
  18. package/dist/modules/wms/search.js.map +2 -2
  19. package/package.json +7 -7
  20. package/src/modules/auth/lib/setup-app.ts +6 -0
  21. package/src/modules/catalog/components/products/ProductUomSection.tsx +31 -21
  22. package/src/modules/entities/lib/field-definitions.ts +15 -0
  23. package/src/modules/entities/lib/install-from-ce.ts +1 -0
  24. package/src/modules/eudr/i18n/de.json +4 -1
  25. package/src/modules/eudr/i18n/en.json +4 -1
  26. package/src/modules/eudr/i18n/es.json +4 -1
  27. package/src/modules/eudr/i18n/ko.json +4 -1
  28. package/src/modules/eudr/i18n/pl.json +4 -1
  29. package/src/modules/eudr/search.ts +3 -5
  30. package/src/modules/sales/components/documents/PaymentDialog.tsx +18 -11
  31. package/src/modules/sales/i18n/de.json +1 -0
  32. package/src/modules/sales/i18n/en.json +1 -0
  33. package/src/modules/sales/i18n/es.json +1 -0
  34. package/src/modules/sales/i18n/ko.json +1 -0
  35. package/src/modules/sales/i18n/pl.json +1 -0
  36. package/src/modules/sales/lib/lineSnapshots.ts +22 -3
  37. package/src/modules/wms/components/backend/AdjustInventoryDialog.tsx +6 -5
  38. package/src/modules/wms/i18n/de.json +4 -0
  39. package/src/modules/wms/i18n/en.json +4 -0
  40. package/src/modules/wms/i18n/es.json +4 -0
  41. package/src/modules/wms/i18n/ko.json +4 -0
  42. package/src/modules/wms/i18n/pl.json +4 -0
  43. package/src/modules/wms/search.ts +4 -4
@@ -36,6 +36,7 @@ const CONFIG_PASSTHROUGH_KEYS: Array<keyof CustomFieldDefinition> = [
36
36
  'formEditable',
37
37
  'listVisible',
38
38
  'indexed',
39
+ 'encrypted',
39
40
  'priority',
40
41
  'editor',
41
42
  'input',
@@ -65,6 +66,12 @@ function configEquals(a: unknown, b: unknown): boolean {
65
66
  return JSON.stringify(normalizeValue(a ?? null)) === JSON.stringify(normalizeValue(b ?? null))
66
67
  }
67
68
 
69
+ function hasEncryptionEnabled(definition: CustomFieldDef | null): boolean {
70
+ const config = definition?.configJson
71
+ if (!config || typeof config !== 'object') return false
72
+ return (config as Record<string, unknown>).encrypted === true
73
+ }
74
+
68
75
  export async function ensureCustomFieldDefinitions(
69
76
  em: EntityManager,
70
77
  sets: FieldSetInput[],
@@ -103,6 +110,14 @@ export async function ensureCustomFieldDefinitions(
103
110
  if (value !== undefined) configJson[key] = value as unknown
104
111
  }
105
112
 
113
+ // configJson is rebuilt from the declaration, so a field encrypted through the
114
+ // definitions API would lose the flag on the next install while its stored
115
+ // values stay ciphertext the read path no longer decrypts. Keep an enabled flag
116
+ // unless the declaration turns it off with an explicit `encrypted: false`.
117
+ if (configJson.encrypted === undefined && hasEncryptionEnabled(existing)) {
118
+ configJson.encrypted = true
119
+ }
120
+
106
121
  if (!existing) {
107
122
  if (!scope.dryRun) {
108
123
  const createdDef = em.create(CustomFieldDef, {
@@ -49,6 +49,7 @@ const FIELD_DETAIL_KEYS: Array<keyof CustomFieldDefinition> = [
49
49
  'formEditable',
50
50
  'listVisible',
51
51
  'indexed',
52
+ 'encrypted',
52
53
  'priority',
53
54
  'editor',
54
55
  'input',
@@ -744,5 +744,8 @@
744
744
  "eudr.supplierPanel.viewSubmissions": "Einreichungen anzeigen",
745
745
  "eudr.supplierPanel.warnings": "Mit Warnungen",
746
746
  "eudr.warnings.harvestBeforeCutoff": "Ernte vor dem EUDR-Stichtag",
747
- "eudr.warnings.speciesMissing": "Bei einer verknüpften Holz-Zuordnung fehlt der wissenschaftliche oder gebräuchliche Artname"
747
+ "eudr.warnings.speciesMissing": "Bei einer verknüpften Holz-Zuordnung fehlt der wissenschaftliche oder gebräuchliche Artname",
748
+ "search.entityType.eudr.eudr_due_diligence_statement": "DDS-Erklärung",
749
+ "search.entityType.eudr.eudr_evidence_submission": "Nachweiseinreichung",
750
+ "search.entityType.eudr.eudr_plot": "Parzelle"
748
751
  }
@@ -744,5 +744,8 @@
744
744
  "eudr.supplierPanel.viewSubmissions": "View submissions",
745
745
  "eudr.supplierPanel.warnings": "With warnings",
746
746
  "eudr.warnings.harvestBeforeCutoff": "Harvest before EUDR cutoff",
747
- "eudr.warnings.speciesMissing": "A linked wood mapping is missing a scientific or common species name"
747
+ "eudr.warnings.speciesMissing": "A linked wood mapping is missing a scientific or common species name",
748
+ "search.entityType.eudr.eudr_due_diligence_statement": "DDS statement",
749
+ "search.entityType.eudr.eudr_evidence_submission": "Evidence submission",
750
+ "search.entityType.eudr.eudr_plot": "Plot"
748
751
  }
@@ -744,5 +744,8 @@
744
744
  "eudr.supplierPanel.viewSubmissions": "Ver presentaciones",
745
745
  "eudr.supplierPanel.warnings": "Con advertencias",
746
746
  "eudr.warnings.harvestBeforeCutoff": "Cosecha anterior a la fecha de corte EUDR",
747
- "eudr.warnings.speciesMissing": "A una asignación de madera vinculada le falta el nombre científico o común de la especie"
747
+ "eudr.warnings.speciesMissing": "A una asignación de madera vinculada le falta el nombre científico o común de la especie",
748
+ "search.entityType.eudr.eudr_due_diligence_statement": "Declaración DDS",
749
+ "search.entityType.eudr.eudr_evidence_submission": "Envío de evidencia",
750
+ "search.entityType.eudr.eudr_plot": "Parcela"
748
751
  }
@@ -744,5 +744,8 @@
744
744
  "eudr.supplierPanel.viewSubmissions": "제출물 보기",
745
745
  "eudr.supplierPanel.warnings": "경고 있음",
746
746
  "eudr.warnings.harvestBeforeCutoff": "EUDR 기준일 이전 수확",
747
- "eudr.warnings.speciesMissing": "연결된 목재 매핑에 학명 또는 일반명이 누락되었습니다"
747
+ "eudr.warnings.speciesMissing": "연결된 목재 매핑에 학명 또는 일반명이 누락되었습니다",
748
+ "search.entityType.eudr.eudr_due_diligence_statement": "DDS 진술서",
749
+ "search.entityType.eudr.eudr_evidence_submission": "증거 제출물",
750
+ "search.entityType.eudr.eudr_plot": "구획"
748
751
  }
@@ -744,5 +744,8 @@
744
744
  "eudr.supplierPanel.viewSubmissions": "Zobacz zgłoszenia",
745
745
  "eudr.supplierPanel.warnings": "Z ostrzeżeniami",
746
746
  "eudr.warnings.harvestBeforeCutoff": "Zbiory przed datą graniczną EUDR",
747
- "eudr.warnings.speciesMissing": "W powiązanym mapowaniu drewna brakuje naukowej lub zwyczajowej nazwy gatunku"
747
+ "eudr.warnings.speciesMissing": "W powiązanym mapowaniu drewna brakuje naukowej lub zwyczajowej nazwy gatunku",
748
+ "search.entityType.eudr.eudr_due_diligence_statement": "Oświadczenie DDS",
749
+ "search.entityType.eudr.eudr_evidence_submission": "Zgłoszenie dowodów",
750
+ "search.entityType.eudr.eudr_plot": "Działka"
748
751
  }
@@ -95,23 +95,21 @@ function resolveSupplierName(record: Record<string, unknown>): string | null {
95
95
  }
96
96
 
97
97
  function buildStatementPresenter(translate: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
98
- const label = translate('eudr.search.badge.statement', 'DDS statement')
99
98
  const title = readRecordText(record, 'title') ?? translate('eudr.common.recordUnavailable')
100
99
  const subtitle = formatSubtitle(
101
100
  readRecordText(record, 'reference_number', 'referenceNumber'),
102
101
  translateToken(translate, 'eudr.commodity', readRecordText(record, 'commodity')),
103
102
  )
104
- return { title, subtitle, icon: 'file-check', badge: label }
103
+ return { title, subtitle, icon: 'file-check' }
105
104
  }
106
105
 
107
106
  function buildPlotPresenter(translate: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
108
- const label = translate('eudr.search.badge.plot', 'Plot')
109
107
  const title = readRecordText(record, 'name') ?? translate('eudr.common.recordUnavailable')
110
108
  const subtitle = formatSubtitle(
111
109
  readRecordText(record, 'origin_country', 'originCountry'),
112
110
  translateToken(translate, 'eudr.plotType', readRecordText(record, 'plot_type', 'plotType')),
113
111
  )
114
- return { title, subtitle, icon: 'map-pin', badge: label }
112
+ return { title, subtitle, icon: 'map-pin' }
115
113
  }
116
114
 
117
115
  function buildSubmissionPresenter(translate: TranslateFn, record: Record<string, unknown>): SearchResultPresenter {
@@ -125,7 +123,7 @@ function buildSubmissionPresenter(translate: TranslateFn, record: Record<string,
125
123
  supplierName,
126
124
  translateToken(translate, 'eudr.submissionStatus', readRecordText(record, 'status')),
127
125
  )
128
- return { title, subtitle, icon: 'package', badge: label }
126
+ return { title, subtitle, icon: 'package' }
129
127
  }
130
128
 
131
129
  export const searchConfig: SearchModuleConfig = {
@@ -15,7 +15,8 @@ import { useDialogKeyHandler } from '@open-mercato/ui/hooks/useDialogKeyHandler'
15
15
  import { Input } from '@open-mercato/ui/primitives/input'
16
16
  import { Spinner } from '@open-mercato/ui/primitives/spinner'
17
17
  import { E } from '#generated/entities.ids.generated'
18
- import { useT } from '@open-mercato/shared/lib/i18n/context'
18
+ import { useT, useLocale } from '@open-mercato/shared/lib/i18n/context'
19
+ import { parseLocaleNumber } from '@open-mercato/shared/lib/number'
19
20
  import { normalizeCustomFieldSubmitValue, extractCustomFieldValues } from './customFieldHelpers'
20
21
  import { createLogger } from '@open-mercato/shared/lib/logger'
21
22
 
@@ -66,13 +67,15 @@ type PaymentDialogProps = {
66
67
  onSaved?: (totals?: PaymentTotals | null) => void | Promise<void>
67
68
  }
68
69
 
69
- const normalizeNumber = (value: unknown): number => {
70
- if (typeof value === 'number' && Number.isFinite(value)) return value
71
- if (typeof value === 'string' && value.trim().length) {
72
- const parsed = Number(value)
73
- if (!Number.isNaN(parsed)) return parsed
74
- }
75
- return 0
70
+ // The amount field is a hand-rolled text input, so the raw string a user typed reaches
71
+ // the submit handler carrying the separator the surrounding UI displays — `110,70` under
72
+ // Polish (issue #5828, same defect class as #5552). A blank/absent value keeps the old
73
+ // "must be a positive amount" message; only genuinely unparseable input returns null.
74
+ const parseAmountInput = (value: unknown, locale?: string): number | null => {
75
+ if (typeof value === 'number') return Number.isFinite(value) ? value : null
76
+ if (typeof value !== 'string') return 0
77
+ if (!value.trim()) return 0
78
+ return parseLocaleNumber(value, locale)
76
79
  }
77
80
 
78
81
  export function PaymentDialog({
@@ -88,6 +91,7 @@ export function PaymentDialog({
88
91
  onSaved,
89
92
  }: PaymentDialogProps) {
90
93
  const t = useT()
94
+ const locale = useLocale()
91
95
  const dialogContentRef = React.useRef<HTMLDivElement | null>(null)
92
96
  const [formResetKey, setFormResetKey] = React.useState(0)
93
97
  const [paymentMethods, setPaymentMethods] = React.useState<PaymentMethodOption[]>([])
@@ -352,9 +356,8 @@ export function PaymentDialog({
352
356
  return (
353
357
  <div className="flex items-center gap-2">
354
358
  <Input
355
- type="number"
359
+ type="text"
356
360
  inputMode="decimal"
357
- step="0.01"
358
361
  value={normalized as string | number}
359
362
  onChange={(event) => setValue(event.target.value)}
360
363
  placeholder="0.00"
@@ -493,10 +496,14 @@ export function PaymentDialog({
493
496
  const handleSubmit = React.useCallback(
494
497
  async (values: Record<string, unknown>) => {
495
498
  const resolvedCurrency = currencyCode ? currencyCode.toUpperCase() : ''
496
- const amountValue = normalizeNumber(values.amount)
499
+ const amountValue = parseAmountInput(values.amount, locale)
497
500
  if (!resolvedCurrency.trim()) {
498
501
  throw createCrudFormError(t('sales.documents.payments.currencyRequired', 'Currency is required.'))
499
502
  }
503
+ if (amountValue === null) {
504
+ const message = t('sales.documents.payments.amountInvalid', 'Enter the amount as a number.')
505
+ throw createCrudFormError(message, { amount: message })
506
+ }
500
507
  if (amountValue <= 0) {
501
508
  throw createCrudFormError(t('sales.documents.payments.amountRequired', 'Enter a positive amount.'), {
502
509
  amount: t('sales.documents.payments.amountRequired', 'Enter a positive amount.'),
@@ -1139,6 +1139,7 @@
1139
1139
  "sales.documents.list.table.unassigned": "Nicht zugewiesen",
1140
1140
  "sales.documents.payments.add": "Zahlung hinzufügen",
1141
1141
  "sales.documents.payments.amount": "Betrag",
1142
+ "sales.documents.payments.amountInvalid": "Geben Sie den Betrag als Zahl ein.",
1142
1143
  "sales.documents.payments.amountRequired": "Geben Sie einen positiven Betrag ein.",
1143
1144
  "sales.documents.payments.created": "Zahlung erfasst.",
1144
1145
  "sales.documents.payments.createdAt": "Erstellt",
@@ -1139,6 +1139,7 @@
1139
1139
  "sales.documents.list.table.unassigned": "Unassigned",
1140
1140
  "sales.documents.payments.add": "Add payment",
1141
1141
  "sales.documents.payments.amount": "Amount",
1142
+ "sales.documents.payments.amountInvalid": "Enter the amount as a number.",
1142
1143
  "sales.documents.payments.amountRequired": "Enter a positive amount.",
1143
1144
  "sales.documents.payments.created": "Payment recorded.",
1144
1145
  "sales.documents.payments.createdAt": "Created",
@@ -1139,6 +1139,7 @@
1139
1139
  "sales.documents.list.table.unassigned": "Sin asignar",
1140
1140
  "sales.documents.payments.add": "Agregar pago",
1141
1141
  "sales.documents.payments.amount": "Importe",
1142
+ "sales.documents.payments.amountInvalid": "Introduce el importe como un número.",
1142
1143
  "sales.documents.payments.amountRequired": "Introduce un importe positivo.",
1143
1144
  "sales.documents.payments.created": "Pago registrado.",
1144
1145
  "sales.documents.payments.createdAt": "Creado",
@@ -1139,6 +1139,7 @@
1139
1139
  "sales.documents.list.table.unassigned": "미지정",
1140
1140
  "sales.documents.payments.add": "결제 추가",
1141
1141
  "sales.documents.payments.amount": "금액",
1142
+ "sales.documents.payments.amountInvalid": "금액을 숫자로 입력하세요.",
1142
1143
  "sales.documents.payments.amountRequired": "0보다 큰 금액을 입력하세요.",
1143
1144
  "sales.documents.payments.created": "결제가 등록되었습니다.",
1144
1145
  "sales.documents.payments.createdAt": "등록일",
@@ -1139,6 +1139,7 @@
1139
1139
  "sales.documents.list.table.unassigned": "Nieprzypisany",
1140
1140
  "sales.documents.payments.add": "Dodaj płatność",
1141
1141
  "sales.documents.payments.amount": "Kwota",
1142
+ "sales.documents.payments.amountInvalid": "Podaj kwotę jako liczbę.",
1142
1143
  "sales.documents.payments.amountRequired": "Wprowadź dodatnią kwotę.",
1143
1144
  "sales.documents.payments.created": "Płatność zarejestrowana.",
1144
1145
  "sales.documents.payments.createdAt": "Utworzono",
@@ -11,9 +11,28 @@ function toNumeric(value: unknown): number {
11
11
  return 0
12
12
  }
13
13
 
14
- function mapPersistedLine(line: SalesOrderLine | SalesQuoteLine): SalesLineSnapshot {
14
+ /**
15
+ * A snapshot rebuilt from a persisted row, plus the columns the calculation
16
+ * engine never reads but the write paths must carry back to the row.
17
+ *
18
+ * The line upsert, line delete and adjustment write paths all rebuild *every*
19
+ * line of the document from these snapshots and then `Object.assign` the result
20
+ * onto the existing entities. Anything the mapper drops is therefore not merely
21
+ * absent from the calculation — it is written back as `null` over the stored
22
+ * value of lines the caller never touched (#5911).
23
+ */
24
+ export type SalesPersistedLineSnapshot = SalesLineSnapshot & {
25
+ statusEntryId: string | null
26
+ catalogSnapshot: Record<string, unknown> | null
27
+ promotionSnapshot: Record<string, unknown> | null
28
+ }
29
+
30
+ function mapPersistedLine(line: SalesOrderLine | SalesQuoteLine): SalesPersistedLineSnapshot {
15
31
  return {
16
32
  id: line.id,
33
+ statusEntryId: line.statusEntryId ?? null,
34
+ catalogSnapshot: line.catalogSnapshot ? cloneJson(line.catalogSnapshot) : null,
35
+ promotionSnapshot: line.promotionSnapshot ? cloneJson(line.promotionSnapshot) : null,
17
36
  lineNumber: line.lineNumber,
18
37
  kind: line.kind,
19
38
  productId: line.productId ?? null,
@@ -60,11 +79,11 @@ function mapPersistedLine(line: SalesOrderLine | SalesQuoteLine): SalesLineSnaps
60
79
  * two files used to carry byte-identical copies, and that duplication is why
61
80
  * the return flows kept the discount defect after the order flows were fixed.
62
81
  */
63
- export function mapOrderLineEntityToSnapshot(line: SalesOrderLine): SalesLineSnapshot {
82
+ export function mapOrderLineEntityToSnapshot(line: SalesOrderLine): SalesPersistedLineSnapshot {
64
83
  return mapPersistedLine(line)
65
84
  }
66
85
 
67
- export function mapQuoteLineEntityToSnapshot(line: SalesQuoteLine): SalesLineSnapshot {
86
+ export function mapQuoteLineEntityToSnapshot(line: SalesQuoteLine): SalesPersistedLineSnapshot {
68
87
  return mapPersistedLine(line)
69
88
  }
70
89
 
@@ -32,7 +32,8 @@ import {
32
32
  } from '@open-mercato/ui/primitives/select'
33
33
  import { StatusBadge } from '@open-mercato/ui/primitives/status-badge'
34
34
  import { Textarea } from '@open-mercato/ui/primitives/textarea'
35
- import { useT } from '@open-mercato/shared/lib/i18n/context'
35
+ import { useT, useLocale } from '@open-mercato/shared/lib/i18n/context'
36
+ import { parseLocaleNumber } from '@open-mercato/shared/lib/number'
36
37
  import { createLogger } from '@open-mercato/shared/lib/logger'
37
38
  import { buildInventoryMutationReferenceId } from '../../lib/inventoryMutationUi'
38
39
  import {
@@ -91,11 +92,10 @@ const EMPTY_FORM: AdjustFormValues = {
91
92
  serialNumber: '',
92
93
  }
93
94
 
94
- function parseDeltaInput(value: string): number | null {
95
+ export function parseDeltaInput(value: string, locale?: string): number | null {
95
96
  const trimmed = value.trim()
96
97
  if (!trimmed || trimmed === '-' || trimmed === '+') return null
97
- const parsed = Number(trimmed)
98
- return Number.isFinite(parsed) ? parsed : null
98
+ return parseLocaleNumber(trimmed, locale)
99
99
  }
100
100
 
101
101
  export function AdjustInventoryDialog({
@@ -108,6 +108,7 @@ export function AdjustInventoryDialog({
108
108
  initialLotId,
109
109
  }: AdjustInventoryDialogProps) {
110
110
  const t = useT()
111
+ const locale = useLocale()
111
112
  const queryClient = useQueryClient()
112
113
  const formRef = React.useRef<HTMLFormElement>(null)
113
114
  const { runMutation, retryLastMutation } = useGuardedMutation<{
@@ -690,7 +691,7 @@ export function AdjustInventoryDialog({
690
691
  inputMode="decimal"
691
692
  value={String(form.delta)}
692
693
  onChange={(event) => {
693
- const parsed = parseDeltaInput(event.target.value)
694
+ const parsed = parseDeltaInput(event.target.value, locale)
694
695
  if (parsed == null) return
695
696
  patchForm({ delta: parsed })
696
697
  }}
@@ -1,4 +1,8 @@
1
1
  {
2
+ "search.entityType.wms.inventory_lot": "Lagerbestand",
3
+ "search.entityType.wms.product_inventory_profile": "Bestandsprofil",
4
+ "search.entityType.wms.warehouse": "Lager",
5
+ "search.entityType.wms.warehouse_location": "Lagerort",
2
6
  "wms.audit.inventory.receive": "Wareneingang buchen",
3
7
  "wms.audit.salesOrder.assignWarehouse": "Lager dem Auftrag zuweisen",
4
8
  "wms.audit.salesOrder.reRunReservation": "Reservierung für Auftrag erneut ausführen",
@@ -1,4 +1,8 @@
1
1
  {
2
+ "search.entityType.wms.inventory_lot": "Inventory lot",
3
+ "search.entityType.wms.product_inventory_profile": "Inventory profile",
4
+ "search.entityType.wms.warehouse": "Warehouse",
5
+ "search.entityType.wms.warehouse_location": "Location",
2
6
  "wms.audit.inventory.receive": "Receive inventory",
3
7
  "wms.audit.salesOrder.assignWarehouse": "Assign warehouse to order",
4
8
  "wms.audit.salesOrder.reRunReservation": "Re-run reservation for order",
@@ -1,4 +1,8 @@
1
1
  {
2
+ "search.entityType.wms.inventory_lot": "Lote de inventario",
3
+ "search.entityType.wms.product_inventory_profile": "Perfil de inventario",
4
+ "search.entityType.wms.warehouse": "Almacén",
5
+ "search.entityType.wms.warehouse_location": "Ubicación",
2
6
  "wms.audit.inventory.receive": "Recibir inventario",
3
7
  "wms.audit.salesOrder.assignWarehouse": "Asignar almacén al pedido",
4
8
  "wms.audit.salesOrder.reRunReservation": "Volver a ejecutar la reserva del pedido",
@@ -1,4 +1,8 @@
1
1
  {
2
+ "search.entityType.wms.inventory_lot": "재고 로트",
3
+ "search.entityType.wms.product_inventory_profile": "재고 프로필",
4
+ "search.entityType.wms.warehouse": "창고",
5
+ "search.entityType.wms.warehouse_location": "위치",
2
6
  "wms.audit.inventory.receive": "재고 수령",
3
7
  "wms.audit.salesOrder.assignWarehouse": "주문할 창고 지정",
4
8
  "wms.audit.salesOrder.reRunReservation": "주문 예약 재실행",
@@ -1,4 +1,8 @@
1
1
  {
2
+ "search.entityType.wms.inventory_lot": "Partia zapasu",
3
+ "search.entityType.wms.product_inventory_profile": "Profil zapasu",
4
+ "search.entityType.wms.warehouse": "Magazyn",
5
+ "search.entityType.wms.warehouse_location": "Lokalizacja",
2
6
  "wms.audit.inventory.receive": "Przyjmij zapas",
3
7
  "wms.audit.salesOrder.assignWarehouse": "Przypisz magazyn do zamówienia",
4
8
  "wms.audit.salesOrder.reRunReservation": "Ponów rezerwację dla zamówienia",
@@ -63,7 +63,7 @@ function buildWarehousePresenter(
63
63
  const label = t('wms.search.badge.warehouse', 'Warehouse')
64
64
  const title = pickString(record.name, record.code, record.id) ?? label
65
65
  const subtitle = formatSubtitle(record.code, record.city, record.country)
66
- return { title, subtitle, icon: 'warehouse', badge: label }
66
+ return { title, subtitle, icon: 'warehouse' }
67
67
  }
68
68
 
69
69
  function buildLocationPresenter(
@@ -73,7 +73,7 @@ function buildLocationPresenter(
73
73
  const label = t('wms.search.badge.location', 'Location')
74
74
  const title = pickString(record.code, record.id) ?? label
75
75
  const subtitle = formatSubtitle(record.type, record.warehouse_id ?? record.warehouseId)
76
- return { title, subtitle, icon: 'map-pinned', badge: label }
76
+ return { title, subtitle, icon: 'map-pinned' }
77
77
  }
78
78
 
79
79
  function buildInventoryProfilePresenter(
@@ -89,7 +89,7 @@ function buildInventoryProfilePresenter(
89
89
  record.default_uom ?? record.defaultUom,
90
90
  variantId ? t('wms.search.profile.variantScoped', 'Variant-scoped') : t('wms.search.profile.productScoped', 'Product-scoped'),
91
91
  )
92
- return { title, subtitle, icon: 'boxes', badge: label }
92
+ return { title, subtitle, icon: 'boxes' }
93
93
  }
94
94
 
95
95
  function buildLotPresenter(
@@ -99,7 +99,7 @@ function buildLotPresenter(
99
99
  const label = t('wms.search.badge.lot', 'Inventory lot')
100
100
  const title = pickString(record.lot_number, record.lotNumber, record.batch_number, record.batchNumber, record.id) ?? label
101
101
  const subtitle = formatSubtitle(record.catalog_variant_id ?? record.catalogVariantId, record.status, record.expires_at ?? record.expiresAt)
102
- return { title, subtitle, icon: 'package-search', badge: label }
102
+ return { title, subtitle, icon: 'package-search' }
103
103
  }
104
104
 
105
105
  export const searchConfig: SearchModuleConfig = {