@things-factory/operato-wms 5.0.13 → 6.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/client/pages/bulk-operation/bulk-operation.js +96 -8
  2. package/client/pages/bulk-operation/validate-gan-popup.js +37 -27
  3. package/client/pages/bulk-operation/validate-ro-popup.js +40 -0
  4. package/client/pages/components/select-inventory-popup.js +633 -0
  5. package/client/pages/constants/order.js +2 -1
  6. package/client/pages/inbound/pallet-label-popup.js +2 -0
  7. package/client/pages/inbound/select-product-batch.js +7 -1
  8. package/client/pages/inbound/undo-unload-popup.js +37 -21
  9. package/client/pages/inbound/unload-product.js +147 -59
  10. package/client/pages/inbound/worksheet-putaway.js +1 -1
  11. package/client/pages/inbound/worksheet-unloading.js +11 -7
  12. package/client/pages/inventory/inventory-adjustment.js +261 -238
  13. package/client/pages/inventory/inventory-by-product-detail.js +99 -92
  14. package/client/pages/inventory/inventory-by-product.js +170 -68
  15. package/client/pages/inventory/onhand-inventory.js +10 -12
  16. package/client/pages/inventory/serial-number-list-popup.js +36 -5
  17. package/client/pages/inventory-check/inspecting-product.js +1 -1
  18. package/client/pages/manifest/create-loading-manifest.js +47 -22
  19. package/client/pages/manifest/dispatcher-verification-popup.js +24 -13
  20. package/client/pages/manifest/loading-manifest-detail.js +311 -46
  21. package/client/pages/manifest/loading-manifest-list.js +86 -13
  22. package/client/pages/order/arrival-notice/arrival-notice-detail.js +305 -52
  23. package/client/pages/order/arrival-notice/arrival-notice-list.js +20 -1
  24. package/client/pages/order/arrival-notice/create-arrival-notice.js +2 -2
  25. package/client/pages/order/goods-received-note/received-note-detail.js +187 -15
  26. package/client/pages/order/release-order/b2b/b2b-order-list.js +76 -80
  27. package/client/pages/order/release-order/b2c/b2c-order-requests.js +148 -123
  28. package/client/pages/order/release-order/batch-picking-popup.js +11 -0
  29. package/client/pages/order/release-order/create-release-order.js +762 -250
  30. package/client/pages/order/release-order/release-extra-product-popup.js +10 -3
  31. package/client/pages/order/release-order/release-order-detail.js +897 -215
  32. package/client/pages/order/transport-order/delivery-note-popup.js +1050 -107
  33. package/client/pages/order/transport-order/print-delivery-note.js +214 -33
  34. package/client/pages/order/transport-order/upload-delivery-note.js +6 -4
  35. package/client/pages/order/transport-order/view-delivery-note.js +0 -1
  36. package/client/pages/outbound/generate-worksheet-popup.js +374 -0
  37. package/client/pages/outbound/inventory-reassign-popup.js +1097 -0
  38. package/client/pages/outbound/loading-product.js +88 -78
  39. package/client/pages/outbound/merged-outbound-worksheet.js +1 -1
  40. package/client/pages/outbound/packing-product.js +193 -82
  41. package/client/pages/outbound/packing-worksheet-list.js +10 -9
  42. package/client/pages/outbound/picking-product.js +979 -905
  43. package/client/pages/outbound/route-label-popup.js +283 -191
  44. package/client/pages/outbound/serial-number-popup.js +1 -0
  45. package/client/pages/outbound/sorting-product.js +12 -12
  46. package/client/pages/outbound/worksheet-batch-picking.js +39 -5
  47. package/client/pages/outbound/worksheet-packing.js +17 -4
  48. package/client/pages/outbound/worksheet-picking.js +45 -6
  49. package/client/pages/report/inbound-serial-number-report.js +86 -9
  50. package/client/pages/report/inventory-report.js +10 -0
  51. package/client/pages/report/inventory-summary-report.js +28 -19
  52. package/client/pages/report/outbound-order-details-report.js +204 -43
  53. package/client/pages/report/outbound-serial-number-report.js +87 -9
  54. package/client/pages/report/release-inventory-report.js +503 -0
  55. package/client/route.js +5 -0
  56. package/client/util/index.js +2 -0
  57. package/client/util/page-settings.js +43 -0
  58. package/client/util/toast.js +10 -0
  59. package/dist-server/graphql/resolvers/board-setting/board-settings.js +3 -3
  60. package/dist-server/graphql/resolvers/board-setting/board-settings.js.map +1 -1
  61. package/dist-server/graphql/resolvers/custom/elccl/elccl-daily-collection-report.js +2 -2
  62. package/dist-server/graphql/resolvers/custom/elccl/elccl-daily-collection-report.js.map +1 -1
  63. package/dist-server/graphql/resolvers/custom/elccl/elccl-daily-order-inventory-report.js +1 -1
  64. package/dist-server/graphql/resolvers/custom/elccl/elccl-daily-order-inventory-report.js.map +1 -1
  65. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-pallet-detail-report.js +2 -2
  66. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-pallet-detail-report.js.map +1 -1
  67. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-report.js +9 -10
  68. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-report.js.map +1 -1
  69. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js +2 -2
  70. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js.map +1 -1
  71. package/dist-server/graphql/resolvers/custom/elccl/elccl-onhand-inventory-counter.js +6 -4
  72. package/dist-server/graphql/resolvers/custom/elccl/elccl-onhand-inventory-counter.js.map +1 -1
  73. package/dist-server/graphql/resolvers/custom/kimeda/kimeda-onhand-inventory-counter.js +6 -4
  74. package/dist-server/graphql/resolvers/custom/kimeda/kimeda-onhand-inventory-counter.js.map +1 -1
  75. package/dist-server/graphql/resolvers/dashboard/arrival-notices-by-status.js +21 -10
  76. package/dist-server/graphql/resolvers/dashboard/arrival-notices-by-status.js.map +1 -1
  77. package/dist-server/graphql/resolvers/dashboard/collection-orders-by-status.js +1 -2
  78. package/dist-server/graphql/resolvers/dashboard/collection-orders-by-status.js.map +1 -1
  79. package/dist-server/graphql/resolvers/dashboard/delivery-orders-by-status.js +1 -2
  80. package/dist-server/graphql/resolvers/dashboard/delivery-orders-by-status.js.map +1 -1
  81. package/dist-server/graphql/resolvers/dashboard/index.js +2 -1
  82. package/dist-server/graphql/resolvers/dashboard/index.js.map +1 -1
  83. package/dist-server/graphql/resolvers/dashboard/inventory-expiry-monitor.js +17 -1
  84. package/dist-server/graphql/resolvers/dashboard/inventory-expiry-monitor.js.map +1 -1
  85. package/dist-server/graphql/resolvers/dashboard/outbound-order-by-status.js +113 -75
  86. package/dist-server/graphql/resolvers/dashboard/outbound-order-by-status.js.map +1 -1
  87. package/dist-server/graphql/resolvers/dashboard/release-goods-by-status.js +21 -10
  88. package/dist-server/graphql/resolvers/dashboard/release-goods-by-status.js.map +1 -1
  89. package/dist-server/graphql/resolvers/dashboard/unit-inbounded-outbounded.js +56 -0
  90. package/dist-server/graphql/resolvers/dashboard/unit-inbounded-outbounded.js.map +1 -0
  91. package/dist-server/graphql/resolvers/index.js +5 -4
  92. package/dist-server/graphql/resolvers/index.js.map +1 -1
  93. package/dist-server/graphql/resolvers/inventory-comparison/inventory-comparison-list.js.map +1 -1
  94. package/dist-server/graphql/resolvers/opa-menu/opa-menus.js +8 -7
  95. package/dist-server/graphql/resolvers/opa-menu/opa-menus.js.map +1 -1
  96. package/dist-server/graphql/resolvers/{extra → other}/add-release-good-products.js +59 -8
  97. package/dist-server/graphql/resolvers/other/add-release-good-products.js.map +1 -0
  98. package/dist-server/graphql/resolvers/{extra → other}/index.js +3 -1
  99. package/dist-server/graphql/resolvers/other/index.js.map +1 -0
  100. package/dist-server/graphql/resolvers/other/page-settings.js +87 -0
  101. package/dist-server/graphql/resolvers/other/page-settings.js.map +1 -0
  102. package/dist-server/graphql/resolvers/reports/costing-report.js +4 -4
  103. package/dist-server/graphql/resolvers/reports/costing-report.js.map +1 -1
  104. package/dist-server/graphql/resolvers/reports/inbound-order-details-report.js +3 -3
  105. package/dist-server/graphql/resolvers/reports/inbound-order-details-report.js.map +1 -1
  106. package/dist-server/graphql/resolvers/reports/inbound-serial-number-report.js +36 -7
  107. package/dist-server/graphql/resolvers/reports/inbound-serial-number-report.js.map +1 -1
  108. package/dist-server/graphql/resolvers/reports/index.js +2 -1
  109. package/dist-server/graphql/resolvers/reports/index.js.map +1 -1
  110. package/dist-server/graphql/resolvers/reports/outbound-order-details-report.js +69 -30
  111. package/dist-server/graphql/resolvers/reports/outbound-order-details-report.js.map +1 -1
  112. package/dist-server/graphql/resolvers/reports/outbound-serial-number-report.js +36 -11
  113. package/dist-server/graphql/resolvers/reports/outbound-serial-number-report.js.map +1 -1
  114. package/dist-server/graphql/resolvers/reports/product-label-report.js +3 -3
  115. package/dist-server/graphql/resolvers/reports/product-label-report.js.map +1 -1
  116. package/dist-server/graphql/resolvers/reports/release-inventory-report.js +180 -0
  117. package/dist-server/graphql/resolvers/reports/release-inventory-report.js.map +1 -0
  118. package/dist-server/graphql/resolvers/shipping-provider/shipping-providers.js +2 -2
  119. package/dist-server/graphql/resolvers/shipping-provider/shipping-providers.js.map +1 -1
  120. package/dist-server/graphql/resolvers/warehouse-inventory-adjustment/warehouse-intentory-adjustment.js +1 -1
  121. package/dist-server/graphql/resolvers/warehouse-inventory-adjustment/warehouse-intentory-adjustment.js.map +1 -1
  122. package/dist-server/graphql/types/dashboard/index.js +1 -0
  123. package/dist-server/graphql/types/dashboard/index.js.map +1 -1
  124. package/dist-server/graphql/types/index.js +7 -2
  125. package/dist-server/graphql/types/index.js.map +1 -1
  126. package/dist-server/graphql/types/other/index.js +19 -0
  127. package/dist-server/graphql/types/other/index.js.map +1 -0
  128. package/dist-server/graphql/types/other/page-setting.js +34 -0
  129. package/dist-server/graphql/types/other/page-setting.js.map +1 -0
  130. package/dist-server/graphql/types/reports/index.js +6 -1
  131. package/dist-server/graphql/types/reports/index.js.map +1 -1
  132. package/dist-server/graphql/types/reports/outbound-order-details-report.js +17 -1
  133. package/dist-server/graphql/types/reports/outbound-order-details-report.js.map +1 -1
  134. package/dist-server/graphql/types/reports/release-inventory-report-list.js +12 -0
  135. package/dist-server/graphql/types/reports/release-inventory-report-list.js.map +1 -0
  136. package/dist-server/graphql/types/reports/release-inventory-report.js +27 -0
  137. package/dist-server/graphql/types/reports/release-inventory-report.js.map +1 -0
  138. package/dist-server/migrations/1568858861188-SeedSetting.js +5 -6
  139. package/dist-server/migrations/1568858861188-SeedSetting.js.map +1 -1
  140. package/dist-server/migrations/1623308919899-SeedLocationRecommendSetting.js +1 -1
  141. package/dist-server/migrations/1623308919899-SeedLocationRecommendSetting.js.map +1 -1
  142. package/dist-server/migrations/1623381200659-SeedStoringRule.js +1 -1
  143. package/dist-server/migrations/1623381200659-SeedStoringRule.js.map +1 -1
  144. package/dist-server/tsconfig.tsbuildinfo +1 -1
  145. package/dist-server/utils/report-query-util.js +5 -2
  146. package/dist-server/utils/report-query-util.js.map +1 -1
  147. package/helps/release-note.ko.md +8 -20
  148. package/helps/release-note.md +8 -20
  149. package/helps/release-note.ms.md +8 -20
  150. package/helps/release-note.zh.md +8 -20
  151. package/package.json +42 -42
  152. package/server/graphql/resolvers/board-setting/board-settings.ts +4 -6
  153. package/server/graphql/resolvers/custom/elccl/elccl-daily-collection-report.ts +4 -5
  154. package/server/graphql/resolvers/custom/elccl/elccl-daily-order-inventory-report.ts +9 -10
  155. package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-pallet-detail-report.ts +4 -5
  156. package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-report.ts +17 -19
  157. package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.ts +10 -8
  158. package/server/graphql/resolvers/custom/elccl/elccl-onhand-inventory-counter.ts +9 -9
  159. package/server/graphql/resolvers/custom/kimeda/kimeda-onhand-inventory-counter.ts +9 -9
  160. package/server/graphql/resolvers/dashboard/arrival-notices-by-status.ts +23 -14
  161. package/server/graphql/resolvers/dashboard/collection-orders-by-status.ts +4 -5
  162. package/server/graphql/resolvers/dashboard/delivery-orders-by-status.ts +4 -5
  163. package/server/graphql/resolvers/dashboard/index.ts +3 -1
  164. package/server/graphql/resolvers/dashboard/inventory-expiry-monitor.ts +18 -6
  165. package/server/graphql/resolvers/dashboard/outbound-order-by-status.ts +114 -81
  166. package/server/graphql/resolvers/dashboard/release-goods-by-status.ts +23 -14
  167. package/server/graphql/resolvers/dashboard/unit-inbounded-outbounded.ts +61 -0
  168. package/server/graphql/resolvers/index.ts +5 -4
  169. package/server/graphql/resolvers/inventory-comparison/inventory-comparison-list.ts +11 -9
  170. package/server/graphql/resolvers/opa-menu/opa-menus.ts +7 -6
  171. package/server/graphql/resolvers/{extra → other}/add-release-good-products.ts +73 -12
  172. package/server/graphql/resolvers/other/index.ts +10 -0
  173. package/server/graphql/resolvers/other/page-settings.ts +105 -0
  174. package/server/graphql/resolvers/reports/costing-report.ts +8 -10
  175. package/server/graphql/resolvers/reports/inbound-order-details-report.ts +7 -9
  176. package/server/graphql/resolvers/reports/inbound-serial-number-report.ts +41 -13
  177. package/server/graphql/resolvers/reports/index.ts +3 -1
  178. package/server/graphql/resolvers/reports/outbound-order-details-report.ts +76 -38
  179. package/server/graphql/resolvers/reports/outbound-serial-number-report.ts +42 -18
  180. package/server/graphql/resolvers/reports/product-label-report.ts +4 -6
  181. package/server/graphql/resolvers/reports/release-inventory-report.ts +201 -0
  182. package/server/graphql/resolvers/shipping-provider/shipping-providers.ts +3 -5
  183. package/server/graphql/resolvers/warehouse-inventory-adjustment/warehouse-intentory-adjustment.ts +10 -10
  184. package/server/graphql/types/dashboard/index.ts +1 -0
  185. package/server/graphql/types/index.ts +8 -2
  186. package/server/graphql/types/other/index.ts +19 -0
  187. package/server/graphql/types/other/page-setting.ts +33 -0
  188. package/server/graphql/types/reports/index.ts +6 -1
  189. package/server/graphql/types/reports/outbound-order-details-report.ts +17 -1
  190. package/server/graphql/types/reports/release-inventory-report-list.ts +8 -0
  191. package/server/graphql/types/reports/release-inventory-report.ts +23 -0
  192. package/server/migrations/1568858861188-SeedSetting.ts +4 -4
  193. package/server/migrations/1623308919899-SeedLocationRecommendSetting.ts +3 -2
  194. package/server/migrations/1623381200659-SeedStoringRule.ts +3 -2
  195. package/server/utils/report-query-util.ts +5 -2
  196. package/things-factory.config.js +4 -0
  197. package/translations/en.json +148 -27
  198. package/translations/ko.json +185 -105
  199. package/translations/ms.json +183 -98
  200. package/translations/zh.json +197 -112
  201. package/dist-server/graphql/resolvers/extra/add-release-good-products.js.map +0 -1
  202. package/dist-server/graphql/resolvers/extra/index.js.map +0 -1
  203. package/dist-server/graphql/types/extra/index.js +0 -11
  204. package/dist-server/graphql/types/extra/index.js.map +0 -1
  205. package/server/graphql/resolvers/extra/index.ts +0 -5
  206. package/server/graphql/types/extra/index.ts +0 -7
@@ -6,12 +6,12 @@ import './show-my-worksheet-list-popup'
6
6
  import '../components/worksheet-information-popup'
7
7
  import './serial-number-popup'
8
8
  import './tote-popup'
9
- import { sleep } from '@operato/utils'
10
9
 
11
10
  import gql from 'graphql-tag'
12
11
  import { css, html } from 'lit-element'
13
12
  import { connect } from 'pwa-helpers/connect-mixin.js'
14
13
 
14
+ import { sleep } from '@operato/utils'
15
15
  import { MultiColumnFormStyles } from '@things-factory/form-ui'
16
16
  import { i18next, localize } from '@things-factory/i18n-base'
17
17
  import { openPopup } from '@things-factory/layout-base'
@@ -21,7 +21,8 @@ import { isMobileDevice } from '@things-factory/utils'
21
21
 
22
22
  import { fetchLocationSortingRule } from '../../fetch-location-sorting-rule'
23
23
  import { fetchSettingRule } from '../../fetch-setting-value'
24
- import { BATCH_PICKING, LOCATION_SORTING_RULE, ORDER_SOURCES, PICKING } from '../constants'
24
+ import { showToast } from '../../util/index'
25
+ import { BATCH_PICKING, LOCATION_SORTING_RULE, LOCATION_TYPE, ORDER_SOURCES, PICKING, RO_TYPES } from '../constants'
25
26
 
26
27
  const PICKING_TYPES = { PICKING, BATCH_PICKING }
27
28
  class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
@@ -42,10 +43,14 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
42
43
  _worksheetInfo: Object,
43
44
  _locationName: String,
44
45
  _scannable: Boolean,
46
+ _enableInputQty: Boolean,
47
+ _releaseGoodType: String,
48
+ _isLastUnit: Boolean,
45
49
  config: Object,
46
50
  data: Object,
47
51
  isWholePicking: Boolean,
48
52
  locationNameSplit: Array,
53
+ _isReleaseGoodRecall: Boolean,
49
54
  locations: Array,
50
55
  orderNo: String,
51
56
  refPickingType: String,
@@ -140,9 +145,9 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
140
145
 
141
146
  if (
142
147
  (this.releaseGoodId || this.taskNo) &&
143
- this._selectedOrderInventory.status !== 'MISSING' &&
144
- this._selectedOrderInventory.hasMissingInventoryChanges !== true &&
145
- this._selectedOrderInventory.status !== 'DONE'
148
+ this._selectedOrderInventory?.status !== 'MISSING' &&
149
+ this._selectedOrderInventory?.hasMissingInventoryChanges !== true &&
150
+ this._selectedOrderInventory?.status !== 'DONE'
146
151
  ) {
147
152
  actions.push({
148
153
  title: i18next.t('button.missing_stock'),
@@ -211,7 +216,9 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
211
216
  }
212
217
 
213
218
  get serialInput() {
214
- return this.shadowRoot.querySelector('barcode-scanable-input[name=serialNumber]')?.shadowRoot.querySelector('input')
219
+ return this.shadowRoot
220
+ ?.querySelector('barcode-scanable-input[name=serialNumber]')
221
+ ?.shadowRoot.querySelector('input')
215
222
  }
216
223
 
217
224
  _focusOnNewLocationInput() {
@@ -286,6 +293,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
286
293
  this._reusablePalletList = { records: [] }
287
294
  this._selectedOrderInventory = null
288
295
  this.scannable = false
296
+ this._isLastUnit = false
289
297
  }
290
298
 
291
299
  render() {
@@ -338,6 +346,16 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
338
346
  this.completeHandler()
339
347
  }
340
348
  }
349
+ let [enableProductScanning, enableToteScanning, enableInputQty] = await Promise.all([
350
+ fetchSettingRule('enable-product-scanning', this._worksheetInfo.partnerDomainId),
351
+ fetchSettingRule('enable-tote-scanning', this._worksheetInfo.partnerDomainId),
352
+ fetchSettingRule('enable-input-qty', this._worksheetInfo.partnerDomainId)
353
+ ])
354
+ this._enableProductScanning = enableProductScanning
355
+ this._enableToteScanning = enableToteScanning
356
+ this._enableInputQty = enableInputQty
357
+
358
+ this.focusOnInput()
341
359
  }
342
360
  }}"
343
361
  >
@@ -349,7 +367,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
349
367
  ${this.scannable
350
368
  ? html`
351
369
  <fieldset>
352
- ${this._hasBinPicking && (!this.toteNo || this.tote !== '')
370
+ ${this._hasBinPicking && (!this.toteNo || this.tote == '')
353
371
  ? html`
354
372
  <label>${i18next.t('label.bin_location')}</label>
355
373
  <barcode-scanable-input
@@ -373,32 +391,41 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
373
391
  <label>${i18next.t('label.lot_id')}</label>
374
392
  <barcode-scanable-input name="palletId" custom-input></barcode-scanable-input>
375
393
  `}
376
- ${this._enableProductScanning
394
+ ${this._enableProductScanning && this._isCartonLabel
377
395
  ? html`
378
396
  <label>${i18next.t('label.product_barcode')}</label>
379
397
  <barcode-scanable-input name="productBarcode" custom-input></barcode-scanable-input>
380
398
  `
381
- : html`
382
- ${this._isRequireSerialNumberScanningOutbound
383
- ? ''
384
- : html`
385
- <label>${i18next.t('label.picked_qty')}</label>
386
- <input type="number" min="1" name="confirmedQty" />
387
- `}
388
- `}
399
+ : ''}
400
+ ${!this._isRequireSerialNumberScanningOutbound &&
401
+ ((this._enableInputQty !== 0 && this._releaseGoodType != RO_TYPES.B2B.value) || !this._isCartonLabel)
402
+ ? html`${(this._enableInputQty == 1 && !this._releaseGoodType) ||
403
+ (this._enableInputQty == 2 && this._releaseGoodType == RO_TYPES.B2C.value) ||
404
+ this._enableInputQty == 3 ||
405
+ !this._isCartonLabel
406
+ ? html`<label>${i18next.t('label.picked_qty')}</label>
407
+ <input type="number" min="1" name="confirmedQty" /> `
408
+ : ''} `
409
+ : ''}
410
+ ${this._isRequireSerialNumberScanningOutbound
411
+ ? html`
412
+ <label>${i18next.t('label.serial_number')}</label>
413
+ <barcode-scanable-input name="serialNumber" custom-input></barcode-scanable-input>
414
+ `
415
+ : ``}
389
416
  ${this.isWholePicking ||
390
417
  this._crossDocking ||
391
418
  this._isCartonLabel ||
392
- this._enableProductScanning ||
393
- this._isRequireSerialNumberScanningOutbound
419
+ (this._enableProductScanning && this._isCartonLabel)
394
420
  ? ''
395
421
  : html`
396
422
  ${this._incompleteLocationName
397
423
  ? ''
398
- : html`
399
- <label>${i18next.t('label.return_location')}</label>
400
- <barcode-scanable-input name="locationName" custom-input></barcode-scanable-input>
401
- `}
424
+ : html`${(this._isRequireSerialNumberScanningOutbound && this._isLastUnit) ||
425
+ !this._isRequireSerialNumberScanningOutbound
426
+ ? html` <label>${i18next.t('label.return_location')}</label>
427
+ <barcode-scanable-input name="locationName" custom-input></barcode-scanable-input>`
428
+ : ''}`}
402
429
  <select
403
430
  ?hidden="${!this._incompleteLocationName}"
404
431
  name="newLocationCode"
@@ -416,12 +443,6 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
416
443
  )}
417
444
  </select>
418
445
  `}
419
- ${this._isRequireSerialNumberScanningOutbound
420
- ? html`
421
- <label>${i18next.t('label.serial_number')}</label>
422
- <barcode-scanable-input name="serialNumber" custom-input></barcode-scanable-input>
423
- `
424
- : ``}
425
446
  </fieldset>
426
447
  `
427
448
  : ''}
@@ -476,7 +497,6 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
476
497
  this.inputForm.reset()
477
498
  this._isReplacement = false
478
499
 
479
- if (this.binLocationInput) this.binLocationInput.value = ''
480
500
  if (this.productBarcodeInput) this.productBarcodeInput.value = ''
481
501
  if (this.cartonInput) this.cartonInput.value = ''
482
502
  if (this.palletInput) this.palletInput.value = ''
@@ -487,6 +507,8 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
487
507
  await this.fetchInventories(
488
508
  this.refPickingType === PICKING_TYPES.PICKING.value ? this.releaseGoodNo : this.taskNo
489
509
  )
510
+
511
+ this.focusOnInput
490
512
  let updatedRecords = this._selectedOrderInventory
491
513
  if (updatedRecords.releaseQty === updatedRecords.pickedQty) {
492
514
  updatedRecords.status = 'DONE'
@@ -603,976 +625,1042 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
603
625
  this._hasBinPicking = await enableBinPickingTask
604
626
  }
605
627
 
606
- autoFetchPickingTasks(orderNo) {
607
- this.releaseGoodNoInput.value = orderNo
608
- this.fetchAll(this.releaseGoodNoInput.value)
609
- }
628
+ formatWorksheetDetailInfos(wsdInfos) {
629
+ return wsdInfos
630
+ .map(record => {
631
+ if (record.pickedQty == record.releaseQty || record.status == 'MISSING') {
632
+ record.completed = true
633
+ } else {
634
+ record.completed = false
635
+ }
636
+ record.locationName = record?.location?.name
637
+ record.product = record?.relatedOrderInv && record?.relatedOrderInv?.product
610
638
 
611
- async fetchInventories(pickingRefNo) {
612
- if (!pickingRefNo) return
639
+ if (this._crossDocking) {
640
+ record.batchId = record.relatedOrderInv.batchId
641
+ record.packingType = record.relatedOrderInv.packingType
642
+ }
613
643
 
614
- const data = this._selectedOrderInventory
615
- let response
616
- switch (this.refPickingType) {
617
- case PICKING_TYPES.PICKING.value:
618
- response = await client.query({
619
- query: gql`
620
- query pickingWorksheet($releaseGoodNo: String!, $locationSortingRules: [Sorting!]) {
621
- pickingWorksheet(releaseGoodNo: $releaseGoodNo, locationSortingRules: $locationSortingRules) {
622
- worksheetInfo {
623
- releaseGood {
624
- id
625
- name
626
- crossDocking
627
- }
628
- bizplaceName
629
- partnerDomainId
630
- refNo
631
- refNo2
632
- refNo3
633
- startedAt
634
- containerNo
635
- marketplaceStatus
636
- shippingProvider
637
- trackingNo
638
- }
639
- worksheetDetailInfos {
640
- hasMissingInventoryChanges
641
- name
642
- palletId
643
- cartonId
644
- batchId
645
- batchIdRef
646
- product {
647
- id
648
- sku
649
- name
650
- description
651
- isRequireSerialNumberScanningOutbound
652
- }
653
- qty
654
- releaseQty
655
- pickedQty
656
- expirationDate
657
- status
658
- description
659
- targetName
660
- packingType
661
- packingSize
662
- location {
663
- name
664
- description
665
- }
666
- binLocation {
667
- name
668
- description
669
- }
670
- relatedOrderInv {
671
- id
672
- batchId
673
- batchIdRef
674
- packingType
675
- binLocation {
676
- id
677
- name
678
- }
679
- product {
680
- id
681
- sku
682
- name
683
- description
684
- isRequireSerialNumberScanningOutbound
685
- }
686
- }
687
- }
688
- }
689
- }
690
- `,
691
- variables: { releaseGoodNo: pickingRefNo, locationSortingRules: this.locationSortingRules }
692
- })
644
+ if (this._hasBinPicking) {
645
+ record.binLocation = record.binLocation?.name
646
+ }
693
647
 
694
- if (!response.errors) {
695
- this.releaseGoodNo = response.data.pickingWorksheet.worksheetInfo.releaseGood.name
696
- this.releaseGoodId = response.data.pickingWorksheet.worksheetInfo.releaseGood.id
697
- if (!response.data?.pickingWorksheet) return
648
+ if (record?.cartonId) {
649
+ record.hasCartonLabel = true
650
+ }
698
651
 
699
- const { worksheetInfo, worksheetDetailInfos } = response.data.pickingWorksheet
700
- this._crossDocking = worksheetInfo.releaseGood?._crossDocking
701
- this._bizplaceName = worksheetInfo.bizplaceName
702
- this._orderNo = this.releaseGoodNo
703
- this._worksheetInfo = worksheetInfo
704
- this.data = { records: this.formatWorksheetDetailInfos(worksheetDetailInfos) }
652
+ record.releaseProgress = `${record.pickedQty} / ${record.releaseQty}`
653
+ record.sku = record?.relatedOrderInv.product?.sku
705
654
 
706
- if (!this._selectedOrderInventory) {
707
- this._selectedOrderInventory = this.data.records[0]
708
- }
655
+ return record
656
+ })
657
+ .sort((a, b) => a.hasMissingInventoryChanges - b.hasMissingInventoryChanges)
658
+ .sort((a, b) => a.completed - b.completed)
659
+ }
709
660
 
710
- if (
711
- this._selectedOrderInventory &&
712
- this._selectedOrderInventory.pickedQty != this._selectedOrderInventory.releaseQty &&
713
- !this._selectedOrderInventory.hasMissingInventoryChanges &&
714
- this._selectedOrderInventory.status !== 'MISSING'
715
- ) {
716
- this.scannable = true
661
+ clearView() {
662
+ this.data = { records: [] }
663
+ this.infoForm.reset()
664
+ this.inputForm.reset()
665
+ this._isRequireSerialNumberScanningOutbound = false
666
+ this.releaseGoodNo = null
667
+ this.releaseGoodId = null
668
+ this.taskNo = null
669
+ this._crossDocking = false
670
+ this._selectedOrderInventory = null
671
+ this._incompleteLocationName = false
672
+ this._isExecuting = false
673
+ this._locationName = null
674
+ this.toteNo = ''
675
+ }
676
+
677
+ fillUpForm(form, data) {
678
+ this._incompleteLocationName = false
679
+ form.reset()
680
+ for (let key in data) {
681
+ Array.from(form.querySelectorAll('input')).forEach(field => {
682
+ if (field.name === key && field.type === 'checkbox') {
683
+ field.checked = data[key]
684
+ } else if (field.name === key && field.type === 'datetime-local') {
685
+ const datetime = Number(data[key])
686
+ const timezoneOffset = new Date(datetime).getTimezoneOffset() * 60000
687
+ field.value = new Date(datetime - timezoneOffset).toISOString().slice(0, -1)
688
+ } else if (field.name === key) {
689
+ if (data[key] instanceof Object) {
690
+ const objectData = data[key]
691
+ field.value = `${objectData.name} ${objectData.description ? `(${objectData.description})` : ''}`
717
692
  } else {
718
- this.scannable = false
693
+ field.value = data[key]
719
694
  }
695
+ }
696
+ })
697
+ }
698
+ }
720
699
 
721
- if (!this._isCartonLabel && data) {
722
- const findPalletId = worksheetDetailInfos.find(res => res.palletId == data.palletId)
700
+ async picking(e) {
701
+ if (e.keyCode !== 13) return
702
+ e.preventDefault()
703
+ try {
704
+ let answer = await this.validatePicking()
705
+ if (answer) {
706
+ if (!answer?.value) return
707
+ }
708
+ let orderNo = this.refPickingType === PICKING_TYPES.PICKING.value ? this.releaseGoodNo : this.taskNo
723
709
 
724
- if (data && findPalletId.hasMissingInventoryChanges) {
725
- this.scannable = false
726
- }
710
+ let response = {}
711
+ if (this.crossDocking) {
712
+ response = await this.pickCrossDocking()
713
+ } else if (this._enableProductScanning && this._isCartonLabel) {
714
+ response = await this.productBarcodePicking()
715
+ } else {
716
+ if (this._isReplacement && !this._isCartonLabel) {
717
+ if (this._isReleaseGoodRecall) {
718
+ throw new Error(i18next.t('text.lot_replacement_is_not_applicable_on_recall_release_order'))
719
+ } else {
720
+ this.openPalletReplacementPopup()
727
721
  }
722
+ return
723
+ } else {
724
+ response = await this.pickCommonPicking()
725
+ }
726
+ }
728
727
 
729
- if (this._isCartonLabel && data) {
730
- const findCartonId = worksheetDetailInfos.find(res => res.cartonId == data.cartonId)
728
+ if (!response.errors) {
729
+ if (this._hasBinPicking && (!this.toteNo || this.tote == '')) {
730
+ this._currentBinLocation = this.binLocationInput.value
731
+ }
732
+ if (this._isRequireSerialNumberScanningOutbound) this.serialInput.value = ''
733
+ else if (this._enableProductScanning) this.productBarcodeInput.value = ''
734
+ else this.releaseQtyInput.value = ''
731
735
 
732
- if (data && findCartonId.hasMissingInventoryChanges) {
733
- this.scannable = false
734
- }
735
- }
736
+ if (!this._isCartonLabel && !this._isRequireSerialNumberScanningOutbound) {
737
+ this.palletInput.value = ''
738
+ }
736
739
 
737
- if (this._selectedOrderInventory) {
738
- const record = this.data.records.find(record => record.name === this._selectedOrderInventory.name)
739
- this._selectedOrderInventory = record
740
- this.updateSelectedItemProp(record)
741
- await this.updateComplete
742
- await this.grist.reset()
743
- this.fillUpForm(this.inputForm, {
744
- ...record,
745
- binLocation: record?.binLocation ? record.binLocation : ''
746
- })
740
+ if (!this.isWholePicking && !this._crossDocking && !this._isCartonLabel && this.locationInput)
741
+ this.locationInput.value = ''
742
+ }
747
743
 
748
- if (record.pickedQty == record.releaseQty) {
749
- if (this.cartonInput) this.cartonInput.value = ''
750
- if (this.palletInput) this.palletInput.value = ''
751
- } else {
752
- // pre-set bin location from last scan if none was set
753
- if (
754
- this._hasBinPicking &&
755
- this.binLocationInput &&
756
- (!this._currentBinLocation || this._currentBinLocation == '')
757
- ) {
758
- this._currentBinLocation = record?.binLocation ? record.binLocation : ''
759
- }
760
- this.focusOnInput()
761
- }
762
- }
744
+ await this.fetchInventories(orderNo)
763
745
 
764
- this._enableProductScanning = await fetchSettingRule('enable-product-scanning', worksheetInfo.partnerDomainId)
765
- this._enableToteScanning = await fetchSettingRule('enable-tote-scanning', worksheetInfo.partnerDomainId)
766
- }
767
- break
768
-
769
- case PICKING_TYPES.BATCH_PICKING.value:
770
- response = await client.query({
771
- query: gql`
772
- query batchPickingWorksheet($taskNo: String!, $locationSortingRules: [Sorting!]) {
773
- batchPickingWorksheet(taskNo: $taskNo, locationSortingRules: $locationSortingRules) {
774
- worksheetInfo {
775
- bizplaceName
776
- partnerDomainId
777
- startedAt
778
- }
779
- worksheetDetailInfos {
780
- hasMissingInventoryChanges
781
- palletId
782
- cartonId
783
- batchId
784
- product {
785
- id
786
- name
787
- description
788
- sku
789
- isRequireSerialNumberScanning
790
- }
791
- qty
792
- releaseQty
793
- pickedQty
794
- expirationDate
795
- status
796
- packingType
797
- packingSize
798
- location {
799
- name
800
- }
801
- binLocation {
802
- name
803
- }
804
- relatedOrderInv {
805
- batchId
806
- packingType
807
- product {
808
- id
809
- name
810
- description
811
- sku
812
- }
813
- }
814
- }
815
- }
816
- }
817
- `,
818
- variables: { taskNo: pickingRefNo, locationSortingRules: this.locationSortingRules }
819
- })
746
+ this.focusOnInput()
820
747
 
821
- if (!response.errors) {
822
- if (!this._selectedOrderInventory) this.clearView()
823
- this.taskNo = pickingRefNo
824
- if (!response.data?.batchPickingWorksheet) return
748
+ this.isReplacement = false
749
+ } catch (e) {
750
+ showToast(e)
751
+ }
752
+ }
825
753
 
826
- const { worksheetInfo, worksheetDetailInfos } = response.data.batchPickingWorksheet
827
- await this.updateComplete
828
- this._bizplaceName = worksheetInfo.bizplaceName
829
- this._orderNo = this.taskNo
830
- this._worksheetInfo = worksheetInfo
831
- this.data = { records: this.formatWorksheetDetailInfos(worksheetDetailInfos) }
754
+ openPalletReplacementPopup() {
755
+ openPopup(
756
+ html`
757
+ <picking-replacement-popup
758
+ .orderInventory="${this._selectedOrderInventory}"
759
+ .refPickingType="${this.refPickingType}"
760
+ .replacePalletId="${this.palletInput.value}"
761
+ @completed="${() => {
762
+ this._selectedOrderInventory = null
763
+ let a = this._selectedOrderInventory
764
+ if (this.refPickingType === PICKING_TYPES.PICKING.value) {
765
+ this.fetchInventories(this.releaseGoodNoInput.value)
766
+ this.fetchPalletsHandler(this.releaseGoodNoInput.value)
767
+ } else {
768
+ this.fetchInventories(this.taskNoInput.value)
769
+ this.fetchPalletsHandler(this.taskNoInput.value)
770
+ }
771
+ // this._selectedTaskStatus = null
772
+ this._isReplacement = false
773
+ this._isExecuting = false
774
+ }}"
775
+ ></picking-replacement-popup>
776
+ `,
777
+ {
778
+ backdrop: true,
779
+ size: 'large',
780
+ title: i18next.t('title.pallet_replacement')
781
+ }
782
+ )
783
+ }
832
784
 
833
- if (!this._selectedOrderInventory) {
834
- this._selectedOrderInventory = this.data.records[0]
835
- }
785
+ async openSerialNumberPopup() {
786
+ await sleep(1010)
787
+ openPopup(
788
+ html`
789
+ <serial-number-popup
790
+ .orderInventory="${this?._selectedOrderInventory?.relatedOrderInv}"
791
+ .orderType="${i18next.t('text.outbound')}"
792
+ .orderSource="${ORDER_SOURCES.PICKING.value}"
793
+ .orderId="${this.releaseGoodId}"
794
+ .data="${this?._selectedOrderInventory}"
795
+ @close-serial-number-popup="${async e => {
796
+ await this.fetchAll(this.releaseGoodNo)
797
+ }}"
798
+ ></serial-number-popup>
799
+ `,
800
+ {
801
+ closable: false,
802
+ backdrop: false,
803
+ escapable: false,
804
+ size: 'large',
805
+ title: i18next.t('title.serial_number_list')
806
+ }
807
+ )
808
+ }
836
809
 
837
- if (
838
- this._selectedOrderInventory &&
839
- this._selectedOrderInventory.pickedQty != this._selectedOrderInventory.releaseQty &&
840
- !this._selectedOrderInventory.hasMissingInventoryChanges &&
841
- this._selectedOrderInventory.status !== 'MISSING'
842
- ) {
843
- this.scannable = true
844
- } else {
845
- this.scannable = false
846
- }
810
+ async openTotePopup() {
811
+ await sleep(1010)
812
+ openPopup(
813
+ html`
814
+ <tote-popup
815
+ .orderNo="${this.releaseGoodNo}"
816
+ .toteNo="${this.toteNo}"
817
+ .bizplace="${this._bizplaceName}"
818
+ @completed="${async e => {
819
+ this.toteNo = e.detail
820
+ }}"
821
+ ></tote-popup>
822
+ `,
823
+ {
824
+ closable: false,
825
+ backdrop: false,
826
+ escapable: false,
827
+ size: 'large',
828
+ title: i18next.t('title.tote_scanning')
829
+ }
830
+ )
831
+ }
847
832
 
848
- if (!this._isCartonLabel && data) {
849
- const findPalletId = worksheetDetailInfos.find(res => res.palletId == data.palletId)
833
+ _openWorksheetInformation() {
834
+ openPopup(
835
+ html`
836
+ <worksheet-information-popup .worksheetInformation="${this._worksheetInfo}"></worksheet-information-popup>
837
+ `,
838
+ {
839
+ backdrop: true,
840
+ size: 'large',
841
+ title: i18next.t('title.order_information')
842
+ }
843
+ )
844
+ }
850
845
 
851
- if (data && findPalletId.hasMissingInventoryChanges) {
852
- this.scannable = false
853
- }
854
- }
846
+ async pick_crossDocking() {
847
+ return await client.mutate({
848
+ mutation: gql`
849
+ mutation crossDockPicking(
850
+ $worksheetDetailName: String!
851
+ $worksheetType: String!
852
+ $palletId: String!
853
+ $releaseQty: Int!
854
+ ) {
855
+ crossDockPicking(
856
+ worksheetDetailName: $worksheetDetailName
857
+ worksheetType: $worksheetType
858
+ palletId: $palletId
859
+ releaseQty: $releaseQty
860
+ )
861
+ }
862
+ `,
863
+ variables: {
864
+ worksheetDetailName: this._selectedOrderInventory.name,
865
+ worksheetType: this.refPickingType,
866
+ palletId: this.palletInput.value,
867
+ releaseQty: parseInt(this.releaseQtyInput.value)
868
+ }
869
+ })
870
+ }
855
871
 
856
- if (this._isCartonLabel && data) {
857
- const findCartonId = worksheetDetailInfos.find(res => res.cartonId == data.cartonId)
872
+ async pickCommonPicking() {
873
+ if (this._isExecuting) throw new Error(i18next.t('text.previous_picking_is_still_executing_please_wait'))
874
+ this._isExecuting = true
858
875
 
859
- if (data && findCartonId.hasMissingInventoryChanges) {
860
- this.scannable = false
876
+ try {
877
+ switch (this.refPickingType) {
878
+ case PICKING_TYPES.PICKING.value:
879
+ return await client.mutate({
880
+ mutation: gql`
881
+ mutation picking(
882
+ $worksheetDetailName: String!
883
+ $worksheetType: String!
884
+ $palletId: String
885
+ $locationName: String!
886
+ $releaseQty: Int!
887
+ $binLocation: String
888
+ $serialNumber: String
889
+ $toteNo: String
890
+ ) {
891
+ picking(
892
+ worksheetDetailName: $worksheetDetailName
893
+ worksheetType: $worksheetType
894
+ palletId: $palletId
895
+ locationName: $locationName
896
+ releaseQty: $releaseQty
897
+ binLocation: $binLocation
898
+ serialNumber: $serialNumber
899
+ toteNo: $toteNo
900
+ )
901
+ }
902
+ `,
903
+ variables: {
904
+ worksheetDetailName: this._selectedOrderInventory.name,
905
+ worksheetType: this.refPickingType,
906
+ palletId: this.palletInput.value.trim(),
907
+ locationName: this._locationName ? this._locationName : this._selectedOrderInventory?.location.name,
908
+ releaseQty: this._isRequireSerialNumberScanningOutbound ? 1 : parseInt(this.releaseQtyInput.value),
909
+ binLocation:
910
+ this._hasBinPicking && (!this.toteNo || this.tote == '') ? this.binLocationInput.value : null,
911
+ serialNumber: this._isRequireSerialNumberScanningOutbound ? this.serialInput.value : null,
912
+ toteNo: this._enableToteScanning && this.toteNo !== '' ? this.toteNo : null
861
913
  }
862
- }
863
-
864
- this._enableProductScanning = await fetchSettingRule('enable-product-scanning', worksheetInfo.partnerDomainId)
865
-
866
- if (this._selectedOrderInventory) {
867
- const record = this.data.records.find(
868
- record =>
869
- record.product.sku === this._selectedOrderInventory.product.sku &&
870
- record.palletId === this._selectedOrderInventory.palletId
871
- )
872
-
873
- this._selectedOrderInventory = record
874
- this.updateSelectedItemProp(record)
914
+ })
875
915
 
876
- if (record.pickedQty == record.releaseQty) {
877
- if (this._isCartonLabel) {
878
- //need to relook into clearview logic
879
- if (this.cartonInput) this.cartonInput.value = ''
880
- if (this.productBarcodeInput) this.productBarcodeInput.value = ''
916
+ case PICKING_TYPES.BATCH_PICKING.value:
917
+ return await client.mutate({
918
+ mutation: gql`
919
+ mutation batchPicking(
920
+ $taskNo: String!
921
+ $worksheetType: String!
922
+ $palletId: String!
923
+ $locationName: String
924
+ $binLocationName: String
925
+ $releaseQty: Int!
926
+ ) {
927
+ batchPicking(
928
+ taskNo: $taskNo
929
+ worksheetType: $worksheetType
930
+ palletId: $palletId
931
+ locationName: $locationName
932
+ binLocationName: $binLocationName
933
+ releaseQty: $releaseQty
934
+ )
881
935
  }
882
- this.fillUpForm(this.inputForm, record)
883
- } else {
884
- this.fillUpForm(this.inputForm, record)
885
- this.focusOnInput()
936
+ `,
937
+ variables: {
938
+ taskNo: this.taskNo,
939
+ worksheetType: this.refPickingType,
940
+ palletId: this.palletInput.value.trim(),
941
+ locationName: this._locationName ? this._locationName : this._selectedOrderInventory?.location.name,
942
+ binLocationName:
943
+ this._hasBinPicking && (!this.toteNo || this.tote == '') ? this.binLocationInput.value : null,
944
+ releaseQty: parseInt(this.releaseQtyInput.value)
886
945
  }
887
- }
888
- }
889
- break
946
+ })
947
+ }
948
+ } catch (e) {
949
+ showToast(e)
950
+ } finally {
951
+ this._isExecuting = false
890
952
  }
891
-
892
- this.updateContext()
893
953
  }
894
954
 
895
- formatWorksheetDetailInfos(wsdInfos) {
896
- return wsdInfos
897
- .map(record => {
898
- if (record.pickedQty == record.releaseQty || record.status == 'MISSING') {
899
- record.completed = true
900
- } else {
901
- record.completed = false
902
- }
903
- record.locationName = record?.location?.name
904
- record.product = record?.relatedOrderInv && record?.relatedOrderInv?.product
955
+ async productBarcodePicking() {
956
+ if (this._isExecuting) throw new Error(i18next.t('text.previous_picking_is_still_executing_please_wait'))
957
+ this._isExecuting = true
905
958
 
906
- if (this._crossDocking) {
907
- record.batchId = record.relatedOrderInv.batchId
908
- record.packingType = record.relatedOrderInv.packingType
909
- }
959
+ try {
960
+ switch (this.refPickingType) {
961
+ case PICKING_TYPES.PICKING.value:
962
+ return await client.mutate({
963
+ mutation: gql`
964
+ mutation scanProductPicking(
965
+ $worksheetDetailName: String!
966
+ $worksheetType: String!
967
+ $productBarcode: String!
968
+ $cartonId: String!
969
+ $binLocation: String
970
+ $serialNumber: String
971
+ $toteNo: String
972
+ $pickingQty: Int
973
+ ) {
974
+ scanProductPicking(
975
+ worksheetDetailName: $worksheetDetailName
976
+ worksheetType: $worksheetType
977
+ productBarcode: $productBarcode
978
+ cartonId: $cartonId
979
+ binLocation: $binLocation
980
+ serialNumber: $serialNumber
981
+ toteNo: $toteNo
982
+ pickingQty: $pickingQty
983
+ )
984
+ }
985
+ `,
986
+ variables: {
987
+ worksheetDetailName: this._selectedOrderInventory.name,
988
+ worksheetType: this.refPickingType,
989
+ productBarcode: this.productBarcodeInput.value.trim(),
990
+ cartonId: this.cartonInput.value.trim(),
991
+ serialNumber: this._isRequireSerialNumberScanningOutbound ? this.serialInput.value : null,
992
+ binLocation:
993
+ this._hasBinPicking && (!this.toteNo || this.tote == '') ? this.binLocationInput.value : null,
994
+ toteNo: this._enableToteScanning && this.toteNo !== '' ? this.toteNo : null,
995
+ pickingQty: this.releaseQtyInput?.value ? parseInt(this.releaseQtyInput.value) : 1
996
+ }
997
+ })
998
+
999
+ case PICKING_TYPES.BATCH_PICKING.value:
1000
+ return await client.mutate({
1001
+ mutation: gql`
1002
+ mutation scanProductBatchPicking(
1003
+ $taskNo: String!
1004
+ $worksheetType: String!
1005
+ $cartonId: String!
1006
+ $inventory: InventoryPatch!
1007
+ $productBarcode: String!
1008
+ $binLocationName: String
1009
+ $pickingQty: Int
1010
+ ) {
1011
+ scanProductBatchPicking(
1012
+ taskNo: $taskNo
1013
+ worksheetType: $worksheetType
1014
+ cartonId: $cartonId
1015
+ inventory: $inventory
1016
+ productBarcode: $productBarcode
1017
+ binLocationName: $binLocationName
1018
+ pickingQty: $pickingQty
1019
+ )
1020
+ }
1021
+ `,
1022
+ variables: {
1023
+ taskNo: this.taskNo,
1024
+ worksheetType: this.refPickingType,
1025
+ cartonId: this.cartonInput.value.trim(),
1026
+ productBarcode: this.productBarcodeInput.value.trim(),
1027
+ inventory: {
1028
+ batchId: this._selectedOrderInventory.batchId,
1029
+ packingType: this._selectedOrderInventory.packingType,
1030
+ packingSize: this._selectedOrderInventory.packingSize,
1031
+ product: { id: this._selectedOrderInventory.product.id }
1032
+ },
1033
+ binLocationName:
1034
+ this._hasBinPicking && (!this.toteNo || this.tote == '') ? this.binLocationInput.value : null,
1035
+ pickingQty: this.releaseQtyInput?.value ? parseInt(this.releaseQtyInput.value) : 1
1036
+ }
1037
+ })
1038
+ }
1039
+ } catch (e) {
1040
+ throw e
1041
+ } finally {
1042
+ this._isExecuting = false
1043
+ }
1044
+ }
910
1045
 
911
- if (this._hasBinPicking) {
912
- record.binLocation = record.binLocation?.name
913
- }
1046
+ async validatePicking() {
1047
+ // validate for order selection
1048
+ // pallet id existing
914
1049
 
915
- if (record?.cartonId) {
916
- record.hasCartonLabel = true
917
- }
1050
+ if ((!this.palletInput?.value || !this.cartonInput?.value) && this._isRequireSerialNumberScanningOutbound) {
1051
+ if (!this.serialInput?.value) {
1052
+ this._focusOnSerialInput()
1053
+ throw new Error(i18next.t('text.empty_serial_number'))
1054
+ }
1055
+ }
918
1056
 
919
- record.releaseProgress = `${record.pickedQty} / ${record.releaseQty}`
920
- record.sku = record?.relatedOrderInv.product?.sku
1057
+ if (!this._isCartonLabel) {
1058
+ if (!this.palletInput.value) {
1059
+ this._focusOnLotNoInput()
1060
+ throw new Error(i18next.t('text.lot_id_is_empty'))
1061
+ } else {
1062
+ if (
1063
+ this._selectedOrderInventory.palletId !== this.palletInput.value &&
1064
+ !this._isRequireSerialNumberScanningOutbound
1065
+ ) {
1066
+ const isInProgressing = await this.checkProgressingPallet(this.palletInput.value)
1067
+ if (isInProgressing) throw new Error(i18next.t('text.pallet_is_in_progressing'))
921
1068
 
922
- return record
923
- })
924
- .sort((a, b) => a.hasMissingInventoryChanges - b.hasMissingInventoryChanges)
925
- .sort((a, b) => a.completed - b.completed)
926
- }
1069
+ this._isReplacement = await this.checkProductIdenticality(
1070
+ this._selectedOrderInventory.palletId,
1071
+ this.palletInput.value
1072
+ )
927
1073
 
928
- async fetchPalletsHandler(releaseGoodNo) {
929
- const response = await client.query({
930
- query: gql`
931
- query pallets($filters: [Filter!]!, $pagination: Pagination) {
932
- pallets(filters: $filters, pagination: $pagination) {
933
- items {
934
- id
935
- name
936
- owner {
937
- id
938
- name
939
- description
940
- }
941
- holder {
942
- id
943
- name
944
- description
945
- }
946
- status
947
- }
1074
+ if (!this._isReplacement) {
1075
+ this._focusOnLotNoInput()
1076
+ throw new Error(i18next.t('text.wrong_lot_id'))
948
1077
  }
949
1078
  }
950
- `,
951
- variables: {
952
- filters: [{ name: 'refOrderNo', value: releaseGoodNo, operator: 'eq' }],
953
- pagination: { page: 1, limit: 9999999 }
954
1079
  }
955
- })
1080
+ } else {
1081
+ if (!this.cartonInput?.value) {
1082
+ this._focusOnCartonNoInput()
1083
+ throw new Error(i18next.t('text.carton_id_is_empty'))
1084
+ }
956
1085
 
957
- if (!response.errors) {
958
- this._reusablePalletList = { records: response.data.pallets.items }
959
- }
960
- }
1086
+ if (this._selectedOrderInventory.cartonId) {
1087
+ if (this._selectedOrderInventory.cartonId !== this.cartonInput.value) {
1088
+ //carton replacement?
1089
+ throw new Error(i18next.t('text.invalid_carton_id'))
1090
+ this._isReplacement = await this.checkCartonIdenticality(
1091
+ this._selectedOrderInventory.cartonId,
1092
+ this._selectedOrderInventory.palletId,
1093
+ this.cartonInput.value
1094
+ )
961
1095
 
962
- clearView() {
963
- this.data = { records: [] }
964
- this.infoForm.reset()
965
- this.inputForm.reset()
966
- this._isRequireSerialNumberScanningOutbound = false
967
- this.releaseGoodNo = null
968
- this.releaseGoodId = null
969
- this.taskNo = null
970
- this._crossDocking = false
971
- this._selectedOrderInventory = null
972
- this._incompleteLocationName = false
973
- this._isExecuting = false
974
- this._locationName = null
975
- this.toteNo = ''
976
- }
1096
+ if (!this._isReplacement) {
1097
+ this.cartonInput.value = ''
1098
+ this._focusOnCartonNoInput()
1099
+ throw new Error(i18next.t('text.wrong_carton_id'))
1100
+ }
1101
+ }
977
1102
 
978
- fillUpForm(form, data) {
979
- this._incompleteLocationName = false
980
- form.reset()
981
- for (let key in data) {
982
- Array.from(form.querySelectorAll('input')).forEach(field => {
983
- if (field.name === key && field.type === 'checkbox') {
984
- field.checked = data[key]
985
- } else if (field.name === key && field.type === 'datetime-local') {
986
- const datetime = Number(data[key])
987
- const timezoneOffset = new Date(datetime).getTimezoneOffset() * 60000
988
- field.value = new Date(datetime - timezoneOffset).toISOString().slice(0, -1)
989
- } else if (field.name === key) {
990
- if (data[key] instanceof Object) {
991
- const objectData = data[key]
992
- field.value = `${objectData.name} ${objectData.description ? `(${objectData.description})` : ''}`
993
- } else {
994
- field.value = data[key]
1103
+ if (this._enableProductScanning) {
1104
+ if (!this.productBarcodeInput?.value) {
1105
+ this._focusOnProductBarcodeInput()
1106
+ throw new Error(i18next.t('text.empty_product_barcode'))
995
1107
  }
996
1108
  }
997
- })
1109
+ }
998
1110
  }
999
- }
1000
1111
 
1001
- async picking(e) {
1002
- if (e.keyCode !== 13) return
1003
- e.preventDefault()
1004
- try {
1005
- let answer = await this.validatePicking()
1112
+ if (!this._isReplacement) {
1113
+ if (!this._isRequireSerialNumberScanningOutbound) {
1114
+ if (this.releaseQtyInput) {
1115
+ if (!parseInt(this.releaseQtyInput?.value)) {
1116
+ this._focusOnReleaseQtyInput()
1117
+ throw new Error(i18next.t('text.release_qty_is_empty'))
1118
+ }
1006
1119
 
1007
- if (answer) {
1008
- if (!answer?.value) return
1009
- }
1120
+ if (!this.releaseQtyInput?.checkValidity()) throw new Error(i18next.t('text.release_qty_invalid'))
1010
1121
 
1011
- let response = {}
1012
- if (this.crossDocking) {
1013
- response = await this.pickCrossDocking()
1014
- } else if (this._enableProductScanning || this._isCartonLabel) {
1015
- response = await this.productBarcodePicking()
1016
- } else {
1017
- if (this._isReplacement && !this._isCartonLabel) {
1018
- this.openPalletReplacementPopup()
1019
- return
1020
- } else {
1021
- response = await this.pickCommonPicking()
1122
+ // typed qty should be matched with release qty.
1123
+ if (
1124
+ parseInt(this.releaseQtyInput.value) !==
1125
+ this._selectedOrderInventory.releaseQty -
1126
+ (this._selectedOrderInventory.pickedQty ? this._selectedOrderInventory.pickedQty : 0) &&
1127
+ !this._isCartonLabel
1128
+ ) {
1129
+ this._focusOnReleaseQtyInput()
1130
+ throw new Error(i18next.t('text.wrong_release_qty'))
1131
+ }
1022
1132
  }
1023
1133
  }
1024
1134
 
1025
- if (!response.errors) {
1026
- if (this._hasBinPicking) {
1027
- this._currentBinLocation = this.binLocationInput.value
1028
- }
1029
- if (this._isRequireSerialNumberScanningOutbound) this.serialInput.value = ''
1030
- else if (this._enableProductScanning) this.productBarcodeInput.value = ''
1031
- else this.releaseQtyInput.value = ''
1135
+ if (!this._isCartonLabel) {
1136
+ // location id existing
1137
+ if (!this.isWholePicking && this.locationInput) {
1138
+ if (!this.locationInput.value) {
1139
+ this._focusOnLocationNameInput()
1140
+ throw new Error(i18next.t('text.location_id_is_empty'))
1141
+ }
1142
+ // check if actual return location
1143
+ this._locationName =
1144
+ this.isWholePicking || !this.locationInput
1145
+ ? this._selectedOrderInventory.location.name
1146
+ : this.locationInput.value
1147
+ // 1. Check whether location is changed
1148
+ if (this._selectedOrderInventory.location.name !== this._locationName) {
1149
+ this.locationNameSplit = this.locationInput.value.split('-')
1150
+ if (this.locationNameSplit.length < 3) {
1151
+ this._focusOnLocationNameInput()
1152
+ throw new Error(i18next.t('text.invalid_return_location'))
1153
+ }
1154
+ const zonePortions = this.locationNameSplit[0].match(/[a-zA-Z0-9]+/g)
1155
+ const rowPortions = this.locationNameSplit[1].match(/[a-zA-Z0-9]+/g)
1156
+ const columnPortions = this.locationNameSplit[2].match(/[a-zA-Z0-9]+/g)
1157
+ const shelfPortions = this.locationNameSplit[3].match(/[a-zA-Z0-9]+/g)
1158
+ if (this.locationNameSplit.length === 3) {
1159
+ this.locations = await this.fetchLocations(zonePortions[0], rowPortions[0], columnPortions[0])
1160
+ this._focusOnNewLocationInput()
1032
1161
 
1033
- if (!this._isCartonLabel && !this._isRequireSerialNumberScanningOutbound) {
1034
- this.palletInput.value = ''
1035
- }
1162
+ const selectedLocations = this.locations.find(res => {
1163
+ return res.name === this._locationName
1164
+ })
1036
1165
 
1037
- if (!this.isWholePicking && !this._crossDocking && !this._isCartonLabel && this.locationInput)
1038
- this.locationInput.value = ''
1039
- if (this.refPickingType === PICKING_TYPES.PICKING.value) {
1040
- await this.fetchInventories(this.releaseGoodNo)
1041
- } else {
1042
- await this.fetchInventories(this.taskNo)
1043
- }
1166
+ if (this._isReleaseGoodRecall) {
1167
+ if (![selectedLocations.type].includes(LOCATION_TYPE.QUARANTINE.value, LOCATION_TYPE.RESERVE.value)) {
1168
+ throw new Error(i18next.t('text.location_scanned_is_not_a_quarantine_zone_or_reserved_zone'))
1169
+ }
1170
+ }
1044
1171
 
1045
- if (
1046
- this._selectedOrderInventory &&
1047
- this._selectedOrderInventory.pickedQty == this._selectedOrderInventory.releaseQty
1048
- ) {
1049
- this._selectedOrderInventory = null
1050
- if (this.refPickingType === PICKING_TYPES.PICKING.value) {
1051
- await this.fetchInventories(this.releaseGoodNo)
1052
- } else {
1053
- await this.fetchInventories(this.taskNo)
1054
- }
1055
- }
1056
- } else {
1057
- this._selectedOrderInventory = null
1058
- if (this.refPickingType === PICKING_TYPES.PICKING.value) {
1059
- await this.fetchInventories(this.releaseGoodNo)
1060
- } else {
1061
- await this.fetchInventories(this.taskNo)
1062
- }
1063
- }
1172
+ if (this.locations.length > 0) {
1173
+ this._incompleteLocationName = true
1174
+ throw new Error(i18next.t('text.please_select_the_location_again'))
1175
+ } else {
1176
+ throw new Error(i18next.t('text.invalid_return_location'))
1177
+ }
1178
+ } else if (this.locationNameSplit.length === 4) {
1179
+ this.locations = await this.fetchLocations(
1180
+ zonePortions[0],
1181
+ rowPortions[0],
1182
+ columnPortions[0],
1183
+ shelfPortions[0]
1184
+ )
1185
+
1186
+ const selectedLocations = this.locations.find(res => {
1187
+ return res.name === this._locationName
1188
+ })
1064
1189
 
1065
- this.focusOnInput()
1190
+ if (this._isReleaseGoodRecall) {
1191
+ if (![selectedLocations.type].includes(LOCATION_TYPE.QUARANTINE.value, LOCATION_TYPE.RESERVE.value)) {
1192
+ throw new Error(i18next.t('text.location_scanned_is_not_a_quarantine_zone_or_reserved_zone'))
1193
+ }
1194
+ }
1066
1195
 
1067
- this.isReplacement = false
1068
- } catch (e) {
1069
- this._showToast(e)
1070
- }
1071
- }
1196
+ let relocateConfirmation = await CustomAlert({
1197
+ title: i18next.t('title.relocate'),
1198
+ text: i18next.t('text.are_you_sure'),
1199
+ confirmButton: { text: i18next.t('button.relocate') },
1200
+ cancelButton: { text: i18next.t('button.cancel') }
1201
+ })
1072
1202
 
1073
- openPalletReplacementPopup() {
1074
- openPopup(
1075
- html`
1076
- <picking-replacement-popup
1077
- .orderInventory="${this._selectedOrderInventory}"
1078
- .refPickingType="${this.refPickingType}"
1079
- .replacePalletId="${this.palletInput.value}"
1080
- @completed="${() => {
1081
- this._selectedOrderInventory = null
1082
- let a = this._selectedOrderInventory
1083
- if (this.refPickingType === PICKING_TYPES.PICKING.value) {
1084
- this.fetchInventories(this.releaseGoodNoInput.value)
1085
- this.fetchPalletsHandler(this.releaseGoodNoInput.value)
1086
- } else {
1087
- this.fetchInventories(this.taskNoInput.value)
1088
- this.fetchPalletsHandler(this.taskNoInput.value)
1203
+ if (!relocateConfirmation.isConfirmed) {
1204
+ this._incompleteLocationName = false
1205
+ this.locationNameSplit = []
1206
+ return relocateConfirmation
1207
+ }
1089
1208
  }
1090
- // this._selectedTaskStatus = null
1091
- this._isReplacement = false
1092
- this._isExecuting = false
1093
- }}"
1094
- ></picking-replacement-popup>
1095
- `,
1096
- {
1097
- backdrop: true,
1098
- size: 'large',
1099
- title: i18next.t('title.pallet_replacement')
1209
+ }
1210
+ }
1100
1211
  }
1101
- )
1102
- }
1212
+ }
1103
1213
 
1104
- async openSerialNumberPopup() {
1105
- await sleep(1010)
1106
- openPopup(
1107
- html`
1108
- <serial-number-popup
1109
- .orderInventory="${this?._selectedOrderInventory?.relatedOrderInv}"
1110
- .orderType="${i18next.t('text.outbound')}"
1111
- .orderSource="${ORDER_SOURCES.PICKING.value}"
1112
- .orderId="${this.releaseGoodId}"
1113
- .data="${this?._selectedOrderInventory}"
1114
- @close-serial-number-popup="${async e => {
1115
- await this.fetchAll(this.releaseGoodNo)
1116
- }}"
1117
- ></serial-number-popup>
1118
- `,
1119
- {
1120
- closable: false,
1121
- backdrop: false,
1122
- escapable: false,
1123
- size: 'large',
1124
- title: i18next.t('title.serial_number_list')
1214
+ if (this._crossDocking) {
1215
+ // typed qty should be smaller than release qty.
1216
+ if (parseInt(this.releaseQtyInput.value) > this._selectedOrderInventory.releaseQty) {
1217
+ this._focusOnReleaseQtyInput()
1218
+ throw new Error(i18next.t('text.wrong_release_qty'))
1125
1219
  }
1126
- )
1220
+ }
1127
1221
  }
1128
1222
 
1129
- async openTotePopup() {
1130
- await sleep(1010)
1131
- openPopup(
1132
- html`
1133
- <tote-popup
1134
- .orderNo="${this.releaseGoodNo}"
1135
- .toteNo="${this.toteNo}"
1136
- .bizplace="${this._bizplaceName}"
1137
- @completed="${async e => {
1138
- this.toteNo = e.detail
1139
- }}"
1140
- ></tote-popup>
1223
+ async checkProgressingPallet(palletId) {
1224
+ const response = await client.query({
1225
+ query: gql`
1226
+ query checkProgressingPallet($palletId: String!) {
1227
+ checkProgressingPallet(palletId: $palletId)
1228
+ }
1141
1229
  `,
1142
- {
1143
- closable: false,
1144
- backdrop: false,
1145
- escapable: false,
1146
- size: 'large',
1147
- title: i18next.t('title.tote_scanning')
1148
- }
1149
- )
1230
+ variables: { palletId }
1231
+ })
1232
+
1233
+ if (!response.errors) {
1234
+ return response.data.checkProgressingPallet
1235
+ }
1150
1236
  }
1151
1237
 
1152
- _openWorksheetInformation() {
1153
- openPopup(
1154
- html`
1155
- <worksheet-information-popup .worksheetInformation="${this._worksheetInfo}"></worksheet-information-popup>
1238
+ async checkProductIdenticality(palletA, palletB) {
1239
+ const response = await client.query({
1240
+ query: gql`
1241
+ query checkProductIdenticality($palletA: String!, $palletB: String!) {
1242
+ checkProductIdenticality(palletA: $palletA, palletB: $palletB)
1243
+ }
1156
1244
  `,
1157
- {
1158
- backdrop: true,
1159
- size: 'large',
1160
- title: i18next.t('title.order_information')
1161
- }
1162
- )
1245
+ variables: { palletA, palletB }
1246
+ })
1247
+
1248
+ if (!response.errors) {
1249
+ return response.data.checkProductIdenticality
1250
+ }
1163
1251
  }
1164
1252
 
1165
- async pick_crossDocking() {
1166
- return await client.mutate({
1167
- mutation: gql`
1168
- mutation crossDockPicking(
1169
- $worksheetDetailName: String!
1170
- $worksheetType: String!
1171
- $palletId: String!
1172
- $releaseQty: Int!
1173
- ) {
1174
- crossDockPicking(
1175
- worksheetDetailName: $worksheetDetailName
1176
- worksheetType: $worksheetType
1177
- palletId: $palletId
1178
- releaseQty: $releaseQty
1179
- )
1253
+ async checkCartonIdenticality(cartonA, palletA, cartonB) {
1254
+ const response = await client.query({
1255
+ query: gql`
1256
+ query checkCartonIdenticality($cartonA: String!, $palletA: String!, $cartonB: String!) {
1257
+ checkCartonIdenticality(cartonA: $cartonA, palletA: $palletA, cartonB: $cartonB)
1180
1258
  }
1181
1259
  `,
1182
- variables: {
1183
- worksheetDetailName: this._selectedOrderInventory.name,
1184
- worksheetType: this.refPickingType,
1185
- palletId: this.palletInput.value,
1186
- releaseQty: parseInt(this.releaseQtyInput.value)
1187
- }
1260
+ variables: { cartonA, palletA, cartonB }
1188
1261
  })
1262
+
1263
+ if (!response.errors) {
1264
+ return response.data.checkCartonIdenticality
1265
+ }
1266
+ }
1267
+
1268
+ async fetchLocations(zone, row, column) {
1269
+ const sortings = [{ name: 'name', desc: false }]
1270
+ const filters = [
1271
+ { name: 'zone', operator: 'eq', value: zone },
1272
+ { name: 'row', operator: 'eq', value: row },
1273
+ { name: 'column', operator: 'eq', value: column }
1274
+ ]
1275
+
1276
+ if (filters) {
1277
+ const response = await client.query({
1278
+ query: gql`
1279
+ query locations($filters: [Filter!], $sortings: [Sorting!]) {
1280
+ locations(filters: $filters, sortings: $sortings) {
1281
+ items {
1282
+ id
1283
+ name
1284
+ zone
1285
+ row
1286
+ column
1287
+ shelf
1288
+ status
1289
+ type
1290
+ }
1291
+ }
1292
+ }
1293
+ `,
1294
+ variables: { filters, sortings }
1295
+ })
1296
+
1297
+ if (!response.errors) {
1298
+ return response.data.locations.items || []
1299
+ }
1300
+ }
1301
+ }
1302
+
1303
+ autoFetchPickingTasks(orderNo) {
1304
+ this.releaseGoodNoInput.value = orderNo
1305
+ this.fetchAll(this.releaseGoodNoInput.value)
1189
1306
  }
1190
1307
 
1191
- async pickCommonPicking() {
1192
- if (this._isExecuting) throw new Error(i18next.t('text.previous_picking_is_still_executing_please_wait'))
1193
- this._isExecuting = true
1308
+ async fetchInventories(pickingRefNo) {
1309
+ if (!pickingRefNo) return
1310
+
1311
+ //this.releaseGoodNo will be incorrect if worksheet list is used, therefore it's assigned here
1312
+ //this._selectedOrderInventory still has the value of previous order, therefore it's cleared here
1313
+ if (this.releaseGoodNo !== pickingRefNo) {
1314
+ this.releaseGoodNo = pickingRefNo
1315
+ this._selectedOrderInventory = null
1316
+ }
1317
+
1318
+ const data = this._selectedOrderInventory
1319
+ let response
1320
+ switch (this.refPickingType) {
1321
+ case PICKING_TYPES.PICKING.value:
1322
+ response = await client.query({
1323
+ query: gql`
1324
+ query pickingWorksheet($releaseGoodNo: String!, $locationSortingRules: [Sorting!]) {
1325
+ pickingWorksheet(releaseGoodNo: $releaseGoodNo, locationSortingRules: $locationSortingRules) {
1326
+ worksheetInfo {
1327
+ releaseGood {
1328
+ id
1329
+ name
1330
+ recall
1331
+ crossDocking
1332
+ type
1333
+ }
1334
+ bizplaceName
1335
+ partnerDomainId
1336
+ refNo
1337
+ refNo2
1338
+ refNo3
1339
+ startedAt
1340
+ containerNo
1341
+ marketplaceStatus
1342
+ shippingProvider
1343
+ trackingNo
1344
+ }
1345
+ worksheetDetailInfos {
1346
+ hasMissingInventoryChanges
1347
+ name
1348
+ palletId
1349
+ cartonId
1350
+ batchId
1351
+ batchIdRef
1352
+ product {
1353
+ id
1354
+ sku
1355
+ name
1356
+ description
1357
+ isRequireSerialNumberScanningOutbound
1358
+ }
1359
+ qty
1360
+ releaseQty
1361
+ pickedQty
1362
+ expirationDate
1363
+ status
1364
+ description
1365
+ targetName
1366
+ packingType
1367
+ packingSize
1368
+ location {
1369
+ name
1370
+ description
1371
+ }
1372
+ binLocation {
1373
+ name
1374
+ description
1375
+ }
1376
+ relatedOrderInv {
1377
+ id
1378
+ batchId
1379
+ batchIdRef
1380
+ packingType
1381
+ binLocation {
1382
+ id
1383
+ name
1384
+ }
1385
+ product {
1386
+ id
1387
+ sku
1388
+ name
1389
+ description
1390
+ isRequireSerialNumberScanningOutbound
1391
+ }
1392
+ }
1393
+ }
1394
+ }
1395
+ }
1396
+ `,
1397
+ variables: { releaseGoodNo: pickingRefNo, locationSortingRules: this.locationSortingRules }
1398
+ })
1399
+
1400
+ if (!response.errors) {
1401
+ this._isReleaseGoodRecall = response.data.pickingWorksheet.worksheetInfo.releaseGood.recall
1402
+ let releaseGood = response.data.pickingWorksheet.worksheetInfo.releaseGood
1403
+ this.releaseGoodId = releaseGood.id
1404
+ this._releaseGoodType = releaseGood.type
1405
+
1406
+ if (!response.data?.pickingWorksheet) return
1407
+ const { worksheetInfo, worksheetDetailInfos } = response.data.pickingWorksheet
1408
+ this._crossDocking = worksheetInfo.releaseGood?._crossDocking
1409
+ this._bizplaceName = worksheetInfo.bizplaceName
1410
+ this._orderNo = this.releaseGoodNo
1411
+ this._worksheetInfo = worksheetInfo
1412
+ let data = { records: this.formatWorksheetDetailInfos(worksheetDetailInfos) }
1413
+ this.data = { ...data }
1194
1414
 
1195
- try {
1196
- switch (this.refPickingType) {
1197
- case PICKING_TYPES.PICKING.value:
1198
- return await client.mutate({
1199
- mutation: gql`
1200
- mutation picking(
1201
- $worksheetDetailName: String!
1202
- $worksheetType: String!
1203
- $palletId: String
1204
- $locationName: String!
1205
- $releaseQty: Int!
1206
- $binLocation: String
1207
- $serialNumber: String
1208
- $toteNo: String
1209
- ) {
1210
- picking(
1211
- worksheetDetailName: $worksheetDetailName
1212
- worksheetType: $worksheetType
1213
- palletId: $palletId
1214
- locationName: $locationName
1215
- releaseQty: $releaseQty
1216
- binLocation: $binLocation
1217
- serialNumber: $serialNumber
1218
- toteNo: $toteNo
1219
- )
1415
+ if (!this._selectedOrderInventory) {
1416
+ this._selectedOrderInventory = data.records[0]
1417
+ } else {
1418
+ let currentData = data.records.find(record => record.name === this._selectedOrderInventory.name)
1419
+
1420
+ if (currentData.completed) {
1421
+ if (this.cartonInput) this.cartonInput.value = ''
1422
+ if (this.palletInput) this.palletInput.value = ''
1423
+ let nextData = data.records.filter(rec => !rec.completed)
1424
+ if (nextData.length > 0) {
1425
+ this._selectedOrderInventory = nextData[0]
1426
+ } else {
1427
+ this._selectedOrderInventory = null
1220
1428
  }
1221
- `,
1222
- variables: {
1223
- worksheetDetailName: this._selectedOrderInventory.name,
1224
- worksheetType: this.refPickingType,
1225
- palletId: this.palletInput.value.trim(),
1226
- locationName: this._locationName ? this._locationName : this._selectedOrderInventory?.location.name,
1227
- releaseQty: this._isRequireSerialNumberScanningOutbound ? 1 : parseInt(this.releaseQtyInput.value),
1228
- binLocation: this._hasBinPicking ? this.binLocationInput.value : null,
1229
- serialNumber: this._isRequireSerialNumberScanningOutbound ? this.serialInput.value : null,
1230
- toteNo: this._enableToteScanning && this.toteNo !== '' ? this.toteNo : null
1231
1429
  }
1232
- })
1430
+ }
1233
1431
 
1234
- case PICKING_TYPES.BATCH_PICKING.value:
1235
- return await client.mutate({
1236
- mutation: gql`
1237
- mutation batchPicking(
1238
- $taskNo: String!
1239
- $worksheetType: String!
1240
- $palletId: String!
1241
- $locationName: String
1242
- $binLocationName: String
1243
- $releaseQty: Int!
1432
+ if (this._selectedOrderInventory) {
1433
+ const record = data.records.find(record => record.name === this._selectedOrderInventory.name)
1434
+ this._selectedOrderInventory = record
1435
+ this.updateSelectedItemProp(record)
1436
+ await this.updateComplete
1437
+ await this.grist.reset()
1438
+ this.fillUpForm(this.inputForm, {
1439
+ ...record,
1440
+ binLocation: record?.binLocation ? record.binLocation : ''
1441
+ })
1442
+
1443
+ if (record.pickedQty == record.releaseQty) {
1444
+ if (this.cartonInput) this.cartonInput.value = ''
1445
+ if (this.palletInput) this.palletInput.value = ''
1446
+ } else {
1447
+ // pre-set bin location from last scan if none was set
1448
+ if (
1449
+ this._hasBinPicking &&
1450
+ this.binLocationInput &&
1451
+ (!this._currentBinLocation || this._currentBinLocation == '')
1244
1452
  ) {
1245
- batchPicking(
1246
- taskNo: $taskNo
1247
- worksheetType: $worksheetType
1248
- palletId: $palletId
1249
- locationName: $locationName
1250
- binLocationName: $binLocationName
1251
- releaseQty: $releaseQty
1252
- )
1453
+ this._currentBinLocation = record?.binLocation ? record.binLocation : ''
1253
1454
  }
1254
- `,
1255
- variables: {
1256
- taskNo: this.taskNo,
1257
- worksheetType: this.refPickingType,
1258
- palletId: this.palletInput.value.trim(),
1259
- locationName: this._locationName ? this._locationName : this._selectedOrderInventory?.location.name,
1260
- binLocationName: this._hasBinPicking ? this.binLocationInput.value : null,
1261
- releaseQty: parseInt(this.releaseQtyInput.value)
1262
1455
  }
1263
- })
1264
- }
1265
- } catch (e) {
1266
- this._showToast(e)
1267
- } finally {
1268
- this._selectedOrderInventory = null
1269
- this._isExecuting = false
1270
- }
1271
- }
1272
1456
 
1273
- async productBarcodePicking() {
1274
- if (this._isExecuting) throw new Error(i18next.t('text.previous_picking_is_still_executing_please_wait'))
1275
- this._isExecuting = true
1457
+ if (
1458
+ record.releaseQty - record.pickedQty == 1 &&
1459
+ !this._isCartonLabel &&
1460
+ this._isRequireSerialNumberScanningOutbound
1461
+ ) {
1462
+ this._isLastUnit = true
1463
+ } else {
1464
+ this._isLastUnit = false
1465
+ }
1466
+ }
1276
1467
 
1277
- try {
1278
- switch (this.refPickingType) {
1279
- case PICKING_TYPES.PICKING.value:
1280
- return await client.mutate({
1281
- mutation: gql`
1282
- mutation scanProductPicking(
1283
- $worksheetDetailName: String!
1284
- $worksheetType: String!
1285
- $productBarcode: String!
1286
- $cartonId: String!
1287
- $binLocation: String
1288
- $serialNumber: String
1289
- $toteNo: String
1290
- ) {
1291
- scanProductPicking(
1292
- worksheetDetailName: $worksheetDetailName
1293
- worksheetType: $worksheetType
1294
- productBarcode: $productBarcode
1295
- cartonId: $cartonId
1296
- binLocation: $binLocation
1297
- serialNumber: $serialNumber
1298
- toteNo: $toteNo
1299
- )
1468
+ if (
1469
+ this._selectedOrderInventory &&
1470
+ this._selectedOrderInventory.pickedQty != this._selectedOrderInventory.releaseQty &&
1471
+ !this._selectedOrderInventory?.hasMissingInventoryChanges &&
1472
+ this._selectedOrderInventory.status !== 'MISSING'
1473
+ ) {
1474
+ this.scannable = true
1475
+ } else {
1476
+ this.scannable = false
1477
+ }
1478
+
1479
+ if (data) {
1480
+ if (!this._isCartonLabel) {
1481
+ const findPalletId = worksheetDetailInfos.find(res => res.palletId == data.palletId)
1482
+
1483
+ if (data && findPalletId?.hasMissingInventoryChanges) {
1484
+ this.scannable = false
1300
1485
  }
1301
- `,
1302
- variables: {
1303
- worksheetDetailName: this._selectedOrderInventory.name,
1304
- worksheetType: this.refPickingType,
1305
- productBarcode: this.productBarcodeInput.value.trim(),
1306
- cartonId: this.cartonInput.value.trim(),
1307
- serialNumber: this._isRequireSerialNumberScanningOutbound ? this.serialInput.value : null,
1308
- binLocation: this._hasBinPicking ? this.binLocationInput.value : null,
1309
- toteNo: this._enableToteScanning && this.toteNo !== '' ? this.toteNo : null
1310
- }
1311
- })
1486
+ } else {
1487
+ const findCartonId = worksheetDetailInfos.find(res => res.cartonId == data.cartonId)
1312
1488
 
1313
- case PICKING_TYPES.BATCH_PICKING.value:
1314
- return await client.mutate({
1315
- mutation: gql`
1316
- mutation scanProductBatchPicking(
1317
- $taskNo: String!
1318
- $worksheetType: String!
1319
- $cartonId: String!
1320
- $inventory: InventoryPatch!
1321
- $productBarcode: String!
1322
- $binLocationName: String
1323
- ) {
1324
- scanProductBatchPicking(
1325
- taskNo: $taskNo
1326
- worksheetType: $worksheetType
1327
- cartonId: $cartonId
1328
- inventory: $inventory
1329
- productBarcode: $productBarcode
1330
- binLocationName: $binLocationName
1331
- )
1489
+ if (data && findCartonId?.hasMissingInventoryChanges) {
1490
+ this.scannable = false
1332
1491
  }
1333
- `,
1334
- variables: {
1335
- taskNo: this.taskNo,
1336
- worksheetType: this.refPickingType,
1337
- cartonId: this.cartonInput.value.trim(),
1338
- productBarcode: this.productBarcodeInput.value.trim(),
1339
- inventory: {
1340
- batchId: this._selectedOrderInventory.batchId,
1341
- packingType: this._selectedOrderInventory.packingType,
1342
- packingSize: this._selectedOrderInventory.packingSize,
1343
- product: { id: this._selectedOrderInventory.product.id }
1344
- },
1345
- binLocationName: this._hasBinPicking ? this.binLocationInput.value : null
1346
1492
  }
1347
- })
1348
- }
1349
- } catch (e) {
1350
- this._showToast(e)
1351
- } finally {
1352
- this._isExecuting = false
1353
- }
1354
- }
1493
+ }
1494
+ }
1495
+ break
1355
1496
 
1356
- async validatePicking() {
1357
- // validate for order selection
1358
- // pallet id existing
1359
- if (!this._isCartonLabel) {
1360
- if (!this.palletInput.value) {
1361
- this._focusOnLotNoInput()
1362
- throw new Error(i18next.t('text.lot_id_is_empty'))
1363
- } else {
1364
- if (
1365
- this._selectedOrderInventory.palletId !== this.palletInput.value &&
1366
- !this._isRequireSerialNumberScanningOutbound
1367
- ) {
1368
- const isInProgressing = await this.checkProgressingPallet(this.palletInput.value)
1369
- if (isInProgressing) throw new Error(i18next.t('text.pallet_is_in_progressing'))
1497
+ case PICKING_TYPES.BATCH_PICKING.value:
1498
+ response = await client.query({
1499
+ query: gql`
1500
+ query batchPickingWorksheet($taskNo: String!, $locationSortingRules: [Sorting!]) {
1501
+ batchPickingWorksheet(taskNo: $taskNo, locationSortingRules: $locationSortingRules) {
1502
+ worksheetInfo {
1503
+ bizplaceName
1504
+ partnerDomainId
1505
+ startedAt
1506
+ }
1507
+ worksheetDetailInfos {
1508
+ hasMissingInventoryChanges
1509
+ palletId
1510
+ cartonId
1511
+ batchId
1512
+ product {
1513
+ id
1514
+ name
1515
+ description
1516
+ sku
1517
+ isRequireSerialNumberScanning
1518
+ }
1519
+ qty
1520
+ releaseQty
1521
+ pickedQty
1522
+ expirationDate
1523
+ status
1524
+ packingType
1525
+ packingSize
1526
+ location {
1527
+ name
1528
+ }
1529
+ binLocation {
1530
+ name
1531
+ }
1532
+ relatedOrderInv {
1533
+ batchId
1534
+ packingType
1535
+ product {
1536
+ id
1537
+ name
1538
+ description
1539
+ sku
1540
+ }
1541
+ }
1542
+ }
1543
+ }
1544
+ }
1545
+ `,
1546
+ variables: { taskNo: pickingRefNo, locationSortingRules: this.locationSortingRules }
1547
+ })
1370
1548
 
1371
- this._isReplacement = await this.checkProductIdenticality(
1372
- this._selectedOrderInventory.palletId,
1373
- this.palletInput.value
1374
- )
1549
+ if (!response.errors) {
1550
+ if (!this._selectedOrderInventory) this.clearView()
1551
+ this.taskNo = pickingRefNo
1552
+ if (!response.data?.batchPickingWorksheet) return
1375
1553
 
1376
- if (!this._isReplacement) {
1377
- this._focusOnLotNoInput()
1378
- throw new Error(i18next.t('text.wrong_lot_id'))
1379
- }
1380
- }
1381
- }
1554
+ const { worksheetInfo, worksheetDetailInfos } = response.data.batchPickingWorksheet
1555
+ await this.updateComplete
1556
+ this._bizplaceName = worksheetInfo.bizplaceName
1557
+ this._orderNo = this.taskNo
1558
+ this._worksheetInfo = worksheetInfo
1559
+ this.data = { records: this.formatWorksheetDetailInfos(worksheetDetailInfos) }
1382
1560
 
1383
- // Release qty existing
1384
- if (!this._isReplacement) {
1385
- if (!this._isRequireSerialNumberScanningOutbound) {
1386
- if (!parseInt(this.releaseQtyInput?.value)) {
1387
- this._focusOnReleaseQtyInput()
1388
- throw new Error(i18next.t('text.release_qty_is_empty'))
1561
+ if (!this._selectedOrderInventory) {
1562
+ this._selectedOrderInventory = this.data.records[0]
1389
1563
  }
1390
1564
 
1391
- if (!this.releaseQtyInput.checkValidity()) throw new Error(i18next.t('text.release_qty_invalid'))
1392
-
1393
- // typed qty should be matched with release qty.
1394
-
1395
1565
  if (
1396
- parseInt(this.releaseQtyInput.value) !==
1397
- this._selectedOrderInventory.releaseQty -
1398
- (this._selectedOrderInventory.pickedQty ? this._selectedOrderInventory.pickedQty : 0)
1566
+ this._selectedOrderInventory &&
1567
+ this._selectedOrderInventory.pickedQty != this._selectedOrderInventory.releaseQty &&
1568
+ !this._selectedOrderInventory?.hasMissingInventoryChanges &&
1569
+ this._selectedOrderInventory.status !== 'MISSING'
1399
1570
  ) {
1400
- this._focusOnReleaseQtyInput()
1401
- throw new Error(i18next.t('text.wrong_release_qty'))
1571
+ this.scannable = true
1572
+ } else {
1573
+ this.scannable = false
1402
1574
  }
1403
- }
1404
1575
 
1405
- // location id existing
1406
- if (!this.isWholePicking && this.locationInput) {
1407
- if (!this.locationInput.value) {
1408
- this._focusOnLocationNameInput()
1409
- throw new Error(i18next.t('text.location_id_is_empty'))
1410
- }
1411
- // check if actual return location
1412
- this._locationName =
1413
- this.isWholePicking || !this.locationInput
1414
- ? this._selectedOrderInventory.location.name
1415
- : this.locationInput.value
1416
- // 1. Check whether location is changed
1417
- if (this._selectedOrderInventory.location.name !== this._locationName) {
1418
- this.locationNameSplit = this.locationInput.value.split('-')
1419
- if (this.locationNameSplit.length < 3) {
1420
- this._focusOnLocationNameInput()
1421
- throw new Error(i18next.t('text.invalid_return_location'))
1422
- }
1423
- const zonePortions = this.locationNameSplit[0].match(/[a-zA-Z0-9]+/g)
1424
- const rowPortions = this.locationNameSplit[1].match(/[a-zA-Z0-9]+/g)
1425
- const columnPortions = this.locationNameSplit[2].match(/[a-zA-Z0-9]+/g)
1426
- if (this.locationNameSplit.length === 3) {
1427
- this.locations = await this.fetchLocations(zonePortions[0], rowPortions[0], columnPortions[0])
1428
- this._focusOnNewLocationInput()
1429
- if (this.locations.length > 0) {
1430
- this._incompleteLocationName = true
1431
- throw new Error(i18next.t('text.please_select_the_location_again'))
1432
- } else {
1433
- throw new Error(i18next.t('text.invalid_return_location'))
1434
- }
1435
- } else if (this.locationNameSplit.length === 4) {
1436
- let relocateConfirmation = await CustomAlert({
1437
- title: i18next.t('title.relocate'),
1438
- text: i18next.t('text.are_you_sure'),
1439
- confirmButton: { text: i18next.t('button.relocate') },
1440
- cancelButton: { text: i18next.t('button.cancel') }
1441
- })
1576
+ if (!this._isCartonLabel && data) {
1577
+ const findPalletId = worksheetDetailInfos.find(res => res.palletId == data.palletId)
1442
1578
 
1443
- if (!relocateConfirmation.isConfirmed) {
1444
- this._incompleteLocationName = false
1445
- this.locationNameSplit = []
1446
- return relocateConfirmation
1447
- }
1579
+ if (data && findPalletId?.hasMissingInventoryChanges) {
1580
+ this.scannable = false
1448
1581
  }
1449
1582
  }
1450
- }
1451
- }
1452
- } else {
1453
- if (!this.cartonInput?.value) {
1454
- this._focusOnCartonNoInput()
1455
- throw new Error(i18next.t('text.carton_id_is_empty'))
1456
- }
1457
1583
 
1458
- if (this._selectedOrderInventory.cartonId) {
1459
- if (this._selectedOrderInventory.cartonId !== this.cartonInput.value) {
1460
- //carton replacement?
1461
- throw new Error(i18next.t('text.invalid_carton_id'))
1462
- this._isReplacement = await this.checkCartonIdenticality(
1463
- this._selectedOrderInventory.cartonId,
1464
- this._selectedOrderInventory.palletId,
1465
- this.cartonInput.value
1466
- )
1467
-
1468
- if (!this._isReplacement) {
1469
- this.cartonInput.value = ''
1470
- this._focusOnCartonNoInput()
1471
- throw new Error(i18next.t('text.wrong_carton_id'))
1472
- }
1473
- }
1584
+ if (this._isCartonLabel && data) {
1585
+ const findCartonId = worksheetDetailInfos.find(res => res.cartonId == data.cartonId)
1474
1586
 
1475
- if (this._enableProductScanning) {
1476
- if (!this.productBarcodeInput?.value) {
1477
- this._focusOnProductBarcodeInput()
1478
- throw new Error(i18next.t('text.empty_product_barcode'))
1587
+ if (data && findCartonId?.hasMissingInventoryChanges) {
1588
+ this.scannable = false
1589
+ }
1479
1590
  }
1480
- }
1481
- }
1482
- }
1483
1591
 
1484
- if (this._isRequireSerialNumberScanningOutbound) {
1485
- if (!this.serialInput?.value) {
1486
- this._focusOnSerialInput()
1487
- throw new Error(i18next.t('text.empty_serial_number'))
1488
- }
1489
- }
1592
+ this._enableProductScanning = await fetchSettingRule('enable-product-scanning', worksheetInfo.partnerDomainId)
1593
+ this._enableInputQty = await fetchSettingRule('enable-input-qty', worksheetInfo.partnerDomainId)
1490
1594
 
1491
- if (this._crossDocking) {
1492
- // typed qty should be smaller than release qty.
1493
- if (parseInt(this.releaseQtyInput.value) > this._selectedOrderInventory.releaseQty) {
1494
- this._focusOnReleaseQtyInput()
1495
- throw new Error(i18next.t('text.wrong_release_qty'))
1496
- }
1497
- }
1498
- }
1595
+ if (this._selectedOrderInventory) {
1596
+ const record = this.data.records.find(
1597
+ record =>
1598
+ record.product.sku === this._selectedOrderInventory.product.sku &&
1599
+ record.palletId === this._selectedOrderInventory.palletId
1600
+ )
1499
1601
 
1500
- async checkProgressingPallet(palletId) {
1501
- const response = await client.query({
1502
- query: gql`
1503
- query checkProgressingPallet($palletId: String!) {
1504
- checkProgressingPallet(palletId: $palletId)
1505
- }
1506
- `,
1507
- variables: { palletId }
1508
- })
1602
+ this._selectedOrderInventory = record
1603
+ await this.updateSelectedItemProp(record)
1509
1604
 
1510
- if (!response.errors) {
1511
- return response.data.checkProgressingPallet
1512
- }
1513
- }
1605
+ if (record.pickedQty == record.releaseQty) {
1606
+ if (this._isCartonLabel) {
1607
+ //need to relook into clearview logic
1608
+ if (this.cartonInput) this.cartonInput.value = ''
1609
+ if (this.productBarcodeInput) this.productBarcodeInput.value = ''
1610
+ }
1611
+ this.fillUpForm(this.inputForm, record)
1612
+ } else {
1613
+ this.fillUpForm(this.inputForm, record)
1614
+ }
1514
1615
 
1515
- async checkProductIdenticality(palletA, palletB) {
1516
- const response = await client.query({
1517
- query: gql`
1518
- query checkProductIdenticality($palletA: String!, $palletB: String!) {
1519
- checkProductIdenticality(palletA: $palletA, palletB: $palletB)
1616
+ if (
1617
+ record.releaseQty - record.pickedQty == 1 &&
1618
+ !this._isCartonLabel &&
1619
+ this._isRequireSerialNumberScanningOutbound
1620
+ ) {
1621
+ this._isLastUnit = true
1622
+ } else {
1623
+ this._isLastUnit = false
1624
+ }
1625
+ }
1520
1626
  }
1521
- `,
1522
- variables: { palletA, palletB }
1523
- })
1524
-
1525
- if (!response.errors) {
1526
- return response.data.checkProductIdenticality
1627
+ break
1527
1628
  }
1629
+
1630
+ this.updateContext()
1528
1631
  }
1529
1632
 
1530
- async checkCartonIdenticality(cartonA, palletA, cartonB) {
1633
+ async fetchPalletsHandler(releaseGoodNo) {
1531
1634
  const response = await client.query({
1532
1635
  query: gql`
1533
- query checkCartonIdenticality($cartonA: String!, $palletA: String!, $cartonB: String!) {
1534
- checkCartonIdenticality(cartonA: $cartonA, palletA: $palletA, cartonB: $cartonB)
1535
- }
1536
- `,
1537
- variables: { cartonA, palletA, cartonB }
1538
- })
1539
-
1540
- if (!response.errors) {
1541
- return response.data.checkCartonIdenticality
1542
- }
1543
- }
1544
-
1545
- async fetchLocations(zone, row, column) {
1546
- const sortings = [{ name: 'name', desc: false }]
1547
- const filters = [
1548
- { name: 'zone', operator: 'eq', value: zone },
1549
- { name: 'row', operator: 'eq', value: row },
1550
- { name: 'column', operator: 'eq', value: column }
1551
- ]
1552
-
1553
- if (filters) {
1554
- const response = await client.query({
1555
- query: gql`
1556
- query locations($filters: [Filter!], $sortings: [Sorting!]) {
1557
- locations(filters: $filters, sortings: $sortings) {
1558
- items {
1636
+ query pallets($filters: [Filter!]!, $pagination: Pagination) {
1637
+ pallets(filters: $filters, pagination: $pagination) {
1638
+ items {
1639
+ id
1640
+ name
1641
+ owner {
1559
1642
  id
1560
1643
  name
1561
- zone
1562
- row
1563
- column
1564
- shelf
1565
- status
1644
+ description
1566
1645
  }
1646
+ holder {
1647
+ id
1648
+ name
1649
+ description
1650
+ }
1651
+ status
1567
1652
  }
1568
1653
  }
1569
- `,
1570
- variables: { filters, sortings }
1571
- })
1572
-
1573
- if (!response.errors) {
1574
- return response.data.locations.items || []
1654
+ }
1655
+ `,
1656
+ variables: {
1657
+ filters: [{ name: 'refOrderNo', value: releaseGoodNo, operator: 'eq' }],
1658
+ pagination: { page: 1, limit: 9999999 }
1575
1659
  }
1660
+ })
1661
+
1662
+ if (!response.errors) {
1663
+ this._reusablePalletList = { records: response.data.pallets.items }
1576
1664
  }
1577
1665
  }
1578
1666
 
@@ -1807,7 +1895,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1807
1895
  }
1808
1896
  }
1809
1897
  } catch (e) {
1810
- this._showToast(e)
1898
+ showToast(e)
1811
1899
  }
1812
1900
  }
1813
1901
 
@@ -1829,44 +1917,41 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1829
1917
  focusOnInput() {
1830
1918
  if (this.scannable) {
1831
1919
  // set bin location value if already has value else focus on bin input if bin picking setting is active
1832
- if (this._currentBinLocation) {
1920
+ if (this._currentBinLocation && this.binLocationInput) {
1833
1921
  this.binLocationInput.value = this._currentBinLocation
1834
1922
  }
1835
1923
 
1836
1924
  if (this._hasBinPicking && this.binLocationInput && this.binLocationInput.value == '') {
1837
- this._focusOnBinLocationInput()
1838
- return true
1925
+ return this._focusOnBinLocationInput()
1839
1926
  } else {
1840
1927
  if (this._isCartonLabel) {
1841
1928
  if (!this._enableProductScanning) this.cartonInput.value = ''
1842
1929
 
1843
1930
  if (this.cartonInput.value == '') {
1844
- this._focusOnCartonNoInput()
1845
- return true
1931
+ return this._focusOnCartonNoInput()
1846
1932
  }
1847
1933
  } else {
1848
1934
  if (!this._enableProductScanning && !this._isRequireSerialNumberScanningOutbound) this.palletInput.value = ''
1849
1935
 
1850
1936
  if (this.palletInput.value == '') {
1851
- this._focusOnLotNoInput()
1852
- return true
1937
+ return this._focusOnLotNoInput()
1853
1938
  }
1854
1939
  }
1855
1940
  }
1856
1941
 
1857
- if (this._enableProductScanning && !this._isRequireSerialNumberScanningOutbound) {
1942
+ if (this._enableProductScanning && this._isCartonLabel && !this._isRequireSerialNumberScanningOutbound) {
1858
1943
  this.productBarcodeInput.value = ''
1859
- this._focusOnProductBarcodeInput()
1860
- return true
1944
+ return this._focusOnProductBarcodeInput()
1861
1945
  }
1862
1946
 
1863
1947
  if (this._isRequireSerialNumberScanningOutbound) {
1864
- this.serialInput.value = ''
1865
- this._focusOnSerialInput()
1866
- return true
1948
+ if (this._isLastUnit) {
1949
+ return this._focusOnNewLocationInput()
1950
+ } else {
1951
+ this.serialInput.value = ''
1952
+ return this._focusOnSerialInput()
1953
+ }
1867
1954
  }
1868
-
1869
- return true
1870
1955
  }
1871
1956
  }
1872
1957
 
@@ -1882,17 +1967,6 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1882
1967
  this._isCartonLabel = selectedRecords.hasCartonLabel
1883
1968
  this._isRequireSerialNumberScanningOutbound = selectedRecords?.product?.isRequireSerialNumberScanningOutbound
1884
1969
  }
1885
-
1886
- _showToast({ type, message }) {
1887
- document.dispatchEvent(
1888
- new CustomEvent('notify', {
1889
- detail: {
1890
- type,
1891
- message
1892
- }
1893
- })
1894
- )
1895
- }
1896
1970
  }
1897
1971
 
1898
1972
  window.customElements.define('picking-product', PickingProduct)