@things-factory/operato-wms 4.3.794 → 4.3.797

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.
@@ -710,14 +710,14 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
710
710
  header: i18next.t('field.total_uom_value'),
711
711
  width: 120
712
712
  },
713
- {
713
+ ...(!this.enableDirectInbound ? [{
714
714
  type: 'integer',
715
715
  name: 'palletQty',
716
716
  header: i18next.t('field.pallet_qty'),
717
717
  imex: { header: i18next.t('field.pallet_qty'), key: 'palletQty', width: 25, type: 'float' },
718
718
  record: { editable: editable, options: { min: 0 } },
719
719
  width: 80
720
- },
720
+ }] : []),
721
721
  ...(this._enableLotIdInput
722
722
  ? [
723
723
  {
@@ -808,7 +808,7 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
808
808
  }
809
809
 
810
810
  if (this.enableDirectInbound) {
811
- const anchor = this._enableLotIdInput ? 'palletId' : 'palletQty'
811
+ const anchor = this._enableLotIdInput ? 'palletId' : 'totalUomValue'
812
812
  insertAfter(productGristColumns, anchor, [expDateColumn])
813
813
 
814
814
  insertAfter(productGristColumns, 'batchIdRef', [warehouseColumn, locationColumn])
@@ -1234,7 +1234,7 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
1234
1234
  arrivalNotice.orderProducts = this._getOrderProducts()
1235
1235
  const fileUploader = this._document?.files ? this._document.files : undefined
1236
1236
 
1237
- if (arrivalNotice.orderProducts.some(orderProduct => !orderProduct.palletQty)) {
1237
+ if (!this.enableDirectInbound && arrivalNotice.orderProducts.some(orderProduct => !orderProduct.palletQty)) {
1238
1238
  const result = await CustomAlert({
1239
1239
  title: i18next.t('title.are_you_sure'),
1240
1240
  text: i18next.t('text.there_is_no_pallet_qty'),
@@ -1439,11 +1439,11 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
1439
1439
  throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('label.uom_value') } }))
1440
1440
  }
1441
1441
 
1442
- if (records.some(({ palletQty }) => palletQty < 0)) {
1442
+ if (!this.enableDirectInbound && records.some(({ palletQty }) => palletQty < 0)) {
1443
1443
  throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('label.pallet_qty') } }))
1444
1444
  }
1445
1445
 
1446
- if (records.some(({ palletQty, packQty }) => palletQty > packQty)) {
1446
+ if (!this.enableDirectInbound && records.some(({ palletQty, packQty }) => palletQty > packQty)) {
1447
1447
  throw new Error(
1448
1448
  i18next.t('text.a_cannot_exceed_b', {
1449
1449
  state: {
@@ -1476,7 +1476,7 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
1476
1476
  )
1477
1477
  }
1478
1478
 
1479
- if (!record.location || !record.location.id) {
1479
+ if (!record.location || (!record.location.id && !record.location.name)) {
1480
1480
  throw new Error(
1481
1481
  i18next.t('text.location_required_for_product', {
1482
1482
  defaultValue: `Row ${index + 1}: Location is missing for product "${record.product?.name}"`,
@@ -1841,13 +1841,13 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
1841
1841
  imex: { header: i18next.t('field.pack_qty'), key: 'packQty', width: 25, type: 'float' },
1842
1842
  width: 100
1843
1843
  },
1844
- {
1844
+ ...(!this.enableDirectInbound ? [{
1845
1845
  type: 'integer',
1846
1846
  name: 'palletQty',
1847
1847
  header: i18next.t('field.pallet_qty'),
1848
1848
  imex: { header: i18next.t('field.pallet_qty'), key: 'palletQty', width: 25, type: 'float' },
1849
1849
  width: 100
1850
- },
1850
+ }] : []),
1851
1851
  ...(this._enableLotIdInput
1852
1852
  ? [
1853
1853
  {
@@ -2087,6 +2087,34 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
2087
2087
 
2088
2088
  async _importableData(records) {
2089
2089
  try {
2090
+ // Remap raw Excel header text keys to imex.key values
2091
+ const headerToKey = {}
2092
+ this.excelColumns()
2093
+ .filter(col => col.imex)
2094
+ .forEach(col => {
2095
+ headerToKey[col.imex.header.toLowerCase()] = col.imex.key
2096
+ })
2097
+
2098
+ records = records.map(record => {
2099
+ const remapped = {}
2100
+ Object.entries(record).forEach(([rawKey, value]) => {
2101
+ if (!rawKey) return
2102
+ const mappedKey = headerToKey[rawKey.toLowerCase()]
2103
+ if (mappedKey) {
2104
+ const parts = mappedKey.split('.')
2105
+ if (parts.length === 2) {
2106
+ remapped[parts[0]] = remapped[parts[0]] || {}
2107
+ remapped[parts[0]][parts[1]] = value
2108
+ } else {
2109
+ remapped[mappedKey] = value
2110
+ }
2111
+ } else {
2112
+ remapped[rawKey] = value
2113
+ }
2114
+ })
2115
+ return remapped
2116
+ })
2117
+
2090
2118
  if (!this.enableDirectInbound && records.some(record => record.location)) {
2091
2119
  throw new Error(
2092
2120
  'Location-based assignment is not allowed. Please delete the' +
@@ -2100,11 +2128,17 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
2100
2128
  .map(record => {
2101
2129
  let warehouseName
2102
2130
  if (this.enableDirectInbound) {
2103
- const match = record.location.name.match(/(.*) \((.*)\)/)
2131
+ const locationItem = record.location?.name
2132
+ const locationName = typeof locationItem === 'object' ? locationItem?.name : locationItem
2133
+ const locationId = typeof locationItem === 'object' ? locationItem?.id : undefined
2134
+ const match = locationName?.match(/(.*) \((.*)\)/)
2104
2135
  if (match && match.length === 3) {
2105
- record.location.name = match[1].trim()
2106
2136
  warehouseName = match[2].trim()
2107
- record = { ...record, warehouseName: warehouseName }
2137
+ record = {
2138
+ ...record,
2139
+ location: { id: locationId, name: match[1].trim() },
2140
+ warehouseName
2141
+ }
2108
2142
  }
2109
2143
  }
2110
2144
  return {
@@ -2112,19 +2146,19 @@ class CreateArrivalNotice extends localize(i18next)(PageView) {
2112
2146
  unitPrice:
2113
2147
  record.unitPrice == null && record.unitPrice !== undefined
2114
2148
  ? '0.00'
2115
- : record.unitPrice === undefined
2149
+ : record.unitPrice === undefined || record.unitPrice == ""
2116
2150
  ? null
2117
2151
  : parseFloat(parseFloat(record.unitPrice).toFixed(2)),
2118
2152
  packQty:
2119
2153
  record.packQty == null && record.packQty !== undefined
2120
2154
  ? '0'
2121
- : record.packQty === undefined
2155
+ : record.packQty === undefined || record.packQty == ""
2122
2156
  ? null
2123
2157
  : parseFloat(parseFloat(record.packQty).toFixed(3)),
2124
2158
  palletQty:
2125
2159
  record.palletQty == null && record.palletQty !== undefined
2126
2160
  ? parseInt('0')
2127
- : record.palletQty === undefined
2161
+ : record.palletQty === undefined || record.palletQty == ""
2128
2162
  ? null
2129
2163
  : parseInt(record.palletQty),
2130
2164
  uomValue: record.uomValue !== null && record.uomValue !== undefined ? parseFloat(record.uomValue) : ''
@@ -7,6 +7,7 @@ import '../components/worksheet-information-popup'
7
7
  import './serial-number-popup'
8
8
  import './tote-popup'
9
9
  import './vas-list-popup'
10
+ import './picking-same-carton-popup'
10
11
 
11
12
  import gql from 'graphql-tag'
12
13
  import { css, html } from 'lit-element'
@@ -1311,14 +1312,27 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1311
1312
  const scannedCartonId = this.cartonInput.value.trim()
1312
1313
  if (scannedCartonId) {
1313
1314
  let candidates = (this.data?.records || []).filter(
1314
- rec => rec.cartonId === scannedCartonId && rec.status !== 'DONE' && rec.status !== 'MISSING'
1315
+ rec =>
1316
+ rec.cartonId === scannedCartonId &&
1317
+ rec.status !== 'DONE' &&
1318
+ rec.status !== 'MISSING' &&
1319
+ !rec.completed &&
1320
+ rec.pickedQty < rec.releaseQty
1315
1321
  )
1316
- candidates = this._filterCandidatesByInputQty(candidates)
1317
-
1318
1322
  // Validate carton id: must have at least one candidate
1319
1323
  if (!candidates || candidates.length === 0) {
1320
1324
  this._focusOnCartonNoInput()
1321
- throw new Error(i18next.t('text.invalid_carton_id'))
1325
+ const hasFullyPickedForCarton = (this.data?.records || []).some(
1326
+ rec =>
1327
+ rec.cartonId === scannedCartonId &&
1328
+ rec.status !== 'DONE' &&
1329
+ rec.status !== 'MISSING' &&
1330
+ !rec.completed &&
1331
+ rec.pickedQty >= rec.releaseQty
1332
+ )
1333
+ throw new Error(
1334
+ i18next.t(hasFullyPickedForCarton ? 'text.qty_exceed_release_qty' : 'text.invalid_carton_id')
1335
+ )
1322
1336
  }
1323
1337
 
1324
1338
  if (this._enableProductScanning) {
@@ -1328,11 +1342,14 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1328
1342
  throw new Error(i18next.t('text.empty_product_barcode'))
1329
1343
  }
1330
1344
 
1345
+ this._popupCancelled = false
1331
1346
  const matchedRecord = await this._selectRecordByGtinFromCandidates(
1332
1347
  this.productBarcodeInput.value.trim(),
1333
1348
  candidates
1334
1349
  )
1335
1350
 
1351
+ if (this._popupCancelled) return { value: false }
1352
+
1336
1353
  if (!matchedRecord) {
1337
1354
  this._focusOnProductBarcodeInput()
1338
1355
  this.productBarcodeInput.value = ''
@@ -1345,7 +1362,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1345
1362
  }
1346
1363
  } else {
1347
1364
  // Product scanning disabled: pick a deterministic candidate
1348
- const matchedRecord = this._pickBestCandidate(candidates)
1365
+ const matchedRecord = this._pickBestCandidate(this._filterCandidatesByInputQty(candidates))
1349
1366
  if (
1350
1367
  matchedRecord &&
1351
1368
  (!this._selectedOrderInventory || this._selectedOrderInventory.name !== matchedRecord.name)
@@ -1409,14 +1426,36 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1409
1426
  if (this._pageSettings.enablePickingRandomSeq == true) {
1410
1427
  let cartonInputValue = this.cartonInput.value
1411
1428
  let candidates = this.data.records.filter(
1412
- rec => rec.cartonId === cartonInputValue && rec.status !== 'DONE' && rec.status !== 'MISSING'
1429
+ rec =>
1430
+ rec.cartonId === cartonInputValue &&
1431
+ rec.status !== 'DONE' &&
1432
+ rec.status !== 'MISSING' &&
1433
+ !rec.completed &&
1434
+ rec.pickedQty < rec.releaseQty
1413
1435
  )
1414
- candidates = this._filterCandidatesByInputQty(candidates)
1436
+ // If no candidates remain, check if it's because all matching items are already fully picked
1437
+ if (!candidates.length) {
1438
+ const hasFullyPickedForCarton = this.data.records.some(
1439
+ rec =>
1440
+ rec.cartonId === cartonInputValue &&
1441
+ rec.status !== 'DONE' &&
1442
+ rec.status !== 'MISSING' &&
1443
+ !rec.completed &&
1444
+ rec.pickedQty >= rec.releaseQty
1445
+ )
1446
+ if (hasFullyPickedForCarton) {
1447
+ this._focusOnCartonNoInput()
1448
+ throw new Error(i18next.t('text.qty_exceed_release_qty'))
1449
+ }
1450
+ }
1451
+
1415
1452
  if (this._enableProductScanning && this.productBarcodeInput?.value) {
1453
+ this._popupCancelled = false
1416
1454
  foundRecord = await this._selectRecordByGtinFromCandidates(
1417
1455
  this.productBarcodeInput.value.trim(),
1418
1456
  candidates
1419
1457
  )
1458
+ if (this._popupCancelled) return { value: false }
1420
1459
  }
1421
1460
  // If product barcode is provided but no GTIN match, stop without fallback
1422
1461
  if (this._enableProductScanning && this.productBarcodeInput?.value && !foundRecord) {
@@ -1427,7 +1466,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1427
1466
 
1428
1467
  // No product barcode: deterministically choose best candidate among duplicates
1429
1468
  if (!foundRecord && (!this._enableProductScanning || !this.productBarcodeInput?.value)) {
1430
- foundRecord = this._pickBestCandidate(candidates)
1469
+ foundRecord = this._pickBestCandidate(this._filterCandidatesByInputQty(candidates))
1431
1470
  }
1432
1471
 
1433
1472
  if (foundRecord) {
@@ -2486,7 +2525,9 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
2486
2525
  _filterCandidatesByInputQty(candidates) {
2487
2526
  const typedQty = this._getTypedQty()
2488
2527
  if (!typedQty || !Array.isArray(candidates) || !candidates.length) return candidates
2489
- const matches = candidates.filter(rec => parseFloat(rec?.releaseQty) === typedQty)
2528
+ const matches = candidates.filter(
2529
+ rec => (parseFloat(rec?.releaseQty) - parseFloat(rec?.pickedQty ?? 0)) === typedQty
2530
+ )
2490
2531
  return matches.length ? matches : candidates
2491
2532
  }
2492
2533
 
@@ -2521,9 +2562,6 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
2521
2562
  try {
2522
2563
  if (!gtin || !candidates?.length) return null
2523
2564
 
2524
- // Apply qty-based narrowing first when duplicates exist
2525
- candidates = this._filterCandidatesByInputQty(candidates)
2526
-
2527
2565
  // Use checkGtin to resolve product-packing info to match candidate rows
2528
2566
  const response = await client.query({
2529
2567
  query: gql`
@@ -2563,16 +2601,77 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
2563
2601
  itm.packingSize === rec.packingSize
2564
2602
  )
2565
2603
  )
2566
- if (exactMatches.length) return this._pickBestCandidate(exactMatches)
2604
+ if (exactMatches.length) return await this._pickBestCandidateOrShowPopup(exactMatches)
2567
2605
 
2568
2606
  const productOnlyMatches = candidates.filter(rec => items.some(itm => itm.product?.id === rec?.product?.id))
2569
- if (productOnlyMatches.length) return this._pickBestCandidate(productOnlyMatches)
2607
+ if (productOnlyMatches.length) return await this._pickBestCandidateOrShowPopup(productOnlyMatches)
2570
2608
 
2571
2609
  return null
2572
2610
  } catch (e) {
2573
2611
  return null
2574
2612
  }
2575
2613
  }
2614
+
2615
+ _hasDuplicateSameProduct(candidates) {
2616
+ return this._getDuplicateSameProductRows(candidates).length > 0
2617
+ }
2618
+
2619
+ _getDuplicateSameProductRows(candidates) {
2620
+ if (!Array.isArray(candidates) || candidates.length <= 1) return []
2621
+
2622
+ // Group by cartonId + SKU, return only rows that belong to a duplicate group
2623
+ const groups = {}
2624
+ candidates.forEach(c => {
2625
+ const key = `${c?.cartonId || ''}|${c?.product?.sku || ''}`
2626
+ if (!groups[key]) groups[key] = []
2627
+ groups[key].push(c)
2628
+ })
2629
+
2630
+ const duplicateRows = []
2631
+ for (const rows of Object.values(groups)) {
2632
+ if (rows.length > 1) duplicateRows.push(...rows)
2633
+ }
2634
+ return duplicateRows
2635
+ }
2636
+
2637
+ _showPickingSameCartonPopup(candidates) {
2638
+ return new Promise(resolve => {
2639
+ openPopup(
2640
+ html`
2641
+ <picking-same-carton-popup
2642
+ .pickingInventories="${candidates}"
2643
+ @selection="${e => {
2644
+ resolve(e.detail)
2645
+ }}"
2646
+ ></picking-same-carton-popup>
2647
+ `,
2648
+ {
2649
+ backdrop: true,
2650
+ size: 'large',
2651
+ title: i18next.t('title.inventory_selection')
2652
+ }
2653
+ )
2654
+ })
2655
+ }
2656
+
2657
+ async _pickBestCandidateOrShowPopup(candidates) {
2658
+ if (!Array.isArray(candidates) || !candidates.length) return null
2659
+
2660
+ // If multiple candidates have the same cartonId + SKU, show popup for user to choose
2661
+ const duplicateRows = this._getDuplicateSameProductRows(candidates)
2662
+ if (duplicateRows.length) {
2663
+ const selectedRecord = await this._showPickingSameCartonPopup(duplicateRows)
2664
+ if (!selectedRecord) {
2665
+ // User cancelled the popup — signal callers to do nothing
2666
+ this._popupCancelled = true
2667
+ return null
2668
+ }
2669
+ return selectedRecord
2670
+ }
2671
+
2672
+ // Otherwise, use the existing logic to pick the best candidate
2673
+ return this._pickBestCandidate(candidates)
2674
+ }
2576
2675
  }
2577
2676
 
2578
2677
  window.customElements.define('picking-product', PickingProduct)
@@ -0,0 +1,217 @@
1
+ import '@things-factory/grist-ui'
2
+
3
+ import { css, html, LitElement } from 'lit-element'
4
+ import { connect } from 'pwa-helpers/connect-mixin'
5
+
6
+ import { SingleColumnFormStyles } from '@things-factory/form-ui'
7
+ import { i18next, localize } from '@things-factory/i18n-base'
8
+ import { store } from '@things-factory/shell'
9
+ import { isMobileDevice } from '@things-factory/utils'
10
+
11
+ class PickingSameCartonPopup extends connect(store)(localize(i18next)(LitElement)) {
12
+ static get properties() {
13
+ return {
14
+ config: Object,
15
+ data: Object,
16
+ pickingInventories: Array
17
+ }
18
+ }
19
+
20
+ constructor() {
21
+ super()
22
+ }
23
+
24
+ static get styles() {
25
+ return [
26
+ SingleColumnFormStyles,
27
+ css`
28
+ .button-container {
29
+ padding: 10px 0 12px 0;
30
+ text-align: center;
31
+ }
32
+ .button-container mwc-button {
33
+ margin: 0 5px;
34
+ }
35
+ data-grist {
36
+ overflow-y: hidden;
37
+ flex: 1;
38
+ }
39
+ .grist {
40
+ display: flex;
41
+ flex-direction: column;
42
+ flex: 1;
43
+ overflow-y: auto;
44
+ }
45
+ :host {
46
+ padding: 10px;
47
+ display: flex;
48
+ flex-direction: column;
49
+ overflow: hidden;
50
+ background-color: white;
51
+ }
52
+ .header {
53
+ padding: 10px;
54
+ font-weight: bold;
55
+ font-size: 14px;
56
+ color: var(--secondary-color);
57
+ border-bottom: 1px solid var(--secondary-color);
58
+ margin-bottom: 10px;
59
+ }
60
+ `
61
+ ]
62
+ }
63
+
64
+ get dataGrist() {
65
+ return this.shadowRoot.querySelector('data-grist')
66
+ }
67
+
68
+ updated(changeProps) {
69
+ if (changeProps.has('pickingInventories')) {
70
+ if (this.pickingInventories && this.pickingInventories.length) {
71
+ this.data = {
72
+ records: this.pickingInventories.map(inv => ({
73
+ ...inv,
74
+ locationName: inv.location?.name || ''
75
+ }))
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ render() {
82
+ return html`
83
+ <div class="header">
84
+ ${i18next.t('text.please_select_an_inventory')}
85
+ </div>
86
+
87
+ <div class="grist">
88
+ <data-grist
89
+ id="grist"
90
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
91
+ .config=${this.config}
92
+ .data="${this.data}"
93
+ ></data-grist>
94
+ </div>
95
+
96
+ <div class="button-container">
97
+ <mwc-button
98
+ raised
99
+ @click="${this._selectPickingInventory.bind(this)}"
100
+ label="${i18next.t('button.select')}"
101
+ ></mwc-button>
102
+ <mwc-button
103
+ @click="${() => {
104
+ this.dispatchEvent(new CustomEvent('selection', { detail: null }))
105
+ history.back()
106
+ }}"
107
+ label="${i18next.t('button.cancel')}"
108
+ ></mwc-button>
109
+ </div>
110
+ `
111
+ }
112
+
113
+ firstUpdated() {
114
+ this.config = {
115
+ pagination: { infinite: true },
116
+ rows: { selectable: { multiple: false }, appendable: false },
117
+ list: {
118
+ fields: [
119
+ 'locationName',
120
+ 'palletId',
121
+ 'batchId',
122
+ 'batchIdRef',
123
+ 'expirationDate',
124
+ 'qty',
125
+ 'releaseQty',
126
+ 'packingType'
127
+ ]
128
+ },
129
+ columns: [
130
+ { type: 'gutter', gutterName: 'sequence' },
131
+ { type: 'gutter', gutterName: 'row-selector', multiple: false, header: { renderer: () => '' } },
132
+ { name: 'name', hidden: true },
133
+ {
134
+ type: 'string',
135
+ name: 'locationName',
136
+ label: true,
137
+ header: i18next.t('field.location'),
138
+ width: 120
139
+ },
140
+ {
141
+ type: 'string',
142
+ name: 'palletId',
143
+ label: true,
144
+ header: i18next.t('field.pallet_id'),
145
+ width: 120
146
+ },
147
+ {
148
+ type: 'string',
149
+ name: 'batchId',
150
+ label: true,
151
+ header: i18next.t('field.batch_no'),
152
+ width: 100
153
+ },
154
+ {
155
+ type: 'string',
156
+ name: 'batchIdRef',
157
+ label: true,
158
+ header: i18next.t('field.lot_id'),
159
+ width: 100
160
+ },
161
+ {
162
+ type: 'date',
163
+ name: 'expirationDate',
164
+ label: true,
165
+ header: i18next.t('field.expiration'),
166
+ width: 100
167
+ },
168
+ {
169
+ type: 'float',
170
+ name: 'qty',
171
+ label: true,
172
+ header: i18next.t('field.available_qty'),
173
+ width: 80
174
+ },
175
+ {
176
+ type: 'float',
177
+ name: 'releaseQty',
178
+ label: true,
179
+ header: i18next.t('field.release_qty'),
180
+ width: 80
181
+ },
182
+ {
183
+ type: 'string',
184
+ name: 'packingType',
185
+ label: true,
186
+ header: i18next.t('field.packing_type'),
187
+ width: 100
188
+ }
189
+ ]
190
+ }
191
+ }
192
+
193
+ async _selectPickingInventory() {
194
+ try {
195
+ const selectedInventory = this.dataGrist.selected[0]
196
+ if (!selectedInventory) throw new Error(i18next.t('text.please_select_inventory'))
197
+
198
+ this.dispatchEvent(new CustomEvent('selection', { detail: selectedInventory }))
199
+ history.back()
200
+ } catch (e) {
201
+ this._showToast(e)
202
+ }
203
+ }
204
+
205
+ _showToast({ type, message }) {
206
+ document.dispatchEvent(
207
+ new CustomEvent('notify', {
208
+ detail: {
209
+ type,
210
+ message
211
+ }
212
+ })
213
+ )
214
+ }
215
+ }
216
+
217
+ window.customElements.define('picking-same-carton-popup', PickingSameCartonPopup)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/operato-wms",
3
- "version": "4.3.794",
3
+ "version": "4.3.797",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -91,7 +91,7 @@
91
91
  "@things-factory/print-ui": "^4.3.767",
92
92
  "@things-factory/product-base": "^4.3.791",
93
93
  "@things-factory/resource-ui": "^4.3.790",
94
- "@things-factory/sales-ui": "^4.3.794",
94
+ "@things-factory/sales-ui": "^4.3.795",
95
95
  "@things-factory/scene-data-transform": "^4.3.767",
96
96
  "@things-factory/scene-excel": "^4.3.767",
97
97
  "@things-factory/scene-firebase": "^4.3.767",
@@ -108,7 +108,7 @@
108
108
  "@things-factory/transport-base": "^4.3.767",
109
109
  "@things-factory/tutorial-ui": "^4.3.767",
110
110
  "@things-factory/warehouse-base": "^4.3.791",
111
- "@things-factory/worksheet-base": "^4.3.794"
111
+ "@things-factory/worksheet-base": "^4.3.797"
112
112
  },
113
113
  "devDependencies": {
114
114
  "@things-factory/builder": "^4.3.767",
@@ -117,5 +117,5 @@
117
117
  "cypress-localstorage-commands": "^1.6.1",
118
118
  "eslint-plugin-cypress": "^2.12.1"
119
119
  },
120
- "gitHead": "cbcc57e2ef7188213c3e64c7e54d977f4f58b3f2"
120
+ "gitHead": "1acd354f47dfc15a5670841ddfb51e338f61d15f"
121
121
  }