@things-factory/operato-wms 3.7.12 → 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 (98) 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 +10 -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 +22 -5
  13. package/client/pages/inbound/worksheet-putaway.js +21 -8
  14. package/client/pages/inbound/worksheet-unloading-return.js +22 -5
  15. package/client/pages/inbound/worksheet-unloading.js +8 -0
  16. package/client/pages/inventory/inventory-adjustment-approval.js +18 -8
  17. package/client/pages/inventory/inventory-adjustment.js +91 -76
  18. package/client/pages/inventory/inventory-by-product-detail.js +1 -1
  19. package/client/pages/inventory/inventory-by-product.js +9 -1
  20. package/client/pages/inventory/inventory-history-by-pallet.js +10 -1
  21. package/client/pages/inventory/inventory-history.js +12 -2
  22. package/client/pages/inventory/onhand-inventory.js +12 -3
  23. package/client/pages/inventory-check/create-cycle-count.js +12 -6
  24. package/client/pages/inventory-check/cycle-count-report.js +8 -0
  25. package/client/pages/inventory-check/worksheet-cycle-count.js +14 -0
  26. package/client/pages/master/location-list.js +58 -17
  27. package/client/pages/order/arrival-notice/arrival-notice-detail.js +134 -115
  28. package/client/pages/order/arrival-notice/arrival-notice-list.js +87 -6
  29. package/client/pages/order/arrival-notice/arrival-notice-requests.js +83 -6
  30. package/client/pages/order/arrival-notice/assign-buffer-location.js +8 -1
  31. package/client/pages/order/arrival-notice/check-arrived-notice.js +9 -1
  32. package/client/pages/order/arrival-notice/create-arrival-notice.js +30 -2
  33. package/client/pages/order/arrival-notice/duplicate-arrival-notice.js +290 -25
  34. package/client/pages/order/arrival-notice/edit-product-popup.js +36 -5
  35. package/client/pages/order/arrival-notice/receive-arrival-notice.js +8 -1
  36. package/client/pages/order/release-order/b2b/b2b-order-requests.js +7 -7
  37. package/client/pages/order/release-order/b2c/b2c-order-requests.js +65 -5
  38. package/client/pages/order/release-order/create-release-order.js +24 -1
  39. package/client/pages/order/release-order/receive-release-order-request.js +8 -0
  40. package/client/pages/order/release-order/release-extra-product-popup.js +12 -4
  41. package/client/pages/order/release-order/release-order-detail.js +9 -1
  42. package/client/pages/order/return-order/check-return-order.js +9 -1
  43. package/client/pages/order/return-order/create-return-order.js +14 -2
  44. package/client/pages/order/return-order/receive-return-order-requests.js +9 -1
  45. package/client/pages/order/return-order/return-order-detail.js +15 -6
  46. package/client/pages/order/return-order/return-order-inventory-popup.js +7 -0
  47. package/client/pages/order/transport-order/delivery-order-list.js +4 -1
  48. package/client/pages/outbound/inventory-assign-popup.js +11 -2
  49. package/client/pages/outbound/inventory-auto-assign-popup.js +9 -0
  50. package/client/pages/outbound/merged-outbound-worksheet.js +9 -5
  51. package/client/pages/outbound/picking-product.js +202 -162
  52. package/client/pages/outbound/picking-replacement-popup.js +2 -2
  53. package/client/pages/outbound/single-outbound-worksheet.js +47 -1
  54. package/client/pages/outbound/worksheet-loading.js +22 -5
  55. package/client/pages/outbound/worksheet-packing.js +8 -0
  56. package/client/pages/outbound/worksheet-picking.js +29 -5
  57. package/client/pages/outbound/worksheet-return.js +9 -1
  58. package/client/pages/outbound/worksheet-sorting.js +9 -1
  59. package/client/pages/report/custom-elccl/elccl-inventory-report.js +31 -30
  60. package/client/pages/report/custom-elccl/elccl-inventory-summary-report.js +23 -26
  61. package/client/pages/report/inventory-pallet-storage-report.js +11 -10
  62. package/client/pages/report/inventory-report.js +41 -43
  63. package/client/pages/report/inventory-summary-report.js +25 -28
  64. package/client/route.js +5 -0
  65. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-report.js +1 -1
  66. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-report.js.map +1 -1
  67. package/dist-server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.js +1 -1
  68. package/dist-server/graphql/resolvers/index.js +3 -1
  69. package/dist-server/graphql/resolvers/index.js.map +1 -1
  70. package/dist-server/graphql/resolvers/shipping-provider/index.js +6 -0
  71. package/dist-server/graphql/resolvers/shipping-provider/index.js.map +1 -0
  72. package/dist-server/graphql/resolvers/shipping-provider/shipping-providers.js +20 -0
  73. package/dist-server/graphql/resolvers/shipping-provider/shipping-providers.js.map +1 -0
  74. package/dist-server/graphql/types/custom/elccl/elccl-inventory-report.js +1 -1
  75. package/dist-server/graphql/types/index.js +5 -2
  76. package/dist-server/graphql/types/index.js.map +1 -1
  77. package/dist-server/graphql/types/shipping-provider/index.js +10 -0
  78. package/dist-server/graphql/types/shipping-provider/index.js.map +1 -0
  79. package/dist-server/graphql/types/shipping-provider/shipping-provider-list.js +13 -0
  80. package/dist-server/graphql/types/shipping-provider/shipping-provider-list.js.map +1 -0
  81. package/dist-server/graphql/types/shipping-provider/shipping-provider.js +13 -0
  82. package/dist-server/graphql/types/shipping-provider/shipping-provider.js.map +1 -0
  83. package/package.json +37 -37
  84. package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-report.ts +4 -2
  85. package/server/graphql/resolvers/custom/elccl/elccl-inventory-history-summary-report.ts +1 -1
  86. package/server/graphql/resolvers/index.ts +3 -1
  87. package/server/graphql/resolvers/shipping-provider/index.ts +5 -0
  88. package/server/graphql/resolvers/shipping-provider/shipping-providers.ts +20 -0
  89. package/server/graphql/types/custom/elccl/elccl-inventory-report.ts +1 -1
  90. package/server/graphql/types/index.ts +5 -2
  91. package/server/graphql/types/shipping-provider/index.ts +8 -0
  92. package/server/graphql/types/shipping-provider/shipping-provider-list.ts +7 -0
  93. package/server/graphql/types/shipping-provider/shipping-provider.ts +7 -0
  94. package/things-factory.config.js +6 -0
  95. package/translations/en.json +27 -0
  96. package/translations/ko.json +84 -36
  97. package/translations/ms.json +85 -37
  98. package/translations/zh.json +98 -51
@@ -1,5 +1,6 @@
1
1
  import '@things-factory/grist-ui'
2
2
  import '@things-factory/biz-ui'
3
+ import '@things-factory/import-ui'
3
4
  import '../../components/select-product-popup'
4
5
  import '../../order/vas-order/popup/vas-create-popup'
5
6
 
@@ -12,7 +13,7 @@ import { i18next, localize } from '@things-factory/i18n-base'
12
13
  import { openPopup } from '@things-factory/layout-base'
13
14
  import { client, CustomAlert, navigate, PageView } from '@things-factory/shell'
14
15
  import { CommonButtonStyles } from '@things-factory/styles'
15
- import { gqlBuilder, isMobileDevice } from '@things-factory/utils'
16
+ import { isMobileDevice } from '@things-factory/utils'
16
17
 
17
18
  import { fetchSettingRule } from '../../../fetch-setting-value'
18
19
  import { VAS_BATCH_AND_PRODUCT_TYPE, VAS_BATCH_NO_TYPE, VAS_PRODUCT_TYPE } from '../../constants'
@@ -353,6 +354,8 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
353
354
  super()
354
355
  this.productData = { records: [] }
355
356
  this.vasData = { records: [] }
357
+ this._bizplaceId = ''
358
+ this._bizplaceName = ''
356
359
  this.containerSizes = []
357
360
  this._importedOrder = false
358
361
  this._hasContainer = false
@@ -365,6 +368,7 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
365
368
  this._enableTransportationServiceSetting = false
366
369
  this._enableTransportForCustomClearanceSetting = false
367
370
  this._disableTransport = false
371
+ this._strictProductSelection = false
368
372
  }
369
373
 
370
374
  get arrivalNoticeForm() {
@@ -515,6 +519,7 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
515
519
  */
516
520
  _configureProductGrist() {
517
521
  let editable = this._bizplaceId ? true : false
522
+ let strictEditable = this._bizplaceId ? !this._strictProductSelection : false
518
523
 
519
524
  const crossDockingColumns = [
520
525
  {
@@ -567,6 +572,13 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
567
572
  },
568
573
  width: 350
569
574
  },
575
+ {
576
+ type: 'string',
577
+ name: 'productBrand',
578
+ header: i18next.t('field.brand'),
579
+ imex: { header: i18next.t('field.brand'), key: 'productBrand', width: 25, type: 'string' },
580
+ width: 150
581
+ },
570
582
  {
571
583
  type: 'object',
572
584
  name: 'product',
@@ -576,8 +588,15 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
576
588
  type: 'select',
577
589
  name: 'packingType',
578
590
  header: i18next.t('field.packing_type'),
591
+ imex: {
592
+ header: i18next.t('field.packing_type'),
593
+ key: 'packingType',
594
+ width: 20,
595
+ type: 'array',
596
+ arrData: this.packingTypes
597
+ },
579
598
  record: {
580
- editable: editable,
599
+ editable: strictEditable,
581
600
  options: [
582
601
  {
583
602
  display: '',
@@ -594,8 +613,15 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
594
613
  type: 'select',
595
614
  name: 'uom',
596
615
  header: i18next.t('field.uom'),
616
+ imex: {
617
+ header: i18next.t('field.uom'),
618
+ key: 'uom',
619
+ width: 20,
620
+ type: 'array',
621
+ arrData: this.uomValueUnits
622
+ },
597
623
  record: {
598
- editable: editable,
624
+ editable: strictEditable,
599
625
  options: [
600
626
  {
601
627
  display: '',
@@ -696,6 +722,18 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
696
722
  ...e.detail
697
723
  })
698
724
 
725
+ this.productGrist.dirtyData.records = this.productGrist.dirtyData.records.map(item => {
726
+ return {
727
+ ...item,
728
+ totalUomValue:
729
+ item?.packQty > 0
730
+ ? item?.totalUomValue
731
+ ? item.totalUomValue
732
+ : `${parseFloat(item.packQty * e.detail.uomValue).toFixed(2)} ${e.detail.uom}`
733
+ : null
734
+ }
735
+ })
736
+
699
737
  this.productData = {
700
738
  ...this.productData,
701
739
  records: [...this.productGrist.dirtyData.records]
@@ -743,6 +781,26 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
743
781
  }
744
782
  }
745
783
 
784
+ if (changedColumn === 'manufactureYear') {
785
+ let manufactureYear = changeRecord.manufactureYear
786
+ const regExp = /^(181[2-9]|18[2-9]\d|19\d\d|2\d{3}|30[0-3]\d|304[0-8])$/
787
+
788
+ if (typeof manufactureYear === undefined || !regExp.test(manufactureYear)) {
789
+ if (manufactureYear === 0) {
790
+ delete event.detail.after[event.detail.column.name]
791
+ } else {
792
+ throw new Error(i18next.t('text.invalid_x', { state: { x: i18next.t('label.manufacture_year') } }))
793
+ }
794
+ }
795
+ }
796
+
797
+ if (changedColumn === 'unitPrice') {
798
+ let unitPrice = changeRecord.unitPrice
799
+ if (typeof unitPrice === undefined || unitPrice < 0) {
800
+ throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('label.unit_price') } }))
801
+ }
802
+ }
803
+
746
804
  this._updateVasTargets(true)
747
805
  } catch (e) {
748
806
  const beforeValue = event.detail.before && event.detail.before[event.detail.column.name]
@@ -1021,7 +1079,7 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
1021
1079
  let arrivalNotice = this._getFormInfo()
1022
1080
  delete arrivalNotice.warehouseTransport
1023
1081
  arrivalNotice.orderProducts = this._getOrderProducts()
1024
- const attachments = this._document?.files ? this._document.files : undefined
1082
+ const fileUploader = this._document?.files ? this._document.files : undefined
1025
1083
 
1026
1084
  if (arrivalNotice.orderProducts.some(orderProduct => !orderProduct.palletQty)) {
1027
1085
  const result = await CustomAlert({
@@ -1039,30 +1097,25 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
1039
1097
  delete arrivalNotice.bizplaceId
1040
1098
  delete arrivalNotice.bizplaceName
1041
1099
 
1042
- const args = {
1043
- arrivalNotice: {
1044
- ...arrivalNotice,
1045
- partnerBizplaceId: this._bizplaceId,
1046
- ownTransport: this._importedOrder ? true : this._ownTransport
1047
- }
1048
- }
1049
-
1050
- const response = await client.query({
1051
- query: gql`
1052
- mutation ($attachments: Upload) {
1053
- generateArrivalNotice(${gqlBuilder.buildArgs(args)}, file:$attachments) {
1054
- id
1055
- name
1056
- crossDocking
1057
- }
1100
+ const response = await client.mutate({
1101
+ mutation: gql`
1102
+ mutation generateArrivalNotice($arrivalNotice: NewArrivalNotice!, $files: [Upload!]) {
1103
+ generateArrivalNotice(arrivalNotice: $arrivalNotice, files: $files) {
1104
+ id
1105
+ name
1106
+ crossDocking
1058
1107
  }
1059
- `,
1108
+ }
1109
+ `,
1060
1110
  variables: {
1061
- attachments
1111
+ arrivalNotice: {
1112
+ ...arrivalNotice,
1113
+ partnerBizplaceId: this._bizplaceId,
1114
+ ownTransport: this._importedOrder ? true : this._ownTransport
1115
+ },
1116
+ files: fileUploader
1062
1117
  },
1063
- context: {
1064
- hasUpload: true
1065
- }
1118
+ context: { hasUpload: true }
1066
1119
  })
1067
1120
 
1068
1121
  if (!response.errors) {
@@ -1506,6 +1559,218 @@ class DuplicateArrivalNotice extends localize(i18next)(PageView) {
1506
1559
  )
1507
1560
  }
1508
1561
 
1562
+ excelColumns() {
1563
+ const productColumns = [
1564
+ {
1565
+ type: 'string',
1566
+ name: 'batchId',
1567
+ header: i18next.t('field.batch_id'),
1568
+ imex: { header: i18next.t('field.batch_id'), key: 'batchId', width: 25, type: 'string' },
1569
+ width: 100
1570
+ },
1571
+ {
1572
+ type: 'string',
1573
+ name: 'productSKU',
1574
+ header: i18next.t('field.sku'),
1575
+ imex: { header: i18next.t('field.sku'), key: 'productSKU', width: 25, type: 'string' },
1576
+ width: 100
1577
+ },
1578
+ {
1579
+ type: 'string',
1580
+ name: 'packingType',
1581
+ header: i18next.t('field.packing_type'),
1582
+ imex: { header: i18next.t('field.packing_type'), key: 'packingType', width: 25, type: 'string' },
1583
+ width: 100
1584
+ },
1585
+ {
1586
+ type: 'integer',
1587
+ name: 'packQty',
1588
+ header: i18next.t('field.pack_qty'),
1589
+ imex: { header: i18next.t('field.pack_qty'), key: 'packQty', width: 25, type: 'float' },
1590
+ width: 100
1591
+ },
1592
+ {
1593
+ type: 'integer',
1594
+ name: 'palletQty',
1595
+ header: i18next.t('field.pallet_qty'),
1596
+ imex: { header: i18next.t('field.pallet_qty'), key: 'palletQty', width: 25, type: 'float' },
1597
+ width: 100
1598
+ },
1599
+ {
1600
+ type: 'integer',
1601
+ name: 'manufactureYear',
1602
+ header: i18next.t('field.manufacture_year'),
1603
+ imex: { header: i18next.t('field.manufacture_year'), key: 'manufactureYear', width: 25, type: 'float' },
1604
+ width: 100
1605
+ },
1606
+ {
1607
+ type: 'string',
1608
+ name: 'batchIdRef',
1609
+ header: i18next.t('field.batch_id_ref'),
1610
+ imex: { header: i18next.t('field.batch_id_ref'), key: 'batchIdRef', width: 25, type: 'string' },
1611
+ width: 100
1612
+ },
1613
+ {
1614
+ type: 'float',
1615
+ name: 'unitPrice',
1616
+ header: i18next.t('field.unit_price'),
1617
+ imex: { header: i18next.t('field.unit_price'), key: 'unitPrice', width: 25, type: 'float' },
1618
+ width: 100
1619
+ },
1620
+ {
1621
+ type: 'string',
1622
+ name: 'remark',
1623
+ header: i18next.t('field.remark'),
1624
+ imex: { header: i18next.t('field.remark'), key: 'remark', width: 25, type: 'string' },
1625
+ width: 100
1626
+ }
1627
+ ]
1628
+
1629
+ return productColumns
1630
+ }
1631
+
1632
+ async _exportableData() {
1633
+ try {
1634
+ var headerSetting = [
1635
+ ...this.excelColumns()
1636
+ .filter(column => column.type !== 'gutter' && column.imex !== undefined)
1637
+ .map(column => {
1638
+ return column.imex
1639
+ })
1640
+ ]
1641
+
1642
+ return { header: headerSetting, data: [] }
1643
+ } catch (e) {
1644
+ this._showToast(e)
1645
+ }
1646
+ }
1647
+
1648
+ async bulkUploadValidateOrderProducts(patches) {
1649
+ const response = await client.query({
1650
+ query: gql`
1651
+ query bulkUploadValidateOrderProducts($orderProducts: [NewOrderProduct], $partnerBizplaceId: String!) {
1652
+ bulkUploadValidateOrderProducts(orderProducts: $orderProducts, partnerBizplaceId: $partnerBizplaceId) {
1653
+ id
1654
+ packingType
1655
+ packingSize
1656
+ uom
1657
+ uomValue
1658
+ totalUomValue
1659
+ packQty
1660
+ palletQty
1661
+ manufactureYear
1662
+ batchId
1663
+ batchIdRef
1664
+ unitPrice
1665
+ remark
1666
+ productSKU
1667
+ productName
1668
+ isError
1669
+ product {
1670
+ id
1671
+ name
1672
+ sku
1673
+ description
1674
+ type
1675
+ primaryUnit
1676
+ primaryValue
1677
+ }
1678
+ }
1679
+ }
1680
+ `,
1681
+ variables: { orderProducts: patches, partnerBizplaceId: this._bizplaceId }
1682
+ })
1683
+
1684
+ if (!response.errors) {
1685
+ const data = response.data.bulkUploadValidateOrderProducts.map(item => {
1686
+ return {
1687
+ ...item,
1688
+ productName: item?.productName,
1689
+ unitPrice: parseFloat(item.unitPrice) || '',
1690
+ manufactureYear: parseFloat(item.manufactureYear) || '',
1691
+ packQty: parseFloat(item.packQty) || '',
1692
+ palletQty: parseFloat(item.palletQty) || ''
1693
+ }
1694
+ })
1695
+ this.productData = {
1696
+ ...this.productData,
1697
+ records: data.map((dt, idx) => {
1698
+ return {
1699
+ ...dt,
1700
+ id: idx,
1701
+ name: idx,
1702
+ __dirty__: '+'
1703
+ }
1704
+ })
1705
+ }
1706
+
1707
+ this.productGrist.fetch()
1708
+ }
1709
+ }
1710
+
1711
+ async importHandler(patches) {
1712
+ patches.map(itm => {
1713
+ itm.unitPrice = parseFloat(itm.unitPrice) || ''
1714
+ itm.manufactureYear = parseFloat(itm.manufactureYear) || ''
1715
+ itm.packQty = parseFloat(itm.packQty) || ''
1716
+ itm.palletQty = parseFloat(itm.palletQty) || ''
1717
+ })
1718
+
1719
+ this.productData = {
1720
+ records: [...patches]
1721
+ }
1722
+
1723
+ const orderProducts = patches.map(patch => {
1724
+ delete patch.cuFlag
1725
+ return {
1726
+ ...patch,
1727
+ unitPrice: parseFloat(patch.unitPrice) || 0,
1728
+ manufactureYear: parseFloat(patch.manufactureYear) || 0,
1729
+ packQty: parseFloat(patch.packQty) || 0,
1730
+ palletQty: parseFloat(patch.palletQty) || 0
1731
+ }
1732
+ })
1733
+ await this.bulkUploadValidateOrderProducts(orderProducts)
1734
+ history.back()
1735
+ }
1736
+
1737
+ async _importableData(records) {
1738
+ try {
1739
+ if (this._bizplaceId) {
1740
+ records = records
1741
+ .filter(record => record.productSKU)
1742
+ .map(record => {
1743
+ return {
1744
+ ...record
1745
+ }
1746
+ })
1747
+
1748
+ openPopup(
1749
+ html`
1750
+ <import-pop-up
1751
+ .records=${records}
1752
+ .config=${{
1753
+ rows: this.productGristConfig.rows,
1754
+ columns: [...this.excelColumns().filter(column => column.imex !== undefined)]
1755
+ }}
1756
+ .importHandler="${await this.importHandler.bind(this)}"
1757
+ ></import-pop-up>
1758
+ `,
1759
+ {
1760
+ backdrop: true,
1761
+ escapable: false,
1762
+ size: 'large',
1763
+ title: i18next.t('title.import')
1764
+ }
1765
+ )
1766
+ } else {
1767
+ throw new Error(i18next.t('text.please_select_a_company'))
1768
+ }
1769
+ } catch (e) {
1770
+ this._showToast(e)
1771
+ }
1772
+ }
1773
+
1509
1774
  _showToast({ type, message }) {
1510
1775
  document.dispatchEvent(
1511
1776
  new CustomEvent('notify', {
@@ -1,12 +1,15 @@
1
1
  import '@things-factory/grist-ui'
2
+ import '../../components/select-product-popup'
3
+
4
+ import gql from 'graphql-tag'
5
+ import { css, html, LitElement } from 'lit-element'
6
+
2
7
  import { i18next, localize } from '@things-factory/i18n-base'
8
+ import { openPopup } from '@things-factory/layout-base'
3
9
  import { client, CustomAlert } from '@things-factory/shell'
4
10
  import { ScrollbarStyles } from '@things-factory/styles'
5
11
  import { isMobileDevice } from '@things-factory/utils'
6
- import { openPopup } from '@things-factory/layout-base'
7
- import gql from 'graphql-tag'
8
- import { css, html, LitElement } from 'lit-element'
9
- import '../../components/select-product-popup'
12
+
10
13
  import { ORDER_PRODUCT_STATUS } from '../../constants'
11
14
 
12
15
  export class EditProductPopup extends localize(i18next)(LitElement) {
@@ -411,6 +414,33 @@ export class EditProductPopup extends localize(i18next)(LitElement) {
411
414
  changeRecord[key] = calcedAmount[key]
412
415
  }
413
416
  }
417
+
418
+ if (changedColumn === 'manufactureYear') {
419
+ let manufactureYear = changeRecord.manufactureYear
420
+ const regExp = /^(181[2-9]|18[2-9]\d|19\d\d|2\d{3}|30[0-3]\d|304[0-8])$/
421
+
422
+ if (typeof manufactureYear === undefined || !regExp.test(manufactureYear)) {
423
+ if (manufactureYear === 0) {
424
+ delete event.detail.after[event.detail.column.name]
425
+ } else {
426
+ throw new Error(i18next.t('text.invalid_x', { state: { x: i18next.t('label.manufacture_year') } }))
427
+ }
428
+ }
429
+ }
430
+
431
+ if (changedColumn === 'unitPrice') {
432
+ let unitPrice = changeRecord.unitPrice
433
+ if (typeof unitPrice === undefined || unitPrice < 0) {
434
+ throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('label.unit_price') } }))
435
+ }
436
+ }
437
+
438
+ if (changedColumn === 'palletQty') {
439
+ let palletQty = changeRecord.palletQty
440
+ if (typeof palletQty === undefined || palletQty < 0 || isNaN(palletQty)) {
441
+ throw new Error(i18next.t('text.invalid_x', { state: { x: i18next.t('label.pallet_qty') } }))
442
+ }
443
+ }
414
444
  } catch (e) {
415
445
  const beforeValue = event.detail.before && event.detail.before[event.detail.column.name]
416
446
  if (beforeValue) {
@@ -635,7 +665,8 @@ export class EditProductPopup extends localize(i18next)(LitElement) {
635
665
  adjustedBatchIdRef: record?.batchIdRef ? record.batchIdRef : null,
636
666
  unitPrice: 0,
637
667
  adjustedUnitPrice: record?.unitPrice ? record.unitPrice : null,
638
- remark: record?.remark ? record.remark : null
668
+ remark: record?.remark ? record.remark : null,
669
+ packingSize: record.packingSize || record.product.packingSize
639
670
  }
640
671
  })
641
672
  }
@@ -454,6 +454,7 @@ class ReceiveArrivalNotice extends localize(i18next)(PageView) {
454
454
  name
455
455
  description
456
456
  sku
457
+ brand
457
458
  }
458
459
  remark
459
460
  unitPrice
@@ -527,7 +528,7 @@ class ReceiveArrivalNotice extends localize(i18next)(PageView) {
527
528
  this.setProductGristConfig()
528
529
  this.productData = {
529
530
  records: orderProducts.map(record => {
530
- return { ...record, productSku: record.product.sku }
531
+ return { ...record, productSku: record.product.sku, productBrand: record.product.brand }
531
532
  })
532
533
  }
533
534
  this.vasData = {
@@ -582,6 +583,12 @@ class ReceiveArrivalNotice extends localize(i18next)(PageView) {
582
583
  record: { options: { queryName: 'products' } },
583
584
  width: 350
584
585
  },
586
+ {
587
+ type: 'string',
588
+ name: 'productBrand',
589
+ header: i18next.t('field.brand'),
590
+ width: 150
591
+ },
585
592
  {
586
593
  type: 'string',
587
594
  name: 'packingType',
@@ -60,13 +60,13 @@ class B2bOrderRequests extends localize(i18next)(PageView) {
60
60
  get context() {
61
61
  return {
62
62
  title: i18next.t('title.release_order_requests'),
63
- actions: [
64
- {
65
- title: i18next.t('button.batch_picking'),
66
- action: this._openBatchPickingPopup.bind(this),
67
- ...CommonButtonStyles.activate
68
- }
69
- ],
63
+ // actions: [
64
+ // {
65
+ // title: i18next.t('button.batch_picking'),
66
+ // action: this._openBatchPickingPopup.bind(this),
67
+ // ...CommonButtonStyles.activate
68
+ // }
69
+ // ],
70
70
  exportable: {
71
71
  name: i18next.t('title.release_order_requests'),
72
72
  data: this._exportableData.bind(this)
@@ -65,12 +65,12 @@ class B2cOrderRequests extends localize(i18next)(PageView) {
65
65
  title: i18next.t('button.generate_packing_list'),
66
66
  action: this._generatePackingList.bind(this),
67
67
  ...CommonButtonStyles.label
68
- },
69
- {
70
- title: i18next.t('button.batch_picking'),
71
- action: this._openBatchPickingPopup.bind(this),
72
- ...CommonButtonStyles.activate
73
68
  }
69
+ // {
70
+ // title: i18next.t('button.batch_picking'),
71
+ // action: this._openBatchPickingPopup.bind(this),
72
+ // ...CommonButtonStyles.activate
73
+ // }
74
74
  ],
75
75
  exportable: {
76
76
  name: i18next.t('title.release_order_requests'),
@@ -88,6 +88,7 @@ class B2cOrderRequests extends localize(i18next)(PageView) {
88
88
  async pageInitialized() {
89
89
  const _orderStatus = await getCodeByName('RO_REQUESTS_STATUS')
90
90
  const _partners = await this._fetchPartners()
91
+ const _shippingProviders = await this._fetchShippingProviders()
91
92
 
92
93
  this._searchFields = [
93
94
  {
@@ -170,6 +171,38 @@ class B2cOrderRequests extends localize(i18next)(PageView) {
170
171
  })()
171
172
  },
172
173
  value: new Date().toISOString().split('T')[0]
174
+ },
175
+ {
176
+ label: i18next.t('field.shipping_provider'),
177
+ name: 'transporter',
178
+ type: 'select',
179
+ props: {
180
+ searchOper: 'eq'
181
+ },
182
+ options: [
183
+ { value: '' },
184
+ ..._shippingProviders.map(item => {
185
+ return {
186
+ name: item.transporter,
187
+ value: item.transporter
188
+ }
189
+ })
190
+ ]
191
+ },
192
+ {
193
+ label: i18next.t('field.no_of_items'),
194
+ name: 'noOfItems',
195
+ type: 'select',
196
+ props: {
197
+ searchOper: 'gte'
198
+ },
199
+ options: [{ value: '' }, { name: 'Single Item', value: 1 }, { name: 'Multiple Item', value: 2 }]
200
+ },
201
+ {
202
+ label: i18next.t('field.sku'),
203
+ name: 'sku',
204
+ type: 'text',
205
+ props: { searchOper: 'i_like' }
173
206
  }
174
207
  ]
175
208
 
@@ -275,6 +308,14 @@ class B2cOrderRequests extends localize(i18next)(PageView) {
275
308
  sortable: true,
276
309
  width: 120
277
310
  },
311
+ {
312
+ type: 'integer',
313
+ name: 'noOfItems',
314
+ header: i18next.t('field.no_of_items'),
315
+ imex: { header: i18next.t('field.no_of_items'), key: 'noOfItems', width: 25, type: 'integer' },
316
+ sortable: true,
317
+ width: 120
318
+ },
278
319
  {
279
320
  type: 'datetime',
280
321
  name: 'updatedAt',
@@ -327,6 +368,7 @@ class B2cOrderRequests extends localize(i18next)(PageView) {
327
368
  refNo
328
369
  refNo2
329
370
  refNo3
371
+ noOfItems
330
372
  updatedAt
331
373
  acceptedBy {
332
374
  id
@@ -380,6 +422,24 @@ class B2cOrderRequests extends localize(i18next)(PageView) {
380
422
  }
381
423
  }
382
424
 
425
+ async _fetchShippingProviders() {
426
+ const response = await client.query({
427
+ query: gql`
428
+ query shippingProviders {
429
+ shippingProviders {
430
+ items {
431
+ transporter
432
+ }
433
+ }
434
+ }
435
+ `
436
+ })
437
+
438
+ if (!response.errors) {
439
+ return response.data.shippingProviders.items
440
+ }
441
+ }
442
+
383
443
  _generatePackingList() {
384
444
  try {
385
445
  if (this.dataGrist.selected?.length == 0) {
@@ -845,6 +845,7 @@ class CreateReleaseOrder extends localize(i18next)(PageView) {
845
845
  header: i18next.t('field.product_info'),
846
846
  width: 280
847
847
  },
848
+ { name: 'productBrand', header: i18next.t('field.brand') },
848
849
  { name: 'packingType', header: i18next.t('field.packing_type') },
849
850
  { name: 'packingSize', header: i18next.t('field.packing_size') },
850
851
  { name: 'uom', header: i18next.t('field.uom') },
@@ -869,6 +870,7 @@ class CreateReleaseOrder extends localize(i18next)(PageView) {
869
870
  'batchId',
870
871
  'batchIdRef',
871
872
  'productName',
873
+ 'productBrand',
872
874
  'packingType',
873
875
  'remainQty',
874
876
  'remainUomValue',
@@ -891,6 +893,12 @@ class CreateReleaseOrder extends localize(i18next)(PageView) {
891
893
  header: i18next.t('field.product'),
892
894
  width: 150
893
895
  },
896
+ {
897
+ type: 'string',
898
+ name: 'productBrand',
899
+ header: i18next.t('field.brand'),
900
+ width: 100
901
+ },
894
902
  {
895
903
  type: 'code',
896
904
  name: 'packingType',
@@ -995,6 +1003,7 @@ class CreateReleaseOrder extends localize(i18next)(PageView) {
995
1003
  { name: 'palletId', header: i18next.t('field.lot_id') },
996
1004
  { name: 'productSKU', header: i18next.t('field.sku') },
997
1005
  { name: 'productName', header: i18next.t('field.product_info') },
1006
+ { name: 'productBrand', header: i18next.t('field.brand') },
998
1007
  { name: 'batchId', header: i18next.t('field.batch_id') },
999
1008
  {
1000
1009
  name: 'location',
@@ -1019,7 +1028,15 @@ class CreateReleaseOrder extends localize(i18next)(PageView) {
1019
1028
  }
1020
1029
  ],
1021
1030
  list: {
1022
- fields: ['palletId', 'productName', 'batchId', 'location', 'remainUomValue', 'batchIdRef']
1031
+ fields: [
1032
+ 'palletId',
1033
+ 'productName',
1034
+ 'productBrand',
1035
+ 'batchId',
1036
+ 'location',
1037
+ 'remainUomValue',
1038
+ 'batchIdRef'
1039
+ ]
1023
1040
  }
1024
1041
  }
1025
1042
  },
@@ -1037,6 +1054,12 @@ class CreateReleaseOrder extends localize(i18next)(PageView) {
1037
1054
  header: i18next.t('field.product'),
1038
1055
  width: 150
1039
1056
  },
1057
+ {
1058
+ type: 'string',
1059
+ name: 'productBrand',
1060
+ header: i18next.t('field.brand'),
1061
+ width: 100
1062
+ },
1040
1063
  {
1041
1064
  type: 'object',
1042
1065
  name: 'location',