@questwork/q-store-model 0.1.35 → 0.1.36

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.
@@ -57,12 +57,15 @@ __webpack_require__.d(__webpack_exports__, {
57
57
  ChainManager: () => (/* reexport */ ChainManager),
58
58
  ChainManagerFactory: () => (/* reexport */ ChainManagerFactory),
59
59
  ChainTarget: () => (/* reexport */ ChainTarget),
60
+ CouponManager: () => (/* reexport */ CouponManager),
60
61
  CreditNote: () => (/* reexport */ CreditNote),
61
62
  CreditNoteLine: () => (/* reexport */ CreditNoteLine),
62
63
  CreditNoteRepo: () => (/* reexport */ CreditNoteRepo),
63
64
  Currency: () => (/* reexport */ Currency),
64
65
  Invoice: () => (/* reexport */ Invoice),
65
66
  InvoiceLine: () => (/* reexport */ InvoiceLine),
67
+ ItemOption: () => (/* reexport */ ItemOption),
68
+ ItemOptionLocale: () => (/* reexport */ ItemOptionLocale),
66
69
  KeyValueObject: () => (/* reexport */ q_utilities_namespaceObject.KeyValueObject),
67
70
  Merchandise: () => (/* reexport */ Merchandise),
68
71
  PaymentGateway: () => (/* reexport */ PaymentGateway),
@@ -71,9 +74,11 @@ __webpack_require__.d(__webpack_exports__, {
71
74
  PriceStrategy: () => (/* reexport */ PriceStrategy),
72
75
  Product: () => (/* reexport */ Product),
73
76
  Status: () => (/* reexport */ Status),
77
+ StoreItem: () => (/* reexport */ StoreItem),
74
78
  Transaction: () => (/* reexport */ Transaction),
75
79
  WalletItem: () => (/* reexport */ WalletItem),
76
80
  adminSettle: () => (/* reexport */ adminSettle),
81
+ calculateByCoupon: () => (/* reexport */ calculateByCoupon),
77
82
  calculator: () => (/* reexport */ calculator),
78
83
  checkDuplicate: () => (/* reexport */ checkDuplicate),
79
84
  convertTimestampToString: () => (/* reexport */ convertTimestampToString),
@@ -109,6 +114,8 @@ __webpack_require__.d(models_namespaceObject, {
109
114
  Currency: () => (Currency),
110
115
  Invoice: () => (Invoice),
111
116
  InvoiceLine: () => (InvoiceLine),
117
+ ItemOption: () => (ItemOption),
118
+ ItemOptionLocale: () => (ItemOptionLocale),
112
119
  KeyValueObject: () => (q_utilities_namespaceObject.KeyValueObject),
113
120
  Merchandise: () => (Merchandise),
114
121
  PaymentGateway: () => (PaymentGateway),
@@ -117,6 +124,7 @@ __webpack_require__.d(models_namespaceObject, {
117
124
  PriceStrategy: () => (PriceStrategy),
118
125
  Product: () => (Product),
119
126
  Status: () => (Status),
127
+ StoreItem: () => (StoreItem),
120
128
  Transaction: () => (Transaction),
121
129
  WalletItem: () => (WalletItem)
122
130
  });
@@ -716,20 +724,83 @@ const stringHelper = {
716
724
 
717
725
 
718
726
 
727
+ ;// ./lib/models/itemOption/itemOptionLocale.js
728
+ const itemOptionLocale_updateAllowedProps = [
729
+ 'label',
730
+ 'locale',
731
+ 'value'
732
+ ]
733
+
734
+ class ItemOptionLocale {
735
+ constructor(options = {}) {
736
+ options = options || {}
737
+ this.locale = options.locale
738
+ this.label = options.label
739
+ this.value = options.value || ''
740
+ }
741
+ static dummyData() {
742
+ return {
743
+ // locale: 'zh-hk',
744
+ }
745
+ }
746
+ static init(options = {}) {
747
+ if (options instanceof this) {
748
+ return options
749
+ }
750
+ const instance = new this(options)
751
+ return instance.isValid ? instance : null
752
+ }
753
+ static initFromArray(arr = []) {
754
+ if (Array.isArray(arr)) {
755
+ return arr.map((a) => this.init(a))
756
+ }
757
+ return []
758
+ }
759
+ static initOnlyValidFromArray(arr = []) {
760
+ return this.initFromArray(arr).filter((i) => i)
761
+ }
762
+ static get _classname() {
763
+ return 'ItemOptionLocale'
764
+ }
765
+ static get _superclass() {
766
+ return 'ItemOptionLocale'
767
+ }
768
+
769
+ get isValid() {
770
+ return !!this
771
+ }
772
+
773
+ update(update) {
774
+ Object.keys(update).forEach((key) => {
775
+ if (itemOptionLocale_updateAllowedProps.includes(key)) {
776
+ this[key] = update[key]
777
+ }
778
+ })
779
+ return this
780
+ }
781
+ }
782
+
783
+
784
+
719
785
  ;// ./lib/models/itemOption/itemOption.js
720
786
 
721
787
 
788
+
722
789
  const itemOption_updateAllowedProps = [
723
790
  'description',
724
791
  'key',
725
792
  'label',
726
793
  'type',
727
- 'value'
794
+ 'value',
795
+ 'locales'
728
796
  ]
729
797
 
730
798
  class ItemOption {
731
799
  constructor(options = {}) {
732
800
  options = options || {}
801
+ const { _ItemOptionLocale } = options._constructor || {}
802
+ this._ItemOptionLocale = _ItemOptionLocale && (_ItemOptionLocale._superclass === ItemOptionLocale._superclass) ? _ItemOptionLocale : ItemOptionLocale
803
+
733
804
  this.approved = options.approved || false
734
805
  this.description = options.description
735
806
  // this.header = options.header
@@ -737,9 +808,11 @@ class ItemOption {
737
808
  this.itemOptionType = options.itemOptionType || 'ItemOption'
738
809
  this.key = options.key
739
810
  this.label = options.label
811
+ this.layout = options.layout
740
812
  this.required = options.required || false
741
813
  this.type = options.type
742
814
  this.value = options.value || ''
815
+ this.locales = this._ItemOptionLocale.initOnlyValidFromArray(options.locales)
743
816
  }
744
817
  static dummyData() {
745
818
  return {
@@ -800,7 +873,12 @@ class ItemOption {
800
873
  update(update) {
801
874
  Object.keys(update).forEach((key) => {
802
875
  if (itemOption_updateAllowedProps.includes(key)) {
803
- this[key] = update[key]
876
+ if (key === 'locales') {
877
+ this[key] = this._ItemOptionLocale.initOnlyValidFromArray(update[key])
878
+ } else {
879
+ this[key] = update[key]
880
+ }
881
+ // this[key] = update[key]
804
882
  }
805
883
  })
806
884
  return this
@@ -822,6 +900,7 @@ function itemOption_setCode(options, key) {
822
900
 
823
901
 
824
902
 
903
+
825
904
  ;// ./lib/models/merchandiseOption/merchandiseOption.js
826
905
  class MerchandiseOption {
827
906
  constructor(options = {}) {
@@ -1131,7 +1210,7 @@ class PriceStrategy {
1131
1210
  acc = acc || matchAnd(key, value, payload)
1132
1211
  // Object.keys(value).forEach((path) => {
1133
1212
  // const val = lodash.get(payload[key], path)
1134
- // acc = acc || matcher(val, value[path])
1213
+ // acc = acc || _matcher(val, value[path])
1135
1214
  // })
1136
1215
  return acc
1137
1216
  }, false)
@@ -1185,7 +1264,8 @@ class PriceStrategy {
1185
1264
  function matchAnd(key, value, payload) {
1186
1265
  return Object.keys(value).reduce((acc, path) => {
1187
1266
  const val = external_lodash_namespaceObject.get(payload[key], path)
1188
- acc = acc && matcher(val, value[path])
1267
+ const actions = Object.keys(value[path])
1268
+ acc = acc && _matcher(val, value[path], actions, true)
1189
1269
  return acc
1190
1270
  }, true)
1191
1271
  }
@@ -1196,20 +1276,40 @@ function matchAnd(key, value, payload) {
1196
1276
  * @param {Object} [formula={}] - The formula object to check the value against.
1197
1277
  * @returns {boolean} - Whether the value matches the formula.
1198
1278
  */
1199
- function matcher(val, formula = {}) {
1200
- const [action] = Object.keys(formula)
1279
+ function _matcher(val, formula = {}, actions = [], match = true) {
1280
+ // const actions = Object.keys(formula)
1281
+ if (!match || actions.length === 0) {
1282
+ return match
1283
+ }
1284
+ const action = actions.shift()
1285
+ // const [action] = Object.keys(formula)
1201
1286
  const formulaValue = formula[action]
1287
+ match = _match({ action, formulaValue, val })
1288
+ return _matcher(val, formula, actions, match)
1289
+ }
1290
+
1291
+ function _match({ action, formulaValue, val }) {
1202
1292
  switch (action) {
1293
+ case 'elemMatch':
1203
1294
  case '$elemMatch': // val is array and formulaValue is object
1204
1295
  return (val || []).some((v) => {
1205
1296
  return (Object.keys(formulaValue)).filter((key) => {
1206
1297
  return Object.prototype.hasOwnProperty.call(v, key) && v[key] === formulaValue[key]
1207
1298
  }).length > 0
1208
1299
  })
1300
+ case 'eq':
1209
1301
  case '$eq':
1210
1302
  return external_lodash_namespaceObject.isEqual(val, formulaValue)
1303
+ case 'gt':
1304
+ case '$gt':
1305
+ return val > formulaValue
1306
+ case 'gte':
1307
+ case '$gte':
1308
+ return val >= formulaValue
1211
1309
  case '$in':
1212
1310
  return formulaValue.includes(val)
1311
+ case '$includes':
1312
+ return val.includes(formulaValue)
1213
1313
  case '$keyValue':
1214
1314
  if (Array.isArray(val)) {
1215
1315
  return (val.find((remark) => {
@@ -1220,6 +1320,15 @@ function matcher(val, formula = {}) {
1220
1320
  return formulaValue.key === val.key && formulaValue.values.includes(val.value)
1221
1321
  }
1222
1322
  return false
1323
+ case 'lt':
1324
+ case '$lt':
1325
+ return val < formulaValue
1326
+ case 'lte':
1327
+ case '$lte':
1328
+ return val <= formulaValue
1329
+ case 'ne':
1330
+ case '$ne':
1331
+ return val !== formulaValue
1223
1332
  default:
1224
1333
  return true
1225
1334
  }
@@ -1273,7 +1382,7 @@ class Price {
1273
1382
  name: 'Standard',
1274
1383
  dateBegin: new Date().valueOf(),
1275
1384
  dateEnd: new Date().valueOf() + 1,
1276
- priceStrategies: [this._PriceStrategy.dummyData()],
1385
+ priceStrategies: [PriceStrategy.dummyData()],
1277
1386
  // roles: []
1278
1387
  // qtyPerTransaction: QtyPerTransaction.init()
1279
1388
  }
@@ -1431,16 +1540,15 @@ class Price {
1431
1540
 
1432
1541
 
1433
1542
  const product_updateAllowedProps = [
1434
- 'active',
1435
- 'deleted',
1543
+ 'couponDetails',
1436
1544
  'description',
1437
1545
  'entitlements',
1438
1546
  'intangible',
1439
1547
  'limitPercentage',
1548
+ 'lineOptions',
1440
1549
  'maxPerWallet',
1441
1550
  'name',
1442
1551
  'originalStock',
1443
- 'owner',
1444
1552
  'printable',
1445
1553
  'printLayoutCodes',
1446
1554
  'printLayoutMappingCodes',
@@ -1448,34 +1556,31 @@ const product_updateAllowedProps = [
1448
1556
  // 'productCategoryCodes',
1449
1557
  'productGroupName',
1450
1558
  'productOptions',
1451
- 'remarks',
1452
1559
  'requiredProductCode',
1453
1560
  'stock'
1454
1561
  ]
1455
1562
 
1456
- class Product {
1563
+ class Product extends q_utilities_namespaceObject.TenantAwareEntity {
1457
1564
  constructor(options = {}) {
1458
1565
  options = options || {}
1566
+ super(options)
1567
+
1459
1568
  const { _ItemOption } = options._constructor || {}
1460
1569
  this._ItemOption = _ItemOption && (_ItemOption._superclass === ItemOption) ? _ItemOption : ItemOption
1461
1570
 
1462
1571
  const id = options._id || options.id
1463
1572
  this.id = setId(id)
1464
1573
  this._type = options._type || 'Product'
1465
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
1466
- this.created = options.created || (new Date()).valueOf()
1467
- this.creator = options.creator
1468
- this.deleted = options.deleted || false
1574
+
1575
+ this.couponDetails = options.couponDetails
1469
1576
  this.description = options.description || ''
1470
1577
  this.entitlements = options.entitlements // ['freeRegistration'], ['presidentialDinner', 'galaDinner']
1471
1578
  this.intangible = options.intangible || false
1472
1579
  this.limitPercentage = options.limitPercentage || 100
1580
+ this.lineOptions = this._ItemOption.initOnlyValidFromArray(options.lineOptions)
1473
1581
  this.maxPerWallet = options.maxPerWallet || 1
1474
- this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
1475
- this.modified = options.modified || (new Date()).valueOf()
1476
1582
  this.name = options.name || ''
1477
1583
  this.originalStock = options.originalStock || 0
1478
- this.owner = options.owner
1479
1584
  this.printable = options.printable || false
1480
1585
  this.printLayoutCodes = options.printLayoutCodes || []
1481
1586
  // will be not use property 'printLayoutMappingCodes'
@@ -1485,10 +1590,9 @@ class Product {
1485
1590
  this.productCode = product_setCode(options, 'productCode')
1486
1591
  this.productGroupName = (typeof options.productGroupName !== 'undefined') ? options.productGroupName.toUpperCase() : options.productGroupName || 'DEFAULT'
1487
1592
  this.productOptions = this._ItemOption.initOnlyValidFromArray(options.productOptions)
1593
+ this.productType = options.productType || 'Product'
1488
1594
  this.requiredProductCode = options.requiredProductCode
1489
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
1490
1595
  this.stock = options.stock || 0
1491
- this.tenantCode = options.tenantCode
1492
1596
  }
1493
1597
 
1494
1598
  // class method
@@ -1498,22 +1602,6 @@ class Product {
1498
1602
  tenantCode: 'tenantCode'
1499
1603
  }
1500
1604
  }
1501
- static init(options = {}) {
1502
- if (options instanceof this) {
1503
- return options
1504
- }
1505
- const instance = new this(options)
1506
- return instance.isValid ? instance : null
1507
- }
1508
- static initFromArray(arr = []) {
1509
- if (Array.isArray(arr)) {
1510
- return arr.map((a) => this.init(a))
1511
- }
1512
- return []
1513
- }
1514
- static initOnlyValidFromArray(arr = []) {
1515
- return this.initFromArray(arr).filter((i) => i)
1516
- }
1517
1605
  static get _classname() {
1518
1606
  return 'Product'
1519
1607
  }
@@ -1523,11 +1611,17 @@ class Product {
1523
1611
 
1524
1612
  // getters
1525
1613
  get isValid() {
1526
- return !!this.tenantCode && !!this.name
1614
+ return super.isValid && !!this.name
1527
1615
  }
1528
1616
  get isBadge() {
1529
1617
  return this.productGroupName === 'BADGE'
1530
1618
  }
1619
+ get isCoupon() {
1620
+ return this.productGroupName === 'COUPON'
1621
+ }
1622
+ get isItemCoupon() {
1623
+ return this.couponDetails ? this.couponDetails.item : false
1624
+ }
1531
1625
  get isPrintable() {
1532
1626
  return this.printLayoutMappingCodes.length > 0
1533
1627
  }
@@ -1566,6 +1660,12 @@ class Product {
1566
1660
  return acc
1567
1661
  }, { errMsgs: [] })
1568
1662
  }
1663
+ getCode() {
1664
+ return this.productCode
1665
+ }
1666
+ getMetadataValueByKey(key) {
1667
+ return q_utilities_namespaceObject.Metadata.getValueByKey(this.metadata || [], key)
1668
+ }
1569
1669
  getProductOptionByKey(key) {
1570
1670
  const arr = this._ItemOption.getByKey(this.productOptions, key)
1571
1671
  if (arr.length === 1) {
@@ -1576,28 +1676,32 @@ class Product {
1576
1676
  hasStock(qty) {
1577
1677
  return this.stock >= qty
1578
1678
  }
1679
+ isApplicableCoupon(obj) {
1680
+ const { merchandiseCodes = [] } = this.couponDetails || {}
1681
+ return merchandiseCodes.length > 0 ? merchandiseCodes.includes(obj.merchandiseCode) : true
1682
+ }
1683
+ isQualified(data) {
1684
+ const rules = this.getMetadataValueByKey('RULES') || []
1685
+ return (rules.length === 0)
1686
+ ? true
1687
+ : rules.reduce((acc, r) => {
1688
+ return acc || (0,q_utilities_namespaceObject.getValidation)(r, data, _getDataByKey, q_utilities_namespaceObject.KeyValueObject)
1689
+ }, false)
1690
+ }
1579
1691
  isTicket() {
1580
1692
  return false
1581
1693
  }
1582
- setModified() {
1583
- this.modified = (new Date()).valueOf()
1584
- return this
1585
- }
1586
1694
  update(update) {
1587
1695
  Object.keys(update).forEach((key) => {
1588
1696
  if (product_updateAllowedProps.includes(key)) {
1589
- if (key === 'metadata') {
1590
- this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
1591
- } else if (key === 'productOptions') {
1697
+ if (key === 'productOptions' || key === 'lineOptions') {
1592
1698
  this[key] = this._ItemOption.initOnlyValidFromArray(update[key])
1593
- } else if (key === 'remarks') {
1594
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
1595
1699
  } else {
1596
1700
  this[key] = update[key]
1597
1701
  }
1598
1702
  }
1599
1703
  })
1600
- return this.setModified()
1704
+ return super.update(update)
1601
1705
  }
1602
1706
  }
1603
1707
 
@@ -1616,6 +1720,10 @@ function product_setCode(options, key) {
1616
1720
  return stringHelper.setCode()
1617
1721
  }
1618
1722
 
1723
+ function _getDataByKey(key, data) {
1724
+ return (0,q_utilities_namespaceObject.getValueByKeys)(key.split('.'), data)
1725
+ }
1726
+
1619
1727
 
1620
1728
 
1621
1729
  ;// ./lib/models/product/productRepo.js
@@ -1655,11 +1763,8 @@ class ProductRepo extends q_utilities_namespaceObject.Repo {
1655
1763
 
1656
1764
 
1657
1765
 
1658
-
1659
1766
  const merchandise_updateAllowedProps = [
1660
- 'active',
1661
1767
  'defaultCurrency',
1662
- 'deleted',
1663
1768
  'description',
1664
1769
  'eventSessionCode',
1665
1770
  'intangible',
@@ -1667,23 +1772,22 @@ const merchandise_updateAllowedProps = [
1667
1772
  'max',
1668
1773
  'merchandiseCategoryCodes',
1669
1774
  'merchandiseOptions',
1670
- 'metadata',
1671
1775
  'name',
1672
1776
  'onlyFor',
1673
- 'owner',
1674
1777
  'prices',
1675
1778
  'pricings',
1676
1779
  'priority',
1677
1780
  'productCodes',
1678
- 'remarks',
1679
1781
  'sku',
1680
1782
  'stock',
1681
1783
  'visibleBy'
1682
1784
  ]
1683
1785
 
1684
- class Merchandise {
1786
+ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
1685
1787
  constructor(options = {}) {
1686
1788
  options = options || {}
1789
+ super(options)
1790
+
1687
1791
  const { _ItemOption, _ItemOptionFillIn, _MerchandiseOption, _Price, _Product } = options._constructor || {}
1688
1792
  this._ItemOption = _ItemOption && (_ItemOption._superclass === ItemOption._superclass) ? _I_ItemOptiontemOptionFillIn : ItemOption
1689
1793
  this._ItemOptionFillIn = _ItemOptionFillIn && (_ItemOptionFillIn._superclass === ItemOptionFillIn._superclass) ? _ItemOptionFillIn : ItemOptionFillIn
@@ -1692,16 +1796,11 @@ class Merchandise {
1692
1796
  this._Product = _Product && (_Product._superclass === Product._superclass) ? _Product : Product
1693
1797
 
1694
1798
  this._products = options._products || []
1695
- this._tenant = options._tenant
1696
1799
  this._type = options._type || 'Merchandise'
1697
1800
 
1698
1801
  const id = options._id || options.id
1699
1802
  this.id = merchandise_setId(id)
1700
- this._type = options._type || 'Merchandise'
1701
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
1702
- this.created = options.created || (new Date()).valueOf()
1703
- this.creator = options.creator
1704
- this.deleted = options.deleted || false
1803
+
1705
1804
  this.defaultCurrency = options.defaultCurrency || 'HKD'
1706
1805
  this.description = options.description
1707
1806
  this.free = options.free || false
@@ -1710,17 +1809,12 @@ class Merchandise {
1710
1809
  this.merchandiseCategoryCodes = options.merchandiseCategoryCodes || []
1711
1810
  this.merchandiseCode = merchandise_setCode(options, 'merchandiseCode')
1712
1811
  this.merchandiseOptions = initMerchandiseOptions(this, options)
1713
- this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
1714
- this.modified = options.modified || (new Date()).valueOf()
1715
1812
  this.name = options.name || ''
1716
- this.owner = options.owner
1717
1813
  this.prices = this._Price.initOnlyValidFromArray(options.prices)
1718
1814
  this.productCodes = options.productCodes || []
1719
1815
  this.priority = options.priority || 100
1720
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
1721
1816
  this.sku = options.sku || ''
1722
1817
  this.stock = options.stock || 0
1723
- this.tenantCode = options.tenantCode
1724
1818
  }
1725
1819
 
1726
1820
  // Class Mehtods
@@ -1741,22 +1835,6 @@ class Merchandise {
1741
1835
  tenantCode: '85223977000',
1742
1836
  }
1743
1837
  }
1744
- static init(options = {}) {
1745
- if (options instanceof this) {
1746
- return options
1747
- }
1748
- const instance = new this(options)
1749
- return instance.isValid ? instance : null
1750
- }
1751
- static initFromArray(arr = []) {
1752
- if (Array.isArray(arr)) {
1753
- return arr.map((a) => this.init(a))
1754
- }
1755
- return []
1756
- }
1757
- static initOnlyValidFromArray(arr = []) {
1758
- return this.initFromArray(arr).filter((i) => i)
1759
- }
1760
1838
  static get _classname() {
1761
1839
  return 'Merchandise'
1762
1840
  }
@@ -1810,7 +1888,7 @@ class Merchandise {
1810
1888
  return this.printOut.isPrintable
1811
1889
  }
1812
1890
  get isValid() {
1813
- return !!this.tenantCode && !!this.name && (!!this.productCodes && this.productCodes.length > 0)
1891
+ return super.isValid && !!this.name && (!!this.productCodes && this.productCodes.length > 0)
1814
1892
  }
1815
1893
  get products() {
1816
1894
  return this._Product.initOnlyValidFromArray(this._products || [])
@@ -1957,6 +2035,43 @@ class Merchandise {
1957
2035
  }
1958
2036
  return info
1959
2037
  }
2038
+ getBeginAndEndDates() {
2039
+ const dates = {
2040
+ dateBegin: null,
2041
+ dateEnd: null
2042
+ }
2043
+ // BUG this.pricings is undefind
2044
+ return this.pricings.reduce((acc, pricing) => {
2045
+ if (!acc.dateBegin || (pricing.dateBegin > acc.dateBegin)) {
2046
+ acc.dateBegin = pricing.dateBegin
2047
+ }
2048
+
2049
+ if (!acc.dateEnd || (pricing.dateEnd <= acc.dateEnd)) {
2050
+ acc.dateEnd = pricing.dateEnd
2051
+ }
2052
+ return acc
2053
+ }, dates)
2054
+ }
2055
+ getCode() {
2056
+ return this.merchandiseCode
2057
+ }
2058
+ getCurrentPrice() {
2059
+ const timestamp = (new Date()).valueOf()
2060
+ const prices = this.getPricesByTime(timestamp)
2061
+ if (prices.length === 1) {
2062
+ return prices[0]
2063
+ }
2064
+ return null
2065
+ }
2066
+ getCurrentPriceByRoleCodes(roleCodes) {
2067
+ const timestamp = (new Date()).valueOf()
2068
+ let prices = this.getPricesByTime(timestamp)
2069
+ prices = Price.getPricesByRoleCodes(prices, roleCodes)
2070
+ if (prices.length === 1) {
2071
+ return prices[0]
2072
+ }
2073
+ return null
2074
+ }
1960
2075
  getItemOptionInfos(cartItems = []) {
1961
2076
  return cartItems.reduce((acc, cartItem) => {
1962
2077
  const itemOptionFillIns = cartItem.getItemOptionFillIns()
@@ -1983,47 +2098,13 @@ class Merchandise {
1983
2098
  }
1984
2099
  return null
1985
2100
  }
1986
- getProducts() {
1987
- return this.products || []
1988
- }
1989
- getCurrentPriceByRoleCodes(roleCodes) {
1990
- const timestamp = (new Date()).valueOf()
1991
- let prices = this.getPricesByTime(timestamp)
1992
- prices = Price.getPricesByRoleCodes(prices, roleCodes)
1993
- if (prices.length === 1) {
1994
- return prices[0]
1995
- }
1996
- return null
1997
- }
1998
- getCurrentPrice() {
1999
- const timestamp = (new Date()).valueOf()
2000
- const prices = this.getPricesByTime(timestamp)
2001
- if (prices.length === 1) {
2002
- return prices[0]
2003
- }
2004
- return null
2101
+ getPrices() {
2102
+ return this.prices ? this.prices : []
2005
2103
  }
2006
2104
  getPricesByTime(timestamp) {
2007
2105
  const copyDate = timestamp || (new Date()).valueOf()
2008
2106
  return Price.getPricesByTime(this.prices, copyDate)
2009
2107
  }
2010
- getBeginAndEndDates() {
2011
- const dates = {
2012
- dateBegin: null,
2013
- dateEnd: null
2014
- }
2015
- // BUG this.pricings is undefind
2016
- return this.pricings.reduce((acc, pricing) => {
2017
- if (!acc.dateBegin || (pricing.dateBegin > acc.dateBegin)) {
2018
- acc.dateBegin = pricing.dateBegin
2019
- }
2020
-
2021
- if (!acc.dateEnd || (pricing.dateEnd <= acc.dateEnd)) {
2022
- acc.dateEnd = pricing.dateEnd
2023
- }
2024
- return acc
2025
- }, dates)
2026
- }
2027
2108
  getPriceByTimeAndRoleCodes(timestamp, roleCodes) {
2028
2109
  let prices = this.getPricesByTime(timestamp)
2029
2110
  prices = Price.getPricesByRoleCodes(prices, roleCodes)
@@ -2032,14 +2113,13 @@ class Merchandise {
2032
2113
  }
2033
2114
  return null
2034
2115
  }
2035
- getPrices() {
2036
- return this.prices ? this.prices : []
2037
- }
2038
- getRemarksByKey(key) {
2039
- return q_utilities_namespaceObject.KeyValueObject.getValuesByKey(this.remarks, key)
2116
+ getProducts() {
2117
+ return this.products || []
2040
2118
  }
2041
- getStock() {
2042
- return this.stock || 0
2119
+ getProductsMetadataValuesByKey(key) {
2120
+ return this.products.map((p) => {
2121
+ return p.getMetadataValueByKey(key)
2122
+ }).filter((i) => i)
2043
2123
  }
2044
2124
  getProductsQty(qty = 1) {
2045
2125
  return this.productCodes.reduce((acc, productCode) => {
@@ -2051,13 +2131,16 @@ class Merchandise {
2051
2131
  return acc
2052
2132
  }, {})
2053
2133
  }
2134
+ getRemarksByKey(key) {
2135
+ return q_utilities_namespaceObject.KeyValueObject.getValuesByKey(this.remarks, key)
2136
+ }
2137
+ getStock() {
2138
+ return this.stock || 0
2139
+ }
2140
+
2054
2141
  reachLimit(qty) {
2055
2142
  return this.max < qty
2056
2143
  }
2057
- setModified() {
2058
- this.modified = (new Date()).valueOf()
2059
- return this
2060
- }
2061
2144
  setPrices(prices) {
2062
2145
  if (Array.isArray(prices)) {
2063
2146
  this.prices = Price.initOnlyValidFromArray(prices)
@@ -2071,18 +2154,14 @@ class Merchandise {
2071
2154
  this[key] = this._ItemOption.initOnlyValidFromArray(update[key])
2072
2155
  } else if (key === 'merchandiseOptions' && !!this.tenantCode) {
2073
2156
  this[key] = MerchandiseOption.initOnlyValidFromArray(update[key])
2074
- } else if (key === 'metadata') {
2075
- this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
2076
2157
  } else if (key === 'prices') {
2077
2158
  this[key] = Price.initOnlyValidFromArray(update[key])
2078
- } else if (key === 'remarks') {
2079
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
2080
2159
  } else {
2081
2160
  this[key] = update[key]
2082
2161
  }
2083
2162
  }
2084
2163
  })
2085
- return this.setModified()
2164
+ return super.update(update)
2086
2165
  }
2087
2166
  }
2088
2167
 
@@ -2602,6 +2681,9 @@ class Status {
2602
2681
  // this.cancelled = null
2603
2682
  // return this
2604
2683
  // }
2684
+ unSetOnHold() {
2685
+ this.onHold = null
2686
+ }
2605
2687
  update(update) {
2606
2688
  Object.keys(update).forEach((key) => {
2607
2689
  if (!notUpdateAllowedProps.includes(key)) {
@@ -2623,14 +2705,14 @@ class Status {
2623
2705
  // import { WalletItem } from '../walletItem/index.js'
2624
2706
 
2625
2707
  const cart_updateAllowedProps = [
2626
- 'active',
2627
- 'remarks',
2628
- 'deleted',
2708
+
2629
2709
  ]
2630
2710
 
2631
- class Cart {
2711
+ class Cart extends q_utilities_namespaceObject.TenantAwareEntity {
2632
2712
  constructor(options = {}) {
2633
2713
  options = options || {}
2714
+ super(options)
2715
+
2634
2716
  const { _CartItem, _Merchandise, _Status } = options._constructor || {}
2635
2717
  this._CartItem = _CartItem && (_CartItem._superclass === CartItem._superclass) ? _CartItem : CartItem
2636
2718
  this._Merchandise = _Merchandise && (_Merchandise._superclass === Merchandise._superclass) ? _Merchandise : Merchandise
@@ -2643,18 +2725,9 @@ class Cart {
2643
2725
  this._merchandises = options._merchandises
2644
2726
  this._type = options._type || 'Cart'
2645
2727
 
2646
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
2647
2728
  this.cartCode = cart_setCode(options, 'cartCode')
2648
2729
  this.cartItems = this._CartItem.initOnlyValidFromArray(options.cartItems)
2649
- this.created = options.created || (new Date()).valueOf()
2650
- this.creator = options.creator
2651
- this.deleted = options.deleted || false
2652
- this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
2653
- this.modified = options.modified || (new Date()).valueOf()
2654
- this.owner = options.owner
2655
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
2656
2730
  this.status = this._Status.init(options.status)
2657
- this.tenantCode = options.tenantCode
2658
2731
  }
2659
2732
 
2660
2733
  // Class Methods
@@ -2664,22 +2737,6 @@ class Cart {
2664
2737
  tenantCode: 'tenantCode'
2665
2738
  }
2666
2739
  }
2667
- static init(options = {}) {
2668
- if (options instanceof this) {
2669
- return options
2670
- }
2671
- const instance = new this(options)
2672
- return instance.isValid ? instance : null
2673
- }
2674
- static initFromArray(arr = []) {
2675
- if (Array.isArray(arr)) {
2676
- return arr.map((a) => this.init(a))
2677
- }
2678
- return []
2679
- }
2680
- static initOnlyValidFromArray(arr = []) {
2681
- return this.initFromArray(arr).filter((i) => i)
2682
- }
2683
2740
  static get _classname() {
2684
2741
  return 'Cart'
2685
2742
  }
@@ -2689,7 +2746,7 @@ class Cart {
2689
2746
 
2690
2747
  // getters
2691
2748
  get isValid() {
2692
- return !!this.tenantCode
2749
+ return super.isValid
2693
2750
  }
2694
2751
  get isActive() {
2695
2752
  return !!this.active
@@ -2805,6 +2862,9 @@ class Cart {
2805
2862
  getCartItemCodes() {
2806
2863
  return this.cartItems.map((cartItem) => cartItem.cartItemCode)
2807
2864
  }
2865
+ getCode() {
2866
+ return this.cartCode
2867
+ }
2808
2868
  getCurrencyCode() {
2809
2869
  return this.cartItems.length > 0
2810
2870
  ? this.cartItems[0].getCurrencyCode()
@@ -2858,10 +2918,6 @@ class Cart {
2858
2918
  this.status.setCompleted()
2859
2919
  return this.setModified()
2860
2920
  }
2861
- setModified() {
2862
- this.modified = (new Date()).valueOf()
2863
- return this
2864
- }
2865
2921
  updateAvailable({ isCoordinator, selectCartItems }) {
2866
2922
  try {
2867
2923
  if (!isCoordinator) {
@@ -2875,16 +2931,10 @@ class Cart {
2875
2931
  update(update) {
2876
2932
  Object.keys(update).forEach((key) => {
2877
2933
  if (cart_updateAllowedProps.includes(key)) {
2878
- if (key === 'metadata') {
2879
- this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
2880
- } else if (key === 'remarks') {
2881
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
2882
- } else {
2883
- this[key] = update[key]
2884
- }
2934
+ this[key] = update[key]
2885
2935
  }
2886
2936
  })
2887
- return this.setModified()
2937
+ return super.update(update)
2888
2938
  }
2889
2939
  updateStock() {
2890
2940
  if (this.cartItems.length === 0) {
@@ -2970,22 +3020,20 @@ class CartRepo extends q_utilities_namespaceObject.Repo {
2970
3020
 
2971
3021
 
2972
3022
  const category_updateAllowedProps = [
2973
- 'active',
2974
3023
  'codes',
2975
- 'deleted',
2976
3024
  'description',
2977
3025
  'max',
2978
3026
  'min',
2979
3027
  'name',
2980
- 'owner',
2981
3028
  'priority',
2982
3029
  'productCodes',
2983
- 'remarks',
2984
3030
  ]
2985
3031
 
2986
- class Category {
3032
+ class Category extends q_utilities_namespaceObject.TenantAwareEntity {
2987
3033
  constructor(options) {
2988
3034
  options = options || {}
3035
+ super(options)
3036
+
2989
3037
  const { _Product } = options._constructor || {}
2990
3038
  this._Product = _Product && (_Product._superclass === Product._superclass) ? _Product : Product
2991
3039
 
@@ -2994,22 +3042,15 @@ class Category {
2994
3042
 
2995
3043
  const id = options._id || options.id
2996
3044
  this.id = category_setId(id)
2997
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3045
+
2998
3046
  this.categoryCode = category_setCode(options, 'categoryCode')
2999
3047
  this.codes = options.codes || []
3000
- this.created = options.created || (new Date()).valueOf()
3001
- this.creator = options.creator
3002
- this.deleted = options.deleted || false
3003
3048
  this.description = options.description
3004
3049
  this.max = options.max || 1
3005
3050
  this.min = options.min || 0
3006
- this.modified = options.modified || (new Date()).valueOf()
3007
3051
  this.name = options.name
3008
- this.owner = options.owner
3009
3052
  this.priority = options.priority || 10
3010
3053
  this.productCodes = options.productCodes || []
3011
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3012
- this.tenantCode = options.tenantCode
3013
3054
  }
3014
3055
 
3015
3056
  // class methods
@@ -3019,22 +3060,6 @@ class Category {
3019
3060
  tenantCode: 'tenantCode'
3020
3061
  }
3021
3062
  }
3022
- static init(options = {}) {
3023
- if (options instanceof this) {
3024
- return options
3025
- }
3026
- const instance = new this(options)
3027
- return instance.isValid ? instance : null
3028
- }
3029
- static initFromArray(arr = []) {
3030
- if (Array.isArray(arr)) {
3031
- return arr.map((a) => this.init(a))
3032
- }
3033
- return []
3034
- }
3035
- static initOnlyValidFromArray(arr = []) {
3036
- return this.initFromArray(arr).filter((i) => i)
3037
- }
3038
3063
  static get _classname() {
3039
3064
  return 'Category'
3040
3065
  }
@@ -3044,29 +3069,20 @@ class Category {
3044
3069
 
3045
3070
  // getters
3046
3071
  get isValid() {
3047
- return !!this.name && !!this.tenantCode && this.max > this. min
3072
+ return super.isValid && !!this.name && this.max > this. min
3048
3073
  }
3049
3074
  get products() {
3050
3075
  return this._Product.initOnlyValidFromArray(this._products)
3051
3076
  }
3052
3077
 
3053
3078
  // instance methods
3054
- setModified() {
3055
- this.modified = (new Date()).valueOf()
3056
- return this
3057
- }
3058
-
3059
3079
  update(update) {
3060
3080
  Object.keys(update).forEach((key) => {
3061
3081
  if (category_updateAllowedProps.includes(key)) {
3062
- if (key === 'remarks') {
3063
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
3064
- } else {
3065
- this[key] = update[key]
3066
- }
3082
+ this[key] = update[key]
3067
3083
  }
3068
3084
  })
3069
- return this.setModified()
3085
+ return super.update(update)
3070
3086
  }
3071
3087
  }
3072
3088
 
@@ -3123,20 +3139,19 @@ class CategoryRepo extends q_utilities_namespaceObject.Repo {
3123
3139
 
3124
3140
 
3125
3141
  const creditNoteLine_updateAllowedProps = [
3126
- 'active',
3127
3142
  'amount',
3128
3143
  // 'deduction',
3129
- 'deleted',
3130
3144
  'description',
3131
3145
  // 'discount',
3132
3146
  'qty',
3133
- 'remarks',
3134
3147
  // 'unitPrice'
3135
3148
  ]
3136
3149
 
3137
- class CreditNoteLine {
3150
+ class CreditNoteLine extends q_utilities_namespaceObject.TenantAwareEntity {
3138
3151
  constructor(options = {}) {
3139
3152
  options = options || {}
3153
+ super(options)
3154
+
3140
3155
  const { _Amount } = options._constructor || {}
3141
3156
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
3142
3157
 
@@ -3145,21 +3160,14 @@ class CreditNoteLine {
3145
3160
 
3146
3161
  const id = options._id || options.id
3147
3162
  this.id = creditNoteLine_setId(id)
3148
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3163
+
3149
3164
  this.amount = this._Amount.init(options.amount)
3150
- this.created = options.created || (new Date()).valueOf()
3151
- this.creator = options.creator
3152
3165
  this.creditNoteCode = options.creditNoteCode
3153
3166
  this.creditNoteLineCode = creditNoteLine_setCode(options, 'creditNoteLineCode')
3154
3167
  // this.deduction = this._Amount.init(options.deduction)
3155
- this.deleted = options.deleted || false
3156
3168
  this.description = options.description
3157
3169
  // this.discount = options.discount || 0
3158
- this.modified = options.modified || (new Date()).valueOf()
3159
- this.owner = options.owner
3160
3170
  this.qty = options.qty || 1
3161
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3162
- this.tenantCode = options.tenantCode
3163
3171
  // this.unitPrice = Amount.init(options.unitPrice)
3164
3172
  }
3165
3173
 
@@ -3170,22 +3178,6 @@ class CreditNoteLine {
3170
3178
  tenantCode: 'tenantCode'
3171
3179
  }
3172
3180
  }
3173
- static init(options = {}) {
3174
- if (options instanceof this) {
3175
- return options
3176
- }
3177
- const instance = new this(options)
3178
- return instance.isValid ? instance : null
3179
- }
3180
- static initFromArray(arr = []) {
3181
- if (Array.isArray(arr)) {
3182
- return arr.map((a) => this.init(a))
3183
- }
3184
- return []
3185
- }
3186
- static initOnlyValidFromArray(arr = []) {
3187
- return this.initFromArray(arr).filter((i) => i)
3188
- }
3189
3181
  static get _classname() {
3190
3182
  return 'CreditNoteLine'
3191
3183
  }
@@ -3196,7 +3188,7 @@ class CreditNoteLine {
3196
3188
 
3197
3189
  // getters
3198
3190
  get isValid() {
3199
- return !!this.creditNoteCode && !!this.tenantCode
3191
+ return super.isValid && !!this.creditNoteCode
3200
3192
  }
3201
3193
 
3202
3194
  // instance methods
@@ -3207,10 +3199,6 @@ class CreditNoteLine {
3207
3199
  }
3208
3200
  return this
3209
3201
  }
3210
- setModified() {
3211
- this.modified = (new Date()).valueOf()
3212
- return this
3213
- }
3214
3202
 
3215
3203
  update(update) {
3216
3204
  Object.keys(update).forEach((key) => {
@@ -3224,7 +3212,7 @@ class CreditNoteLine {
3224
3212
  }
3225
3213
  }
3226
3214
  })
3227
- return this.setModified()
3215
+ return super.update(update)
3228
3216
  }
3229
3217
  }
3230
3218
 
@@ -3283,17 +3271,16 @@ class CreditNoteLineRepo extends q_utilities_namespaceObject.Repo {
3283
3271
 
3284
3272
 
3285
3273
  const creditNote_updateAllowedProps = [
3286
- 'active',
3287
- 'deleted',
3288
3274
  'description',
3289
- 'remarks',
3290
3275
  'status'
3291
3276
  ]
3292
3277
 
3293
- class CreditNote {
3278
+ class CreditNote extends q_utilities_namespaceObject.TenantAwareEntity {
3294
3279
  constructor(options = {}) {
3295
3280
  options = options || {}
3296
- const { _Amount, _CreditNoteLine } = options._constructor || {}
3281
+ super(options)
3282
+
3283
+ const { _Amount, _CreditNoteLine, _Status } = options._constructor || {}
3297
3284
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
3298
3285
  this._CreditNoteLine = _CreditNoteLine && (_CreditNoteLine._superclass === CreditNoteLine._superclass) ? _CreditNoteLine : CreditNoteLine
3299
3286
  this._Status = _Status && (_Status._superclass === Status._superclass) ? _Status : Status
@@ -3302,21 +3289,13 @@ class CreditNote {
3302
3289
 
3303
3290
  const id = options._id || options.id
3304
3291
  this.id = creditNote_setId(id)
3305
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3292
+
3306
3293
  this.amount = this._Amount.init(options.amount)
3307
- this.created = options.created || (new Date()).valueOf()
3308
- this.creator = options.creator
3309
3294
  this.creditNoteCode = creditNote_setCode(options, 'creditNoteCode')
3310
3295
  this.creditNoteLines = this._CreditNoteLine.initOnlyValidFromArray(options.creditNoteLines)
3311
- this.deleted = options.deleted || false
3312
3296
  this.description = options.description
3313
3297
  this.invoiceCode = options.invoiceCode
3314
- this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
3315
- this.modified = options.modified || (new Date()).valueOf()
3316
- this.owner = options.owner
3317
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3318
3298
  this.status = this._Status.init(options.status)
3319
- this.tenantCode = options.tenantCode
3320
3299
  }
3321
3300
 
3322
3301
  // Class Methods
@@ -3326,22 +3305,6 @@ class CreditNote {
3326
3305
  tenantCode: 'tenantCode'
3327
3306
  }
3328
3307
  }
3329
- static init(options = {}) {
3330
- if (options instanceof this) {
3331
- return options
3332
- }
3333
- const instance = new this(options)
3334
- return instance.isValid ? instance : null
3335
- }
3336
- static initFromArray(arr = []) {
3337
- if (Array.isArray(arr)) {
3338
- return arr.map((a) => this.init(a))
3339
- }
3340
- return []
3341
- }
3342
- static initOnlyValidFromArray(arr = []) {
3343
- return this.initFromArray(arr).filter((i) => i)
3344
- }
3345
3308
  static get _classname() {
3346
3309
  return 'CreditNote'
3347
3310
  }
@@ -3359,9 +3322,11 @@ class CreditNote {
3359
3322
  }
3360
3323
 
3361
3324
  get isValid() {
3362
- return !!this.tenantCode && !!this.invoiceCode
3325
+ return super.isValid && !!this.invoiceCode
3326
+ }
3327
+ getCode() {
3328
+ return this.creditNoteCode
3363
3329
  }
3364
-
3365
3330
  setAmount(amount) {
3366
3331
  const a = this_Amount.init(amount)
3367
3332
  if (this.isPending && a) {
@@ -3373,10 +3338,6 @@ class CreditNote {
3373
3338
  this.status.setCompleted()
3374
3339
  return this.setModified()
3375
3340
  }
3376
- setModified() {
3377
- this.modified = (new Date()).valueOf()
3378
- return this
3379
- }
3380
3341
  setPaid(t) {
3381
3342
  this.status.setPaid(t)
3382
3343
  return this.setModified()
@@ -3386,10 +3347,6 @@ class CreditNote {
3386
3347
  if (creditNote_updateAllowedProps.includes(key)) {
3387
3348
  if (key === 'amount') {
3388
3349
  this[key] = this._Amount.init(update[key])
3389
- } else if (key === 'metadata') {
3390
- this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
3391
- } else if (key === 'remarks') {
3392
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
3393
3350
  } else if (key === 'status') {
3394
3351
  this[key] = this._Status.init(update[key])
3395
3352
  } else {
@@ -3397,7 +3354,7 @@ class CreditNote {
3397
3354
  }
3398
3355
  }
3399
3356
  })
3400
- return this.setModified()
3357
+ return super.update(update)
3401
3358
  }
3402
3359
  }
3403
3360
 
@@ -3451,35 +3408,27 @@ class CreditNoteRepo extends q_utilities_namespaceObject.Repo {
3451
3408
 
3452
3409
 
3453
3410
  const currency_updateAllowedProps = [
3454
- 'active',
3455
- 'deleted',
3456
3411
  'description',
3457
3412
  'name',
3458
- 'remarks',
3459
3413
  'symbol'
3460
3414
  ]
3461
3415
 
3462
- class Currency {
3416
+ class Currency extends q_utilities_namespaceObject.TenantAwareEntity {
3463
3417
  constructor(options = {}) {
3464
3418
  options = options || {}
3419
+ super(options)
3420
+
3465
3421
  const id = options._id || options.id
3466
3422
  this.id = currency_setId(id)
3467
3423
 
3468
3424
  this._type = options._type || 'Currency'
3469
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3425
+
3470
3426
  this.code = options.code // 'HKD'
3471
- this.created = options.created || (new Date()).valueOf()
3472
- this.creator = options.creator
3473
3427
  this.currencyCode = currency_setCode(options, 'currencyCode')
3474
- this.deleted = options.deleted || false
3475
3428
  this.description = options.description
3476
3429
  this.factor = options.factor || 1 // 100
3477
- this.modified = options.modified || (new Date()).valueOf()
3478
3430
  this.name = options.name
3479
- this.owner = options.owner
3480
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3481
3431
  this.symbol = options.symbol || null
3482
- this.tenantCode = options.tenantCode
3483
3432
  this.unit = options.unit
3484
3433
  }
3485
3434
  static dummyData() {
@@ -3491,22 +3440,6 @@ class Currency {
3491
3440
  unit: 'Cent',
3492
3441
  }
3493
3442
  }
3494
- static init(options = {}) {
3495
- if (options instanceof this) {
3496
- return options
3497
- }
3498
- const instance = new this(options)
3499
- return instance.isValid ? instance : null
3500
- }
3501
- static initFromArray(arr = []) {
3502
- if (Array.isArray(arr)) {
3503
- return arr.map((a) => this.init(a))
3504
- }
3505
- return []
3506
- }
3507
- static initOnlyValidFromArray(arr = []) {
3508
- return this.initFromArray(arr).filter((i) => i)
3509
- }
3510
3443
  static get _classname() {
3511
3444
  return 'Currency'
3512
3445
  }
@@ -3515,29 +3448,23 @@ class Currency {
3515
3448
  }
3516
3449
 
3517
3450
  get isValid() {
3518
- return !!this.code && typeof this.factor === 'number' && !!this.name && !!this.unit && !!this.tenantCode
3451
+ return super.isValid && !!this.code && typeof this.factor === 'number' && !!this.name && !!this.unit
3519
3452
  }
3520
3453
 
3521
3454
  fromCurrencyValue(value) {
3522
3455
  return value / this.factor
3523
3456
  }
3524
-
3525
- setModified() {
3526
- this.modified = (new Date()).valueOf()
3527
- return this
3457
+ getCode() {
3458
+ return this.currencyCode
3528
3459
  }
3529
3460
 
3530
3461
  update(update) {
3531
3462
  Object.keys(update).forEach((key) => {
3532
3463
  if (currency_updateAllowedProps.includes(key)) {
3533
- if (key === 'remarks') {
3534
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
3535
- } else {
3536
- this[key] = update[key]
3537
- }
3464
+ this[key] = update[key]
3538
3465
  }
3539
3466
  })
3540
- return this.setModified()
3467
+ return super.update(update)
3541
3468
  }
3542
3469
  }
3543
3470
 
@@ -3588,6 +3515,74 @@ class CurrencyRepo extends q_utilities_namespaceObject.Repo {
3588
3515
 
3589
3516
 
3590
3517
 
3518
+ ;// ./lib/helpers/getPurchaseOptionValue/getPurchaseOptionValue.js
3519
+ function getPurchaseOptionValue(options) {
3520
+ const {
3521
+ delimiter = ': ',
3522
+ key,
3523
+ purchaseOptions,
3524
+ tag = 'div'
3525
+ } = options || {}
3526
+ if (!key) {
3527
+ return purchaseOptions.reduce((acc, purchaseOption) => {
3528
+ const arr = _getOnePurchaseOptionValue({
3529
+ delimiter, purchaseOption, tag
3530
+ })
3531
+ if (tag) {
3532
+ acc.push(`<${tag}>${arr.join('')}</${tag}>`)
3533
+ } else {
3534
+ acc.push(`${arr.join('; ')}`)
3535
+ }
3536
+ return acc
3537
+ }, [])
3538
+ }
3539
+ const purchaseOption = (purchaseOptions || []).find((po) => {
3540
+ return !!key && po.key === key
3541
+ })
3542
+ if (!purchaseOption) {
3543
+ return []
3544
+ }
3545
+ return _getOnePurchaseOptionValue({
3546
+ delimiter, purchaseOption, tag
3547
+ })
3548
+ }
3549
+
3550
+ function _getOnePurchaseOptionValue({
3551
+ delimiter = ': ',
3552
+ purchaseOption,
3553
+ tag = 'div'
3554
+ }) {
3555
+ return (purchaseOption.value || []).reduce((acc, val) => {
3556
+ const { label, value = {} } = val || {}
3557
+ const _label = label ?? ''
3558
+ if (Array.isArray(value)) {
3559
+ if (tag) {
3560
+ acc.push(`<${tag}>${_label}${delimiter}${value.join(delimiter)}</${tag}>`)
3561
+ } else {
3562
+ acc.push(`${_label}${delimiter}${value.join(delimiter)}`)
3563
+ }
3564
+ } else if (typeof value === 'object') {
3565
+ Object.keys(value).map((key) => {
3566
+ if (tag) {
3567
+ acc.push(`<${tag}>${key}${delimiter}${value[key]}</${tag}>`)
3568
+ } else {
3569
+ acc.push(`${key}${delimiter}${value[key]}`)
3570
+ }
3571
+ })
3572
+ } else {
3573
+ if (tag) {
3574
+ acc.push(`<${tag}>${_label}${delimiter}${value}</${tag}>`)
3575
+ } else {
3576
+ acc.push(`${_label}${delimiter}${value}`)
3577
+ }
3578
+ }
3579
+
3580
+ return acc
3581
+ }, [])
3582
+ }
3583
+
3584
+
3585
+
3591
3586
  ;// ./lib/models/invoiceLine/invoiceLine.js
3592
3587
 
3593
3588
 
@@ -3596,22 +3591,22 @@ class CurrencyRepo extends q_utilities_namespaceObject.Repo {
3596
3591
 
3597
3592
 
3598
3593
 
3594
+
3599
3595
  const invoiceLine_updateAllowedProps = [
3600
- 'active',
3601
3596
  'amount',
3602
3597
  'deduction',
3603
- 'deleted',
3604
3598
  'description',
3605
3599
  'discount',
3606
3600
  'purchaseOptions',
3607
3601
  'qty',
3608
- 'remarks',
3609
3602
  'unitPrice'
3610
3603
  ]
3611
3604
 
3612
- class InvoiceLine {
3605
+ class InvoiceLine extends q_utilities_namespaceObject.TenantAwareEntity {
3613
3606
  constructor(options = {}) {
3614
3607
  options = options || {}
3608
+ super(options)
3609
+
3615
3610
  const { _Amount, _Invoice, _Merchandise, _Status } = options._constructor || {}
3616
3611
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
3617
3612
  this._Invoice = _Invoice && (_Invoice._superclass === Invoice._superclass) ? _Invoice : Invoice
@@ -3624,23 +3619,16 @@ class InvoiceLine {
3624
3619
  const id = options._id || options.id
3625
3620
  this.id = invoiceLine_setId(id)
3626
3621
  this._type = options._type || 'InvoiceLine'
3627
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3628
3622
  this.amount = this._Amount.init(options.amount)
3629
- this.created = options.created || (new Date()).valueOf()
3630
- this.creator = options.creator
3631
3623
  this.deduction = this._Amount.init(options.deduction)
3632
- this.deleted = options.deleted || false
3633
3624
  this.description = options.description
3634
3625
  this.discount = options.discount || 0
3635
3626
  this.invoiceCode = options.invoiceCode
3636
3627
  this.invoiceLineCode = invoiceLine_setCode(options, 'invoiceLineCode')
3637
3628
  this.merchandiseCode = options.merchandiseCode
3638
- this.modified = options.modified || (new Date()).valueOf()
3639
3629
  this.purchaseOptions = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.purchaseOptions)
3640
3630
  this.qty = options.qty || 1
3641
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3642
3631
  this.status = this._Status.init(options.status)
3643
- this.tenantCode = options.tenantCode
3644
3632
  this.unitPrice = this._Amount.init(options.unitPrice)
3645
3633
  this.waived = options.waived || 0
3646
3634
  }
@@ -3653,24 +3641,8 @@ class InvoiceLine {
3653
3641
  tenantCode: 'tenantCode'
3654
3642
  }
3655
3643
  }
3656
- static init(options = {}) {
3657
- if (options instanceof this) {
3658
- return options
3659
- }
3660
- const instance = new this(options)
3661
- return instance.isValid ? instance : null
3662
- }
3663
- static initFromArray(arr = []) {
3664
- if (Array.isArray(arr)) {
3665
- return arr.map((a) => this.init(a))
3666
- }
3667
- return []
3668
- }
3669
- static initOnlyValidFromArray(arr = []) {
3670
- return this.initFromArray(arr).filter((i) => i)
3671
- }
3672
- static get _classname() {
3673
- return 'InvoiceLine'
3644
+ static get _classname() {
3645
+ return 'InvoiceLine'
3674
3646
  }
3675
3647
  static get _superclass() {
3676
3648
  return 'InvoiceLine'
@@ -3678,7 +3650,7 @@ class InvoiceLine {
3678
3650
 
3679
3651
  // getters
3680
3652
  get isValid() {
3681
- return !!this.amount && !!this.invoiceCode && !!this.tenantCode
3653
+ return super.isValid && !!this.amount && !!this.invoiceCode
3682
3654
  }
3683
3655
  get invoice() {
3684
3656
  return this._Invoice.init(this._invoice)
@@ -3688,11 +3660,13 @@ class InvoiceLine {
3688
3660
  }
3689
3661
 
3690
3662
  // instance methods
3691
- setModified() {
3692
- this.modified = (new Date()).valueOf()
3693
- return this
3663
+ getPurchaseOptionValue(options) {
3664
+ const { delimiter, key, tag } = options || {}
3665
+ return getPurchaseOptionValue({
3666
+ key,
3667
+ purchaseOptions: this.purchaseOptions
3668
+ })
3694
3669
  }
3695
-
3696
3670
  update(update) {
3697
3671
  Object.keys(update).forEach((key) => {
3698
3672
  if (invoiceLine_updateAllowedProps.includes(key)) {
@@ -3705,7 +3679,7 @@ class InvoiceLine {
3705
3679
  }
3706
3680
  }
3707
3681
  })
3708
- return this.setModified()
3682
+ return super.update(update)
3709
3683
  }
3710
3684
  }
3711
3685
 
@@ -3815,45 +3789,38 @@ class Issuer {
3815
3789
 
3816
3790
 
3817
3791
 
3792
+
3818
3793
  // import { Transaction } from '../transaction/index.js'
3819
3794
 
3820
3795
  const walletItem_updateAllowedProps = [
3821
- 'active',
3822
- 'deleted',
3823
- 'owner',
3824
3796
  'purchaseOptions',
3825
3797
  'qty',
3826
- 'remarks',
3827
3798
  'status',
3828
3799
  ]
3829
3800
 
3830
- class WalletItem {
3801
+ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
3831
3802
  constructor(options = {}) {
3832
3803
  options = options || {}
3804
+ super(options)
3805
+
3833
3806
  const { _Product, _Status } = options._constructor || {}
3834
3807
  this._Product = _Product && (_Product._superclass === Product._superclass) ? _Product : Product
3835
3808
  this._Status = _Status && (_Status._superclass === Status._superclass) ? _Status : Status
3836
3809
  // this._Transaction = _Transaction && (_Transaction._superclass === Transaction._superclass) ? _Transaction : Transaction
3837
3810
 
3811
+ this._eventRegistration = options._eventRegistration
3812
+ this._invoiceLine = options._invoiceLine
3838
3813
  this._product = options._product
3839
3814
  this._tenant = options._tenant
3840
3815
  this._transaction = options._transaction
3841
3816
 
3842
3817
  const id = options._id || options.id
3843
3818
  this.id = walletItem_setId(id)
3844
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3845
- this.created = options.created || (new Date()).valueOf()
3846
- this.creator = options.creator
3847
- this.deleted = options.deleted || false
3848
- this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
3849
- this.modified = options.modified || (new Date()).valueOf()
3850
- this.owner = options.owner
3819
+ this.invoiceLineCode = options.invoiceLineCode
3851
3820
  this.productCode = options.productCode
3852
3821
  this.purchaseOptions = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.purchaseOptions)
3853
3822
  this.qty = options.qty || 1
3854
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3855
3823
  this.status = this._Status.init(options.status)
3856
- this.tenantCode = options.tenantCode
3857
3824
  this.transactionCode = options.transactionCode
3858
3825
  this.walletItemCode = walletItem_setCode(options, 'walletItemCode')
3859
3826
  }
@@ -3869,22 +3836,7 @@ class WalletItem {
3869
3836
  transactionCode: 'transactionCode'
3870
3837
  }
3871
3838
  }
3872
- static init(options = {}) {
3873
- if (options instanceof this) {
3874
- return options
3875
- }
3876
- const instance = new this(options)
3877
- return instance.isValid ? instance : null
3878
- }
3879
- static initFromArray(arr = []) {
3880
- if (Array.isArray(arr)) {
3881
- return arr.map((a) => this.init(a))
3882
- }
3883
- return []
3884
- }
3885
- static initOnlyValidFromArray(arr = []) {
3886
- return this.initFromArray(arr).filter((i) => i)
3887
- }
3839
+
3888
3840
  static get _classname() {
3889
3841
  return 'WalletItem'
3890
3842
  }
@@ -3894,11 +3846,14 @@ class WalletItem {
3894
3846
 
3895
3847
  // getters
3896
3848
  get isValid() {
3897
- return !!this.tenantCode && !!this.productCode
3849
+ return super.isValid && !!this.productCode
3898
3850
  }
3899
3851
  get isAssigned() {
3900
3852
  return this.status.isAssigned
3901
3853
  }
3854
+ get isAvailableCoupon() {
3855
+ return this.isCoupon && !this.isCancelled && !this.isUsed
3856
+ }
3902
3857
  get isCancelled() {
3903
3858
  return this.status.isCancelled
3904
3859
  }
@@ -3908,9 +3863,21 @@ class WalletItem {
3908
3863
  get isConfirmed() {
3909
3864
  return this.status.isConfirmed
3910
3865
  }
3866
+ get isCoupon() {
3867
+ return this.product ? this.product.isCoupon : false
3868
+ }
3911
3869
  get isDelivered() {
3912
3870
  return this.status.isDelivered
3913
3871
  }
3872
+ get isInWallet() {
3873
+ return !this.isCancelled && !this.isRefundRequested
3874
+ }
3875
+ get isItemCoupon() {
3876
+ return this.product ? this.product.isItemCoupon : false
3877
+ }
3878
+ get isOnHold() {
3879
+ return this.status.onHold
3880
+ }
3914
3881
  get isOwned() {
3915
3882
  return (
3916
3883
  !this.isCancelled && !this.isRejected && !this.isRefunded
@@ -3934,6 +3901,9 @@ class WalletItem {
3934
3901
  get isRefunded() {
3935
3902
  return this.status.isRefunded
3936
3903
  }
3904
+ get isRefundRequested() {
3905
+ return this.status.isRefundRequested
3906
+ }
3937
3907
  get isRejected() {
3938
3908
  return this.status.rejected
3939
3909
  }
@@ -3949,6 +3919,10 @@ class WalletItem {
3949
3919
  get isWaived() {
3950
3920
  return this.status.isWaived
3951
3921
  }
3922
+
3923
+ get couponDetails() {
3924
+ return this.product ? this.product.couponDetails : null
3925
+ }
3952
3926
  get product() {
3953
3927
  return this._Product.init(this._product)
3954
3928
  }
@@ -3980,8 +3954,23 @@ class WalletItem {
3980
3954
  return this
3981
3955
  }
3982
3956
  }
3957
+ getCode() {
3958
+ return this.walletItemCode
3959
+ }
3960
+ getPurchaseOptionValue(options) {
3961
+ const { delimiter, key, tag } = options || {}
3962
+ return getPurchaseOptionValue({
3963
+ delimiter,
3964
+ key,
3965
+ purchaseOptions: this.purchaseOptions,
3966
+ tag,
3967
+ })
3968
+ }
3969
+ isApplicableCoupon(obj) {
3970
+ return this.isAvailableCoupon && (this.product ? this.product.isApplicableCoupon(obj) : false)
3971
+ }
3983
3972
  isSameOwner(userId) {
3984
- return userId
3973
+ return userId && this.owner
3985
3974
  ? (userId === this.owner)
3986
3975
  : false
3987
3976
  }
@@ -3997,8 +3986,8 @@ class WalletItem {
3997
3986
  this.status.setDelivered(value)
3998
3987
  return this
3999
3988
  }
4000
- setModified() {
4001
- this.modified = (new Date()).valueOf()
3989
+ setOnHold() {
3990
+ this.status.setOnHold()
4002
3991
  return this
4003
3992
  }
4004
3993
  setPaid() {
@@ -4031,6 +4020,11 @@ class WalletItem {
4031
4020
  // this.statusTimestamp.setUsed()
4032
4021
  return this
4033
4022
  }
4023
+ setUsedCouponFor(walletItemCode) {
4024
+ const _usedFor = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(this.metadata, 'USED_COUPON_FOR') || []
4025
+ _usedFor.push(walletItemCode)
4026
+ this.metadata = q_utilities_namespaceObject.Metadata.insertOrUpdateRecord(this.metadata, 'USED_COUPON_FOR', _usedFor)
4027
+ }
4034
4028
  setWaived() {
4035
4029
  this.status.setWaived()
4036
4030
  return this
@@ -4051,12 +4045,14 @@ class WalletItem {
4051
4045
  // walletItemCode: this.walletItemCode
4052
4046
  // }
4053
4047
  // }
4048
+ unSetOnHold() {
4049
+ this.status.unSetOnHold()
4050
+ return this
4051
+ }
4054
4052
  update(update) {
4055
4053
  Object.keys(update).forEach((key) => {
4056
4054
  if (walletItem_updateAllowedProps.includes(key)) {
4057
- if (key === 'metadata') {
4058
- this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
4059
- } else if (key === 'purchaseOptions' || key === 'remarks') {
4055
+ if (key === 'purchaseOptions') {
4060
4056
  this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
4061
4057
  } else if (key === 'status') {
4062
4058
  this[key] = this._Status.init(update[key])
@@ -4065,7 +4061,7 @@ class WalletItem {
4065
4061
  }
4066
4062
  }
4067
4063
  })
4068
- return this.setModified()
4064
+ return super.update(update)
4069
4065
  }
4070
4066
  }
4071
4067
 
@@ -4121,18 +4117,17 @@ class WalletItemRepo extends q_utilities_namespaceObject.Repo {
4121
4117
 
4122
4118
 
4123
4119
  const transaction_updateAllowedProps = [
4124
- 'active',
4125
4120
  'amount',
4126
4121
  'couponCodes',
4127
- 'deleted',
4128
4122
  // 'refundedAmount',
4129
- 'remarks',
4130
4123
  'status'
4131
4124
  ]
4132
4125
 
4133
- class Transaction {
4126
+ class Transaction extends q_utilities_namespaceObject.TenantAwareEntity {
4134
4127
  constructor(options = {}) {
4135
4128
  options = options || {}
4129
+ super(options)
4130
+
4136
4131
  const { _Amount, _Status, _WalletItem } = options._constructor || {}
4137
4132
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
4138
4133
  this._Status = _Status && (_Status._superclass === Status._superclass) ? _Status : Status
@@ -4148,22 +4143,14 @@ class Transaction {
4148
4143
  const id = options._id || options.id
4149
4144
  this.id = transaction_setId(id)
4150
4145
  this._type = options._type || 'Transaction'
4151
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
4146
+
4152
4147
  this.amount = this._Amount.init(options.amount)
4153
4148
  this.couponCodes = options.couponCodes || []
4154
- this.created = options.created || (new Date()).valueOf()
4155
- this.creator = options.creator
4156
4149
  this.creditNoteCodes = options.creditNoteCodes || []
4157
- this.deleted = options.deleted || false
4158
4150
  this.invoiceCode = options.invoiceCode
4159
- this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
4160
- this.modified = options.modified || (new Date()).valueOf()
4161
- this.owner = options.owner
4162
4151
  this.paymentGatewayCode = options.paymentGatewayCode
4163
4152
  this.paymentResultRef = options.paymentResultRef
4164
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
4165
4153
  this.status = this._Status.init(options.status)
4166
- this.tenantCode = options.tenantCode
4167
4154
  this.transactionCode = transaction_setCode(options, 'transactionCode')
4168
4155
  }
4169
4156
 
@@ -4174,22 +4161,6 @@ class Transaction {
4174
4161
  tenantCode: 'tenantCode'
4175
4162
  }
4176
4163
  }
4177
- static init(options = {}) {
4178
- if (options instanceof this) {
4179
- return options
4180
- }
4181
- const instance = new this(options)
4182
- return instance.isValid ? instance : null
4183
- }
4184
- static initFromArray(arr = []) {
4185
- if (Array.isArray(arr)) {
4186
- return arr.map((a) => this.init(a))
4187
- }
4188
- return []
4189
- }
4190
- static initOnlyValidFromArray(arr = []) {
4191
- return this.initFromArray(arr).filter((i) => i)
4192
- }
4193
4164
  static get _classname() {
4194
4165
  return 'Transaction'
4195
4166
  }
@@ -4199,7 +4170,7 @@ class Transaction {
4199
4170
 
4200
4171
  // getters
4201
4172
  get isValid() {
4202
- return !!this.tenantCode
4173
+ return super.isValid
4203
4174
  }
4204
4175
  get isActive() {
4205
4176
  return this.active === true
@@ -4338,9 +4309,6 @@ class Transaction {
4338
4309
  setFailed() {
4339
4310
  return this.status.setFailed()
4340
4311
  }
4341
- setModified() {
4342
- return this.modified = (new Date()).valueOf()
4343
- }
4344
4312
  setOnHold() {
4345
4313
  return this.status.setOnHold()
4346
4314
  }
@@ -4397,10 +4365,6 @@ class Transaction {
4397
4365
  if (transaction_updateAllowedProps.includes(key)) {
4398
4366
  if (key === 'amount') {
4399
4367
  this[key] = this._Amount.init(update[key])
4400
- } else if (key === 'metadata') {
4401
- this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
4402
- } else if (key === 'remarks') {
4403
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
4404
4368
  } else if (key === 'status') {
4405
4369
  this[key] = this._Status.init(update[key])
4406
4370
  // } else if (key === 'refundedAmount') {
@@ -4410,7 +4374,7 @@ class Transaction {
4410
4374
  }
4411
4375
  }
4412
4376
  })
4413
- return this.setModified()
4377
+ return super.update(update)
4414
4378
  }
4415
4379
  // updatePayment(payment = {}) {
4416
4380
  // this.payments = Payment.updatePaymentItem(this.payments, payment)
@@ -4485,21 +4449,19 @@ class TransactionRepo extends q_utilities_namespaceObject.Repo {
4485
4449
 
4486
4450
 
4487
4451
  const invoice_updateAllowedProps = [
4488
- 'active',
4489
4452
  'checkoutDateTime',
4490
- 'deleted',
4491
4453
  'description',
4492
4454
  'invoiceDate',
4493
4455
  'issuer',
4494
- 'metadata',
4495
- 'remarks',
4496
4456
  'revisionNumber',
4497
4457
  'status'
4498
4458
  ]
4499
4459
 
4500
- class Invoice {
4460
+ class Invoice extends q_utilities_namespaceObject.TenantAwareEntity {
4501
4461
  constructor(options) {
4502
4462
  options = options || {}
4463
+ super(options)
4464
+
4503
4465
  const { _Amount, _Cart, _InvoiceLine, _Issuer, _Status, _Transaction } = options._constructor || {}
4504
4466
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
4505
4467
  this._Cart = _Cart && (_Cart._superclass === Cart._superclass) ? _Cart : Cart
@@ -4515,25 +4477,16 @@ class Invoice {
4515
4477
  const id = options._id || options.id
4516
4478
  this.id = invoice_setId(id)
4517
4479
  this._type = options._type || 'Invoice'
4518
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
4519
4480
  this.amount = this._Amount.init(options.amount)
4520
4481
  this.cartCode = options.cartCode
4521
4482
  this.checkoutDateTime = options.checkoutDateTime || (new Date()).valueOf()
4522
- this.created = options.created || (new Date()).valueOf()
4523
- this.creator = options.creator
4524
- this.deleted = options.deleted || false
4525
4483
  this.description = options.description
4526
4484
  this.invoiceCode = invoice_setCode(options, 'invoiceCode')
4527
4485
  this.invoiceDate = options.invoiceDate || (new Date()).valueOf()
4528
4486
  this.invoiceNumber = options.invoiceNumber
4529
4487
  this.issuer = this._Issuer.init(options.issuer)
4530
- this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
4531
- this.modified = options.modified || (new Date()).valueOf()
4532
- this.owner = options.owner
4533
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
4534
4488
  this.revisionNumber = options.revisionNumber || 1
4535
4489
  this.status = this._Status.init(options.status)
4536
- this.tenantCode = options.tenantCode
4537
4490
  }
4538
4491
 
4539
4492
  static dummyData() {
@@ -4541,22 +4494,6 @@ class Invoice {
4541
4494
  tenantCode: 'tenantCode'
4542
4495
  }
4543
4496
  }
4544
- static init(options = {}) {
4545
- if (options instanceof this) {
4546
- return options
4547
- }
4548
- const instance = new this(options)
4549
- return instance.isValid ? instance : null
4550
- }
4551
- static initFromArray(arr = []) {
4552
- if (Array.isArray(arr)) {
4553
- return arr.map((a) => this.init(a))
4554
- }
4555
- return []
4556
- }
4557
- static initOnlyValidFromArray(arr = []) {
4558
- return this.initFromArray(arr).filter((i) => i)
4559
- }
4560
4497
  static get _classname() {
4561
4498
  return 'Invoice'
4562
4499
  }
@@ -4565,7 +4502,7 @@ class Invoice {
4565
4502
  }
4566
4503
 
4567
4504
  get isValid() {
4568
- return !!this.tenantCode
4505
+ return super.isValid
4569
4506
  }
4570
4507
  get cart() {
4571
4508
  return this._Cart.init(this._cart)
@@ -4638,7 +4575,9 @@ class Invoice {
4638
4575
  getAmount() {
4639
4576
  return this.amount
4640
4577
  }
4641
-
4578
+ getCode() {
4579
+ return this.invoiceCode
4580
+ }
4642
4581
  getCurrencyCode() {
4643
4582
  return this.amount ? this.amount.getCurrencyCode() : null
4644
4583
  }
@@ -4662,12 +4601,6 @@ class Invoice {
4662
4601
  }
4663
4602
  return this
4664
4603
  }
4665
-
4666
- setModified() {
4667
- this.modified = (new Date()).valueOf()
4668
- return this
4669
- }
4670
-
4671
4604
  setCompleted() {
4672
4605
  this.status.setCompleted()
4673
4606
  return this.setModified()
@@ -4681,12 +4614,8 @@ class Invoice {
4681
4614
  update(update) {
4682
4615
  Object.keys(update).forEach((key) => {
4683
4616
  if (invoice_updateAllowedProps.includes(key)) {
4684
- if (key === 'remarks') {
4685
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
4686
- } else if (key === 'amount') {
4617
+ if (key === 'amount') {
4687
4618
  this[key] = this._Amount.init(update[key])
4688
- } else if (key === 'metadata') {
4689
- this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
4690
4619
  } else if (key === 'issuer') {
4691
4620
  this[key] = this._Issuer.init(update[key])
4692
4621
  } else if (key === 'status') {
@@ -4696,7 +4625,7 @@ class Invoice {
4696
4625
  }
4697
4626
  }
4698
4627
  })
4699
- return this.setModified()
4628
+ return super.update(update)
4700
4629
  }
4701
4630
  }
4702
4631
 
@@ -4751,40 +4680,33 @@ class InvoiceRepo extends q_utilities_namespaceObject.Repo {
4751
4680
  ;// ./lib/models/paymentGateway/paymentGateway.js
4752
4681
 
4753
4682
 
4683
+
4754
4684
  const paymentGateway_updateAllowedProps = [
4755
- 'active',
4756
- 'deleted',
4757
4685
  'label',
4758
4686
  'logoUrl',
4759
4687
  'name',
4760
- 'owner',
4761
4688
  'sandbox',
4762
4689
  'setting'
4763
4690
  ]
4764
4691
 
4765
-
4766
- class PaymentGateway {
4692
+ class PaymentGateway extends q_utilities_namespaceObject.TenantAwareEntity {
4767
4693
  constructor(options = {}) {
4768
4694
  options = options || {}
4695
+ super(options)
4696
+
4769
4697
  const id = options._id || options.id
4770
4698
  this.id = paymentGateway_setId(id)
4771
4699
  this._type = options._type || 'PaymentGateway'
4772
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
4773
- this.created = options.created || (new Date()).valueOf()
4774
- this.creator = options.creator
4775
- this.deleted = options.deleted || false
4700
+
4776
4701
  this.hasWebhook = options.hasWebhook || false
4777
4702
  this.label = options.label
4778
4703
  this.logoUrl = options.logoUrl
4779
- this.modified = options.modified || (new Date()).valueOf()
4780
4704
  this.name = options.name || ''
4781
- this.owner = options.owner
4782
4705
  this.paymentGatewayCode = paymentGateway_setCode(options, 'paymentGatewayCode')
4783
4706
  this.paymentGatewayType = options.paymentGatewayType || 'PaymentGateway'
4784
4707
  this.paymentResultType = options.paymentResultType || 'PaymentResult'
4785
4708
  this.sandbox = options.sandbox || false
4786
4709
  this.setting = options.setting || null
4787
- this.tenantCode = options.tenantCode
4788
4710
  }
4789
4711
  static dummyData() {
4790
4712
  return {
@@ -4792,22 +4714,6 @@ class PaymentGateway {
4792
4714
  tenantCode: 'tenantCode'
4793
4715
  }
4794
4716
  }
4795
- static init(options = {}) {
4796
- if (options instanceof this) {
4797
- return options
4798
- }
4799
- const instance = new this(options)
4800
- return instance.isValid ? instance : null
4801
- }
4802
- static initFromArray(arr = []) {
4803
- if (Array.isArray(arr)) {
4804
- return arr.map((a) => this.init(a))
4805
- }
4806
- return []
4807
- }
4808
- static initOnlyValidFromArray(arr = []) {
4809
- return this.initFromArray(arr).filter((i) => i)
4810
- }
4811
4717
  static get _classname() {
4812
4718
  return 'PaymentGateway'
4813
4719
  }
@@ -4817,7 +4723,7 @@ class PaymentGateway {
4817
4723
 
4818
4724
  // getters
4819
4725
  get isValid() {
4820
- return !!this.name && !!this.tenantCode
4726
+ return super.isValid && !!this.name
4821
4727
  }
4822
4728
 
4823
4729
  // instance methods
@@ -4827,6 +4733,9 @@ class PaymentGateway {
4827
4733
  async getAppPayParams() {
4828
4734
  throw new Error(`${this._classname} subclass should implement getAppPayParams`)
4829
4735
  }
4736
+ getCode() {
4737
+ return this.paymentGatewayCode
4738
+ }
4830
4739
  async updatePayment() {
4831
4740
  throw new Error(`${this._classname} subclass should implement updatePayment`)
4832
4741
  }
@@ -4840,18 +4749,13 @@ class PaymentGateway {
4840
4749
  setCompletedRelatedStatus(status) {
4841
4750
  throw new Error(`${this.name} subclass should implement setCompletedRelatedStatus`)
4842
4751
  }
4843
-
4844
- setModified() {
4845
- this.modified = (new Date()).valueOf()
4846
- return this
4847
- }
4848
4752
  update(update) {
4849
4753
  Object.keys(update).forEach((key) => {
4850
4754
  if (paymentGateway_updateAllowedProps.includes(key)) {
4851
4755
  this[key] = update[key]
4852
4756
  }
4853
4757
  })
4854
- return this.setModified()
4758
+ return super.update(update)
4855
4759
  }
4856
4760
  }
4857
4761
 
@@ -4912,9 +4816,11 @@ const paymentResult_updateAllowedProps = [
4912
4816
  'result'
4913
4817
  ]
4914
4818
 
4915
- class PaymentResult {
4819
+ class PaymentResult extends q_utilities_namespaceObject.TenantAwareEntity {
4916
4820
  constructor(options = {}) {
4917
4821
  options = options || {}
4822
+ super(options)
4823
+
4918
4824
  const { _Transaction } = options._constructor || {}
4919
4825
  this._Transaction = _Transaction && (_Transaction._superclass === Transaction._superclass) ? _Transaction : Transaction
4920
4826
 
@@ -4923,20 +4829,12 @@ class PaymentResult {
4923
4829
 
4924
4830
  const id = options._id || options.id
4925
4831
  this.id = paymentResult_setId(id)
4926
- this.active = typeof options.active !== 'undefined' ? !!options.active : true
4927
- this.created = options.created || (new Date()).valueOf()
4928
- this.creator = options.creator
4929
- this.deleted = options.deleted || false
4930
- this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
4931
- this.modified = options.modified || (new Date()).valueOf()
4932
- this.owner = options.owner
4832
+
4933
4833
  this.paymentResultCode = paymentResult_setCode(options, 'paymentResultCode')
4934
4834
  this.paymentResultType = options.paymentResultType || 'PaymentResult'
4935
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
4936
4835
  this.result = options.result
4937
4836
  this.resultRef = options.resultRef
4938
4837
  this.resultType = options.resultType
4939
- this.tenantCode = options.tenantCode
4940
4838
  // this.transaction = this._Transaction.init(options.transaction)
4941
4839
  this.transactionCode = options.transactionCode
4942
4840
  }
@@ -4951,22 +4849,6 @@ class PaymentResult {
4951
4849
  transactionCode: 'transactionCode'
4952
4850
  }
4953
4851
  }
4954
- static init(options = {}) {
4955
- if (options instanceof this) {
4956
- return options
4957
- }
4958
- const instance = new this(options)
4959
- return instance.isValid ? instance : null
4960
- }
4961
- static initFromArray(arr = []) {
4962
- if (Array.isArray(arr)) {
4963
- return arr.map((a) => this.init(a))
4964
- }
4965
- return []
4966
- }
4967
- static initOnlyValidFromArray(arr = []) {
4968
- return this.initFromArray(arr).filter((i) => i)
4969
- }
4970
4852
  static get _classname() {
4971
4853
  return 'PaymentResult'
4972
4854
  }
@@ -4976,7 +4858,7 @@ class PaymentResult {
4976
4858
 
4977
4859
  // getters
4978
4860
  get isValid() {
4979
- return !!this.resultType && !!this.tenantCode && !!this.transactionCode
4861
+ return super.isValid && !!this.resultType && !!this.transactionCode
4980
4862
  // return !!this.result && !!this.resultType && !!this.tenantCode
4981
4863
  }
4982
4864
  get amount() {
@@ -4986,7 +4868,7 @@ class PaymentResult {
4986
4868
  throw new Error(`${this._classname} subclass should implement get paymentMethod`)
4987
4869
  }
4988
4870
  get transaction() {
4989
- return this._transaction.init(this._transaction)
4871
+ return this._Transaction.init(this._transaction)
4990
4872
  }
4991
4873
 
4992
4874
  // instance methods
@@ -5002,71 +4884,288 @@ class PaymentResult {
5002
4884
  return this
5003
4885
  }
5004
4886
 
5005
- compareStatus(paymentResult) {
5006
- throw new Error(`${this.paymentResultType} subclass should implement compareStatus`)
5007
- }
5008
- getPaidAmount() {
5009
- throw new Error(`${this.paymentResultType} subclass should implement getPaidAmount`)
5010
- }
5011
- getPaidTimestamp() {
5012
- throw new Error(
5013
- `${this.paymentResultType} subclass should implement getPaidTimestamp in milliseconds`
5014
- )
4887
+ compareStatus(paymentResult) {
4888
+ throw new Error(`${this.paymentResultType} subclass should implement compareStatus`)
4889
+ }
4890
+ getCode() {
4891
+ return this.paymentResultCode
4892
+ }
4893
+ getPaidAmount() {
4894
+ throw new Error(`${this.paymentResultType} subclass should implement getPaidAmount`)
4895
+ }
4896
+ getPaidTimestamp() {
4897
+ throw new Error(
4898
+ `${this.paymentResultType} subclass should implement getPaidTimestamp in milliseconds`
4899
+ )
4900
+ }
4901
+ getPaymentCode() {
4902
+ throw new Error(`${this.paymentResultType} subclass should implement getPaymentCode`)
4903
+ }
4904
+ getTransactionStatus() {
4905
+ throw new Error(`${this.paymentResultType} subclass should implement getTransactionStatus`)
4906
+ }
4907
+ handlePayment(payment) {
4908
+ if (!this.isForThisPayment(payment)) {
4909
+ return { payment, err: new Error('the payment result is not for this payment') }
4910
+ }
4911
+ if (!this.isSameAmount(payment)) {
4912
+ return { payment, err: new Error('the amount was not matched') }
4913
+ }
4914
+ try {
4915
+ payment.settled()
4916
+ payment
4917
+ .setPaidAmount(this.getPaidAmount())
4918
+ .setPaidTimestamp(this.getPaidTimestamp())
4919
+ .setPaymentResultCode(this.paymentResultCode)
4920
+ return { payment, err: null }
4921
+ } catch (err) {
4922
+ return { payment, err }
4923
+ }
4924
+ }
4925
+ isForThisPayment(payment) {
4926
+ return this.getPaymentCode() === payment.paymentCode
4927
+ }
4928
+ isSameAmount(payment) {
4929
+ return this.getPaidAmount() === payment.getAmount()
4930
+ }
4931
+ isSuccess() {
4932
+ throw new Error(`${this.paymentResultType} subclass should implement isSuccess`)
4933
+ }
4934
+ setupMetadata() {
4935
+ const amount = this.amount
4936
+ const paymentMethod = this.paymentMethod
4937
+ q_utilities_namespaceObject.Metadata.addItem(this.metadata, 'AMOUNT', amount)
4938
+ q_utilities_namespaceObject.Metadata.addItem(this.metadata, 'PAYMENT_METHOD', paymentMethod)
4939
+ q_utilities_namespaceObject.KeyValueObject.addItem(this.remarks, 'amount', amount)
4940
+ q_utilities_namespaceObject.KeyValueObject.addItem(this.remarks, 'paymentMethod', paymentMethod)
4941
+ return this
4942
+ }
4943
+ setupRemarks() {
4944
+ return this.setupMetadata()
4945
+ }
4946
+ update(update) {
4947
+ Object.keys(update).forEach((key) => {
4948
+ if (paymentResult_updateAllowedProps.includes(key)) {
4949
+ this[key] = update[key]
4950
+ }
4951
+ })
4952
+ return super.update(update)
4953
+ }
4954
+ }
4955
+
4956
+ function paymentResult_setCode(options, key) {
4957
+ const copyOptions = options || {}
4958
+ if (copyOptions[key]) {
4959
+ return copyOptions[key]
4960
+ }
4961
+ return stringHelper.setCode()
4962
+ }
4963
+
4964
+ function paymentResult_setId(id) {
4965
+ if (id && typeof id.toString === 'function') {
4966
+ return id.toString()
4967
+ }
4968
+ return id
4969
+ }
4970
+
4971
+
4972
+
4973
+ ;// ./lib/models/paymentResult/paymentResultRepo.js
4974
+
4975
+
4976
+
4977
+ class PaymentResultRepo extends q_utilities_namespaceObject.Repo {
4978
+ constructor(options = {}) {
4979
+ options = options || {}
4980
+ super(options)
4981
+ const { _PaymentResult } = options._constructor || {}
4982
+ this._PaymentResult = _PaymentResult && (_PaymentResult._superclass === PaymentResult._superclass) ? _PaymentResult : PaymentResult
4983
+ }
4984
+ static get _classname() {
4985
+ return 'PaymentResultRepo'
4986
+ }
4987
+ init(options) {
4988
+ return this._PaymentResult.init(options)
4989
+ }
4990
+ }
4991
+
4992
+
4993
+
4994
+ ;// ./lib/models/paymentResult/index.js
4995
+
4996
+
4997
+
4998
+
4999
+
5000
+
5001
+ ;// ./lib/models/status/index.js
5002
+
5003
+
5004
+
5005
+
5006
+
5007
+ ;// ./lib/models/storeItem/storeItem.js
5008
+
5009
+
5010
+
5011
+
5012
+
5013
+ const storeItem_updateAllowedProps = [
5014
+ 'active',
5015
+ 'deleted',
5016
+ 'description',
5017
+ 'intangible',
5018
+ 'limitPercentage',
5019
+ 'lineOptions',
5020
+ 'maxPerWallet',
5021
+ 'name',
5022
+ 'originalStock',
5023
+ 'owner',
5024
+ 'productOptions',
5025
+ 'remarks',
5026
+ 'requiredStoreItemCode',
5027
+ 'stock'
5028
+ ]
5029
+
5030
+ class StoreItem {
5031
+ constructor(options = {}) {
5032
+ options = options || {}
5033
+ const { _ItemOption } = options._constructor || {}
5034
+ this._ItemOption = _ItemOption && (_ItemOption._superclass === ItemOption) ? _ItemOption : ItemOption
5035
+
5036
+ const id = options._id || options.id
5037
+ this.id = storeItem_setId(id)
5038
+ this._type = options._type || 'StoreItem'
5039
+ this.active = (typeof options.active !== 'undefined') ? !!options.active : true
5040
+ this.created = options.created || (new Date()).valueOf()
5041
+ this.creator = options.creator
5042
+ this.deleted = options.deleted || false
5043
+ this.description = options.description || ''
5044
+ this.intangible = options.intangible || false
5045
+ this.limitPercentage = options.limitPercentage || 100
5046
+ this.lineOptions = this._ItemOption.initOnlyValidFromArray(options.lineOptions)
5047
+ this.maxPerWallet = options.maxPerWallet || 1
5048
+ this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
5049
+ this.modified = options.modified || (new Date()).valueOf()
5050
+ this.name = options.name || ''
5051
+ this.originalStock = options.originalStock || 0
5052
+ this.owner = options.owner
5053
+ this.productCode = storeItem_setCode(options, 'productCode')
5054
+ this.productOptions = this._ItemOption.initOnlyValidFromArray(options.productOptions)
5055
+ this.requiredStoreItemCode = options.requiredStoreItemCode
5056
+ this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
5057
+ this.stock = options.stock || 0
5058
+ this.storeItemType = options.storeItemType || 'StoreItem'
5059
+ this.tenantCode = options.tenantCode
5060
+ }
5061
+
5062
+ // class method
5063
+ static dummyData() {
5064
+ return {
5065
+ name: 'badge',
5066
+ tenantCode: 'tenantCode'
5067
+ }
5068
+ }
5069
+ static init(options = {}) {
5070
+ if (options instanceof this) {
5071
+ return options
5072
+ }
5073
+ const instance = new this(options)
5074
+ return instance.isValid ? instance : null
5075
+ }
5076
+ static initFromArray(arr = []) {
5077
+ if (Array.isArray(arr)) {
5078
+ return arr.map((a) => this.init(a))
5079
+ }
5080
+ return []
5081
+ }
5082
+ static initOnlyValidFromArray(arr = []) {
5083
+ return this.initFromArray(arr).filter((i) => i)
5084
+ }
5085
+ static get _classname() {
5086
+ return 'StoreItem'
5087
+ }
5088
+ static get _superclass() {
5089
+ return 'StoreItem'
5090
+ }
5091
+
5092
+ // getters
5093
+ get isValid() {
5094
+ return !!this.tenantCode && !!this.name
5095
+ }
5096
+ get isReachedLimitPercentage() {
5097
+ return this.soldPercentage >= this.limitPercentage
5098
+ }
5099
+ get soldPercentage() {
5100
+ return ((this.originalStock - this.stock) / this.originalStock) * 100
5101
+ }
5102
+ get summary() {
5103
+ return {
5104
+ product: this,
5105
+ productCode: this.productCode,
5106
+ name: this.name,
5107
+ }
5108
+ }
5109
+
5110
+ // instance methods
5111
+ ableToHave(qty) {
5112
+ return this.maxPerWallet >= qty
5113
+ }
5114
+
5115
+ checkStoreItemItemOptions(itemOptionFillIns = []) {
5116
+ const copyItemOptionsFillIns = ItemOptionFillIn.getItemOptionFillInsByTarget({ itemOptionFillIns, target: 'StoreItem', targetCode: this.productCode })
5117
+ return copyItemOptionsFillIns.reduce((acc, fillIn) => {
5118
+ const key = fillIn.getKey()
5119
+ const itemOption = this.getStoreItemOptionByKey(key)
5120
+ if (!itemOption) {
5121
+ acc.errMsgs.push(`options of the product(${this.productCode}) does not contain key: "${key}"`)
5122
+ return acc
5123
+ }
5124
+ const isValid = itemOption.isValidFillInValue(fillIn.getValue())
5125
+ if (!isValid) {
5126
+ acc.errMsgs.push(`the product(${this.productCode}) option's(${key}) fillInValue is invalid`)
5127
+ }
5128
+ return acc
5129
+ }, { errMsgs: [] })
5015
5130
  }
5016
- getPaymentCode() {
5017
- throw new Error(`${this.paymentResultType} subclass should implement getPaymentCode`)
5131
+ getCode() {
5132
+ return this.productCode
5018
5133
  }
5019
- getTransactionStatus() {
5020
- throw new Error(`${this.paymentResultType} subclass should implement getTransactionStatus`)
5134
+ getMetadataValueByKey(key) {
5135
+ return q_utilities_namespaceObject.Metadata.getValueByKey(this.metadata || [], key)
5021
5136
  }
5022
- handlePayment(payment) {
5023
- if (!this.isForThisPayment(payment)) {
5024
- return { payment, err: new Error('the payment result is not for this payment') }
5025
- }
5026
- if (!this.isSameAmount(payment)) {
5027
- return { payment, err: new Error('the amount was not matched') }
5028
- }
5029
- try {
5030
- payment.settled()
5031
- payment
5032
- .setPaidAmount(this.getPaidAmount())
5033
- .setPaidTimestamp(this.getPaidTimestamp())
5034
- .setPaymentResultCode(this.paymentResultCode)
5035
- return { payment, err: null }
5036
- } catch (err) {
5037
- return { payment, err }
5137
+ getStoreItemOptionByKey(key) {
5138
+ const arr = this._ItemOption.getByKey(this.productOptions, key)
5139
+ if (arr.length === 1) {
5140
+ return arr[0]
5038
5141
  }
5142
+ return null
5039
5143
  }
5040
- isForThisPayment(payment) {
5041
- return this.getPaymentCode() === payment.paymentCode
5144
+ hasStock(qty) {
5145
+ return this.stock >= qty
5042
5146
  }
5043
- isSameAmount(payment) {
5044
- return this.getPaidAmount() === payment.getAmount()
5147
+ isQualified(data) {
5148
+ const rules = this.getMetadataValueByKey('RULES') || []
5149
+ return (rules.length === 0)
5150
+ ? true
5151
+ : rules.reduce((acc, r) => {
5152
+ return acc || (0,q_utilities_namespaceObject.getValidation)(r, data, storeItem_getDataByKey, q_utilities_namespaceObject.KeyValueObject)
5153
+ }, false)
5045
5154
  }
5046
- isSuccess() {
5047
- throw new Error(`${this.paymentResultType} subclass should implement isSuccess`)
5155
+ isTicket() {
5156
+ return false
5048
5157
  }
5049
5158
  setModified() {
5050
5159
  this.modified = (new Date()).valueOf()
5051
5160
  return this
5052
5161
  }
5053
- setupMetadata() {
5054
- const amount = this.amount
5055
- const paymentMethod = this.paymentMethod
5056
- q_utilities_namespaceObject.Metadata.addItem(this.metadata, 'AMOUNT', amount)
5057
- q_utilities_namespaceObject.Metadata.addItem(this.metadata, 'PAYMENT_METHOD', paymentMethod)
5058
- q_utilities_namespaceObject.KeyValueObject.addItem(this.remarks, 'amount', amount)
5059
- q_utilities_namespaceObject.KeyValueObject.addItem(this.remarks, 'paymentMethod', paymentMethod)
5060
- return this
5061
- }
5062
- setupRemarks() {
5063
- return this.setupMetadata()
5064
- }
5065
5162
  update(update) {
5066
5163
  Object.keys(update).forEach((key) => {
5067
- if (paymentResult_updateAllowedProps.includes(key)) {
5164
+ if (storeItem_updateAllowedProps.includes(key)) {
5068
5165
  if (key === 'metadata') {
5069
5166
  this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
5167
+ } else if (key === 'productOptions') {
5168
+ this[key] = this._ItemOption.initOnlyValidFromArray(update[key])
5070
5169
  } else if (key === 'remarks') {
5071
5170
  this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
5072
5171
  } else {
@@ -5078,58 +5177,35 @@ class PaymentResult {
5078
5177
  }
5079
5178
  }
5080
5179
 
5081
- function paymentResult_setCode(options, key) {
5082
- const copyOptions = options || {}
5083
- if (copyOptions[key]) {
5084
- return copyOptions[key]
5085
- }
5086
- return stringHelper.setCode()
5087
- }
5088
-
5089
- function paymentResult_setId(id) {
5180
+ function storeItem_setId(id) {
5090
5181
  if (id && typeof id.toString === 'function') {
5091
5182
  return id.toString()
5092
5183
  }
5093
5184
  return id
5094
5185
  }
5095
5186
 
5096
-
5097
-
5098
- ;// ./lib/models/paymentResult/paymentResultRepo.js
5099
-
5100
-
5101
-
5102
- class PaymentResultRepo extends q_utilities_namespaceObject.Repo {
5103
- constructor(options = {}) {
5104
- options = options || {}
5105
- super(options)
5106
- const { _PaymentResult } = options._constructor || {}
5107
- this._PaymentResult = _PaymentResult && (_PaymentResult._superclass === PaymentResult._superclass) ? _PaymentResult : PaymentResult
5108
- }
5109
- static get _classname() {
5110
- return 'PaymentResultRepo'
5111
- }
5112
- init(options) {
5113
- return this._PaymentResult.init(options)
5187
+ function storeItem_setCode(options, key) {
5188
+ const copyOptions = options || {}
5189
+ if (copyOptions[key]) {
5190
+ return copyOptions[key]
5114
5191
  }
5192
+ return stringHelper.setCode()
5115
5193
  }
5116
5194
 
5117
-
5118
-
5119
- ;// ./lib/models/paymentResult/index.js
5120
-
5121
-
5195
+ function storeItem_getDataByKey(key, data) {
5196
+ return (0,q_utilities_namespaceObject.getValueByKeys)(key.split('.'), data)
5197
+ }
5122
5198
 
5123
5199
 
5124
5200
 
5201
+ ;// ./lib/models/storeItem/index.js
5125
5202
 
5126
- ;// ./lib/models/status/index.js
5127
5203
 
5128
5204
 
5129
5205
 
5206
+ ;// ./lib/models/index.js
5130
5207
 
5131
5208
 
5132
- ;// ./lib/models/index.js
5133
5209
 
5134
5210
 
5135
5211
 
@@ -5261,6 +5337,34 @@ class Chain {
5261
5337
 
5262
5338
 
5263
5339
 
5340
+ ;// ./lib/helpers/calculateByCoupon/calculateCoupon.js
5341
+
5342
+ function calculateByCoupon({ coupon, price }) {
5343
+ const { couponDetails } = coupon
5344
+ if (!couponDetails) {
5345
+ return 0
5346
+ }
5347
+ const { type, item } = couponDetails
5348
+ if (item) {
5349
+ switch(type) {
5350
+ case ('Percentage'): {
5351
+ return _caculateByPercentage(price, couponDetails)
5352
+ }
5353
+ default: {
5354
+ return 0
5355
+ }
5356
+ }
5357
+ }
5358
+ }
5359
+
5360
+ function _caculateByPercentage(price, couponDetails) {
5361
+ const { value } = couponDetails
5362
+ return price.value * (value / 100)
5363
+ }
5364
+
5365
+
5366
+
5367
+
5264
5368
  ;// ./lib/eventManager/chains/helpers.js
5265
5369
 
5266
5370
 
@@ -5269,6 +5373,7 @@ class Chain {
5269
5373
 
5270
5374
 
5271
5375
 
5376
+
5272
5377
  ;// ./lib/eventManager/chains/chainCategoryLimit.js
5273
5378
 
5274
5379
 
@@ -5388,6 +5493,7 @@ class ChainGetPrice extends Chain {
5388
5493
  // }
5389
5494
  })
5390
5495
  cutEntitlements(lines, entitlements, this.currency.code)
5496
+ // useCoupons(lines, this.currency.code)
5391
5497
  // getAmount()
5392
5498
  await this.next(chainTarget)
5393
5499
  } catch (err) {
@@ -5604,6 +5710,13 @@ function getStrategiesByRestrictions(prices, line, user) {
5604
5710
  }
5605
5711
 
5606
5712
 
5713
+ // function useCoupons(lines, currencyCode) {
5714
+ // lines.forEach((line) => {
5715
+
5716
+ // })
5717
+ // }
5718
+
5719
+
5607
5720
 
5608
5721
  ;// ./lib/eventManager/chains/ChainGetPriceForGroup.js
5609
5722
 
@@ -5859,7 +5972,7 @@ class ChainMerchandiseLimit extends Chain {
5859
5972
  const stock = merchandise.getStock()
5860
5973
  if (stock === 0) {
5861
5974
  line.disabled = true
5862
- line.errors.push('Sold out.')
5975
+ line.errors.push('Full.')
5863
5976
  } else {
5864
5977
  const { qty } = updatedItem
5865
5978
  updatedItem.qty = qty > stock ? stock : qty
@@ -5904,7 +6017,7 @@ class ChainProductLimit extends Chain {
5904
6017
  // const newRest = balance - ordered
5905
6018
  if (balance === 0) {
5906
6019
  updatedItem.qty = 0
5907
- line.errors.push(`"${name}" is out of stock`)
6020
+ // line.errors.push(`"${name}" is out of stock`)
5908
6021
  } else {
5909
6022
  const ordered = (productQty * qty)
5910
6023
  const newBalance = balance - ordered
@@ -6048,22 +6161,141 @@ class ChainPurchaseOptions extends Chain {
6048
6161
  if (required && !value && !notFinishRequired) {
6049
6162
  notFinishRequired = true
6050
6163
  line.validated = false
6051
- line.errors.push('Need to fill in options.')
6164
+ line.errors.push('Please fill in the option(s).')
6052
6165
  }
6053
6166
  if (validated && !notFinishValidated) {
6054
6167
  notFinishValidated = true
6055
- line.errors.push('Has not validated options.')
6168
+ line.errors.push('Invalid option(s).')
6056
6169
  }
6057
6170
  })
6058
6171
  })
6059
6172
  })
6060
6173
  await this.next(chainTarget)
6061
6174
  } catch (err) {
6062
- chainTarget.addException('check product restriction fail', err.message)
6175
+ chainTarget.addException('Check product restriction failed.', err.message)
6176
+ this.exitChain()
6177
+ }
6178
+ }
6179
+ }
6180
+
6181
+
6182
+
6183
+ ;// ./lib/eventManager/chains/chainRelatedCoupons.js
6184
+
6185
+ // import { WalletItem } from '../../models/walletItem/index.js'
6186
+
6187
+ class ChainRelatedCoupons extends Chain {
6188
+ constructor(options = {}) {
6189
+ super(options)
6190
+ this.autoUseCoupon = options.autoUseCoupon || false
6191
+ this.currency = options.currency
6192
+ this.walletItems = options.walletItems
6193
+ }
6194
+
6195
+ async handleRequest(chainTarget) {
6196
+ try {
6197
+ const { lines, users } = chainTarget
6198
+ // const walletItems = WalletItem.initOnlyValidFromArray(this.walletItems)
6199
+ const couponWalletItems = this.walletItems.filter((i) => i.isCoupon)
6200
+ lines.forEach((line) => {
6201
+ _calculateAmountByCoupons({ line, currencyCode: this.currency.code })
6202
+ _updateRelatedCoupons(line, couponWalletItems, this.autoUseCoupon, this.currency.code)
6203
+ })
6204
+ lines.forEach((line) => {
6205
+ _getAvailableCoupons(line)
6206
+ })
6207
+ await this.next(chainTarget)
6208
+ } catch (err) {
6209
+ chainTarget.addException('calculate categories limit fail', err.message)
6063
6210
  this.exitChain()
6064
6211
  }
6065
6212
  }
6066
6213
  }
6214
+ function _calculateAmountByCoupons({ line, currencyCode }) {
6215
+ const { usedCoupons = {}, updatedItem } = line
6216
+ Object.keys(usedCoupons).forEach((key) => {
6217
+ usedCoupons[key].forEach((coupon) => {
6218
+ const obj = _calculateAmountByOneCoupon({ updatedItem, coupon, currencyCode })
6219
+ Object.assign(updatedItem, obj)
6220
+ })
6221
+ })
6222
+ }
6223
+
6224
+ function _calculateAmountByOneCoupon({ updatedItem, coupon, currencyCode }) {
6225
+ const { couponDetails, walletItemCode } = coupon
6226
+ if (!couponDetails) {
6227
+ return updatedItem
6228
+ }
6229
+ const { price, qty, discount, remarks, subTotal } = updatedItem
6230
+ const _discount = calculateByCoupon({ coupon, price })
6231
+ const discountValue = _discount + discount.value
6232
+ const subTotalValue = subTotal.value > _discount ? subTotal.value - _discount : 0
6233
+ const _usedCoupons = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(remarks, 'USED_ITEM_COUPONS') || []
6234
+ _usedCoupons.push(walletItemCode)
6235
+ return {
6236
+ ...updatedItem,
6237
+ discount: Amount.init({ value: discountValue, currencyCode }),
6238
+ remarks: q_utilities_namespaceObject.KeyValueObject.insertOrUpdateRecord(remarks, 'USED_ITEM_COUPONS', _usedCoupons ),
6239
+ subTotal: Amount.init({ value: subTotalValue, currencyCode })
6240
+ }
6241
+ }
6242
+
6243
+
6244
+ function _getAvailableCoupons(line) {
6245
+ const { relatedCoupons = [] } = line
6246
+ line.relatedCoupons = relatedCoupons.map((c) => ({
6247
+ ...c,
6248
+ availableCoupons: c.coupons.filter((_c) => (!_c.isOnHold))
6249
+ }))
6250
+ }
6251
+
6252
+ function _getRelatedCoupons(cartItemLine, couponWalletItems, autoUseCoupon, currencyCode) {
6253
+ const { merchandise, usedCoupons = {}, updatedItem = {} } = cartItemLine
6254
+ const relatedWalletItems = couponWalletItems.filter(
6255
+ item => item.isApplicableCoupon(merchandise) && item.isItemCoupon
6256
+ )
6257
+ // .sort((a, b) => (
6258
+ // b.couponDetails.value - a.couponDetails.value
6259
+ // ))
6260
+ return relatedWalletItems.reduce((acc, w) => {
6261
+ const productCode = w.product.productCode
6262
+ let exist = acc.find((i) => i.productCode === productCode)
6263
+ const isOnHold = w.isOnHold // max? || only use One Coupon?
6264
+ if (!exist) {
6265
+ exist = {
6266
+ coupons: [],
6267
+ product: w.product,
6268
+ productCode: productCode,
6269
+ usedQty: (usedCoupons[productCode] || []).length
6270
+ }
6271
+ acc.push(exist)
6272
+ }
6273
+ exist.coupons.push(w)
6274
+ const { qty: itemQty, subTotal } = updatedItem
6275
+ if (autoUseCoupon && !isOnHold && exist.usedQty < itemQty && subTotal.value > 0) {
6276
+ // use coupon
6277
+ w.setOnHold()
6278
+ usedCoupons[productCode] = [
6279
+ ...usedCoupons[productCode] || [],
6280
+ w
6281
+ ]
6282
+ const obj = _calculateAmountByOneCoupon({ updatedItem, currencyCode, coupon: w })
6283
+ Object.assign(updatedItem, obj)
6284
+ exist.usedQty = usedCoupons[productCode].length
6285
+ }
6286
+ return acc
6287
+ }, [])
6288
+ }
6289
+
6290
+
6291
+ function _updateRelatedCoupons(line, couponWalletItems, autoUseCoupon, currencyCode) {
6292
+ if (couponWalletItems.length > 0) {
6293
+ line.relatedCoupons = _getRelatedCoupons(line, couponWalletItems, autoUseCoupon, currencyCode)
6294
+ }
6295
+ }
6296
+
6297
+
6298
+
6067
6299
 
6068
6300
 
6069
6301
 
@@ -6079,6 +6311,7 @@ class ChainPurchaseOptions extends Chain {
6079
6311
 
6080
6312
 
6081
6313
 
6314
+
6082
6315
  ;// ./lib/helpers/corHelper/chainException.js
6083
6316
 
6084
6317
  class ChainException {
@@ -6340,6 +6573,7 @@ class ChainManagerFactory {
6340
6573
 
6341
6574
  function _calculateAmountChainsFactory(payload) {
6342
6575
  const {
6576
+ autoUseCoupon,
6343
6577
  categories,
6344
6578
  currency,
6345
6579
  dateTime,
@@ -6363,6 +6597,7 @@ function _calculateAmountChainsFactory(payload) {
6363
6597
  new ChainGetPrice({
6364
6598
  currency, dateTime, entitlements, merchandises
6365
6599
  }),
6600
+ new ChainRelatedCoupons({ currency, autoUseCoupon, walletItems }),
6366
6601
  ]
6367
6602
  }
6368
6603
 
@@ -6504,6 +6739,11 @@ function getFakeClass() {
6504
6739
 
6505
6740
 
6506
6741
 
6742
+ ;// ./lib/helpers/calculateByCoupon/index.js
6743
+
6744
+
6745
+
6746
+
6507
6747
  ;// ./lib/helpers/corHelper/index.js
6508
6748
 
6509
6749
 
@@ -6511,6 +6751,150 @@ function getFakeClass() {
6511
6751
 
6512
6752
 
6513
6753
 
6754
+ ;// ./lib/helpers/getRolesChangesRelatedCouponsHelper/getRolesChangesRelatedCouponsHelper.js
6755
+ function getRolesChangesRelatedCouponsHelper({ newRoles, originalRoles }) {
6756
+ const couponFromNewRoles = _getCouponsByRoles(newRoles)
6757
+ const couponFromOriginalRoles = _getCouponsByRoles(originalRoles)
6758
+ const allKeys = new Set([
6759
+ ...Object.keys(couponFromNewRoles),
6760
+ ...Object.keys(couponFromOriginalRoles)
6761
+ ])
6762
+ return Array.from(allKeys).reduce((acc, key) => {
6763
+ const newValue = couponFromNewRoles[key] || 0;
6764
+ const originalValue = couponFromOriginalRoles[key] || 0;
6765
+ const delta = newValue - originalValue;
6766
+ if (delta !== 0) {
6767
+ acc.push({
6768
+ key,
6769
+ value: {
6770
+ delta,
6771
+ newValue,
6772
+ originalValue
6773
+ }
6774
+ });
6775
+ }
6776
+ return acc
6777
+ }, [])
6778
+ }
6779
+
6780
+
6781
+ function _getCouponsByRoles(roles) {
6782
+ return roles.reduce((acc, role) => {
6783
+ const couponCodes = role.getCouponCodes()
6784
+ couponCodes.forEach((c) => {
6785
+ const { key, value } = c
6786
+ acc[key] = acc[key] ? acc[key] + value : value
6787
+ })
6788
+ return acc
6789
+ }, {})
6790
+ }
6791
+
6792
+
6793
+
6794
+ ;// ./lib/helpers/couponManager/couponManager.js
6795
+
6796
+
6797
+
6798
+
6799
+ class CouponManager {
6800
+ constructor(options) {
6801
+ this.products = options.products || []
6802
+ this.walletItems = options.walletItems || []
6803
+ this.originalRoles = options.originalRoles || []
6804
+ this.newRoles = options.newRoles || []
6805
+ }
6806
+
6807
+ static init(options = {}) {
6808
+ if (options instanceof this) {
6809
+ return options
6810
+ }
6811
+ const instance = new this(options)
6812
+ return instance.isValid ? instance : null
6813
+ }
6814
+
6815
+ get isValid() {
6816
+ return !!this
6817
+ }
6818
+
6819
+ get couponProducts() {
6820
+ return this.products.filter((p) => p.isCoupon)
6821
+ }
6822
+
6823
+ get couponWalletItems() {
6824
+ return this.walletItems.filter((w) => w.isCoupon)
6825
+ }
6826
+
6827
+ get roleRelatedCoupons() {
6828
+ return getRolesChangesRelatedCouponsHelper({ newRoles: this.newRoles, originalRoles: this.originalRoles })
6829
+ }
6830
+
6831
+
6832
+ get couponItemList() {
6833
+ return this.couponProducts.map((p) => {
6834
+ const relatedWalletItems = this.walletItems.filter(
6835
+ item => item.productCode === p.productCode
6836
+ )
6837
+
6838
+ const usedCoupons = relatedWalletItems.filter(item => item.isUsed)
6839
+ usedCoupons.forEach((c) => {
6840
+ c.useForWalletItems = this.walletItems.filter((item) => (c.useFor || []).includes(item.walletItemCode)) // useFor
6841
+ })
6842
+
6843
+ const availableCoupons = relatedWalletItems.filter(item => !item.isAvailableCoupon)
6844
+
6845
+ const roleBase = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(this.roleRelatedCoupons, p.productCode) || {}
6846
+
6847
+ const remainingQuota = p.maxPerWallet - (usedCoupons.length + availableCoupons.length)
6848
+
6849
+ const { qty, remarks } = _handler({ product: p, availableCoupons, roleBase, remainingQuota })
6850
+
6851
+ return {
6852
+ product: p,
6853
+ usedCoupons,
6854
+ availableCoupons,
6855
+ alreadyHave: usedCoupons.length + availableCoupons.length,
6856
+ maxLimit: p.maxPerWallet,
6857
+ remainingQuota,
6858
+ qty,
6859
+ roleBase,
6860
+ remarks
6861
+ };
6862
+ })
6863
+ }
6864
+
6865
+ setNewRoles() {
6866
+ this.newRoles = newRoles
6867
+ }
6868
+
6869
+ }
6870
+
6871
+
6872
+
6873
+
6874
+ function _handler({ product, remainingQuota, availableCoupons, roleBase }) {
6875
+ const { delta = 0 } = roleBase
6876
+ const { maxPerWallet } = product
6877
+ let qty = delta
6878
+ const remarks = []
6879
+ if (delta > 0 && maxPerWallet && delta > remainingQuota) {
6880
+ qty = 0
6881
+ remarks.push(`max ${maxPerWallet}`)
6882
+ }
6883
+ if (delta < 0 && maxPerWallet && availableCoupons.length < delta) {
6884
+ qty = availableCoupons.length
6885
+ remarks.push(`only ${availableCoupons.length} could be cancelled`)
6886
+ }
6887
+ return {
6888
+ qty,
6889
+ remarks
6890
+ }
6891
+ }
6892
+
6893
+ ;// ./lib/helpers/couponManager/index.js
6894
+
6895
+
6896
+
6897
+
6514
6898
  ;// ./lib/helpers/dateHelper/handler/handler.js
6515
6899
  class Handler {
6516
6900
  constructor(date) {
@@ -6638,7 +7022,11 @@ function createDate(timestamp) {
6638
7022
  const mthIdx = Number(mthStr) - 1
6639
7023
  return new Date(timestamp.slice(0, 4), mthIdx, timestamp.slice(6, 8))
6640
7024
  }
6641
- throw new Error('timestamp does not meet the requirements')
7025
+ try {
7026
+ return new Date(timestamp)
7027
+ } catch (e) {
7028
+ throw new Error('timestamp does not meet the requirements')
7029
+ }
6642
7030
  }
6643
7031
 
6644
7032
  function convert(date, dateFormat) {
@@ -6907,6 +7295,8 @@ function isDescendingOrder({ arr = [], key }) {
6907
7295
 
6908
7296
 
6909
7297
 
7298
+
7299
+
6910
7300
  ;// ./lib/index.js
6911
7301
 
6912
7302
  const models = models_namespaceObject