@things-factory/operato-wms 3.7.15 → 3.8.0

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 (83) hide show
  1. package/client/pages/adjustment/transfer-inventory.js +364 -158
  2. package/client/pages/bulk-operation/bulk-operation.js +316 -0
  3. package/client/pages/bulk-operation/validate-ro-popup.js +445 -0
  4. package/client/pages/components/select-product-popup.js +1 -1
  5. package/client/pages/constants/inventory.js +1 -0
  6. package/client/pages/constants/location.js +33 -6
  7. package/client/pages/constants/worksheet.js +2 -2
  8. package/client/pages/inbound/inbound-worksheet.js +81 -15
  9. package/client/pages/inbound/putaway-product.js +60 -8
  10. package/client/pages/inbound/putaway-worksheet-generate-popup.js +29 -5
  11. package/client/pages/inbound/unload-product.js +80 -19
  12. package/client/pages/inbound/worksheet-putaway-return.js +14 -5
  13. package/client/pages/inbound/worksheet-putaway.js +13 -8
  14. package/client/pages/inbound/worksheet-unloading-return.js +14 -5
  15. package/client/pages/inventory/inventory-adjustment-approval.js +18 -8
  16. package/client/pages/inventory/inventory-adjustment.js +81 -76
  17. package/client/pages/inventory/inventory-by-product-detail.js +1 -1
  18. package/client/pages/inventory/inventory-by-product.js +1 -1
  19. package/client/pages/inventory/inventory-history-by-pallet.js +1 -1
  20. package/client/pages/inventory/inventory-history.js +2 -2
  21. package/client/pages/inventory/onhand-inventory.js +1 -2
  22. package/client/pages/inventory-check/create-cycle-count.js +1 -6
  23. package/client/pages/master/location-list.js +58 -17
  24. package/client/pages/order/arrival-notice/arrival-notice-detail.js +15 -8
  25. package/client/pages/order/arrival-notice/arrival-notice-list.js +87 -6
  26. package/client/pages/order/arrival-notice/arrival-notice-requests.js +83 -6
  27. package/client/pages/order/arrival-notice/create-arrival-notice.js +23 -2
  28. package/client/pages/order/arrival-notice/duplicate-arrival-notice.js +290 -25
  29. package/client/pages/order/arrival-notice/edit-product-popup.js +36 -5
  30. package/client/pages/order/release-order/b2b/b2b-order-requests.js +7 -7
  31. package/client/pages/order/release-order/b2c/b2c-order-requests.js +65 -5
  32. package/client/pages/order/release-order/release-extra-product-popup.js +12 -4
  33. package/client/pages/order/release-order/release-order-detail.js +1 -1
  34. package/client/pages/order/return-order/create-return-order.js +1 -1
  35. package/client/pages/order/return-order/return-order-detail.js +6 -5
  36. package/client/pages/order/transport-order/delivery-order-list.js +4 -1
  37. package/client/pages/outbound/inventory-assign-popup.js +1 -1
  38. package/client/pages/outbound/merged-outbound-worksheet.js +9 -5
  39. package/client/pages/outbound/picking-product.js +202 -162
  40. package/client/pages/outbound/picking-replacement-popup.js +2 -2
  41. package/client/pages/outbound/single-outbound-worksheet.js +47 -1
  42. package/client/pages/outbound/worksheet-loading.js +14 -5
  43. package/client/pages/outbound/worksheet-picking.js +10 -5
  44. package/client/pages/report/custom-elccl/elccl-inventory-report.js +31 -30
  45. package/client/pages/report/custom-elccl/elccl-inventory-summary-report.js +23 -26
  46. package/client/pages/report/inventory-pallet-storage-report.js +11 -10
  47. package/client/pages/report/inventory-report.js +41 -43
  48. package/client/pages/report/inventory-summary-report.js +25 -28
  49. package/client/route.js +5 -0
  50. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-report.js +1 -1
  51. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-report.js.map +1 -1
  52. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js +1 -1
  53. package/dist-server/graphql/resolvers/index.js +3 -1
  54. package/dist-server/graphql/resolvers/index.js.map +1 -1
  55. package/dist-server/graphql/resolvers/shipping-provider/index.js +6 -0
  56. package/dist-server/graphql/resolvers/shipping-provider/index.js.map +1 -0
  57. package/dist-server/graphql/resolvers/shipping-provider/shipping-providers.js +20 -0
  58. package/dist-server/graphql/resolvers/shipping-provider/shipping-providers.js.map +1 -0
  59. package/dist-server/graphql/types/custom/elccl/elccl-inventory-report.js +1 -1
  60. package/dist-server/graphql/types/index.js +5 -2
  61. package/dist-server/graphql/types/index.js.map +1 -1
  62. package/dist-server/graphql/types/shipping-provider/index.js +10 -0
  63. package/dist-server/graphql/types/shipping-provider/index.js.map +1 -0
  64. package/dist-server/graphql/types/shipping-provider/shipping-provider-list.js +13 -0
  65. package/dist-server/graphql/types/shipping-provider/shipping-provider-list.js.map +1 -0
  66. package/dist-server/graphql/types/shipping-provider/shipping-provider.js +13 -0
  67. package/dist-server/graphql/types/shipping-provider/shipping-provider.js.map +1 -0
  68. package/package.json +37 -37
  69. package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-report.ts +4 -2
  70. package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.ts +1 -1
  71. package/server/graphql/resolvers/index.ts +3 -1
  72. package/server/graphql/resolvers/shipping-provider/index.ts +5 -0
  73. package/server/graphql/resolvers/shipping-provider/shipping-providers.ts +20 -0
  74. package/server/graphql/types/custom/elccl/elccl-inventory-report.ts +1 -1
  75. package/server/graphql/types/index.ts +5 -2
  76. package/server/graphql/types/shipping-provider/index.ts +8 -0
  77. package/server/graphql/types/shipping-provider/shipping-provider-list.ts +7 -0
  78. package/server/graphql/types/shipping-provider/shipping-provider.ts +7 -0
  79. package/things-factory.config.js +6 -0
  80. package/translations/en.json +27 -0
  81. package/translations/ko.json +84 -36
  82. package/translations/ms.json +85 -37
  83. package/translations/zh.json +98 -51
@@ -8,7 +8,7 @@ import { getCodeByName } from '@things-factory/code-base'
8
8
  import { i18next, localize } from '@things-factory/i18n-base'
9
9
  import { client, navigate, PageView } from '@things-factory/shell'
10
10
  import { ScrollbarStyles } from '@things-factory/styles'
11
- import { gqlBuilder, isMobileDevice } from '@things-factory/utils'
11
+ import { isMobileDevice } from '@things-factory/utils'
12
12
 
13
13
  import { WORKSHEET_TYPE } from '../constants'
14
14
 
@@ -181,13 +181,24 @@ class InboundWorksheet extends localize(i18next)(PageView) {
181
181
 
182
182
  this.config = {
183
183
  list: {
184
- fields: ['arrivalNotice', 'bizplace', 'type', 'arrivalRefNo', 'status', 'startedAt', 'endedAt']
184
+ fields: [
185
+ 'arrivalNotice',
186
+ 'bizplace',
187
+ 'type',
188
+ 'arrivalRefNo',
189
+ 'status',
190
+ 'createdAt',
191
+ 'startedAt',
192
+ 'endedAt',
193
+ 'updater',
194
+ 'updatedAt'
195
+ ]
185
196
  },
186
- rows: { appendable: false },
197
+ rows: { appendable: false, selectable: { multiple: true } },
187
198
  pagination: { limit: 100, pages: [20, 50, 100, 200, 500] },
188
199
  columns: [
189
- { type: 'gutter', gutterName: 'dirty' },
190
200
  { type: 'gutter', gutterName: 'sequence' },
201
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
191
202
  {
192
203
  type: 'gutter',
193
204
  gutterName: 'button',
@@ -215,6 +226,7 @@ class InboundWorksheet extends localize(i18next)(PageView) {
215
226
  type: 'object',
216
227
  name: 'arrivalNotice',
217
228
  header: i18next.t('field.arrival_notice'),
229
+ label: true,
218
230
  sortable: true,
219
231
  width: 160
220
232
  },
@@ -222,6 +234,7 @@ class InboundWorksheet extends localize(i18next)(PageView) {
222
234
  type: 'string',
223
235
  name: 'arrivalRefNo',
224
236
  header: i18next.t('field.ref_no'),
237
+ label: true,
225
238
  sortable: true,
226
239
  width: 120
227
240
  },
@@ -229,12 +242,14 @@ class InboundWorksheet extends localize(i18next)(PageView) {
229
242
  type: 'boolean',
230
243
  name: 'crossDocking',
231
244
  header: i18next.t('field.cross_docking'),
245
+ label: true,
232
246
  width: 100
233
247
  },
234
248
  {
235
249
  type: 'object',
236
250
  name: 'bizplace',
237
251
  header: i18next.t('field.company'),
252
+ label: true,
238
253
  sortable: true,
239
254
  width: 200
240
255
  },
@@ -242,6 +257,7 @@ class InboundWorksheet extends localize(i18next)(PageView) {
242
257
  type: 'string',
243
258
  name: 'type',
244
259
  header: i18next.t('field.type'),
260
+ label: true,
245
261
  sortable: true,
246
262
  width: 120
247
263
  },
@@ -249,6 +265,7 @@ class InboundWorksheet extends localize(i18next)(PageView) {
249
265
  type: 'string',
250
266
  name: 'status',
251
267
  header: i18next.t('field.status'),
268
+ label: true,
252
269
  sortable: true,
253
270
  width: 120
254
271
  },
@@ -256,6 +273,7 @@ class InboundWorksheet extends localize(i18next)(PageView) {
256
273
  type: 'datetime',
257
274
  name: 'createdAt',
258
275
  header: i18next.t('field.created_at'),
276
+ label: true,
259
277
  sortable: true,
260
278
  width: 160
261
279
  },
@@ -263,6 +281,7 @@ class InboundWorksheet extends localize(i18next)(PageView) {
263
281
  type: 'datetime',
264
282
  name: 'startedAt',
265
283
  header: i18next.t('field.started_at'),
284
+ label: true,
266
285
  sortable: true,
267
286
  width: 160
268
287
  },
@@ -270,6 +289,7 @@ class InboundWorksheet extends localize(i18next)(PageView) {
270
289
  type: 'datetime',
271
290
  name: 'endedAt',
272
291
  header: i18next.t('field.ended_at'),
292
+ label: true,
273
293
  sortable: true,
274
294
  width: 160
275
295
  },
@@ -277,6 +297,7 @@ class InboundWorksheet extends localize(i18next)(PageView) {
277
297
  type: 'object',
278
298
  name: 'updater',
279
299
  header: i18next.t('field.updater'),
300
+ label: true,
280
301
  sortable: true,
281
302
  width: 150
282
303
  },
@@ -284,6 +305,7 @@ class InboundWorksheet extends localize(i18next)(PageView) {
284
305
  type: 'datetime',
285
306
  name: 'updatedAt',
286
307
  header: i18next.t('field.updated_at'),
308
+ label: true,
287
309
  sortable: true,
288
310
  width: 200
289
311
  }
@@ -311,12 +333,8 @@ class InboundWorksheet extends localize(i18next)(PageView) {
311
333
 
312
334
  const response = await client.query({
313
335
  query: gql`
314
- query {
315
- worksheets(${gqlBuilder.buildArgs({
316
- filters,
317
- pagination: { page, limit },
318
- sortings: sorters
319
- })}) {
336
+ query worksheets($filters: [Filter!]!, $pagination: Pagination, $sortings: [Sorting!]!) {
337
+ worksheets(filters: $filters, pagination: $pagination, sortings: $sortings) {
320
338
  items {
321
339
  id
322
340
  name
@@ -346,7 +364,8 @@ class InboundWorksheet extends localize(i18next)(PageView) {
346
364
  total
347
365
  }
348
366
  }
349
- `
367
+ `,
368
+ variables: { filters, pagination: { page, limit }, sortings: sorters }
350
369
  })
351
370
 
352
371
  if (!response.errors) {
@@ -419,12 +438,59 @@ class InboundWorksheet extends localize(i18next)(PageView) {
419
438
  }
420
439
  }
421
440
 
422
- get _columns() {
423
- return this.config.columns
441
+ async _exportableData() {
442
+ try {
443
+ let data = []
444
+
445
+ var headerSetting = [
446
+ { header: i18next.t('field.order_no'), key: 'orderNo', width: 25, type: 'string' },
447
+ { header: i18next.t('field.company'), key: 'bizplaceName', width: 25, type: 'string' },
448
+ { header: i18next.t('field.ref_no'), key: 'arrivalRefNo', width: 25, type: 'string' },
449
+ { header: i18next.t('field.cross_docking'), key: 'crossDocking', width: 30, type: 'string' },
450
+ { header: i18next.t('field.type'), key: 'type', width: 25, type: 'string' },
451
+ { header: i18next.t('field.status'), key: 'status', width: 25, type: 'string' },
452
+ { header: i18next.t('field.created_at'), key: 'createdAt', width: 30, type: 'date' },
453
+ { header: i18next.t('field.started_at'), key: 'startedAt', width: 30, type: 'date' },
454
+ { header: i18next.t('field.ended_at'), key: 'endedAt', width: 30, type: 'date' },
455
+ { header: i18next.t('field.updated_at'), key: 'updatedAt', width: 30, type: 'date' },
456
+ { header: i18next.t('field.updater'), key: 'updaterName', width: 25, type: 'string' }
457
+ ]
458
+
459
+ if (this.dataGrist.selected && this.dataGrist.selected.length > 0) {
460
+ data = this.dataGrist.selected.map(record => {
461
+ return {
462
+ ...record,
463
+ orderNo: record.arrivalNotice?.name,
464
+ bizplaceName: record.bizplace?.name,
465
+ updaterName: record.updater?.name
466
+ }
467
+ })
468
+ } else {
469
+ data = (await this.fetchHandler({ page: 1, limit: 9999999 })).records.map(record => {
470
+ return {
471
+ ...record,
472
+ orderNo: record.arrivalNotice?.name,
473
+ bizplaceName: record.bizplace?.name,
474
+ updaterName: record.updater?.name
475
+ }
476
+ })
477
+ }
478
+
479
+ return { header: headerSetting, data }
480
+ } catch (e) {
481
+ this._showToast(e)
482
+ }
424
483
  }
425
484
 
426
- _exportableData() {
427
- return this.dataGrist.exportRecords()
485
+ _showToast({ type, message }) {
486
+ document.dispatchEvent(
487
+ new CustomEvent('notify', {
488
+ detail: {
489
+ type,
490
+ message
491
+ }
492
+ })
493
+ )
428
494
  }
429
495
  }
430
496
 
@@ -39,7 +39,10 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
39
39
  incompleteLocationName: Boolean,
40
40
  locations: Array,
41
41
  recommendLocationName: String,
42
- _scanning: Boolean
42
+ _scanning: Boolean,
43
+ _expirationPeriod: Number,
44
+ _expirationDate: Number,
45
+ _locationType: String
43
46
  }
44
47
  }
45
48
 
@@ -330,6 +333,9 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
330
333
  this.recommendLocationName = null
331
334
  this._operationType = OPERATION_TYPE.PUTAWAY
332
335
  this._scanning = false
336
+ this._expirationPeriod = 0
337
+ this._expirationDate = 0
338
+ this._locationType = ''
333
339
  }
334
340
 
335
341
  get completed() {
@@ -498,6 +504,7 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
498
504
  sku
499
505
  name
500
506
  description
507
+ expirationPeriod
501
508
  }
502
509
  qty
503
510
  status
@@ -537,7 +544,9 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
537
544
  ...record,
538
545
  completed: record.status === WORKSHEET_STATUS.DONE.value,
539
546
  packingTypeSize: `${record.packingType}(${record.packingSize})`,
540
- reusablePalletName: reusablePalletName
547
+ reusablePalletName: reusablePalletName,
548
+ expirationPeriod: record.product.expirationPeriod,
549
+ expirationDate: record.expirationDate
541
550
  }
542
551
  })
543
552
  .sort((a, b) => {
@@ -583,6 +592,7 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
583
592
  name
584
593
  description
585
594
  sku
595
+ expirationPeriod
586
596
  }
587
597
  qty
588
598
  status
@@ -621,7 +631,9 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
621
631
  ...record,
622
632
  completed: record.status === WORKSHEET_STATUS.DONE.value,
623
633
  packingTypeSize: `${record.packingType}(${record.packingSize})`,
624
- reusablePalletName: reusablePalletName
634
+ reusablePalletName: reusablePalletName,
635
+ expirationPeriod: record.product.expirationPeriod,
636
+ expirationDate: record.expirationDate
625
637
  }
626
638
  })
627
639
  .sort((a, b) => {
@@ -786,8 +798,20 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
786
798
  await this._validatePutaway()
787
799
  if (!this.incompleteLocationName) {
788
800
  let worksheetDetailNames = []
789
- if (this._enableCartonLabel) worksheetDetailNames = this._getSelectedOrderProducts(this.cartonInput.value)
790
- else worksheetDetailNames.push(this._selectedOrderProduct.name)
801
+ const locationDetails = await this._fetchLocation(this.locationInput.value.trim())
802
+
803
+ if (this._enableCartonLabel) {
804
+ let worksheetDetail = this._getSelectedOrderProducts(this.cartonInput.value)
805
+ worksheetDetailNames.push(worksheetDetail[0].name)
806
+ if (worksheetDetail[0].expirationPeriod > 0 && locationDetails.type !== 'QUARANTINE') {
807
+ await this._expiryAlert()
808
+ }
809
+ } else {
810
+ worksheetDetailNames.push(this._selectedOrderProduct.name)
811
+ if (this._selectedOrderProduct.expirationPeriod > 0 && locationDetails.type !== 'QUARANTINE') {
812
+ await this._expiryAlert()
813
+ }
814
+ }
791
815
 
792
816
  const response = await client.mutate({
793
817
  mutation: gql`
@@ -847,8 +871,20 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
847
871
  await this._validatePutaway()
848
872
  if (!this.incompleteLocationName) {
849
873
  let worksheetDetailNames = []
850
- if (this._enableCartonLabel) worksheetDetailNames = this._getSelectedOrderProducts(this.cartonInput.value)
851
- else worksheetDetailNames.push(this._selectedOrderProduct.name)
874
+ const locationDetails = await this._fetchLocation(this.locationInput.value.trim())
875
+
876
+ if (this._enableCartonLabel) {
877
+ worksheetDetailNames.push(worksheetDetail[0].name)
878
+ let worksheetDetail = this._getSelectedOrderProducts(this.cartonInput.value)
879
+ if (worksheetDetail[0].expirationPeriod > 0 && locationDetails.type !== 'QUARANTINE') {
880
+ await this._expiryAlert()
881
+ }
882
+ } else {
883
+ worksheetDetailNames.push(this._selectedOrderProduct.name)
884
+ if (this._selectedOrderProduct.expirationPeriod > 0 && locationDetails.type !== 'QUARANTINE') {
885
+ await this._expiryAlert()
886
+ }
887
+ }
852
888
 
853
889
  const response = await client.mutate({
854
890
  mutation: gql`
@@ -995,8 +1031,23 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
995
1031
  }
996
1032
  }
997
1033
 
1034
+ async _expiryAlert() {
1035
+ await CustomAlert({
1036
+ title: i18next.t('title.location_scanned_is_not_a_quarantine_zone'),
1037
+ confirmButton: { text: i18next.t('button.confirm') }
1038
+ })
1039
+ }
1040
+
998
1041
  _getSelectedOrderProducts(scannedCartonId) {
999
- return this.data.records.filter(record => record.cartonId === scannedCartonId).map(record => record.name)
1042
+ return this.data.records
1043
+ .filter(record => record.cartonId === scannedCartonId)
1044
+ .map(record => {
1045
+ return {
1046
+ name: record.name,
1047
+ expirationDate: record.expirationDate,
1048
+ expirationPeriod: record.product.expirationPeriod
1049
+ }
1050
+ })
1000
1051
  }
1001
1052
 
1002
1053
  async _validatePutaway() {
@@ -1136,6 +1187,7 @@ class PutawayProduct extends connect(store)(localize(i18next)(PageView)) {
1136
1187
  row
1137
1188
  column
1138
1189
  shelf
1190
+ type
1139
1191
  }
1140
1192
  }
1141
1193
  `,
@@ -1,8 +1,10 @@
1
- import { i18next, localize } from '@things-factory/i18n-base'
2
- import { client, CustomAlert } from '@things-factory/shell'
3
- import { gqlBuilder, isMobileDevice } from '@things-factory/utils'
4
1
  import gql from 'graphql-tag'
5
2
  import { css, html, LitElement } from 'lit-element'
3
+
4
+ import { i18next, localize } from '@things-factory/i18n-base'
5
+ import { client, CustomAlert } from '@things-factory/shell'
6
+ import { isMobileDevice } from '@things-factory/utils'
7
+
6
8
  import { INVENTORY_STATUS, ORDER_INVENTORY_STATUS } from '../constants'
7
9
 
8
10
  class PutawayWorksheetGeneratePopup extends localize(i18next)(LitElement) {
@@ -165,7 +167,18 @@ class PutawayWorksheetGeneratePopup extends localize(i18next)(LitElement) {
165
167
 
166
168
  this.inventoryGristConfig = {
167
169
  list: {
168
- fields: ['batchId', 'product', 'packingType', 'palletId', 'cartonId', 'qty', 'uomValue', 'uom', 'updatedAt']
170
+ fields: [
171
+ 'batchId',
172
+ 'product',
173
+ 'packingType',
174
+ 'packingSize',
175
+ 'palletId',
176
+ 'cartonId',
177
+ 'qty',
178
+ 'uomValue',
179
+ 'uom',
180
+ 'updatedAt'
181
+ ]
169
182
  },
170
183
  pagination: { infinite: true },
171
184
  rows: { selectable: { multiple: true }, appendable: false },
@@ -176,6 +189,7 @@ class PutawayWorksheetGeneratePopup extends localize(i18next)(LitElement) {
176
189
  type: 'string',
177
190
  name: 'batchId',
178
191
  header: i18next.t('field.batch_id'),
192
+ label: true,
179
193
  sortable: true,
180
194
  width: 150
181
195
  },
@@ -183,6 +197,7 @@ class PutawayWorksheetGeneratePopup extends localize(i18next)(LitElement) {
183
197
  type: 'object',
184
198
  name: 'product',
185
199
  header: i18next.t('field.product'),
200
+ label: true,
186
201
  sortable: true,
187
202
  width: 200
188
203
  },
@@ -190,6 +205,7 @@ class PutawayWorksheetGeneratePopup extends localize(i18next)(LitElement) {
190
205
  type: 'string',
191
206
  name: 'packingType',
192
207
  header: i18next.t('field.packing_type'),
208
+ label: true,
193
209
  sortable: true,
194
210
  width: 200
195
211
  },
@@ -197,6 +213,7 @@ class PutawayWorksheetGeneratePopup extends localize(i18next)(LitElement) {
197
213
  type: 'number',
198
214
  name: 'packingSize',
199
215
  header: i18next.t('field.packing_size'),
216
+ label: true,
200
217
  sortable: true,
201
218
  width: 100
202
219
  },
@@ -204,36 +221,42 @@ class PutawayWorksheetGeneratePopup extends localize(i18next)(LitElement) {
204
221
  type: 'string',
205
222
  name: 'palletId',
206
223
  header: i18next.t('field.lot_id'),
224
+ label: true,
207
225
  width: 150
208
226
  },
209
227
  {
210
228
  type: 'string',
211
229
  name: 'cartonId',
212
230
  header: i18next.t('field.carton_id'),
231
+ label: true,
213
232
  width: 150
214
233
  },
215
234
  {
216
235
  type: 'number',
217
236
  name: 'qty',
218
237
  header: i18next.t('field.qty'),
238
+ label: true,
219
239
  width: 80
220
240
  },
221
241
  {
222
242
  type: 'number',
223
243
  name: 'uomValue',
224
244
  header: i18next.t('field.uom_value'),
245
+ label: true,
225
246
  width: 80
226
247
  },
227
248
  {
228
249
  type: 'string',
229
250
  name: 'uom',
230
251
  header: i18next.t('field.uom'),
252
+ label: true,
231
253
  width: 80
232
254
  },
233
255
  {
234
256
  type: 'datetime',
235
257
  name: 'updatedAt',
236
258
  header: i18next.t('field.updated_at'),
259
+ label: true,
237
260
  sortable: true,
238
261
  width: 150
239
262
  },
@@ -241,6 +264,7 @@ class PutawayWorksheetGeneratePopup extends localize(i18next)(LitElement) {
241
264
  type: 'object',
242
265
  name: 'updater',
243
266
  header: i18next.t('field.updater'),
267
+ label: true,
244
268
  width: 150
245
269
  }
246
270
  ]
@@ -269,7 +293,7 @@ class PutawayWorksheetGeneratePopup extends localize(i18next)(LitElement) {
269
293
  try {
270
294
  const response = await client.query({
271
295
  query: gql`
272
- query inventories($filters: [Filter]) {
296
+ query inventories($filters: [Filter!]!) {
273
297
  inventories(filters: $filters) {
274
298
  items {
275
299
  id
@@ -35,6 +35,7 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
35
35
  _enableCartonLabel: Boolean,
36
36
  _enableInputQty: Boolean,
37
37
  _isRequiredCheckExpiry: Boolean,
38
+ _expirationPeriod: Number,
38
39
  customerCompanyDomainId: String,
39
40
  orderProductConfig: Object,
40
41
  orderProductData: Object,
@@ -161,8 +162,7 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
161
162
  })
162
163
  }
163
164
 
164
- if (this.orderProductData && this.orderProductData.records.length
165
- && this.completable) {
165
+ if (this.orderProductData && this.orderProductData.records.length && this.completable) {
166
166
  actions.push({
167
167
  title: i18next.t('button.complete'),
168
168
  action: this._complete.bind(this),
@@ -219,7 +219,7 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
219
219
  get productBarcodeInput() {
220
220
  return this.shadowRoot
221
221
  .querySelector('barcode-scanable-input[name=productBarcode]')
222
- .shadowRoot.querySelector('input')
222
+ ?.shadowRoot?.querySelector('input')
223
223
  }
224
224
 
225
225
  get actualQtyInput() {
@@ -403,6 +403,7 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
403
403
  this._isQtyChecked = false
404
404
  this._enableProductScanning = false
405
405
  this._isRequiredCheckExpiry = false
406
+ this._expirationPeriod = 0
406
407
  this._orderNo = ''
407
408
  this._productName = ''
408
409
  this._productSku = ''
@@ -950,7 +951,6 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
950
951
  if (this._enableInputQty) {
951
952
  this.actualQtyInput.value = ''
952
953
  this.cartonInput.value = ''
953
- this._isRequiredCheckExpiry = false
954
954
  this._focusOnCartonInput()
955
955
  }
956
956
  } else {
@@ -1020,9 +1020,21 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
1020
1020
  }
1021
1021
 
1022
1022
  async _scanProductUnload() {
1023
- if (this._scanning === false){
1023
+ if (this._scanning === false) {
1024
1024
  this._scanning = true
1025
1025
  try {
1026
+ if (this._isRequiredCheckExpiry && this._expirationPeriod > 0) {
1027
+ let date = new Date()
1028
+ const acceptBefore = new Date(date.setDate(date.getDate() + this._expirationPeriod))
1029
+ let expiryDate = new Date(this.expDateInput.value)
1030
+ if (expiryDate < acceptBefore) {
1031
+ await CustomAlert({
1032
+ title: i18next.t('title.item_unloading_is_expiring_soon'),
1033
+ confirmButton: { text: i18next.t('button.confirm') }
1034
+ })
1035
+ }
1036
+ }
1037
+
1026
1038
  const response = await client.mutate({
1027
1039
  mutation: gql`
1028
1040
  mutation scanProductUnload(
@@ -1056,15 +1068,27 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
1056
1068
  }
1057
1069
 
1058
1070
  this._scanning = false
1059
- }else {
1071
+ } else {
1060
1072
  this._showToast({ message: i18next.t('text.previous_scan_is_executing') })
1061
1073
  }
1062
1074
  }
1063
1075
 
1064
1076
  async _qtyUnload() {
1065
- if (this._scanning === false){
1077
+ if (this._scanning === false) {
1066
1078
  this._scanning = true
1067
1079
  try {
1080
+ if (this._isRequiredCheckExpiry && this._expirationPeriod > 0) {
1081
+ let date = new Date()
1082
+ const acceptBefore = new Date(date.setDate(date.getDate() + this._expirationPeriod))
1083
+ let expiryDate = new Date(this.expDateInput.value)
1084
+ if (expiryDate < acceptBefore) {
1085
+ await CustomAlert({
1086
+ title: i18next.t('title.item_unloading_is_expiring_soon'),
1087
+ confirmButton: { text: i18next.t('button.confirm') }
1088
+ })
1089
+ }
1090
+ }
1091
+
1068
1092
  const response = await client.mutate({
1069
1093
  mutation: gql`
1070
1094
  mutation unload($worksheetDetailName: String!, $inventory: InventoryPatch!, $productBarcode: String) {
@@ -1090,8 +1114,40 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
1090
1114
  }
1091
1115
 
1092
1116
  this._scanning = false
1093
- }else {
1094
- this._showToast({ message: i18next.t('text.previous_scan_is_executing')})
1117
+ } else {
1118
+ this._showToast({ message: i18next.t('text.previous_scan_is_executing') })
1119
+ }
1120
+ }
1121
+
1122
+ //need to enhance
1123
+ async _checkedLotScannedProduct() {
1124
+ const response = await client.query({
1125
+ query: gql`
1126
+ query productDetail($gtin: String!, $productId: String!, $customerCompanyDomainId: String!) {
1127
+ productDetail(gtin: $gtin, productId: $productId, customerCompanyDomainId: $customerCompanyDomainId) {
1128
+ id
1129
+ name
1130
+ packingType
1131
+ packingSize
1132
+ gtin
1133
+ product {
1134
+ id
1135
+ name
1136
+ sku
1137
+ isRequiredCheckExpiry
1138
+ expirationPeriod
1139
+ }
1140
+ }
1141
+ }
1142
+ `,
1143
+ variables: {
1144
+ gtin: '',
1145
+ productId: this._selectedOrderProduct.product.id,
1146
+ customerCompanyDomainId: this.customerCompanyDomainId
1147
+ }
1148
+ })
1149
+ if (!response.errors) {
1150
+ this._expirationPeriod = response.data.productDetail.product.expirationPeriod
1095
1151
  }
1096
1152
  }
1097
1153
 
@@ -1099,8 +1155,8 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
1099
1155
  try {
1100
1156
  const response = await client.query({
1101
1157
  query: gql`
1102
- query productDetail($gtin: String!, $customerCompanyDomainId: String!) {
1103
- productDetail(gtin: $gtin, customerCompanyDomainId: $customerCompanyDomainId) {
1158
+ query productDetail($gtin: String!, $productId: String!, $customerCompanyDomainId: String!) {
1159
+ productDetail(gtin: $gtin, productId: $productId, customerCompanyDomainId: $customerCompanyDomainId) {
1104
1160
  id
1105
1161
  name
1106
1162
  packingType
@@ -1111,23 +1167,27 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
1111
1167
  name
1112
1168
  sku
1113
1169
  isRequiredCheckExpiry
1170
+ expirationPeriod
1114
1171
  }
1115
1172
  }
1116
1173
  }
1117
1174
  `,
1118
- variables: { gtin: this.productBarcodeInput.value, customerCompanyDomainId: this.customerCompanyDomainId }
1175
+ variables: {
1176
+ gtin: this.productBarcodeInput?.value || '',
1177
+ productId: '',
1178
+ customerCompanyDomainId: this.customerCompanyDomainId
1179
+ }
1119
1180
  })
1120
1181
  if (!response.errors) {
1121
1182
  const { product, packingSize, packingType, id } = response.data.productDetail
1122
1183
  const foundOrderProducts = this.orderProductData.records.filter(
1123
1184
  orderProduct =>
1124
- orderProduct.product.id === product.id &&
1125
- orderProduct.packingType === packingType &&
1126
- orderProduct.packingSize === packingSize
1185
+ orderProduct.product.id === product.id &&
1186
+ orderProduct.packingType === packingType &&
1187
+ orderProduct.packingSize === packingSize
1127
1188
  )
1128
1189
  const foundParentProducts = this.orderProductData.records.filter(
1129
- orderProduct =>
1130
- orderProduct.product.id === product.id
1190
+ orderProduct => orderProduct.product.id === product.id
1131
1191
  )
1132
1192
 
1133
1193
  if (!foundOrderProducts?.length) {
@@ -1140,6 +1200,7 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
1140
1200
  throw new Error(i18next.t('text.no_matching_product_found'))
1141
1201
  }
1142
1202
  }
1203
+ this._expirationPeriod = product.expirationPeriod
1143
1204
  this._isRequiredCheckExpiry = product.isRequiredCheckExpiry
1144
1205
 
1145
1206
  if (this._selectedOrderProduct && this._selectedOrderProduct.product.sku !== product.sku)
@@ -1154,8 +1215,7 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
1154
1215
  this._selectedOrderProduct.product.description ? `(${this._selectedOrderProduct.product.description})` : ''
1155
1216
  }`
1156
1217
  this._fillUpForm(this.inputForm, this._selectedOrderProduct)
1157
-
1158
- } else if (foundOrderProducts?.length == 0 && foundParentProducts?.length == 1 && !this._selectedOrderProduct){
1218
+ } else if (foundOrderProducts?.length == 0 && foundParentProducts?.length == 1 && !this._selectedOrderProduct) {
1159
1219
  this._selectedOrderProduct = foundParentProducts[0]
1160
1220
 
1161
1221
  this._productName = `(${this._selectedOrderProduct.product.sku})${this._selectedOrderProduct.product.name} ${
@@ -1659,6 +1719,7 @@ class UnloadProduct extends connect(store)(localize(i18next)(PageView)) {
1659
1719
  this._openPopupUnloading(this.palletInput.value, this.orderProductData, this.palletProductData)
1660
1720
  } else {
1661
1721
  await this._validateUnloading()
1722
+ await this._checkedLotScannedProduct()
1662
1723
  this._qtyUnload()
1663
1724
  }
1664
1725
  }