@things-factory/operato-wms 3.7.6 → 3.7.10

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 (27) hide show
  1. package/client/pages/components/select-product-popup.js +5 -1
  2. package/client/pages/constants/order.js +10 -0
  3. package/client/pages/inventory-check/inspecting-product.js +9 -8
  4. package/client/pages/manifest/create-loading-manifest.js +314 -0
  5. package/client/pages/manifest/dispatcher-verification-popup.js +86 -0
  6. package/client/pages/manifest/loading-manifest-detail.js +345 -0
  7. package/client/pages/manifest/loading-manifest-list.js +305 -0
  8. package/client/pages/order/goods-received-note/received-note-list.js +138 -6
  9. package/client/pages/order/release-order/b2b/b2b-order-list.js +1 -1
  10. package/client/pages/order/release-order/b2b/b2b-order-requests.js +1 -1
  11. package/client/pages/order/release-order/b2c/b2c-order-requests.js +111 -14
  12. package/client/pages/order/reverse-kitting-order/reverse-kitting-order-detail.js +115 -50
  13. package/client/pages/order/reverse-kitting-order/reverse-kitting-order-list.js +1 -6
  14. package/client/pages/order/reverse-kitting-order/reverse-kitting-pallet-label-popup.js +239 -0
  15. package/client/pages/order/transport-order/delivery-order-list.js +47 -3
  16. package/client/pages/outbound/picking-product.js +200 -66
  17. package/client/pages/outbound/serial-number-popup.js +280 -0
  18. package/client/pages/vas/reverse-kitting/execute-reverse-kitting.js +32 -12
  19. package/client/pages/vas/reverse-kitting/popup-combination-sets.js +106 -10
  20. package/client/pages/vas/reverse-kitting/popup-reverse-kitting-template.js +130 -19
  21. package/client/route.js +12 -0
  22. package/package.json +10 -10
  23. package/things-factory.config.js +12 -0
  24. package/translations/en.json +42 -6
  25. package/translations/ko.json +35 -1
  26. package/translations/ms.json +36 -1
  27. package/translations/zh.json +35 -1
@@ -3,6 +3,7 @@ import '@things-factory/grist-ui'
3
3
  import './outbound-reusable-pallet'
4
4
  import './picking-replacement-popup'
5
5
  import './show-my-worksheet-list-popup'
6
+ import './serial-number-popup'
6
7
 
7
8
  import gql from 'graphql-tag'
8
9
  import { css, html } from 'lit-element'
@@ -34,6 +35,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
34
35
  orderNo: String,
35
36
  _productName: String,
36
37
  _productSku: String,
38
+ _isRequireSerialNumberScanning: Boolean,
37
39
  // _selectedTaskStatus: String,
38
40
  _reusablePalletList: Object,
39
41
  _hasBinPicking: Boolean,
@@ -106,7 +108,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
106
108
  padding-top: var(--grist-title-with-grid-padding);
107
109
  }
108
110
 
109
- div.reusable_pallet {
111
+ div.full_width {
110
112
  grid-column: span 12 / auto;
111
113
  display: inline-flex;
112
114
  align-items: center;
@@ -161,6 +163,10 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
161
163
  return this.shadowRoot.querySelector('barcode-scanable-input[name=taskNo]')?.shadowRoot.querySelector('input')
162
164
  }
163
165
 
166
+ get binLocationInput() {
167
+ return this.shadowRoot.querySelector('barcode-scanable-input[name=binLocation]')?.shadowRoot.querySelector('input')
168
+ }
169
+
164
170
  get palletInput() {
165
171
  return this.shadowRoot.querySelector('barcode-scanable-input[name=palletId]')?.shadowRoot.querySelector('input')
166
172
  }
@@ -179,8 +185,8 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
179
185
  ?.shadowRoot.querySelector('input')
180
186
  }
181
187
 
182
- get binLocationInput() {
183
- return this.shadowRoot.querySelector('barcode-scanable-input[name=binLocation]')?.shadowRoot.querySelector('input')
188
+ get serialInput() {
189
+ return this.shadowRoot.querySelector('barcode-scanable-input[name=serialNumber]')?.shadowRoot.querySelector('input')
184
190
  }
185
191
 
186
192
  get newLocationInput() {
@@ -216,11 +222,15 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
216
222
  }
217
223
 
218
224
  _focusOnLotNoInput() {
219
- setTimeout(() => this.palletInput.focus(), 50)
225
+ if (this.palletInput) {
226
+ setTimeout(() => this.palletInput.focus(), 50)
227
+ }
220
228
  }
221
229
 
222
230
  _focusOnCartonNoInput() {
223
- setTimeout(() => this.cartonInput.focus(), 50)
231
+ if (this.cartonInput) {
232
+ setTimeout(() => this.cartonInput.focus(), 50)
233
+ }
224
234
  }
225
235
 
226
236
  _focusOnProductBarcodeInput() {
@@ -229,8 +239,16 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
229
239
  }
230
240
  }
231
241
 
242
+ _focusOnSerialInput() {
243
+ if (this.serialInput) {
244
+ setTimeout(() => this.serialInput.focus(), 50)
245
+ }
246
+ }
247
+
232
248
  _focusOnReleaseQtyInput() {
233
- setTimeout(() => this.releaseQtyInput.focus(), 50)
249
+ if (this.releaseQtyInput) {
250
+ setTimeout(() => this.releaseQtyInput.focus(), 50)
251
+ }
234
252
  }
235
253
 
236
254
  get context() {
@@ -295,6 +313,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
295
313
  this._hasBinPicking = false
296
314
  this._isCartonLabel = false
297
315
  this._enableProductScanning = false
316
+ this._isRequireSerialNumberScanning = false
298
317
  this._incompleteLocationName = false
299
318
 
300
319
  /* A flag to indicate either PICKING process is executing */
@@ -334,7 +353,9 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
334
353
  e.preventDefault()
335
354
  this._currentBinLocation = null
336
355
  if (this.releaseGoodNoInput.value) {
337
- this.fetchAll(this.releaseGoodNoInput.value)
356
+ this.releaseGoodNo = this.releaseGoodNoInput.value
357
+ await this.fetchAll(this.releaseGoodNo)
358
+ this.completeHandler()
338
359
  }
339
360
  }
340
361
  }}"
@@ -406,11 +427,11 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
406
427
  <input name="releaseProgress" readonly />
407
428
  </fieldset>
408
429
 
409
- ${this.releaseGoodNo
430
+ ${this.releaseGoodNo || ''
410
431
  ? html`
411
432
  <fieldset>
412
433
  <legend>${i18next.t('title.reusable_pallet')}</legend>
413
- <div class="reusable_pallet" @click="${this.openPalletOutbound.bind(this)}">
434
+ <div class="full_width" @click="${this.openPalletOutbound.bind(this)}">
414
435
  <mwc-icon>apps</mwc-icon>Plastic Pallets
415
436
  </div>
416
437
  </fieldset>
@@ -426,9 +447,12 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
426
447
  <barcode-scanable-input
427
448
  name="binLocation"
428
449
  custom-input
429
- @change=${e => {
430
- this._currentBinLocation = e.detail.value
431
- }}
450
+ @keypress="${e => {
451
+ if (e.keyCode === 13) {
452
+ e.preventDefault()
453
+ this._currentBinLocation = this.binLocationInput.value
454
+ }
455
+ }}"
432
456
  ></barcode-scanable-input>
433
457
  `
434
458
  : ''}
@@ -447,10 +471,18 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
447
471
  <barcode-scanable-input name="productBarcode" custom-input></barcode-scanable-input>
448
472
  `
449
473
  : html`
450
- <label>${i18next.t('label.picked_qty')}</label>
451
- <input type="number" min="1" name="confirmedQty" />
474
+ ${this._isRequireSerialNumberScanning
475
+ ? ''
476
+ : html`
477
+ <label>${i18next.t('label.picked_qty')}</label>
478
+ <input type="number" min="1" name="confirmedQty" />
479
+ `}
452
480
  `}
453
- ${this.isWholePicking || this._crossDocking || this._isCartonLabel || this._enableProductScanning
481
+ ${this.isWholePicking ||
482
+ this._crossDocking ||
483
+ this._isCartonLabel ||
484
+ this._enableProductScanning ||
485
+ this._isRequireSerialNumberScanning
454
486
  ? ''
455
487
  : html`
456
488
  ${this._incompleteLocationName
@@ -476,9 +508,26 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
476
508
  )}
477
509
  </select>
478
510
  `}
511
+ ${this._isRequireSerialNumberScanning
512
+ ? html`
513
+ <label>${i18next.t('label.serial_number')}</label>
514
+ <barcode-scanable-input name="serialNumber" custom-input></barcode-scanable-input>
515
+ `
516
+ : ``}
479
517
  </fieldset>
480
518
  `
481
519
  : ''}
520
+ ${this._selectedOrderInventory && this._isRequireSerialNumberScanning
521
+ ? html`
522
+ <fieldset>
523
+ <fieldset>
524
+ <div class="full_width" @click="${this.openSerialNumberPopup.bind(this)}">
525
+ <mwc-icon>list</mwc-icon>${i18next.t('label.serial_number_list')}
526
+ </div>
527
+ </fieldset>
528
+ </fieldset>
529
+ `
530
+ : ``}
482
531
  </form>
483
532
  </div>
484
533
  </div>
@@ -502,6 +551,11 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
502
551
  this.config = {
503
552
  rows: {
504
553
  appendable: false,
554
+ classifier: (record, rowIndex) => {
555
+ return {
556
+ emphasized: record.completed == true
557
+ }
558
+ },
505
559
  handlers: {
506
560
  click: async (columns, data, column, record, rowIndex) => {
507
561
  try {
@@ -509,11 +563,12 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
509
563
  if (data.records.length && record) {
510
564
  this.inputForm.reset()
511
565
  this._isReplacement = false
512
- if (this._isCartonLabel) {
513
- if (this.cartonInput) this.cartonInput.value = ''
514
- } else {
515
- if (this.palletInput) this.palletInput.value = ''
516
- }
566
+
567
+ if (this.binLocationInput) this.binLocationInput.value = ''
568
+ if (this.productBarcodeInput) this.productBarcodeInput.value = ''
569
+ if (this.cartonInput) this.cartonInput.value = ''
570
+ if (this.palletInput) this.palletInput.value = ''
571
+ if (this.serialInput) this.serialInput.value = ''
517
572
 
518
573
  this._selectedOrderInventory = record
519
574
  await this.fetchInventories(this.releaseGoodNo)
@@ -524,13 +579,14 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
524
579
  updatedRecords.status = 'PICKING'
525
580
  }
526
581
 
527
- this._isCartonLabel = updatedRecords.hasCartonLabel
528
- this._productName = updatedRecords.product?.name
529
- ? `${updatedRecords.product.sku + ' - ' + updatedRecords.product.name} ${
530
- updatedRecords.product?.description ? `(${updatedRecords.product.description})` : ''
531
- }`
532
- : ''
533
- this.isWholePicking = updatedRecords.releaseQty === updatedRecords.qty
582
+ // this._isCartonLabel = updatedRecords.hasCartonLabel
583
+ // this._productName = updatedRecords.product?.name
584
+ // ? `${updatedRecords.product.sku + ' - ' + updatedRecords.product.name} ${
585
+ // updatedRecords.product?.description ? `(${updatedRecords.product.description})` : ''
586
+ // }`
587
+ // : ''
588
+ // this._isRequireSerialNumberScanning = updatedRecords?.product?.isRequireSerialNumberScanning
589
+ // this.isWholePicking = updatedRecords.releaseQty === updatedRecords.qty
534
590
  }
535
591
  } catch (ex) {
536
592
  console.log(ex)
@@ -635,6 +691,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
635
691
  sku
636
692
  name
637
693
  description
694
+ isRequireSerialNumberScanning
638
695
  }
639
696
  qty
640
697
  releaseQty
@@ -654,6 +711,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
654
711
  description
655
712
  }
656
713
  relatedOrderInv {
714
+ id
657
715
  batchId
658
716
  batchIdRef
659
717
  packingType
@@ -665,6 +723,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
665
723
  sku
666
724
  name
667
725
  description
726
+ isRequireSerialNumberScanning
668
727
  }
669
728
  }
670
729
  }
@@ -684,10 +743,10 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
684
743
  this.fillUpForm(this.infoForm, { ...worksheetInfo, _crossDocking: this._crossDocking })
685
744
  this.data = { records: this.formatWorksheetDetailInfos(worksheetDetailInfos) }
686
745
 
687
- this._enableProductScanning = await fetchSettingRule('enable-product-scanning', worksheetInfo.partnerDomainId)
688
-
689
746
  if (this._selectedOrderInventory) {
690
747
  const record = this.data.records.find(record => record.name === this._selectedOrderInventory.name)
748
+ this.updateSelectedItemProp(record)
749
+ await this.updateComplete
691
750
  this.fillUpForm(this.inputForm, {
692
751
  ...record,
693
752
  binLocation: record?.binLocation ? record.binLocation : ''
@@ -696,7 +755,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
696
755
  if (record.pickedQty == record.releaseQty) {
697
756
  if (this.cartonInput) this.cartonInput.value = ''
698
757
  if (this.palletInput) this.palletInput.value = ''
699
- this.isWholePicking = true
758
+ // this.isWholePicking = true
700
759
  } else {
701
760
  // pre-set bin location from last scan if none was set
702
761
  if (
@@ -708,10 +767,9 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
708
767
  }
709
768
  this.focusOnInput()
710
769
  }
711
-
712
- this._selectedOrderInventory = record
713
770
  }
714
- this.completeHandler()
771
+
772
+ this._enableProductScanning = await fetchSettingRule('enable-product-scanning', worksheetInfo.partnerDomainId)
715
773
  }
716
774
  break
717
775
 
@@ -734,6 +792,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
734
792
  name
735
793
  description
736
794
  sku
795
+ isRequireSerialNumberScanning
737
796
  }
738
797
  qty
739
798
  releaseQty
@@ -771,6 +830,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
771
830
  if (!response.data?.batchPickingWorksheet) return
772
831
 
773
832
  const { worksheetInfo, worksheetDetailInfos } = response.data.batchPickingWorksheet
833
+ await this.updateComplete
774
834
  this.fillUpForm(this.infoForm, { ...worksheetInfo })
775
835
  this.data = { records: this.formatWorksheetDetailInfos(worksheetDetailInfos) }
776
836
 
@@ -780,22 +840,25 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
780
840
  const record = this.data.records.find(
781
841
  record => record.product.sku === this._selectedOrderInventory.product.sku
782
842
  )
843
+
844
+ this.updateSelectedItemProp(record)
845
+
783
846
  if (record.pickedQty == record.releaseQty) {
784
847
  if (this._isCartonLabel) {
785
848
  this.cartonInput.value = ''
786
849
  this._focusOnCartonNoInput()
787
850
  }
788
- this._selectedOrderInventory = null
789
851
  this.inputForm.reset()
790
852
  } else {
791
853
  this._focusOnProductBarcodeInput()
792
854
  this.fillUpForm(this.inputForm, record)
793
855
  }
794
856
  }
795
- this.completeHandler()
796
857
  }
797
858
  break
798
859
  }
860
+
861
+ this.updateContext()
799
862
  }
800
863
 
801
864
  formatWorksheetDetailInfos(wsdInfos) {
@@ -869,6 +932,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
869
932
  this.infoForm.reset()
870
933
  this.inputForm.reset()
871
934
  this._productName = ''
935
+ this._isRequireSerialNumberScanning = false
872
936
  this.releaseGoodNo = null
873
937
  this.taskNo = null
874
938
  this._crossDocking = false
@@ -907,7 +971,6 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
907
971
  await this.validatePicking()
908
972
 
909
973
  let response = {}
910
- this._isExecuting = true
911
974
  if (this.crossDocking) {
912
975
  response = await this.pickCrossDocking()
913
976
  } else if (this._enableProductScanning || this._isCartonLabel) {
@@ -922,16 +985,19 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
922
985
  }
923
986
 
924
987
  if (!response.errors) {
925
- if (this._enableProductScanning) this.productBarcodeInput.value = ''
988
+ if (this._isRequireSerialNumberScanning) this.serialInput.value = ''
989
+ else if (this._enableProductScanning && !this._isRequireSerialNumberScanning)
990
+ this.productBarcodeInput.value = ''
926
991
  else this.releaseQtyInput.value = ''
927
992
 
928
- if (!this._isCartonLabel) {
993
+ if (!this._isCartonLabel && !this._isRequireSerialNumberScanning) {
929
994
  this.palletInput.value = ''
930
995
  // this._selectedTaskStatus = null
931
996
  this._selectedOrderInventory = null
932
997
  }
933
998
 
934
- if (!this.isWholePicking && !this._crossDocking && !this._isCartonLabel) this.locationInput.value = ''
999
+ if (!this.isWholePicking && !this._crossDocking && !this._isCartonLabel && this.locationInput)
1000
+ this.locationInput.value = ''
935
1001
  if (this.refPickingType === PICKING_TYPES.PICKING.value) {
936
1002
  this.fetchInventories(this.releaseGoodNo)
937
1003
  } else {
@@ -940,7 +1006,6 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
940
1006
  }
941
1007
 
942
1008
  this.isReplacement = false
943
- this._isExecuting = false
944
1009
  } catch (e) {
945
1010
  this._showToast(e)
946
1011
  } finally {
@@ -979,7 +1044,34 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
979
1044
  )
980
1045
  }
981
1046
 
982
- async pickCrossDocking() {
1047
+ openSerialNumberPopup() {
1048
+ openPopup(
1049
+ html`
1050
+ <serial-number-popup
1051
+ .orderInventory="${this?._selectedOrderInventory?.relatedOrderInv}"
1052
+ @completed="${() => {
1053
+ // if (this.refPickingType === PICKING_TYPES.PICKING.value) {
1054
+ // this.fetchInventories(this.releaseGoodNoInput.value)
1055
+ // this.fetchPalletsHandler(this.releaseGoodNoInput.value)
1056
+ // } else {
1057
+ // this.fetchInventories(this.taskNoInput.value)
1058
+ // this.fetchPalletsHandler(this.taskNoInput.value)
1059
+ // }
1060
+ // // this._selectedTaskStatus = null
1061
+ // this._selectedOrderInventory = null
1062
+ // this._isReplacement = false
1063
+ }}"
1064
+ ></serial-number-popup>
1065
+ `,
1066
+ {
1067
+ backdrop: true,
1068
+ size: 'large',
1069
+ title: i18next.t('title.serial_number_list')
1070
+ }
1071
+ )
1072
+ }
1073
+
1074
+ async pick_crossDocking() {
983
1075
  return await client.mutate({
984
1076
  mutation: gql`
985
1077
  mutation crossDockPicking(
@@ -1006,7 +1098,8 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1006
1098
  }
1007
1099
 
1008
1100
  async pickCommonPicking() {
1009
- const locationName = this.isWholePicking ? this._selectedOrderInventory.location.name : this.locationInput.value
1101
+ const locationName =
1102
+ this.isWholePicking || !this.locationInput ? this._selectedOrderInventory.location.name : this.locationInput.value
1010
1103
  // 1. Check whether location is changed
1011
1104
  if (this._selectedOrderInventory.location.name !== locationName) {
1012
1105
  this.locationNameSplit = this.locationInput.value.split('-')
@@ -1046,6 +1139,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1046
1139
  $locationName: String!
1047
1140
  $releaseQty: Int!
1048
1141
  $binLocation: String
1142
+ $serialNumber: String
1049
1143
  ) {
1050
1144
  picking(
1051
1145
  worksheetDetailName: $worksheetDetailName
@@ -1054,6 +1148,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1054
1148
  locationName: $locationName
1055
1149
  releaseQty: $releaseQty
1056
1150
  binLocation: $binLocation
1151
+ serialNumber: $serialNumber
1057
1152
  )
1058
1153
  }
1059
1154
  `,
@@ -1062,8 +1157,9 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1062
1157
  worksheetType: this.refPickingType,
1063
1158
  palletId: this.palletInput.value.trim(),
1064
1159
  locationName,
1065
- releaseQty: parseInt(this.releaseQtyInput.value),
1066
- binLocation: this._hasBinPicking ? this.binLocationInput.value : null
1160
+ releaseQty: this._isRequireSerialNumberScanning ? 1 : parseInt(this.releaseQtyInput.value),
1161
+ binLocation: this._hasBinPicking ? this.binLocationInput.value : null,
1162
+ serialNumber: this._isRequireSerialNumberScanning ? this.serialInput.value : null
1067
1163
  }
1068
1164
  })
1069
1165
 
@@ -1111,6 +1207,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1111
1207
  $productBarcode: String!
1112
1208
  $cartonId: String!
1113
1209
  $binLocation: String
1210
+ $serialNumber: String
1114
1211
  ) {
1115
1212
  scanProductPicking(
1116
1213
  worksheetDetailName: $worksheetDetailName
@@ -1118,6 +1215,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1118
1215
  productBarcode: $productBarcode
1119
1216
  cartonId: $cartonId
1120
1217
  binLocation: $binLocation
1218
+ serialNumber: $serialNumber
1121
1219
  )
1122
1220
  }
1123
1221
  `,
@@ -1126,6 +1224,7 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1126
1224
  worksheetType: this.refPickingType,
1127
1225
  productBarcode: this.productBarcodeInput.value.trim(),
1128
1226
  cartonId: this.cartonInput.value.trim(),
1227
+ serialNumber: this._isRequireSerialNumberScanning ? this.serialInput.value : null,
1129
1228
  binLocation: this._hasBinPicking ? this.binLocationInput.value : null
1130
1229
  }
1131
1230
  })
@@ -1201,23 +1300,27 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1201
1300
 
1202
1301
  // Release qty existing
1203
1302
  if (!this._isReplacement) {
1204
- if (!parseInt(this.releaseQtyInput?.value)) {
1205
- this._focusOnReleaseQtyInput()
1206
- throw new Error(i18next.t('text.release_qty_is_empty'))
1207
- }
1303
+ if (!this._isRequireSerialNumberScanning) {
1304
+ if (!parseInt(this.releaseQtyInput?.value)) {
1305
+ this._focusOnReleaseQtyInput()
1306
+ throw new Error(i18next.t('text.release_qty_is_empty'))
1307
+ }
1208
1308
 
1209
- if (!this.releaseQtyInput.checkValidity()) throw new Error(i18next.t('text.release_qty_invalid'))
1309
+ if (!this.releaseQtyInput.checkValidity()) throw new Error(i18next.t('text.release_qty_invalid'))
1210
1310
 
1211
- // typed qty should be matched with release qty.
1212
- if (parseInt(this.releaseQtyInput.value) !== this._selectedOrderInventory.releaseQty) {
1213
- this._focusOnReleaseQtyInput()
1214
- throw new Error(i18next.t('text.wrong_release_qty'))
1311
+ // typed qty should be matched with release qty.
1312
+ if (parseInt(this.releaseQtyInput.value) !== this._selectedOrderInventory.releaseQty) {
1313
+ this._focusOnReleaseQtyInput()
1314
+ throw new Error(i18next.t('text.wrong_release_qty'))
1315
+ }
1215
1316
  }
1216
1317
 
1217
1318
  // location id existing
1218
- if (!this.isWholePicking && !this.locationInput.value) {
1219
- this._focusOnLocationNameInput()
1220
- throw new Error(i18next.t('text.location_id_is_empty'))
1319
+ if (!this.isWholePicking && this.locationInput) {
1320
+ if (!this.locationInput.value) {
1321
+ this._focusOnLocationNameInput()
1322
+ throw new Error(i18next.t('text.location_id_is_empty'))
1323
+ }
1221
1324
  }
1222
1325
  }
1223
1326
  } else {
@@ -1250,6 +1353,13 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1250
1353
  }
1251
1354
  }
1252
1355
 
1356
+ if (this._isRequireSerialNumberScanning) {
1357
+ if (!this.serialInput?.value) {
1358
+ this._focusOnSerialInput()
1359
+ throw new Error(i18next.t('text.empty_serial_number'))
1360
+ }
1361
+ }
1362
+
1253
1363
  if (this._crossDocking) {
1254
1364
  // typed qty should be smaller than release qty.
1255
1365
  if (parseInt(this.releaseQtyInput.value) > this._selectedOrderInventory.releaseQty) {
@@ -1519,8 +1629,6 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1519
1629
  }
1520
1630
  }
1521
1631
  this.fillUpForm(this.infoForm, { ...worksheetInfo, _crossDocking: this._crossDocking })
1522
-
1523
- this.completeHandler()
1524
1632
  }
1525
1633
  } catch (e) {
1526
1634
  this._showToast(e)
@@ -1543,8 +1651,6 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1543
1651
  // Prioritized input focus
1544
1652
  focusOnInput() {
1545
1653
  if (this.scannable) {
1546
- let focused = false
1547
-
1548
1654
  // set bin location value if already has value else focus on bin input if bin picking setting is active
1549
1655
  if (this._currentBinLocation) {
1550
1656
  this.binLocationInput.value = this._currentBinLocation
@@ -1552,31 +1658,59 @@ class PickingProduct extends connect(store)(localize(i18next)(PageView)) {
1552
1658
 
1553
1659
  if (this._hasBinPicking && this.binLocationInput && this.binLocationInput.value == '') {
1554
1660
  this._focusOnBinLocationInput()
1555
- focused = true
1661
+ return true
1556
1662
  } else {
1557
1663
  if (this._isCartonLabel) {
1558
1664
  if (!this._enableProductScanning) this.cartonInput.value = ''
1559
1665
 
1560
1666
  if (this.cartonInput.value == '') {
1561
1667
  this._focusOnCartonNoInput()
1562
- focused = true
1668
+ return true
1563
1669
  }
1564
1670
  } else {
1565
- if (!this._enableProductScanning) this.palletInput.value = ''
1671
+ if (!this._enableProductScanning && !this._isRequireSerialNumberScanning) this.palletInput.value = ''
1566
1672
 
1567
1673
  if (this.palletInput.value == '') {
1568
1674
  this._focusOnLotNoInput()
1569
- focused = true
1675
+ return true
1570
1676
  }
1571
1677
  }
1572
1678
  }
1573
1679
 
1574
- if (this._enableProductScanning && !focused) {
1680
+ if (this._enableProductScanning && !this._isRequireSerialNumberScanning) {
1575
1681
  this.productBarcodeInput.value = ''
1576
1682
  this._focusOnProductBarcodeInput()
1577
- focused = true
1683
+ return true
1578
1684
  }
1685
+
1686
+ if (this._isRequireSerialNumberScanning) {
1687
+ this.serialInput.value = ''
1688
+ this._focusOnSerialInput()
1689
+ return true
1690
+ }
1691
+
1692
+ return true
1693
+ }
1694
+ }
1695
+
1696
+ updateSelectedItemProp(selectedRecords) {
1697
+ if (selectedRecords.releaseQty === selectedRecords.qty) {
1698
+ this.isWholePicking = true
1699
+ this._selectedOrderInventory = selectedRecords
1700
+ } else {
1701
+ this.isWholePicking = false
1702
+ this._selectedOrderInventory = selectedRecords
1579
1703
  }
1704
+
1705
+ this._isCartonLabel = selectedRecords.hasCartonLabel
1706
+ this._productName = selectedRecords.product?.name
1707
+ ? `${selectedRecords.product.sku + ' - ' + selectedRecords.product.name} ${
1708
+ selectedRecords.product?.description ? `(${selectedRecords.product.description})` : ''
1709
+ }`
1710
+ : ''
1711
+ this._isRequireSerialNumberScanning = selectedRecords?.product?.isRequireSerialNumberScanning
1712
+
1713
+ // this.isWholePicking = selectedRecords.releaseQty === selectedRecords.qty
1580
1714
  }
1581
1715
 
1582
1716
  _showToast({ type, message }) {