@things-factory/sales-ui 4.3.21 → 4.3.22

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.
@@ -676,7 +676,7 @@ class PurchaseOrderApprovalDetail extends connect(store)(localize(i18next)(PageV
676
676
  packQty = packQty || 0
677
677
  miscAmt = parseFloat((miscAmt || 0).toFixed(2))
678
678
  unitPrice = parseFloat((unitPrice || 0).toFixed(2))
679
- taxRate = parseFloat((taxRate || 0).toFixed(1))
679
+ taxRate = parseFloat((taxRate || 0).toFixed(2))
680
680
  discountAmt = parseFloat((discountAmt || 0).toFixed(2))
681
681
 
682
682
  let totalAmtBeforeTax = packQty * unitPrice + miscAmt - discountAmt
@@ -1,6 +1,7 @@
1
1
  import '@things-factory/grist-ui'
2
2
  import '@things-factory/biz-ui'
3
3
  import '@things-factory/warehouse-ui'
4
+ import '@things-factory/import-ui/client/components/import-pop-up'
4
5
 
5
6
  import gql from 'graphql-tag'
6
7
  import { css, html } from 'lit-element'
@@ -439,7 +440,14 @@ class PurchaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
439
440
  return {
440
441
  title: `${i18next.t('title.purchase_order_detail')} `,
441
442
  actions,
442
- help: 'operato-wms/po-detail'
443
+ help: 'operato-wms/po-detail',
444
+ exportable: {
445
+ name: i18next.t('title.create_purchase_order'),
446
+ data: this._exportableData.bind(this)
447
+ },
448
+ importable: {
449
+ handler: this._importableData.bind(this)
450
+ }
443
451
  }
444
452
  }
445
453
 
@@ -703,6 +711,13 @@ class PurchaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
703
711
  'totalAmt'
704
712
  ]
705
713
  },
714
+ rows: {
715
+ classifier: (record, rowIndex) => {
716
+ return {
717
+ emphasized: record.isError
718
+ }
719
+ }
720
+ },
706
721
  columns: productGristColumns
707
722
  }
708
723
 
@@ -856,7 +871,7 @@ class PurchaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
856
871
  packQty = packQty || 0
857
872
  unitPrice = parseFloat((unitPrice || 0).toFixed(2))
858
873
  miscAmt = parseFloat((miscAmt || 0).toFixed(2))
859
- taxRate = parseFloat((taxRate || 0).toFixed(1))
874
+ taxRate = parseFloat((taxRate || 0).toFixed(2))
860
875
  discountAmt = parseFloat((discountAmt || 0).toFixed(2))
861
876
 
862
877
  let totalAmtBeforeTax = packQty * unitPrice + miscAmt - discountAmt
@@ -896,21 +911,30 @@ class PurchaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
896
911
  this._validateProducts()
897
912
 
898
913
  const result = await CustomAlert({
899
- title: i18next.t('title.are_you_sure'),
900
- text: i18next.t('text.update_purchase_order'),
914
+ title: i18next.t('title.update_purchase_order'),
915
+ text:
916
+ status == PURCHASE_ORDER_STATUS.DRAFT
917
+ ? ''
918
+ : i18next.t('text.pack_qty_and_unit_price_will_be_updated_to_1_if_the_value_is_empty_or_0'),
901
919
  confirmButton: { text: i18next.t('button.submit') },
902
920
  cancelButton: { text: i18next.t('button.cancel') }
903
921
  })
904
922
 
905
923
  if (!result.value) return
906
924
 
925
+ //comment start
926
+ //detailed review needed 19 May 2022 by @ChrisLim-git
907
927
  let purchaseOrder = {
908
928
  ...this._purchaseOrderData,
909
929
  ...this._getFormInfo()
910
930
  }
911
931
 
912
- purchaseOrder.orderProducts = this._getOrderProducts()
913
- purchaseOrder.otherCharges = this._getPoOtherCharges()
932
+ purchaseOrder = {
933
+ ...purchaseOrder,
934
+ orderProducts: this._getOrderProducts(status),
935
+ otherCharges: this._getPoOtherCharges()
936
+ }
937
+ //comment end
914
938
 
915
939
  const fileUploader = this._document?.files ? this._document.files : undefined
916
940
 
@@ -1146,12 +1170,32 @@ class PurchaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
1146
1170
  const records = this.productGrist.dirtyData.records
1147
1171
  if (!records?.length) throw new Error(i18next.t('text.no_products'))
1148
1172
 
1149
- const checkRequiredFields = ({ batchId, packingType, uomValue, uom, packQty, unitPrice }) =>
1150
- !batchId || !packingType || !uomValue || !uom || !packQty || !unitPrice
1173
+ const checkRequiredFields = ({ batchId, packingType, uomValue, uom }) =>
1174
+ !batchId || !packingType || !uomValue || !uom
1151
1175
 
1152
1176
  if (records.some(checkRequiredFields)) {
1153
1177
  throw new Error(i18next.t('text.empty_value_in_list'))
1154
1178
  }
1179
+
1180
+ if (records.some(({ packQty }) => packQty < 0)) {
1181
+ throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('label.pack_qty') } }))
1182
+ }
1183
+
1184
+ if (records.some(({ unitPrice }) => unitPrice < 0)) {
1185
+ throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('label.unit_price') } }))
1186
+ }
1187
+
1188
+ if (records.some(({ miscAmt }) => miscAmt < 0)) {
1189
+ throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('label.misc_amt') } }))
1190
+ }
1191
+
1192
+ if (records.some(({ discountAmt }) => discountAmt < 0)) {
1193
+ throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('label.total_disc_amt') } }))
1194
+ }
1195
+
1196
+ if (records.some(({ taxRate }) => taxRate < 0)) {
1197
+ throw new Error(i18next.t('text.x_should_be_positive', { state: { x: i18next.t('label.tax_rate') } }))
1198
+ }
1155
1199
  }
1156
1200
 
1157
1201
  _getFormInfo() {
@@ -1160,7 +1204,7 @@ class PurchaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
1160
1204
  return formData
1161
1205
  }
1162
1206
 
1163
- _getOrderProducts() {
1207
+ _getOrderProducts(status) {
1164
1208
  return this.productGrist.dirtyData.records.map(record => {
1165
1209
  let orderProduct = {
1166
1210
  id: record.id || null,
@@ -1169,11 +1213,12 @@ class PurchaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
1169
1213
  packingType: record.packingType,
1170
1214
  uomValue: record?.uomValue ? record.uomValue : 0,
1171
1215
  uom: record.uom,
1172
- packQty: record.packQty,
1216
+ packQty: status == PURCHASE_ORDER_STATUS.DRAFT ? record.packQty : record.packQty > 1 ? record.packQty : 1,
1173
1217
  totalUomValue: record?.uomValue ? `${(record.uomValue * record.packQty).toFixed(2)} ${record.uom}` : ``,
1174
1218
  remark: record?.remark || null,
1175
1219
  discountAmt: record.discountAmt,
1176
- unitPrice: record.unitPrice,
1220
+ unitPrice:
1221
+ status == PURCHASE_ORDER_STATUS.DRAFT ? record.unitPrice : record.unitPrice > 1 ? record.unitPrice : 1,
1177
1222
  miscAmt: record.miscAmt,
1178
1223
  taxRate: record.taxRate
1179
1224
  }
@@ -1249,7 +1294,7 @@ class PurchaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
1249
1294
  }
1250
1295
 
1251
1296
  this.partnerBizplaceId = e.detail.id
1252
- this.companyInput.value = this._purchaseOrderData.bizplace.name
1297
+ this.companyInput.value = e.detail.name
1253
1298
  this.productGrist.reset()
1254
1299
  this._configureProductGrist()
1255
1300
  }}"
@@ -1359,6 +1404,215 @@ class PurchaseOrderDetail extends connect(store)(localize(i18next)(PageView)) {
1359
1404
  if (!this._bizplaces) this._bizplaces = await this.fetchBizplaces()
1360
1405
  }
1361
1406
 
1407
+ poExcelColumns() {
1408
+ const productGrist = [
1409
+ {
1410
+ type: 'string',
1411
+ name: 'batchId',
1412
+ header: i18next.t('field.batch_id'),
1413
+ imex: { header: i18next.t('field.batch_id'), key: 'batchId', width: 25, type: 'string' },
1414
+ width: 100
1415
+ },
1416
+ {
1417
+ type: 'string',
1418
+ name: 'productSKU',
1419
+ header: i18next.t('field.sku'),
1420
+ imex: { header: i18next.t('field.sku'), key: 'productSKU', width: 25, type: 'string' },
1421
+ width: 100
1422
+ },
1423
+ {
1424
+ type: 'string',
1425
+ name: 'packingType',
1426
+ header: i18next.t('field.packing_type'),
1427
+ imex: { header: i18next.t('field.packing_type'), key: 'packingType', width: 25, type: 'string' },
1428
+ width: 100
1429
+ },
1430
+ {
1431
+ type: 'string',
1432
+ name: 'remark',
1433
+ header: i18next.t('field.remark'),
1434
+ imex: { header: i18next.t('field.remark'), key: 'remark', width: 25, type: 'string' },
1435
+ width: 100
1436
+ },
1437
+ {
1438
+ type: 'integer',
1439
+ name: 'packQty',
1440
+ header: i18next.t('field.pack_qty'),
1441
+ imex: { header: i18next.t('field.pack_qty'), key: 'packQty', width: 25, type: 'float' },
1442
+ width: 100
1443
+ },
1444
+ {
1445
+ type: 'float',
1446
+ name: 'unitPrice',
1447
+ header: i18next.t('field.unit_price'),
1448
+ imex: { header: i18next.t('field.unit_price'), key: 'unitPrice', width: 25, type: 'float' },
1449
+ width: 100
1450
+ },
1451
+ {
1452
+ type: 'float',
1453
+ name: 'miscAmt',
1454
+ header: i18next.t('field.misc_amt'),
1455
+ imex: { header: i18next.t('field.misc_amt'), key: 'miscAmt', width: 25, type: 'float' },
1456
+ width: 100
1457
+ },
1458
+ {
1459
+ type: 'float',
1460
+ name: 'discountAmt',
1461
+ header: i18next.t('field.total_disc_amt'),
1462
+ imex: { header: i18next.t('field.total_disc_amt'), key: 'discountAmt', width: 25, type: 'float' },
1463
+ width: 100
1464
+ },
1465
+ {
1466
+ type: 'float',
1467
+ name: 'taxRate',
1468
+ header: i18next.t('field.tax_rate') + '(%)',
1469
+ imex: { header: i18next.t('field.tax_rate'), key: 'taxRate', width: 25, type: 'float' },
1470
+ width: 90
1471
+ }
1472
+ ]
1473
+
1474
+ return productGrist
1475
+ }
1476
+
1477
+ async _exportableData() {
1478
+ try {
1479
+ var headerSetting = [
1480
+ ...this.poExcelColumns()
1481
+ .filter(column => column.type !== 'gutter' && column.imex !== undefined)
1482
+ .map(column => {
1483
+ return column.imex
1484
+ })
1485
+ ]
1486
+
1487
+ return { header: headerSetting, data: [] }
1488
+ } catch (e) {
1489
+ this._showToast(e)
1490
+ }
1491
+ }
1492
+
1493
+ async bulkUploadValidatePoOrderProducts(patches) {
1494
+ const response = await client.query({
1495
+ query: gql`
1496
+ query bulkUploadValidatePoOrderProducts($orderProducts: [NewOrderProduct!], $partnerBizplaceId: String!) {
1497
+ bulkUploadValidatePoOrderProducts(orderProducts: $orderProducts, partnerBizplaceId: $partnerBizplaceId) {
1498
+ id
1499
+ packingType
1500
+ packingSize
1501
+ uom
1502
+ uomValue
1503
+ totalUomValue
1504
+ packQty
1505
+ unitPrice
1506
+ miscAmt
1507
+ discountAmt
1508
+ taxRate
1509
+ batchId
1510
+ batchIdRef
1511
+ unitPrice
1512
+ remark
1513
+ productSKU
1514
+ productName
1515
+ productBrand
1516
+ isError
1517
+ product {
1518
+ id
1519
+ name
1520
+ sku
1521
+ description
1522
+ type
1523
+ brand
1524
+ primaryUnit
1525
+ primaryValue
1526
+ }
1527
+ }
1528
+ }
1529
+ `,
1530
+ variables: { orderProducts: patches, partnerBizplaceId: this.partnerBizplaceId }
1531
+ })
1532
+
1533
+ if (!response.errors) {
1534
+ const data = response.data.bulkUploadValidatePoOrderProducts.map(item => {
1535
+ return {
1536
+ ...item,
1537
+ productName: item?.productName,
1538
+ unitPrice: parseFloat(item.unitPrice) || 0,
1539
+ packQty: parseInt(item.packQty) || 0,
1540
+ miscAmt: parseFloat(item.miscAmt) || 0,
1541
+ discountAmt: parseFloat(item.discountAmt) || 0,
1542
+ taxRate: parseFloat(item.taxRate) || 0
1543
+ }
1544
+ })
1545
+ this.productData = {
1546
+ ...this.productData,
1547
+ records: data.map((dt, idx) => {
1548
+ return {
1549
+ ...dt,
1550
+ name: idx,
1551
+ __dirty__: '+'
1552
+ }
1553
+ })
1554
+ }
1555
+
1556
+ this.productGrist.fetch()
1557
+ }
1558
+ }
1559
+
1560
+ async importHandler(records) {
1561
+ this.productData = { records }
1562
+
1563
+ const orderProducts = records.map(record => {
1564
+ delete record.cuFlag
1565
+ delete record.id
1566
+ return {
1567
+ ...record,
1568
+ unitPrice: record?.unitPrice > 0 ? parseFloat(record?.unitPrice?.toFixed(2)) : 0,
1569
+ packQty: parseInt(record?.packQty) || 0,
1570
+ miscAmt: record?.miscAmt > 0 ? parseFloat(record?.miscAmt?.toFixed(2)) : 0,
1571
+ discountAmt: record?.discountAmt > 0 ? parseFloat(record?.discountAmt?.toFixed(2)) : 0,
1572
+ taxRate: record?.taxRate > 0 ? parseFloat(record?.taxRate?.toFixed(2)) : 0
1573
+ }
1574
+ })
1575
+ await this.bulkUploadValidatePoOrderProducts(orderProducts)
1576
+ history.back()
1577
+ }
1578
+
1579
+ async _importableData(records) {
1580
+ try {
1581
+ if (this.partnerBizplaceId) {
1582
+ records = records
1583
+ .filter(record => record.productSKU)
1584
+ .map(record => {
1585
+ return {
1586
+ ...record
1587
+ }
1588
+ })
1589
+
1590
+ openPopup(
1591
+ html`
1592
+ <import-pop-up
1593
+ .records=${records}
1594
+ .config=${{
1595
+ rows: this.productGristConfig.rows,
1596
+ columns: [...this.poExcelColumns().filter(column => column.imex !== undefined)]
1597
+ }}
1598
+ .importHandler="${await this.importHandler.bind(this)}"
1599
+ ></import-pop-up>
1600
+ `,
1601
+ {
1602
+ backdrop: true,
1603
+ escapable: false,
1604
+ size: 'large',
1605
+ title: i18next.t('title.import')
1606
+ }
1607
+ )
1608
+ } else {
1609
+ throw new Error(i18next.t('text.please_select_a_company'))
1610
+ }
1611
+ } catch (e) {
1612
+ this._showToast(e)
1613
+ }
1614
+ }
1615
+
1362
1616
  _showToast({ type, message }) {
1363
1617
  document.dispatchEvent(
1364
1618
  new CustomEvent('notify', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/sales-ui",
3
- "version": "4.3.21",
3
+ "version": "4.3.22",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -29,10 +29,10 @@
29
29
  "@things-factory/grist-ui": "^4.3.20",
30
30
  "@things-factory/i18n-base": "^4.3.20",
31
31
  "@things-factory/import-ui": "^4.3.20",
32
- "@things-factory/sales-base": "^4.3.21",
32
+ "@things-factory/sales-base": "^4.3.22",
33
33
  "@things-factory/setting-ui": "^4.3.20",
34
34
  "@things-factory/shell": "^4.3.20",
35
- "@things-factory/warehouse-ui": "^4.3.21"
35
+ "@things-factory/warehouse-ui": "^4.3.22"
36
36
  },
37
- "gitHead": "2021cf9407cfd29d9e1b32063f834584c7b97714"
37
+ "gitHead": "9dd1ce192948dbc0e4f3611e11f4804b71d06643"
38
38
  }
@@ -17,9 +17,14 @@
17
17
  "field.total_disc_amt": "total disc amt",
18
18
  "field.uom": "uom",
19
19
  "label.currency": "currency",
20
+ "label.misc_amt": "misc amt",
20
21
  "label.module": "module",
22
+ "label.pack_qty": "pack qty",
21
23
  "label.please_select_a_currency": "please select a currency",
22
24
  "label.supplier": "supplier",
25
+ "label.tax_rate": "tax rate",
26
+ "label.total_disc_amt": "total disc amt",
27
+ "label.unit_price": "unit price",
23
28
  "text.draft_order_saved": "draft order saved",
24
29
  "text.generate_release_order(s)": "generate release order(s)",
25
30
  "text.please_select_a_valid_draft_order_to_generate_release_order": "please select a valid draft order to generate release order",
@@ -36,5 +36,10 @@
36
36
  "title.purchase_order_detail": "[ko]purchase order detail",
37
37
  "title.purchase_order": "[ko]purchase order",
38
38
  "title.purchase_orders_approval": "[ko]purchase orders approval",
39
- "title.purchase_orders": "[ko]purchase orders"
39
+ "title.purchase_orders": "[ko]purchase orders",
40
+ "label.pack_qty": "[ko] pack qty",
41
+ "label.unit_price": "[ko] unit price",
42
+ "label.misc_amt": "[ko] misc amt",
43
+ "label.total_disc_amt": "[ko] total disc amt",
44
+ "label.tax_rate": "[ko] tax rate"
40
45
  }
@@ -36,5 +36,10 @@
36
36
  "title.purchase_order_detail": "[ms]purchase order detail",
37
37
  "title.purchase_order": "[ms]purchase order",
38
38
  "title.purchase_orders_approval": "[ms]purchase orders approval",
39
- "title.purchase_orders": "[ms]purchase orders"
39
+ "title.purchase_orders": "[ms]purchase orders",
40
+ "label.pack_qty": "[ms] pack qty",
41
+ "label.unit_price": "[ms] unit price",
42
+ "label.misc_amt": "[ms] misc amt",
43
+ "label.total_disc_amt": "[ms] total disc amt",
44
+ "label.tax_rate": "[ms] tax rate"
40
45
  }
@@ -36,5 +36,10 @@
36
36
  "title.purchase_order_detail": "[zh]purchase order detail",
37
37
  "title.purchase_order": "[zh]purchase order",
38
38
  "title.purchase_orders_approval": "[zh]purchase orders approval",
39
- "title.purchase_orders": "[zh]purchase orders"
39
+ "title.purchase_orders": "[zh]purchase orders",
40
+ "label.pack_qty": "[zh] pack qty",
41
+ "label.unit_price": "[zh] unit price",
42
+ "label.misc_amt": "[zh] misc amt",
43
+ "label.total_disc_amt": "[zh] total disc amt",
44
+ "label.tax_rate": "[zh] tax rate"
40
45
  }