@things-factory/operato-wms 4.3.752 → 4.3.755

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 (78) hide show
  1. package/client/pages/inbound/unload-product.js +30 -33
  2. package/client/pages/outbound/loading-product.js +2 -3
  3. package/client/pages/outbound/loading-v2/loading-execution-base.js +568 -56
  4. package/client/pages/outbound/loading-v2/loading-execution.js +258 -8
  5. package/client/pages/outbound/loading-v2/loading.js +82 -12
  6. package/client/pages/outbound/picking-product.js +11 -6
  7. package/client/pages/outbound/picking-v2/picking-execution-base.js +8 -8
  8. package/client/pages/outbound/picking-v2/picking-execution.js +75 -0
  9. package/client/pages/outbound/route-label-history-dialog.js +253 -0
  10. package/client/pages/outbound/route-label-popup.js +637 -131
  11. package/client/pages/outbound/show-ro-list-popup.js +8 -4
  12. package/client/pages/outbound/single-outbound-worksheet.js +55 -6
  13. package/client/pages/outbound/sorting-product.js +71 -25
  14. package/client/pages/outbound/zone-worksheet.js +62 -3
  15. package/dist-server/entities/index.js +9 -0
  16. package/dist-server/entities/index.js.map +1 -0
  17. package/dist-server/entities/route-label-sequence-counter.js +75 -0
  18. package/dist-server/entities/route-label-sequence-counter.js.map +1 -0
  19. package/dist-server/entities/route-label-sequence-log.js +74 -0
  20. package/dist-server/entities/route-label-sequence-log.js.map +1 -0
  21. package/dist-server/graphql/resolvers/index.js +3 -0
  22. package/dist-server/graphql/resolvers/index.js.map +1 -1
  23. package/dist-server/graphql/resolvers/outbound/complete-load.js +40 -3
  24. package/dist-server/graphql/resolvers/outbound/complete-load.js.map +1 -1
  25. package/dist-server/graphql/resolvers/outbound/find-loadable-release-good-by-bin.js +50 -11
  26. package/dist-server/graphql/resolvers/outbound/find-loadable-release-good-by-bin.js.map +1 -1
  27. package/dist-server/graphql/resolvers/outbound/find-loadable-release-good.js +90 -48
  28. package/dist-server/graphql/resolvers/outbound/find-loadable-release-good.js.map +1 -1
  29. package/dist-server/graphql/resolvers/outbound/loading-worksheet-v2.js +15 -7
  30. package/dist-server/graphql/resolvers/outbound/loading-worksheet-v2.js.map +1 -1
  31. package/dist-server/graphql/resolvers/outbound/sort-item.js +95 -16
  32. package/dist-server/graphql/resolvers/outbound/sort-item.js.map +1 -1
  33. package/dist-server/graphql/resolvers/route-label/index.js +7 -0
  34. package/dist-server/graphql/resolvers/route-label/index.js.map +1 -0
  35. package/dist-server/graphql/resolvers/route-label/route-label.js +220 -0
  36. package/dist-server/graphql/resolvers/route-label/route-label.js.map +1 -0
  37. package/dist-server/graphql/resolvers/zone-worksheet/index.js.map +1 -1
  38. package/dist-server/graphql/resolvers/zone-worksheet/zone-picking.js +123 -27
  39. package/dist-server/graphql/resolvers/zone-worksheet/zone-picking.js.map +1 -1
  40. package/dist-server/graphql/resolvers/zone-worksheet/zone-worksheet.js.map +1 -1
  41. package/dist-server/graphql/types/index.js +4 -0
  42. package/dist-server/graphql/types/index.js.map +1 -1
  43. package/dist-server/graphql/types/outbound/index.js +7 -1
  44. package/dist-server/graphql/types/outbound/index.js.map +1 -1
  45. package/dist-server/graphql/types/route-label/index.js +14 -0
  46. package/dist-server/graphql/types/route-label/index.js.map +1 -0
  47. package/dist-server/graphql/types/route-label/route-label-sequence.js +53 -0
  48. package/dist-server/graphql/types/route-label/route-label-sequence.js.map +1 -0
  49. package/dist-server/index.js +5 -0
  50. package/dist-server/index.js.map +1 -1
  51. package/dist-server/validators/setting-validators.js +519 -0
  52. package/dist-server/validators/setting-validators.js.map +1 -0
  53. package/helps/operato-wms/outbound/picking-product.en.md +156 -158
  54. package/package.json +50 -50
  55. package/server/entities/index.ts +6 -0
  56. package/server/entities/route-label-sequence-counter.ts +56 -0
  57. package/server/entities/route-label-sequence-log.ts +47 -0
  58. package/server/graphql/resolvers/index.ts +3 -0
  59. package/server/graphql/resolvers/outbound/complete-load.ts +42 -1
  60. package/server/graphql/resolvers/outbound/find-loadable-release-good-by-bin.ts +56 -13
  61. package/server/graphql/resolvers/outbound/find-loadable-release-good.ts +120 -57
  62. package/server/graphql/resolvers/outbound/loading-worksheet-v2.ts +9 -2
  63. package/server/graphql/resolvers/outbound/sort-item.ts +125 -21
  64. package/server/graphql/resolvers/route-label/index.ts +16 -0
  65. package/server/graphql/resolvers/route-label/route-label.ts +264 -0
  66. package/server/graphql/resolvers/zone-worksheet/index.ts +2 -2
  67. package/server/graphql/resolvers/zone-worksheet/zone-picking.ts +156 -39
  68. package/server/graphql/resolvers/zone-worksheet/zone-worksheet.ts +1 -2
  69. package/server/graphql/types/index.ts +4 -0
  70. package/server/graphql/types/outbound/index.ts +7 -1
  71. package/server/graphql/types/route-label/index.ts +18 -0
  72. package/server/graphql/types/route-label/route-label-sequence.ts +50 -0
  73. package/server/index.ts +7 -1
  74. package/server/validators/setting-validators.ts +668 -0
  75. package/translations/en.json +280 -252
  76. package/translations/ko.json +29 -1
  77. package/translations/ms.json +28 -0
  78. package/translations/zh.json +28 -0
@@ -124,10 +124,14 @@ class ShowRoListPopup extends localize(i18next)(LitElement) {
124
124
  updated(changeProps) {
125
125
  if (changeProps.has('releaseOrders')) {
126
126
  if (this.releaseOrders && this.releaseOrders.length) {
127
- const processedRecords = this.releaseOrders.map(ro => ({
128
- ...ro,
129
- itemCounts: ro.itemCounts ? `${ro.itemCounts.pending || 0}/${ro.itemCounts.total || 0}` : '0/0'
130
- }))
127
+ const processedRecords = this.releaseOrders.map(ro => {
128
+ const completed = ro.itemCounts ? ro.itemCounts.total - ro.itemCounts.pending : 0
129
+ const total = ro.itemCounts?.total || 0
130
+ return {
131
+ ...ro,
132
+ itemCounts: ro.itemCounts ? `${completed}/${total}` : '0/0'
133
+ }
134
+ })
131
135
  this.data = { records: processedRecords }
132
136
  }
133
137
  }
@@ -182,6 +182,27 @@ class SingleOutboundWorksheet extends localize(i18next)(PageView) {
182
182
  ],
183
183
  props: { searchOper: 'eq' }
184
184
  },
185
+ {
186
+ name: 'type',
187
+ label: i18next.t('field.type'),
188
+ type: 'select',
189
+ options: [
190
+ { value: '' },
191
+ {
192
+ name: WORKSHEET_TYPE.PICKING.name,
193
+ value: WORKSHEET_TYPE.PICKING.value
194
+ },
195
+ {
196
+ name: WORKSHEET_TYPE.LOADING.name,
197
+ value: WORKSHEET_TYPE.LOADING.value
198
+ },
199
+ {
200
+ name: WORKSHEET_TYPE.WAREHOUSE_RETURN.name,
201
+ value: WORKSHEET_TYPE.WAREHOUSE_RETURN.value
202
+ }
203
+ ],
204
+ props: { searchOper: 'eq' }
205
+ },
185
206
  {
186
207
  name: 'assignee',
187
208
  label: i18next.t('field.picker'),
@@ -407,11 +428,35 @@ class SingleOutboundWorksheet extends localize(i18next)(PageView) {
407
428
 
408
429
  async fetchHandler({ page, limit, sorters = [{ name: 'createdAt', desc: true }] }) {
409
430
  const filters = this.searchForm.queryFilters
410
- filters.push({
411
- name: 'type',
412
- operator: 'in',
413
- value: [WORKSHEET_TYPE.PICKING.value, WORKSHEET_TYPE.LOADING.value, WORKSHEET_TYPE.WAREHOUSE_RETURN.value]
414
- })
431
+
432
+ // Handle type filter: convert 'eq' to 'in' format if user selected a type, or add default filter
433
+ const typeFilterIndex = filters.findIndex(filter => filter.name === 'type')
434
+ if (typeFilterIndex >= 0) {
435
+ const typeFilter = filters[typeFilterIndex]
436
+ // Convert 'eq' operator to 'in' format for consistency with backend
437
+ if (typeFilter.operator === 'eq' && typeFilter.value) {
438
+ filters[typeFilterIndex] = {
439
+ name: 'type',
440
+ operator: 'in',
441
+ value: [typeFilter.value]
442
+ }
443
+ } else if (!typeFilter.value || typeFilter.value === '') {
444
+ // Remove empty type filter and use default instead
445
+ filters.splice(typeFilterIndex, 1)
446
+ filters.push({
447
+ name: 'type',
448
+ operator: 'in',
449
+ value: [WORKSHEET_TYPE.PICKING.value, WORKSHEET_TYPE.LOADING.value, WORKSHEET_TYPE.WAREHOUSE_RETURN.value]
450
+ })
451
+ }
452
+ } else {
453
+ // Only add default type filter if user hasn't selected a type filter
454
+ filters.push({
455
+ name: 'type',
456
+ operator: 'in',
457
+ value: [WORKSHEET_TYPE.PICKING.value, WORKSHEET_TYPE.LOADING.value, WORKSHEET_TYPE.WAREHOUSE_RETURN.value]
458
+ })
459
+ }
415
460
 
416
461
  // Add extra condition if path variable has assigneeId
417
462
  // It's for navigate from picking UI to list up assigned tasks of user
@@ -674,7 +719,11 @@ class SingleOutboundWorksheet extends localize(i18next)(PageView) {
674
719
 
675
720
  openPopup(
676
721
  html`
677
- <route-label-popup .partnerId="${bizplaceFilters.value}" .worksheetType="${'single'}"></route-label-popup>
722
+ <route-label-popup
723
+ .partnerId="${bizplaceFilters.value}"
724
+ .worksheetType="${'single'}"
725
+ .sourceWorksheetType="${'PICKING'}"
726
+ ></route-label-popup>
678
727
  `,
679
728
  {
680
729
  backdrop: true,
@@ -30,7 +30,8 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
30
30
  _selectedTaskStatus: String,
31
31
  _worksheetInfo: Object,
32
32
  _selectedReleaseGood: Object,
33
- _enableToteScanning: Boolean,
33
+ _enableToteScanningValue: Number,
34
+ _disableQC: Boolean,
34
35
  _enableSortingQty: Boolean,
35
36
  bizplaceName: String,
36
37
  customerCompanyDomainId: String,
@@ -79,7 +80,8 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
79
80
  var actions = []
80
81
 
81
82
  if (this.taskNo) {
82
- if (this._enableToteScanning) {
83
+ // Tote button only appears when disable-qc-in-loading is true AND enable-tote-scanning is 1 or above
84
+ if (this._disableQC && this._enableToteScanningValue >= 1) {
83
85
  actions.push({
84
86
  title: i18next.t('button.tote'),
85
87
  action: this._openTotePopup.bind(this),
@@ -133,9 +135,8 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
133
135
  }
134
136
 
135
137
  get productBarcodeInput() {
136
- return this.shadowRoot
137
- .querySelector('barcode-scanable-input[name=productBarcode]')
138
- .shadowRoot.querySelector('input')
138
+ const element = this.shadowRoot?.querySelector('barcode-scanable-input[name=productBarcode]')
139
+ return element?.shadowRoot?.querySelector('input')
139
140
  }
140
141
 
141
142
  get scannable() {
@@ -143,27 +144,35 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
143
144
  }
144
145
 
145
146
  get sortingQtyInput() {
146
- return this.shadowRoot.querySelector('input[name=sortingQty]')
147
+ return this.shadowRoot?.querySelector('input[name=sortingQty]')
147
148
  }
148
149
 
149
150
  get taskNoInput() {
150
- return this.shadowRoot.querySelector('barcode-scanable-input[name=taskNo]').shadowRoot.querySelector('input')
151
+ const element = this.shadowRoot?.querySelector('barcode-scanable-input[name=taskNo]')
152
+ return element?.shadowRoot?.querySelector('input')
151
153
  }
152
154
 
153
155
  get serialInput() {
154
- return this.shadowRoot.querySelector('barcode-scanable-input[name=serialNumber]')?.shadowRoot.querySelector('input')
156
+ const element = this.shadowRoot?.querySelector('barcode-scanable-input[name=serialNumber]')
157
+ return element?.shadowRoot?.querySelector('input')
155
158
  }
156
159
 
157
160
  _focusOnTaskNoInput() {
158
- setTimeout(() => this.taskNoInput.focus(), 100)
161
+ if (this.taskNoInput) {
162
+ setTimeout(() => this.taskNoInput.focus(), 100)
163
+ }
159
164
  }
160
165
 
161
166
  _focusOnProductBarcodeInput() {
162
- setTimeout(() => this.productBarcodeInput.focus(), 100)
167
+ if (this.productBarcodeInput) {
168
+ setTimeout(() => this.productBarcodeInput.focus(), 100)
169
+ }
163
170
  }
164
171
 
165
172
  _focusOnSortingQtyInput() {
166
- setTimeout(() => this.sortingQtyInput.focus(), 100)
173
+ if (this.sortingQtyInput) {
174
+ setTimeout(() => this.sortingQtyInput.focus(), 100)
175
+ }
167
176
  }
168
177
 
169
178
  _focusOnSerialInput() {
@@ -259,10 +268,19 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
259
268
  this._selectedTaskStatus = null
260
269
  this._enableSortingQty = false
261
270
  this._qrProcessing = 0
271
+ this._enableToteScanningValue = 0
272
+ this._disableQC = false
262
273
  }
263
274
 
264
275
  updated(changedProps) {
265
- if (changedProps.has('_selectedTaskStatus') && this._selectedTaskStatus) {
276
+ // Update context when relevant properties change
277
+ const shouldUpdateContext =
278
+ (changedProps.has('_selectedTaskStatus') && this._selectedTaskStatus) ||
279
+ changedProps.has('_enableToteScanningValue') ||
280
+ changedProps.has('_disableQC') ||
281
+ changedProps.has('taskNo')
282
+
283
+ if (shouldUpdateContext) {
266
284
  this.updateContext()
267
285
  }
268
286
  }
@@ -395,6 +413,10 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
395
413
  deliveryAddress4
396
414
  deliveryAddress5
397
415
  sortedByUser
416
+ itemCounts {
417
+ total
418
+ pending
419
+ }
398
420
  }
399
421
  selectedReleaseGood
400
422
  taskNo
@@ -444,8 +466,8 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
444
466
  <show-ro-list-popup
445
467
  .releaseOrders=${this.releaseOrders}
446
468
  .sorting=${true}
447
- @ro-selected-sorting=${e => {
448
- this._setSelectedRO(e.detail.ro?.name)
469
+ @ro-selected-sorting=${async e => {
470
+ await this._setSelectedRO(e.detail.ro?.name)
449
471
  }}
450
472
  ></show-ro-list-popup>
451
473
  `,
@@ -457,14 +479,25 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
457
479
  )
458
480
  }
459
481
 
460
- _setSelectedRO(ro) {
482
+ async _setSelectedRO(ro) {
461
483
  this._selectedReleaseGood = ro
462
- this._fetchItemList(this._selectedReleaseGood)
463
- if (this._enableProductScanning) this.productBarcodeInput.value = ''
464
- if (this.sortingQtyInput) this.sortingQtyInput.value = ''
465
- if (this.serialInput) this.serialInput.value = ''
484
+ await this._fetchItemList(this._selectedReleaseGood)
485
+ // Wait for component to finish updating before accessing DOM elements
486
+ await this.updateComplete
487
+ // Clear input fields after component has rendered
488
+ if (this._enableProductScanning && this.productBarcodeInput) {
489
+ this.productBarcodeInput.value = ''
490
+ }
491
+ if (this.sortingQtyInput) {
492
+ this.sortingQtyInput.value = ''
493
+ }
494
+ if (this.serialInput) {
495
+ this.serialInput.value = ''
496
+ }
466
497
  this.toteNo = ''
467
498
  this._lastScannedProductId = ''
499
+ // Properties are updated in _fetchItemList, which triggers updated() hook
500
+ // which will call updateContext() automatically
468
501
  }
469
502
 
470
503
  _openWorksheetInformation() {
@@ -567,7 +600,13 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
567
600
  settings: {
568
601
  name: 'name',
569
602
  operator: 'in',
570
- value: ['enable-product-scanning', 'enable-tote-scanning', 'enable-sorting-qty', 'qr-code-scanning']
603
+ value: [
604
+ 'enable-product-scanning',
605
+ 'enable-tote-scanning',
606
+ 'enable-sorting-qty',
607
+ 'qr-code-scanning',
608
+ 'disable-QC-in-loading'
609
+ ]
571
610
  },
572
611
  settingsDomain: worksheetInfo.partnerDomainId
573
612
  })
@@ -575,10 +614,14 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
575
614
  const settingsMap = new Map(pageSettings.settings.map(setting => [setting.name, setting.value]))
576
615
 
577
616
  this._enableProductScanning = settingsMap.get('enable-product-scanning') === 'true'
578
- this._enableToteScanning = settingsMap.get('enable-tote-scanning') === 'true'
617
+ this._enableToteScanningValue = parseInt(settingsMap.get('enable-tote-scanning') || '0', 10)
618
+ // Handle both boolean true and string 'true' (case-insensitive)
619
+ const disableQCValue = settingsMap.get('disable-QC-in-loading')
620
+ this._disableQC = disableQCValue === true || String(disableQCValue).toLowerCase().trim() === 'true'
579
621
  this._enableSortingQty = settingsMap.get('enable-sorting-qty') === 'true'
580
622
  this._qrProcessing = settingsMap.get('qr-code-scanning')
581
623
 
624
+ // Update context after properties are set
582
625
  this.updateContext()
583
626
  this._completeHandler()
584
627
 
@@ -586,17 +629,20 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
586
629
  }
587
630
  }
588
631
 
589
- focusPage(worksheetDetailInfos) {
632
+ async focusPage(worksheetDetailInfos) {
590
633
  this.data = { records: this.formatWorksheetDetailInfos(worksheetDetailInfos) }
591
634
  if (!this._selectedOrderInventory) {
592
635
  this._selectedOrderInventory = worksheetDetailInfos[0]
593
636
  this._isRequireSerialNumberScanningOutbound = worksheetDetailInfos[0].isRequireSerialNumberScanningOutbound
594
637
  }
595
638
 
639
+ // Wait for component to finish updating before accessing DOM elements
640
+ await this.updateComplete
641
+
596
642
  if (this._isRequireSerialNumberScanningOutbound && !this._enableProductScanning) {
597
643
  this._focusOnSerialInput()
598
644
  } else if (this._enableProductScanning) {
599
- if (this.productBarcodeInput.value) {
645
+ if (this.productBarcodeInput?.value) {
600
646
  if (this._isRequireSerialNumberScanningOutbound) {
601
647
  this._focusOnSerialInput()
602
648
  } else if (this._enableSortingQty) {
@@ -735,7 +781,7 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
735
781
  productId: this._selectedOrderInventory?.product.id,
736
782
  sortingQty: this._isRequireSerialNumberScanningOutbound ? 1 : parseFloat(this.sortingQtyInput.value),
737
783
  serialNumber: this._isRequireSerialNumberScanningOutbound ? this.serialInput.value.trim() : null,
738
- toteNo: this._enableToteScanning && this.toteNo !== '' ? this.toteNo : null
784
+ toteNo: this._enableToteScanningValue >= 1 && this.toteNo !== '' ? this.toteNo : null
739
785
  }
740
786
  })
741
787
  }
@@ -746,7 +792,7 @@ class SortingProduct extends connect(store)(localize(i18next)(PageView)) {
746
792
  taskNo: this.taskNo,
747
793
  productBarcode: this.productBarcodeInput.value.trim(),
748
794
  serialNumber: this._isRequireSerialNumberScanningOutbound ? this.serialInput.value.trim() : null,
749
- toteNo: this._enableToteScanning && this.toteNo !== '' ? this.toteNo : null,
795
+ toteNo: this._enableToteScanningValue >= 1 && this.toteNo !== '' ? this.toteNo : null,
750
796
  sortingQty:
751
797
  this._enableSortingQty && !this._isRequireSerialNumberScanningOutbound
752
798
  ? parseFloat(this.sortingQtyInput.value)
@@ -1,5 +1,6 @@
1
1
  import '@things-factory/form-ui'
2
2
  import '@things-factory/grist-ui'
3
+ import './route-label-popup'
3
4
  import './select-operator-popup'
4
5
 
5
6
  import gql from 'graphql-tag'
@@ -12,6 +13,7 @@ import { ScrollbarStyles, CommonButtonStyles } from '@things-factory/styles'
12
13
  import { isMobileDevice } from '@things-factory/utils'
13
14
  import { openPopup } from '@things-factory/layout-base'
14
15
  import { applyParamsToFields } from '../../util'
16
+ import { fetchSettingRule } from '../../fetch-setting-value'
15
17
 
16
18
  import { WORKSHEET_TYPE } from '../constants'
17
19
 
@@ -23,7 +25,9 @@ class ZoneWorksheet extends localize(i18next)(PageView) {
23
25
  assignee: String,
24
26
  status: String,
25
27
  _searchFields: Array,
26
- _partnersList: Array
28
+ _partnersList: Array,
29
+ _routeLabelSetting: Boolean,
30
+ _routeLabelSettingDomainId: String
27
31
  }
28
32
  }
29
33
 
@@ -60,7 +64,17 @@ class ZoneWorksheet extends localize(i18next)(PageView) {
60
64
  }
61
65
 
62
66
  get context() {
63
- var actions = [
67
+ var actions = []
68
+
69
+ if (this._routeLabelSetting) {
70
+ actions.push({
71
+ title: i18next.t('button.print_route_label'),
72
+ action: this._openPrintLabelPopup.bind(this),
73
+ ...CommonButtonStyles.label
74
+ })
75
+ }
76
+
77
+ actions = actions.concat([
64
78
  {
65
79
  title: i18next.t('button.assign_picker'),
66
80
  action: this._assignPicker.bind(this),
@@ -71,7 +85,7 @@ class ZoneWorksheet extends localize(i18next)(PageView) {
71
85
  action: this._activateBulkWorksheet.bind(this),
72
86
  ...CommonButtonStyles.activate
73
87
  }
74
- ]
88
+ ])
75
89
 
76
90
  return {
77
91
  title: i18next.t('title.zone_worksheet'),
@@ -382,6 +396,12 @@ class ZoneWorksheet extends localize(i18next)(PageView) {
382
396
  })
383
397
 
384
398
  if (!response.errors) {
399
+ // Decide whether to show route label printing based on setting.
400
+ const domain = response.data.worksheets.items[0]?.domain
401
+ if (domain) {
402
+ this._routeLabelSetting = await fetchSettingRule('enable-print-route-label', domain.id)
403
+ this._routeLabelSettingDomainId = domain.id
404
+ }
385
405
  this.updateContext()
386
406
  return {
387
407
  total: response.data.worksheets.total || 0,
@@ -417,6 +437,45 @@ class ZoneWorksheet extends localize(i18next)(PageView) {
417
437
  }
418
438
  }
419
439
 
440
+ async _openPrintLabelPopup() {
441
+ try {
442
+ const bizplaceFilters = (await this.searchForm.getQueryFilters()).find(x => x.name === 'bizplaceId')
443
+ if (!bizplaceFilters) {
444
+ throw new Error(`Please select a customer to print route label.`)
445
+ }
446
+
447
+ const selectedPartner = this._partnersList.items.find(itm => itm.id == bizplaceFilters.value)
448
+ const selectedDomainId = selectedPartner?.domain?.id
449
+
450
+ // Reuse cached setting if same domain, otherwise fetch
451
+ let routeLabelEnabled = this._routeLabelSetting
452
+ if (selectedDomainId && selectedDomainId !== this._routeLabelSettingDomainId) {
453
+ routeLabelEnabled = await fetchSettingRule('enable-print-route-label', selectedDomainId)
454
+ }
455
+
456
+ if (!routeLabelEnabled) {
457
+ throw new Error(`Route label printing is not enabled for this partner.`)
458
+ }
459
+
460
+ openPopup(
461
+ html`
462
+ <route-label-popup
463
+ .partnerId="${bizplaceFilters.value}"
464
+ .worksheetType="${'single'}"
465
+ .sourceWorksheetType="${'ZONE_PICKING'}"
466
+ ></route-label-popup>
467
+ `,
468
+ {
469
+ backdrop: true,
470
+ size: 'large',
471
+ title: i18next.t('title.print_route_label')
472
+ }
473
+ )
474
+ } catch (e) {
475
+ this._showToast(e)
476
+ }
477
+ }
478
+
420
479
  _assignPicker() {
421
480
  try {
422
481
  let selectedData = this.dataGrist.selected.filter(item => {
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RouteLabelSequenceLog = exports.RouteLabelSequenceCounter = exports.entities = void 0;
4
+ const route_label_sequence_counter_1 = require("./route-label-sequence-counter");
5
+ Object.defineProperty(exports, "RouteLabelSequenceCounter", { enumerable: true, get: function () { return route_label_sequence_counter_1.RouteLabelSequenceCounter; } });
6
+ const route_label_sequence_log_1 = require("./route-label-sequence-log");
7
+ Object.defineProperty(exports, "RouteLabelSequenceLog", { enumerable: true, get: function () { return route_label_sequence_log_1.RouteLabelSequenceLog; } });
8
+ exports.entities = [route_label_sequence_counter_1.RouteLabelSequenceCounter, route_label_sequence_log_1.RouteLabelSequenceLog];
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/entities/index.ts"],"names":[],"mappings":";;;AAAA,iFAA0E;AAKjE,0GALA,wDAAyB,OAKA;AAJlC,yEAAkE;AAI9B,sGAJ3B,gDAAqB,OAI2B;AAF5C,QAAA,QAAQ,GAAG,CAAC,wDAAyB,EAAE,gDAAqB,CAAC,CAAA"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var _a, _b, _c;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.RouteLabelSequenceCounter = void 0;
14
+ const typeorm_1 = require("typeorm");
15
+ const shell_1 = require("@things-factory/shell");
16
+ const auth_base_1 = require("@things-factory/auth-base");
17
+ let RouteLabelSequenceCounter = class RouteLabelSequenceCounter {
18
+ };
19
+ __decorate([
20
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
21
+ __metadata("design:type", String)
22
+ ], RouteLabelSequenceCounter.prototype, "id", void 0);
23
+ __decorate([
24
+ (0, typeorm_1.ManyToOne)(type => shell_1.Domain),
25
+ __metadata("design:type", typeof (_a = typeof shell_1.Domain !== "undefined" && shell_1.Domain) === "function" ? _a : Object)
26
+ ], RouteLabelSequenceCounter.prototype, "domain", void 0);
27
+ __decorate([
28
+ (0, typeorm_1.RelationId)((c) => c.domain),
29
+ __metadata("design:type", String)
30
+ ], RouteLabelSequenceCounter.prototype, "domainId", void 0);
31
+ __decorate([
32
+ (0, typeorm_1.Column)(),
33
+ __metadata("design:type", String)
34
+ ], RouteLabelSequenceCounter.prototype, "releaseGoodId", void 0);
35
+ __decorate([
36
+ (0, typeorm_1.Column)(),
37
+ __metadata("design:type", String)
38
+ ], RouteLabelSequenceCounter.prototype, "field", void 0);
39
+ __decorate([
40
+ (0, typeorm_1.Column)({ type: 'int', default: 0 }),
41
+ __metadata("design:type", Number)
42
+ ], RouteLabelSequenceCounter.prototype, "lastSeq", void 0);
43
+ __decorate([
44
+ (0, typeorm_1.CreateDateColumn)(),
45
+ __metadata("design:type", Date)
46
+ ], RouteLabelSequenceCounter.prototype, "createdAt", void 0);
47
+ __decorate([
48
+ (0, typeorm_1.UpdateDateColumn)(),
49
+ __metadata("design:type", Date)
50
+ ], RouteLabelSequenceCounter.prototype, "updatedAt", void 0);
51
+ __decorate([
52
+ (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
53
+ __metadata("design:type", typeof (_b = typeof auth_base_1.User !== "undefined" && auth_base_1.User) === "function" ? _b : Object)
54
+ ], RouteLabelSequenceCounter.prototype, "creator", void 0);
55
+ __decorate([
56
+ (0, typeorm_1.RelationId)((c) => c.creator),
57
+ __metadata("design:type", String)
58
+ ], RouteLabelSequenceCounter.prototype, "creatorId", void 0);
59
+ __decorate([
60
+ (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
61
+ __metadata("design:type", typeof (_c = typeof auth_base_1.User !== "undefined" && auth_base_1.User) === "function" ? _c : Object)
62
+ ], RouteLabelSequenceCounter.prototype, "updater", void 0);
63
+ __decorate([
64
+ (0, typeorm_1.RelationId)((c) => c.updater),
65
+ __metadata("design:type", String)
66
+ ], RouteLabelSequenceCounter.prototype, "updaterId", void 0);
67
+ RouteLabelSequenceCounter = __decorate([
68
+ (0, typeorm_1.Entity)('route_label_sequence_counters'),
69
+ (0, typeorm_1.Index)('ix_route_label_sequence_counters_0', (c) => [c.domain, c.releaseGoodId, c.field], {
70
+ unique: true
71
+ }),
72
+ (0, typeorm_1.Index)('ix_route_label_sequence_counters_1', (c) => [c.domain, c.field])
73
+ ], RouteLabelSequenceCounter);
74
+ exports.RouteLabelSequenceCounter = RouteLabelSequenceCounter;
75
+ //# sourceMappingURL=route-label-sequence-counter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-label-sequence-counter.js","sourceRoot":"","sources":["../../server/entities/route-label-sequence-counter.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,qCASgB;AAEhB,iDAA8C;AAC9C,yDAAgD;AAOzC,IAAM,yBAAyB,GAA/B,MAAM,yBAAyB;CAoCrC,CAAA;AAnCC;IAAC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;qDACZ;AAEnB;IAAC,IAAA,mBAAS,EAAC,IAAI,CAAC,EAAE,CAAC,cAAM,CAAC;kDACjB,cAAM,oBAAN,cAAM;yDAAA;AAEf;IAAC,IAAA,oBAAU,EAAC,CAAC,CAA4B,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;;2DACtC;AAEjB;IAAC,IAAA,gBAAM,GAAE;;gEACY;AAErB;IAAC,IAAA,gBAAM,GAAE;;wDACI;AAEb;IAAC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;0DACrB;AAEf;IAAC,IAAA,0BAAgB,GAAE;8BACP,IAAI;4DAAA;AAEhB;IAAC,IAAA,0BAAgB,GAAE;8BACP,IAAI;4DAAA;AAEhB;IAAC,IAAA,mBAAS,EAAC,IAAI,CAAC,EAAE,CAAC,gBAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;kDAClC,gBAAI,oBAAJ,gBAAI;0DAAA;AAEd;IAAC,IAAA,oBAAU,EAAC,CAAC,CAA4B,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;;4DACtC;AAElB;IAAC,IAAA,mBAAS,EAAC,IAAI,CAAC,EAAE,CAAC,gBAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;kDAClC,gBAAI,oBAAJ,gBAAI;0DAAA;AAEd;IAAC,IAAA,oBAAU,EAAC,CAAC,CAA4B,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;;4DACtC;AAnCP,yBAAyB;IALrC,IAAA,gBAAM,EAAC,+BAA+B,CAAC;IACvC,IAAA,eAAK,EAAC,oCAAoC,EAAE,CAAC,CAA4B,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;QACnH,MAAM,EAAE,IAAI;KACb,CAAC;IACD,IAAA,eAAK,EAAC,oCAAoC,EAAE,CAAC,CAA4B,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;GACtF,yBAAyB,CAoCrC;AApCY,8DAAyB"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var _a, _b;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.RouteLabelSequenceLog = void 0;
14
+ const typeorm_1 = require("typeorm");
15
+ const shell_1 = require("@things-factory/shell");
16
+ const auth_base_1 = require("@things-factory/auth-base");
17
+ let RouteLabelSequenceLog = class RouteLabelSequenceLog {
18
+ };
19
+ __decorate([
20
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
21
+ __metadata("design:type", String)
22
+ ], RouteLabelSequenceLog.prototype, "id", void 0);
23
+ __decorate([
24
+ (0, typeorm_1.ManyToOne)(type => shell_1.Domain),
25
+ __metadata("design:type", typeof (_a = typeof shell_1.Domain !== "undefined" && shell_1.Domain) === "function" ? _a : Object)
26
+ ], RouteLabelSequenceLog.prototype, "domain", void 0);
27
+ __decorate([
28
+ (0, typeorm_1.RelationId)((l) => l.domain),
29
+ __metadata("design:type", String)
30
+ ], RouteLabelSequenceLog.prototype, "domainId", void 0);
31
+ __decorate([
32
+ (0, typeorm_1.Column)(),
33
+ __metadata("design:type", String)
34
+ ], RouteLabelSequenceLog.prototype, "releaseGoodId", void 0);
35
+ __decorate([
36
+ (0, typeorm_1.Column)(),
37
+ __metadata("design:type", String)
38
+ ], RouteLabelSequenceLog.prototype, "field", void 0);
39
+ __decorate([
40
+ (0, typeorm_1.Column)({ type: 'int' }),
41
+ __metadata("design:type", Number)
42
+ ], RouteLabelSequenceLog.prototype, "from", void 0);
43
+ __decorate([
44
+ (0, typeorm_1.Column)({ type: 'int' }),
45
+ __metadata("design:type", Number)
46
+ ], RouteLabelSequenceLog.prototype, "to", void 0);
47
+ __decorate([
48
+ (0, typeorm_1.Column)({ type: 'int' }),
49
+ __metadata("design:type", Number)
50
+ ], RouteLabelSequenceLog.prototype, "qty", void 0);
51
+ __decorate([
52
+ (0, typeorm_1.CreateDateColumn)(),
53
+ __metadata("design:type", Date)
54
+ ], RouteLabelSequenceLog.prototype, "createdAt", void 0);
55
+ __decorate([
56
+ (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
57
+ __metadata("design:type", typeof (_b = typeof auth_base_1.User !== "undefined" && auth_base_1.User) === "function" ? _b : Object)
58
+ ], RouteLabelSequenceLog.prototype, "creator", void 0);
59
+ __decorate([
60
+ (0, typeorm_1.RelationId)((l) => l.creator),
61
+ __metadata("design:type", String)
62
+ ], RouteLabelSequenceLog.prototype, "creatorId", void 0);
63
+ RouteLabelSequenceLog = __decorate([
64
+ (0, typeorm_1.Entity)('route_label_sequence_logs'),
65
+ (0, typeorm_1.Index)('ix_route_label_sequence_logs_0', (l) => [
66
+ l.domain,
67
+ l.releaseGoodId,
68
+ l.field,
69
+ l.createdAt
70
+ ]),
71
+ (0, typeorm_1.Index)('ix_route_label_sequence_logs_1', (l) => [l.domain, l.field, l.createdAt])
72
+ ], RouteLabelSequenceLog);
73
+ exports.RouteLabelSequenceLog = RouteLabelSequenceLog;
74
+ //# sourceMappingURL=route-label-sequence-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-label-sequence-log.js","sourceRoot":"","sources":["../../server/entities/route-label-sequence-log.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,qCAAgH;AAEhH,iDAA8C;AAC9C,yDAAgD;AAUzC,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;CAiCjC,CAAA;AAhCC;IAAC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;iDACZ;AAEnB;IAAC,IAAA,mBAAS,EAAC,IAAI,CAAC,EAAE,CAAC,cAAM,CAAC;kDACjB,cAAM,oBAAN,cAAM;qDAAA;AAEf;IAAC,IAAA,oBAAU,EAAC,CAAC,CAAwB,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;;uDAClC;AAEjB;IAAC,IAAA,gBAAM,GAAE;;4DACY;AAErB;IAAC,IAAA,gBAAM,GAAE;;oDACI;AAEb;IAAC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;mDACZ;AAEZ;IAAC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;iDACd;AAEV;IAAC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;kDACb;AAEX;IAAC,IAAA,0BAAgB,GAAE;8BACP,IAAI;wDAAA;AAEhB;IAAC,IAAA,mBAAS,EAAC,IAAI,CAAC,EAAE,CAAC,gBAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;kDAClC,gBAAI,oBAAJ,gBAAI;sDAAA;AAEd;IAAC,IAAA,oBAAU,EAAC,CAAC,CAAwB,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;;wDAClC;AAhCP,qBAAqB;IARjC,IAAA,gBAAM,EAAC,2BAA2B,CAAC;IACnC,IAAA,eAAK,EAAC,gCAAgC,EAAE,CAAC,CAAwB,EAAE,EAAE,CAAC;QACrE,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,aAAa;QACf,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,SAAS;KACZ,CAAC;IACD,IAAA,eAAK,EAAC,gCAAgC,EAAE,CAAC,CAAwB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;GAC3F,qBAAqB,CAiCjC;AAjCY,sDAAqB"}
@@ -34,6 +34,7 @@ const Reports = __importStar(require("./reports"));
34
34
  const InventoryComparison = __importStar(require("./inventory-comparison"));
35
35
  const ShippingProviders = __importStar(require("./shipping-provider"));
36
36
  const WarehouseInventoryAdjustment = __importStar(require("./warehouse-inventory-adjustment"));
37
+ const RouteLabel = __importStar(require("./route-label"));
37
38
  const ZoneWorksheet = __importStar(require("./zone-worksheet"));
38
39
  const Outbound = __importStar(require("./outbound"));
39
40
  exports.queries = [
@@ -46,12 +47,14 @@ exports.queries = [
46
47
  Other.Query,
47
48
  Reports.Query,
48
49
  ShippingProviders.Query,
50
+ RouteLabel.Query,
49
51
  ZoneWorksheet.Query,
50
52
  Outbound.Query
51
53
  ];
52
54
  exports.mutations = [
53
55
  Other.Mutation,
54
56
  WarehouseInventoryAdjustment.Mutation,
57
+ RouteLabel.Mutation,
55
58
  ZoneWorksheet.Mutation,
56
59
  Outbound.Mutation
57
60
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/graphql/resolvers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8DAA+C;AAC/C,4DAA6C;AAC7C,8DAA+C;AAC/C,uDAAwC;AACxC,+CAAgC;AAChC,oDAAqC;AACrC,mDAAoC;AACpC,4EAA6D;AAC7D,uEAAwD;AACxD,+FAAgF;AAChF,gEAAiD;AACjD,qDAAsC;AAEzB,QAAA,OAAO,GAAG;IACrB,YAAY,CAAC,KAAK;IAClB,WAAW,CAAC,KAAK;IACjB,YAAY,CAAC,KAAK;IAClB,SAAS,CAAC,KAAK;IACf,mBAAmB,CAAC,KAAK;IACzB,OAAO,CAAC,KAAK;IACb,KAAK,CAAC,KAAK;IACX,OAAO,CAAC,KAAK;IACb,iBAAiB,CAAC,KAAK;IACvB,aAAa,CAAC,KAAK;IACnB,QAAQ,CAAC,KAAK;CACf,CAAA;AAEY,QAAA,SAAS,GAAG;IACvB,KAAK,CAAC,QAAQ;IACd,4BAA4B,CAAC,QAAQ;IACrC,aAAa,CAAC,QAAQ;IACtB,QAAQ,CAAC,QAAQ;CAClB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/graphql/resolvers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8DAA+C;AAC/C,4DAA6C;AAC7C,8DAA+C;AAC/C,uDAAwC;AACxC,+CAAgC;AAChC,oDAAqC;AACrC,mDAAoC;AACpC,4EAA6D;AAC7D,uEAAwD;AACxD,+FAAgF;AAChF,0DAA2C;AAC3C,gEAAiD;AACjD,qDAAsC;AAEzB,QAAA,OAAO,GAAG;IACrB,YAAY,CAAC,KAAK;IAClB,WAAW,CAAC,KAAK;IACjB,YAAY,CAAC,KAAK;IAClB,SAAS,CAAC,KAAK;IACf,mBAAmB,CAAC,KAAK;IACzB,OAAO,CAAC,KAAK;IACb,KAAK,CAAC,KAAK;IACX,OAAO,CAAC,KAAK;IACb,iBAAiB,CAAC,KAAK;IACvB,UAAU,CAAC,KAAK;IAChB,aAAa,CAAC,KAAK;IACnB,QAAQ,CAAC,KAAK;CACf,CAAA;AAEY,QAAA,SAAS,GAAG;IACvB,KAAK,CAAC,QAAQ;IACd,4BAA4B,CAAC,QAAQ;IACrC,UAAU,CAAC,QAAQ;IACnB,aAAa,CAAC,QAAQ;IACtB,QAAQ,CAAC,QAAQ;CAClB,CAAA"}