@questwork/q-store-model 0.1.35 → 0.1.38

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,14 @@ 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()
1812
+ this.merchandiseType = options.merchandiseType || 'merchandise'
1715
1813
  this.name = options.name || ''
1716
- this.owner = options.owner
1717
1814
  this.prices = this._Price.initOnlyValidFromArray(options.prices)
1718
1815
  this.productCodes = options.productCodes || []
1719
1816
  this.priority = options.priority || 100
1720
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
1721
1817
  this.sku = options.sku || ''
1722
1818
  this.stock = options.stock || 0
1723
- this.tenantCode = options.tenantCode
1819
+ this.targets = options.targets || []
1724
1820
  }
1725
1821
 
1726
1822
  // Class Mehtods
@@ -1741,22 +1837,6 @@ class Merchandise {
1741
1837
  tenantCode: '85223977000',
1742
1838
  }
1743
1839
  }
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
1840
  static get _classname() {
1761
1841
  return 'Merchandise'
1762
1842
  }
@@ -1806,11 +1886,17 @@ class Merchandise {
1806
1886
  get isAvailableByDate() {
1807
1887
  return !this.afterEnd && !this.beforeBegin
1808
1888
  }
1889
+ get isForPersonal() {
1890
+ return !Array.isArray(this.targets) || this.targets.length === 0
1891
+ }
1892
+ get isForGroup() {
1893
+ return Array.isArray(this.targets) && this.targets.includes('GROUP')
1894
+ }
1809
1895
  get isPrintable() {
1810
1896
  return this.printOut.isPrintable
1811
1897
  }
1812
1898
  get isValid() {
1813
- return !!this.tenantCode && !!this.name && (!!this.productCodes && this.productCodes.length > 0)
1899
+ return super.isValid && !!this.name && (!!this.productCodes && this.productCodes.length > 0)
1814
1900
  }
1815
1901
  get products() {
1816
1902
  return this._Product.initOnlyValidFromArray(this._products || [])
@@ -1957,6 +2043,43 @@ class Merchandise {
1957
2043
  }
1958
2044
  return info
1959
2045
  }
2046
+ getBeginAndEndDates() {
2047
+ const dates = {
2048
+ dateBegin: null,
2049
+ dateEnd: null
2050
+ }
2051
+ // BUG this.pricings is undefind
2052
+ return this.pricings.reduce((acc, pricing) => {
2053
+ if (!acc.dateBegin || (pricing.dateBegin > acc.dateBegin)) {
2054
+ acc.dateBegin = pricing.dateBegin
2055
+ }
2056
+
2057
+ if (!acc.dateEnd || (pricing.dateEnd <= acc.dateEnd)) {
2058
+ acc.dateEnd = pricing.dateEnd
2059
+ }
2060
+ return acc
2061
+ }, dates)
2062
+ }
2063
+ getCode() {
2064
+ return this.merchandiseCode
2065
+ }
2066
+ getCurrentPrice() {
2067
+ const timestamp = (new Date()).valueOf()
2068
+ const prices = this.getPricesByTime(timestamp)
2069
+ if (prices.length === 1) {
2070
+ return prices[0]
2071
+ }
2072
+ return null
2073
+ }
2074
+ getCurrentPriceByRoleCodes(roleCodes) {
2075
+ const timestamp = (new Date()).valueOf()
2076
+ let prices = this.getPricesByTime(timestamp)
2077
+ prices = Price.getPricesByRoleCodes(prices, roleCodes)
2078
+ if (prices.length === 1) {
2079
+ return prices[0]
2080
+ }
2081
+ return null
2082
+ }
1960
2083
  getItemOptionInfos(cartItems = []) {
1961
2084
  return cartItems.reduce((acc, cartItem) => {
1962
2085
  const itemOptionFillIns = cartItem.getItemOptionFillIns()
@@ -1983,47 +2106,13 @@ class Merchandise {
1983
2106
  }
1984
2107
  return null
1985
2108
  }
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
2109
+ getPrices() {
2110
+ return this.prices ? this.prices : []
2005
2111
  }
2006
2112
  getPricesByTime(timestamp) {
2007
2113
  const copyDate = timestamp || (new Date()).valueOf()
2008
2114
  return Price.getPricesByTime(this.prices, copyDate)
2009
2115
  }
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
2116
  getPriceByTimeAndRoleCodes(timestamp, roleCodes) {
2028
2117
  let prices = this.getPricesByTime(timestamp)
2029
2118
  prices = Price.getPricesByRoleCodes(prices, roleCodes)
@@ -2032,14 +2121,13 @@ class Merchandise {
2032
2121
  }
2033
2122
  return null
2034
2123
  }
2035
- getPrices() {
2036
- return this.prices ? this.prices : []
2037
- }
2038
- getRemarksByKey(key) {
2039
- return q_utilities_namespaceObject.KeyValueObject.getValuesByKey(this.remarks, key)
2124
+ getProducts() {
2125
+ return this.products || []
2040
2126
  }
2041
- getStock() {
2042
- return this.stock || 0
2127
+ getProductsMetadataValuesByKey(key) {
2128
+ return this.products.map((p) => {
2129
+ return p.getMetadataValueByKey(key)
2130
+ }).filter((i) => i)
2043
2131
  }
2044
2132
  getProductsQty(qty = 1) {
2045
2133
  return this.productCodes.reduce((acc, productCode) => {
@@ -2051,13 +2139,16 @@ class Merchandise {
2051
2139
  return acc
2052
2140
  }, {})
2053
2141
  }
2142
+ getRemarksByKey(key) {
2143
+ return q_utilities_namespaceObject.KeyValueObject.getValuesByKey(this.remarks, key)
2144
+ }
2145
+ getStock() {
2146
+ return this.stock || 0
2147
+ }
2148
+
2054
2149
  reachLimit(qty) {
2055
2150
  return this.max < qty
2056
2151
  }
2057
- setModified() {
2058
- this.modified = (new Date()).valueOf()
2059
- return this
2060
- }
2061
2152
  setPrices(prices) {
2062
2153
  if (Array.isArray(prices)) {
2063
2154
  this.prices = Price.initOnlyValidFromArray(prices)
@@ -2071,18 +2162,14 @@ class Merchandise {
2071
2162
  this[key] = this._ItemOption.initOnlyValidFromArray(update[key])
2072
2163
  } else if (key === 'merchandiseOptions' && !!this.tenantCode) {
2073
2164
  this[key] = MerchandiseOption.initOnlyValidFromArray(update[key])
2074
- } else if (key === 'metadata') {
2075
- this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
2076
2165
  } else if (key === 'prices') {
2077
2166
  this[key] = Price.initOnlyValidFromArray(update[key])
2078
- } else if (key === 'remarks') {
2079
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
2080
2167
  } else {
2081
2168
  this[key] = update[key]
2082
2169
  }
2083
2170
  }
2084
2171
  })
2085
- return this.setModified()
2172
+ return super.update(update)
2086
2173
  }
2087
2174
  }
2088
2175
 
@@ -2352,6 +2439,7 @@ class Status {
2352
2439
  this.onHold = options.onHold || null
2353
2440
  this.processing = options.processing || null
2354
2441
  this.paid = options.paid || null
2442
+ this.payLater = options.payLater || null
2355
2443
  this.pending = options.pending
2356
2444
  this.redeemed = options.redeemed || null
2357
2445
  this.refunded = options.refunded || null
@@ -2359,6 +2447,7 @@ class Status {
2359
2447
  this.rejected = options.rejected || null
2360
2448
  this.shared = options.shared || null
2361
2449
  this.submitted = options.submitted || null
2450
+ this.terminated = options.terminated || null
2362
2451
  this.used = options.used || null
2363
2452
  this.waived = options.waived || null
2364
2453
  }
@@ -2431,6 +2520,9 @@ class Status {
2431
2520
  get isPaid() {
2432
2521
  return this.paid !== null
2433
2522
  }
2523
+ get isPayLater() {
2524
+ return this.payLater !== null
2525
+ }
2434
2526
  get isPending() {
2435
2527
  return !this.isSettled && !this.isCancelled && !this.isRefundRequested
2436
2528
  }
@@ -2455,6 +2547,9 @@ class Status {
2455
2547
  get isSubmitted() {
2456
2548
  return this.submitted !== null
2457
2549
  }
2550
+ get isTerminated() {
2551
+ return this.terminated !== null
2552
+ }
2458
2553
  get isUsed() {
2459
2554
  return this.used !== null
2460
2555
  }
@@ -2554,6 +2649,10 @@ class Status {
2554
2649
  this.waived = null
2555
2650
  return this
2556
2651
  }
2652
+ setPayLater(value) {
2653
+ this.payLater = value || (new Date()).valueOf()
2654
+ return this
2655
+ }
2557
2656
  setPending(value) {
2558
2657
  this.pending = value || (new Date()).valueOf()
2559
2658
  return this
@@ -2582,6 +2681,10 @@ class Status {
2582
2681
  this.submitted = value || (new Date()).valueOf()
2583
2682
  return this
2584
2683
  }
2684
+ setTerminated(value) {
2685
+ this.terminated = value || (new Date()).valueOf()
2686
+ return this
2687
+ }
2585
2688
  setUsed(value) {
2586
2689
  this.used = value || (new Date()).valueOf()
2587
2690
  this.delivered = this.delivered || this.used
@@ -2602,6 +2705,9 @@ class Status {
2602
2705
  // this.cancelled = null
2603
2706
  // return this
2604
2707
  // }
2708
+ unSetOnHold() {
2709
+ this.onHold = null
2710
+ }
2605
2711
  update(update) {
2606
2712
  Object.keys(update).forEach((key) => {
2607
2713
  if (!notUpdateAllowedProps.includes(key)) {
@@ -2623,14 +2729,14 @@ class Status {
2623
2729
  // import { WalletItem } from '../walletItem/index.js'
2624
2730
 
2625
2731
  const cart_updateAllowedProps = [
2626
- 'active',
2627
- 'remarks',
2628
- 'deleted',
2732
+
2629
2733
  ]
2630
2734
 
2631
- class Cart {
2735
+ class Cart extends q_utilities_namespaceObject.TenantAwareEntity {
2632
2736
  constructor(options = {}) {
2633
2737
  options = options || {}
2738
+ super(options)
2739
+
2634
2740
  const { _CartItem, _Merchandise, _Status } = options._constructor || {}
2635
2741
  this._CartItem = _CartItem && (_CartItem._superclass === CartItem._superclass) ? _CartItem : CartItem
2636
2742
  this._Merchandise = _Merchandise && (_Merchandise._superclass === Merchandise._superclass) ? _Merchandise : Merchandise
@@ -2643,18 +2749,9 @@ class Cart {
2643
2749
  this._merchandises = options._merchandises
2644
2750
  this._type = options._type || 'Cart'
2645
2751
 
2646
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
2647
2752
  this.cartCode = cart_setCode(options, 'cartCode')
2648
2753
  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
2754
  this.status = this._Status.init(options.status)
2657
- this.tenantCode = options.tenantCode
2658
2755
  }
2659
2756
 
2660
2757
  // Class Methods
@@ -2664,22 +2761,6 @@ class Cart {
2664
2761
  tenantCode: 'tenantCode'
2665
2762
  }
2666
2763
  }
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
2764
  static get _classname() {
2684
2765
  return 'Cart'
2685
2766
  }
@@ -2689,7 +2770,7 @@ class Cart {
2689
2770
 
2690
2771
  // getters
2691
2772
  get isValid() {
2692
- return !!this.tenantCode
2773
+ return super.isValid
2693
2774
  }
2694
2775
  get isActive() {
2695
2776
  return !!this.active
@@ -2805,6 +2886,9 @@ class Cart {
2805
2886
  getCartItemCodes() {
2806
2887
  return this.cartItems.map((cartItem) => cartItem.cartItemCode)
2807
2888
  }
2889
+ getCode() {
2890
+ return this.cartCode
2891
+ }
2808
2892
  getCurrencyCode() {
2809
2893
  return this.cartItems.length > 0
2810
2894
  ? this.cartItems[0].getCurrencyCode()
@@ -2850,6 +2934,9 @@ class Cart {
2850
2934
  // }, [])
2851
2935
  // return initWalletItems
2852
2936
  // }
2937
+ getRelatedRegistrationGroupCode() {
2938
+ return q_utilities_namespaceObject.KeyValueObject.getValueByKey(this.remarks || [], 'registrationGroupCode')
2939
+ }
2853
2940
  setCartItems(cartItems) {
2854
2941
  this.cartItems = this._CartItem.initOnlyValidFromArray(cartItems)
2855
2942
  return this
@@ -2858,10 +2945,6 @@ class Cart {
2858
2945
  this.status.setCompleted()
2859
2946
  return this.setModified()
2860
2947
  }
2861
- setModified() {
2862
- this.modified = (new Date()).valueOf()
2863
- return this
2864
- }
2865
2948
  updateAvailable({ isCoordinator, selectCartItems }) {
2866
2949
  try {
2867
2950
  if (!isCoordinator) {
@@ -2875,16 +2958,10 @@ class Cart {
2875
2958
  update(update) {
2876
2959
  Object.keys(update).forEach((key) => {
2877
2960
  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
- }
2961
+ this[key] = update[key]
2885
2962
  }
2886
2963
  })
2887
- return this.setModified()
2964
+ return super.update(update)
2888
2965
  }
2889
2966
  updateStock() {
2890
2967
  if (this.cartItems.length === 0) {
@@ -2970,22 +3047,20 @@ class CartRepo extends q_utilities_namespaceObject.Repo {
2970
3047
 
2971
3048
 
2972
3049
  const category_updateAllowedProps = [
2973
- 'active',
2974
3050
  'codes',
2975
- 'deleted',
2976
3051
  'description',
2977
3052
  'max',
2978
3053
  'min',
2979
3054
  'name',
2980
- 'owner',
2981
3055
  'priority',
2982
3056
  'productCodes',
2983
- 'remarks',
2984
3057
  ]
2985
3058
 
2986
- class Category {
3059
+ class Category extends q_utilities_namespaceObject.TenantAwareEntity {
2987
3060
  constructor(options) {
2988
3061
  options = options || {}
3062
+ super(options)
3063
+
2989
3064
  const { _Product } = options._constructor || {}
2990
3065
  this._Product = _Product && (_Product._superclass === Product._superclass) ? _Product : Product
2991
3066
 
@@ -2994,22 +3069,15 @@ class Category {
2994
3069
 
2995
3070
  const id = options._id || options.id
2996
3071
  this.id = category_setId(id)
2997
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3072
+
2998
3073
  this.categoryCode = category_setCode(options, 'categoryCode')
2999
3074
  this.codes = options.codes || []
3000
- this.created = options.created || (new Date()).valueOf()
3001
- this.creator = options.creator
3002
- this.deleted = options.deleted || false
3003
3075
  this.description = options.description
3004
3076
  this.max = options.max || 1
3005
3077
  this.min = options.min || 0
3006
- this.modified = options.modified || (new Date()).valueOf()
3007
3078
  this.name = options.name
3008
- this.owner = options.owner
3009
3079
  this.priority = options.priority || 10
3010
3080
  this.productCodes = options.productCodes || []
3011
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3012
- this.tenantCode = options.tenantCode
3013
3081
  }
3014
3082
 
3015
3083
  // class methods
@@ -3019,22 +3087,6 @@ class Category {
3019
3087
  tenantCode: 'tenantCode'
3020
3088
  }
3021
3089
  }
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
3090
  static get _classname() {
3039
3091
  return 'Category'
3040
3092
  }
@@ -3044,29 +3096,20 @@ class Category {
3044
3096
 
3045
3097
  // getters
3046
3098
  get isValid() {
3047
- return !!this.name && !!this.tenantCode && this.max > this. min
3099
+ return super.isValid && !!this.name && this.max > this. min
3048
3100
  }
3049
3101
  get products() {
3050
3102
  return this._Product.initOnlyValidFromArray(this._products)
3051
3103
  }
3052
3104
 
3053
3105
  // instance methods
3054
- setModified() {
3055
- this.modified = (new Date()).valueOf()
3056
- return this
3057
- }
3058
-
3059
3106
  update(update) {
3060
3107
  Object.keys(update).forEach((key) => {
3061
3108
  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
- }
3109
+ this[key] = update[key]
3067
3110
  }
3068
3111
  })
3069
- return this.setModified()
3112
+ return super.update(update)
3070
3113
  }
3071
3114
  }
3072
3115
 
@@ -3123,20 +3166,19 @@ class CategoryRepo extends q_utilities_namespaceObject.Repo {
3123
3166
 
3124
3167
 
3125
3168
  const creditNoteLine_updateAllowedProps = [
3126
- 'active',
3127
3169
  'amount',
3128
3170
  // 'deduction',
3129
- 'deleted',
3130
3171
  'description',
3131
3172
  // 'discount',
3132
3173
  'qty',
3133
- 'remarks',
3134
3174
  // 'unitPrice'
3135
3175
  ]
3136
3176
 
3137
- class CreditNoteLine {
3177
+ class CreditNoteLine extends q_utilities_namespaceObject.TenantAwareEntity {
3138
3178
  constructor(options = {}) {
3139
3179
  options = options || {}
3180
+ super(options)
3181
+
3140
3182
  const { _Amount } = options._constructor || {}
3141
3183
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
3142
3184
 
@@ -3145,21 +3187,14 @@ class CreditNoteLine {
3145
3187
 
3146
3188
  const id = options._id || options.id
3147
3189
  this.id = creditNoteLine_setId(id)
3148
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3190
+
3149
3191
  this.amount = this._Amount.init(options.amount)
3150
- this.created = options.created || (new Date()).valueOf()
3151
- this.creator = options.creator
3152
3192
  this.creditNoteCode = options.creditNoteCode
3153
3193
  this.creditNoteLineCode = creditNoteLine_setCode(options, 'creditNoteLineCode')
3154
3194
  // this.deduction = this._Amount.init(options.deduction)
3155
- this.deleted = options.deleted || false
3156
3195
  this.description = options.description
3157
3196
  // this.discount = options.discount || 0
3158
- this.modified = options.modified || (new Date()).valueOf()
3159
- this.owner = options.owner
3160
3197
  this.qty = options.qty || 1
3161
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3162
- this.tenantCode = options.tenantCode
3163
3198
  // this.unitPrice = Amount.init(options.unitPrice)
3164
3199
  }
3165
3200
 
@@ -3170,22 +3205,6 @@ class CreditNoteLine {
3170
3205
  tenantCode: 'tenantCode'
3171
3206
  }
3172
3207
  }
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
3208
  static get _classname() {
3190
3209
  return 'CreditNoteLine'
3191
3210
  }
@@ -3196,7 +3215,7 @@ class CreditNoteLine {
3196
3215
 
3197
3216
  // getters
3198
3217
  get isValid() {
3199
- return !!this.creditNoteCode && !!this.tenantCode
3218
+ return super.isValid && !!this.creditNoteCode
3200
3219
  }
3201
3220
 
3202
3221
  // instance methods
@@ -3207,10 +3226,6 @@ class CreditNoteLine {
3207
3226
  }
3208
3227
  return this
3209
3228
  }
3210
- setModified() {
3211
- this.modified = (new Date()).valueOf()
3212
- return this
3213
- }
3214
3229
 
3215
3230
  update(update) {
3216
3231
  Object.keys(update).forEach((key) => {
@@ -3224,7 +3239,7 @@ class CreditNoteLine {
3224
3239
  }
3225
3240
  }
3226
3241
  })
3227
- return this.setModified()
3242
+ return super.update(update)
3228
3243
  }
3229
3244
  }
3230
3245
 
@@ -3283,17 +3298,16 @@ class CreditNoteLineRepo extends q_utilities_namespaceObject.Repo {
3283
3298
 
3284
3299
 
3285
3300
  const creditNote_updateAllowedProps = [
3286
- 'active',
3287
- 'deleted',
3288
3301
  'description',
3289
- 'remarks',
3290
3302
  'status'
3291
3303
  ]
3292
3304
 
3293
- class CreditNote {
3305
+ class CreditNote extends q_utilities_namespaceObject.TenantAwareEntity {
3294
3306
  constructor(options = {}) {
3295
3307
  options = options || {}
3296
- const { _Amount, _CreditNoteLine } = options._constructor || {}
3308
+ super(options)
3309
+
3310
+ const { _Amount, _CreditNoteLine, _Status } = options._constructor || {}
3297
3311
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
3298
3312
  this._CreditNoteLine = _CreditNoteLine && (_CreditNoteLine._superclass === CreditNoteLine._superclass) ? _CreditNoteLine : CreditNoteLine
3299
3313
  this._Status = _Status && (_Status._superclass === Status._superclass) ? _Status : Status
@@ -3302,21 +3316,13 @@ class CreditNote {
3302
3316
 
3303
3317
  const id = options._id || options.id
3304
3318
  this.id = creditNote_setId(id)
3305
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3319
+
3306
3320
  this.amount = this._Amount.init(options.amount)
3307
- this.created = options.created || (new Date()).valueOf()
3308
- this.creator = options.creator
3309
3321
  this.creditNoteCode = creditNote_setCode(options, 'creditNoteCode')
3310
3322
  this.creditNoteLines = this._CreditNoteLine.initOnlyValidFromArray(options.creditNoteLines)
3311
- this.deleted = options.deleted || false
3312
3323
  this.description = options.description
3313
3324
  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
3325
  this.status = this._Status.init(options.status)
3319
- this.tenantCode = options.tenantCode
3320
3326
  }
3321
3327
 
3322
3328
  // Class Methods
@@ -3326,22 +3332,6 @@ class CreditNote {
3326
3332
  tenantCode: 'tenantCode'
3327
3333
  }
3328
3334
  }
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
3335
  static get _classname() {
3346
3336
  return 'CreditNote'
3347
3337
  }
@@ -3359,9 +3349,11 @@ class CreditNote {
3359
3349
  }
3360
3350
 
3361
3351
  get isValid() {
3362
- return !!this.tenantCode && !!this.invoiceCode
3352
+ return super.isValid && !!this.invoiceCode
3353
+ }
3354
+ getCode() {
3355
+ return this.creditNoteCode
3363
3356
  }
3364
-
3365
3357
  setAmount(amount) {
3366
3358
  const a = this_Amount.init(amount)
3367
3359
  if (this.isPending && a) {
@@ -3373,10 +3365,6 @@ class CreditNote {
3373
3365
  this.status.setCompleted()
3374
3366
  return this.setModified()
3375
3367
  }
3376
- setModified() {
3377
- this.modified = (new Date()).valueOf()
3378
- return this
3379
- }
3380
3368
  setPaid(t) {
3381
3369
  this.status.setPaid(t)
3382
3370
  return this.setModified()
@@ -3386,10 +3374,6 @@ class CreditNote {
3386
3374
  if (creditNote_updateAllowedProps.includes(key)) {
3387
3375
  if (key === 'amount') {
3388
3376
  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
3377
  } else if (key === 'status') {
3394
3378
  this[key] = this._Status.init(update[key])
3395
3379
  } else {
@@ -3397,7 +3381,7 @@ class CreditNote {
3397
3381
  }
3398
3382
  }
3399
3383
  })
3400
- return this.setModified()
3384
+ return super.update(update)
3401
3385
  }
3402
3386
  }
3403
3387
 
@@ -3451,35 +3435,27 @@ class CreditNoteRepo extends q_utilities_namespaceObject.Repo {
3451
3435
 
3452
3436
 
3453
3437
  const currency_updateAllowedProps = [
3454
- 'active',
3455
- 'deleted',
3456
3438
  'description',
3457
3439
  'name',
3458
- 'remarks',
3459
3440
  'symbol'
3460
3441
  ]
3461
3442
 
3462
- class Currency {
3443
+ class Currency extends q_utilities_namespaceObject.TenantAwareEntity {
3463
3444
  constructor(options = {}) {
3464
3445
  options = options || {}
3446
+ super(options)
3447
+
3465
3448
  const id = options._id || options.id
3466
3449
  this.id = currency_setId(id)
3467
3450
 
3468
3451
  this._type = options._type || 'Currency'
3469
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3452
+
3470
3453
  this.code = options.code // 'HKD'
3471
- this.created = options.created || (new Date()).valueOf()
3472
- this.creator = options.creator
3473
3454
  this.currencyCode = currency_setCode(options, 'currencyCode')
3474
- this.deleted = options.deleted || false
3475
3455
  this.description = options.description
3476
3456
  this.factor = options.factor || 1 // 100
3477
- this.modified = options.modified || (new Date()).valueOf()
3478
3457
  this.name = options.name
3479
- this.owner = options.owner
3480
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3481
3458
  this.symbol = options.symbol || null
3482
- this.tenantCode = options.tenantCode
3483
3459
  this.unit = options.unit
3484
3460
  }
3485
3461
  static dummyData() {
@@ -3491,22 +3467,6 @@ class Currency {
3491
3467
  unit: 'Cent',
3492
3468
  }
3493
3469
  }
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
3470
  static get _classname() {
3511
3471
  return 'Currency'
3512
3472
  }
@@ -3515,29 +3475,23 @@ class Currency {
3515
3475
  }
3516
3476
 
3517
3477
  get isValid() {
3518
- return !!this.code && typeof this.factor === 'number' && !!this.name && !!this.unit && !!this.tenantCode
3478
+ return super.isValid && !!this.code && typeof this.factor === 'number' && !!this.name && !!this.unit
3519
3479
  }
3520
3480
 
3521
3481
  fromCurrencyValue(value) {
3522
3482
  return value / this.factor
3523
3483
  }
3524
-
3525
- setModified() {
3526
- this.modified = (new Date()).valueOf()
3527
- return this
3484
+ getCode() {
3485
+ return this.currencyCode
3528
3486
  }
3529
3487
 
3530
3488
  update(update) {
3531
3489
  Object.keys(update).forEach((key) => {
3532
3490
  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
- }
3491
+ this[key] = update[key]
3538
3492
  }
3539
3493
  })
3540
- return this.setModified()
3494
+ return super.update(update)
3541
3495
  }
3542
3496
  }
3543
3497
 
@@ -3588,6 +3542,74 @@ class CurrencyRepo extends q_utilities_namespaceObject.Repo {
3588
3542
 
3589
3543
 
3590
3544
 
3545
+ ;// ./lib/helpers/getPurchaseOptionValue/getPurchaseOptionValue.js
3546
+ function getPurchaseOptionValue(options) {
3547
+ const {
3548
+ delimiter = ': ',
3549
+ key,
3550
+ purchaseOptions,
3551
+ tag = 'div'
3552
+ } = options || {}
3553
+ if (!key) {
3554
+ return purchaseOptions.reduce((acc, purchaseOption) => {
3555
+ const arr = _getOnePurchaseOptionValue({
3556
+ delimiter, purchaseOption, tag
3557
+ })
3558
+ if (tag) {
3559
+ acc.push(`<${tag}>${arr.join('')}</${tag}>`)
3560
+ } else {
3561
+ acc.push(`${arr.join('; ')}`)
3562
+ }
3563
+ return acc
3564
+ }, [])
3565
+ }
3566
+ const purchaseOption = (purchaseOptions || []).find((po) => {
3567
+ return !!key && po.key === key
3568
+ })
3569
+ if (!purchaseOption) {
3570
+ return []
3571
+ }
3572
+ return _getOnePurchaseOptionValue({
3573
+ delimiter, purchaseOption, tag
3574
+ })
3575
+ }
3576
+
3577
+ function _getOnePurchaseOptionValue({
3578
+ delimiter = ': ',
3579
+ purchaseOption,
3580
+ tag = 'div'
3581
+ }) {
3582
+ return (purchaseOption.value || []).reduce((acc, val) => {
3583
+ const { label, value = {} } = val || {}
3584
+ const _label = label ?? ''
3585
+ if (Array.isArray(value)) {
3586
+ if (tag) {
3587
+ acc.push(`<${tag}>${_label}${delimiter}${value.join(delimiter)}</${tag}>`)
3588
+ } else {
3589
+ acc.push(`${_label}${delimiter}${value.join(delimiter)}`)
3590
+ }
3591
+ } else if (typeof value === 'object') {
3592
+ Object.keys(value).map((key) => {
3593
+ if (tag) {
3594
+ acc.push(`<${tag}>${key}${delimiter}${value[key]}</${tag}>`)
3595
+ } else {
3596
+ acc.push(`${key}${delimiter}${value[key]}`)
3597
+ }
3598
+ })
3599
+ } else {
3600
+ if (tag) {
3601
+ acc.push(`<${tag}>${_label}${delimiter}${value}</${tag}>`)
3602
+ } else {
3603
+ acc.push(`${_label}${delimiter}${value}`)
3604
+ }
3605
+ }
3606
+
3607
+ return acc
3608
+ }, [])
3609
+ }
3610
+
3611
+
3612
+
3591
3613
  ;// ./lib/models/invoiceLine/invoiceLine.js
3592
3614
 
3593
3615
 
@@ -3596,22 +3618,22 @@ class CurrencyRepo extends q_utilities_namespaceObject.Repo {
3596
3618
 
3597
3619
 
3598
3620
 
3621
+
3599
3622
  const invoiceLine_updateAllowedProps = [
3600
- 'active',
3601
3623
  'amount',
3602
3624
  'deduction',
3603
- 'deleted',
3604
3625
  'description',
3605
3626
  'discount',
3606
3627
  'purchaseOptions',
3607
3628
  'qty',
3608
- 'remarks',
3609
3629
  'unitPrice'
3610
3630
  ]
3611
3631
 
3612
- class InvoiceLine {
3632
+ class InvoiceLine extends q_utilities_namespaceObject.TenantAwareEntity {
3613
3633
  constructor(options = {}) {
3614
3634
  options = options || {}
3635
+ super(options)
3636
+
3615
3637
  const { _Amount, _Invoice, _Merchandise, _Status } = options._constructor || {}
3616
3638
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
3617
3639
  this._Invoice = _Invoice && (_Invoice._superclass === Invoice._superclass) ? _Invoice : Invoice
@@ -3624,23 +3646,16 @@ class InvoiceLine {
3624
3646
  const id = options._id || options.id
3625
3647
  this.id = invoiceLine_setId(id)
3626
3648
  this._type = options._type || 'InvoiceLine'
3627
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
3628
3649
  this.amount = this._Amount.init(options.amount)
3629
- this.created = options.created || (new Date()).valueOf()
3630
- this.creator = options.creator
3631
3650
  this.deduction = this._Amount.init(options.deduction)
3632
- this.deleted = options.deleted || false
3633
3651
  this.description = options.description
3634
3652
  this.discount = options.discount || 0
3635
3653
  this.invoiceCode = options.invoiceCode
3636
3654
  this.invoiceLineCode = invoiceLine_setCode(options, 'invoiceLineCode')
3637
3655
  this.merchandiseCode = options.merchandiseCode
3638
- this.modified = options.modified || (new Date()).valueOf()
3639
3656
  this.purchaseOptions = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.purchaseOptions)
3640
3657
  this.qty = options.qty || 1
3641
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3642
3658
  this.status = this._Status.init(options.status)
3643
- this.tenantCode = options.tenantCode
3644
3659
  this.unitPrice = this._Amount.init(options.unitPrice)
3645
3660
  this.waived = options.waived || 0
3646
3661
  }
@@ -3653,22 +3668,6 @@ class InvoiceLine {
3653
3668
  tenantCode: 'tenantCode'
3654
3669
  }
3655
3670
  }
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
3671
  static get _classname() {
3673
3672
  return 'InvoiceLine'
3674
3673
  }
@@ -3678,7 +3677,7 @@ class InvoiceLine {
3678
3677
 
3679
3678
  // getters
3680
3679
  get isValid() {
3681
- return !!this.amount && !!this.invoiceCode && !!this.tenantCode
3680
+ return super.isValid && !!this.amount && !!this.invoiceCode
3682
3681
  }
3683
3682
  get invoice() {
3684
3683
  return this._Invoice.init(this._invoice)
@@ -3688,11 +3687,13 @@ class InvoiceLine {
3688
3687
  }
3689
3688
 
3690
3689
  // instance methods
3691
- setModified() {
3692
- this.modified = (new Date()).valueOf()
3693
- return this
3690
+ getPurchaseOptionValue(options) {
3691
+ const { delimiter, key, tag } = options || {}
3692
+ return getPurchaseOptionValue({
3693
+ key,
3694
+ purchaseOptions: this.purchaseOptions
3695
+ })
3694
3696
  }
3695
-
3696
3697
  update(update) {
3697
3698
  Object.keys(update).forEach((key) => {
3698
3699
  if (invoiceLine_updateAllowedProps.includes(key)) {
@@ -3705,7 +3706,7 @@ class InvoiceLine {
3705
3706
  }
3706
3707
  }
3707
3708
  })
3708
- return this.setModified()
3709
+ return super.update(update)
3709
3710
  }
3710
3711
  }
3711
3712
 
@@ -3815,45 +3816,38 @@ class Issuer {
3815
3816
 
3816
3817
 
3817
3818
 
3819
+
3818
3820
  // import { Transaction } from '../transaction/index.js'
3819
3821
 
3820
3822
  const walletItem_updateAllowedProps = [
3821
- 'active',
3822
- 'deleted',
3823
- 'owner',
3824
3823
  'purchaseOptions',
3825
3824
  'qty',
3826
- 'remarks',
3827
3825
  'status',
3828
3826
  ]
3829
3827
 
3830
- class WalletItem {
3828
+ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
3831
3829
  constructor(options = {}) {
3832
3830
  options = options || {}
3831
+ super(options)
3832
+
3833
3833
  const { _Product, _Status } = options._constructor || {}
3834
3834
  this._Product = _Product && (_Product._superclass === Product._superclass) ? _Product : Product
3835
3835
  this._Status = _Status && (_Status._superclass === Status._superclass) ? _Status : Status
3836
3836
  // this._Transaction = _Transaction && (_Transaction._superclass === Transaction._superclass) ? _Transaction : Transaction
3837
3837
 
3838
+ this._eventRegistration = options._eventRegistration
3839
+ this._invoiceLine = options._invoiceLine
3838
3840
  this._product = options._product
3839
3841
  this._tenant = options._tenant
3840
3842
  this._transaction = options._transaction
3841
3843
 
3842
3844
  const id = options._id || options.id
3843
3845
  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
3846
+ this.invoiceLineCode = options.invoiceLineCode
3851
3847
  this.productCode = options.productCode
3852
3848
  this.purchaseOptions = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.purchaseOptions)
3853
3849
  this.qty = options.qty || 1
3854
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
3855
3850
  this.status = this._Status.init(options.status)
3856
- this.tenantCode = options.tenantCode
3857
3851
  this.transactionCode = options.transactionCode
3858
3852
  this.walletItemCode = walletItem_setCode(options, 'walletItemCode')
3859
3853
  }
@@ -3869,22 +3863,7 @@ class WalletItem {
3869
3863
  transactionCode: 'transactionCode'
3870
3864
  }
3871
3865
  }
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
- }
3866
+
3888
3867
  static get _classname() {
3889
3868
  return 'WalletItem'
3890
3869
  }
@@ -3894,11 +3873,14 @@ class WalletItem {
3894
3873
 
3895
3874
  // getters
3896
3875
  get isValid() {
3897
- return !!this.tenantCode && !!this.productCode
3876
+ return super.isValid && !!this.productCode
3898
3877
  }
3899
3878
  get isAssigned() {
3900
3879
  return this.status.isAssigned
3901
3880
  }
3881
+ get isAvailableCoupon() {
3882
+ return this.isCoupon && !this.isCancelled && !this.isUsed
3883
+ }
3902
3884
  get isCancelled() {
3903
3885
  return this.status.isCancelled
3904
3886
  }
@@ -3908,9 +3890,21 @@ class WalletItem {
3908
3890
  get isConfirmed() {
3909
3891
  return this.status.isConfirmed
3910
3892
  }
3893
+ get isCoupon() {
3894
+ return this.product ? this.product.isCoupon : false
3895
+ }
3911
3896
  get isDelivered() {
3912
3897
  return this.status.isDelivered
3913
3898
  }
3899
+ get isInWallet() {
3900
+ return !this.isCancelled && !this.isRefundRequested
3901
+ }
3902
+ get isItemCoupon() {
3903
+ return this.product ? this.product.isItemCoupon : false
3904
+ }
3905
+ get isOnHold() {
3906
+ return this.status.onHold
3907
+ }
3914
3908
  get isOwned() {
3915
3909
  return (
3916
3910
  !this.isCancelled && !this.isRejected && !this.isRefunded
@@ -3934,6 +3928,9 @@ class WalletItem {
3934
3928
  get isRefunded() {
3935
3929
  return this.status.isRefunded
3936
3930
  }
3931
+ get isRefundRequested() {
3932
+ return this.status.isRefundRequested
3933
+ }
3937
3934
  get isRejected() {
3938
3935
  return this.status.rejected
3939
3936
  }
@@ -3949,6 +3946,10 @@ class WalletItem {
3949
3946
  get isWaived() {
3950
3947
  return this.status.isWaived
3951
3948
  }
3949
+
3950
+ get couponDetails() {
3951
+ return this.product ? this.product.couponDetails : null
3952
+ }
3952
3953
  get product() {
3953
3954
  return this._Product.init(this._product)
3954
3955
  }
@@ -3980,8 +3981,23 @@ class WalletItem {
3980
3981
  return this
3981
3982
  }
3982
3983
  }
3984
+ getCode() {
3985
+ return this.walletItemCode
3986
+ }
3987
+ getPurchaseOptionValue(options) {
3988
+ const { delimiter, key, tag } = options || {}
3989
+ return getPurchaseOptionValue({
3990
+ delimiter,
3991
+ key,
3992
+ purchaseOptions: this.purchaseOptions,
3993
+ tag,
3994
+ })
3995
+ }
3996
+ isApplicableCoupon(obj) {
3997
+ return this.isAvailableCoupon && (this.product ? this.product.isApplicableCoupon(obj) : false)
3998
+ }
3983
3999
  isSameOwner(userId) {
3984
- return userId
4000
+ return userId && this.owner
3985
4001
  ? (userId === this.owner)
3986
4002
  : false
3987
4003
  }
@@ -3997,8 +4013,8 @@ class WalletItem {
3997
4013
  this.status.setDelivered(value)
3998
4014
  return this
3999
4015
  }
4000
- setModified() {
4001
- this.modified = (new Date()).valueOf()
4016
+ setOnHold() {
4017
+ this.status.setOnHold()
4002
4018
  return this
4003
4019
  }
4004
4020
  setPaid() {
@@ -4031,6 +4047,11 @@ class WalletItem {
4031
4047
  // this.statusTimestamp.setUsed()
4032
4048
  return this
4033
4049
  }
4050
+ setUsedCouponFor(walletItemCode) {
4051
+ const _usedFor = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(this.metadata, 'USED_COUPON_FOR') || []
4052
+ _usedFor.push(walletItemCode)
4053
+ this.metadata = q_utilities_namespaceObject.Metadata.insertOrUpdateRecord(this.metadata, 'USED_COUPON_FOR', _usedFor)
4054
+ }
4034
4055
  setWaived() {
4035
4056
  this.status.setWaived()
4036
4057
  return this
@@ -4051,12 +4072,14 @@ class WalletItem {
4051
4072
  // walletItemCode: this.walletItemCode
4052
4073
  // }
4053
4074
  // }
4075
+ unSetOnHold() {
4076
+ this.status.unSetOnHold()
4077
+ return this
4078
+ }
4054
4079
  update(update) {
4055
4080
  Object.keys(update).forEach((key) => {
4056
4081
  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') {
4082
+ if (key === 'purchaseOptions') {
4060
4083
  this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
4061
4084
  } else if (key === 'status') {
4062
4085
  this[key] = this._Status.init(update[key])
@@ -4065,7 +4088,7 @@ class WalletItem {
4065
4088
  }
4066
4089
  }
4067
4090
  })
4068
- return this.setModified()
4091
+ return super.update(update)
4069
4092
  }
4070
4093
  }
4071
4094
 
@@ -4121,18 +4144,17 @@ class WalletItemRepo extends q_utilities_namespaceObject.Repo {
4121
4144
 
4122
4145
 
4123
4146
  const transaction_updateAllowedProps = [
4124
- 'active',
4125
4147
  'amount',
4126
4148
  'couponCodes',
4127
- 'deleted',
4128
4149
  // 'refundedAmount',
4129
- 'remarks',
4130
4150
  'status'
4131
4151
  ]
4132
4152
 
4133
- class Transaction {
4153
+ class Transaction extends q_utilities_namespaceObject.TenantAwareEntity {
4134
4154
  constructor(options = {}) {
4135
4155
  options = options || {}
4156
+ super(options)
4157
+
4136
4158
  const { _Amount, _Status, _WalletItem } = options._constructor || {}
4137
4159
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
4138
4160
  this._Status = _Status && (_Status._superclass === Status._superclass) ? _Status : Status
@@ -4148,22 +4170,14 @@ class Transaction {
4148
4170
  const id = options._id || options.id
4149
4171
  this.id = transaction_setId(id)
4150
4172
  this._type = options._type || 'Transaction'
4151
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
4173
+
4152
4174
  this.amount = this._Amount.init(options.amount)
4153
4175
  this.couponCodes = options.couponCodes || []
4154
- this.created = options.created || (new Date()).valueOf()
4155
- this.creator = options.creator
4156
4176
  this.creditNoteCodes = options.creditNoteCodes || []
4157
- this.deleted = options.deleted || false
4158
4177
  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
4178
  this.paymentGatewayCode = options.paymentGatewayCode
4163
4179
  this.paymentResultRef = options.paymentResultRef
4164
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
4165
4180
  this.status = this._Status.init(options.status)
4166
- this.tenantCode = options.tenantCode
4167
4181
  this.transactionCode = transaction_setCode(options, 'transactionCode')
4168
4182
  }
4169
4183
 
@@ -4174,22 +4188,6 @@ class Transaction {
4174
4188
  tenantCode: 'tenantCode'
4175
4189
  }
4176
4190
  }
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
4191
  static get _classname() {
4194
4192
  return 'Transaction'
4195
4193
  }
@@ -4199,7 +4197,7 @@ class Transaction {
4199
4197
 
4200
4198
  // getters
4201
4199
  get isValid() {
4202
- return !!this.tenantCode
4200
+ return super.isValid
4203
4201
  }
4204
4202
  get isActive() {
4205
4203
  return this.active === true
@@ -4338,9 +4336,6 @@ class Transaction {
4338
4336
  setFailed() {
4339
4337
  return this.status.setFailed()
4340
4338
  }
4341
- setModified() {
4342
- return this.modified = (new Date()).valueOf()
4343
- }
4344
4339
  setOnHold() {
4345
4340
  return this.status.setOnHold()
4346
4341
  }
@@ -4397,10 +4392,6 @@ class Transaction {
4397
4392
  if (transaction_updateAllowedProps.includes(key)) {
4398
4393
  if (key === 'amount') {
4399
4394
  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
4395
  } else if (key === 'status') {
4405
4396
  this[key] = this._Status.init(update[key])
4406
4397
  // } else if (key === 'refundedAmount') {
@@ -4410,7 +4401,7 @@ class Transaction {
4410
4401
  }
4411
4402
  }
4412
4403
  })
4413
- return this.setModified()
4404
+ return super.update(update)
4414
4405
  }
4415
4406
  // updatePayment(payment = {}) {
4416
4407
  // this.payments = Payment.updatePaymentItem(this.payments, payment)
@@ -4485,21 +4476,19 @@ class TransactionRepo extends q_utilities_namespaceObject.Repo {
4485
4476
 
4486
4477
 
4487
4478
  const invoice_updateAllowedProps = [
4488
- 'active',
4489
4479
  'checkoutDateTime',
4490
- 'deleted',
4491
4480
  'description',
4492
4481
  'invoiceDate',
4493
4482
  'issuer',
4494
- 'metadata',
4495
- 'remarks',
4496
4483
  'revisionNumber',
4497
4484
  'status'
4498
4485
  ]
4499
4486
 
4500
- class Invoice {
4487
+ class Invoice extends q_utilities_namespaceObject.TenantAwareEntity {
4501
4488
  constructor(options) {
4502
4489
  options = options || {}
4490
+ super(options)
4491
+
4503
4492
  const { _Amount, _Cart, _InvoiceLine, _Issuer, _Status, _Transaction } = options._constructor || {}
4504
4493
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
4505
4494
  this._Cart = _Cart && (_Cart._superclass === Cart._superclass) ? _Cart : Cart
@@ -4515,25 +4504,16 @@ class Invoice {
4515
4504
  const id = options._id || options.id
4516
4505
  this.id = invoice_setId(id)
4517
4506
  this._type = options._type || 'Invoice'
4518
- this.active = (typeof options.active !== 'undefined') ? !!options.active : true
4519
4507
  this.amount = this._Amount.init(options.amount)
4520
4508
  this.cartCode = options.cartCode
4521
4509
  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
4510
  this.description = options.description
4526
4511
  this.invoiceCode = invoice_setCode(options, 'invoiceCode')
4527
4512
  this.invoiceDate = options.invoiceDate || (new Date()).valueOf()
4528
4513
  this.invoiceNumber = options.invoiceNumber
4529
4514
  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
4515
  this.revisionNumber = options.revisionNumber || 1
4535
4516
  this.status = this._Status.init(options.status)
4536
- this.tenantCode = options.tenantCode
4537
4517
  }
4538
4518
 
4539
4519
  static dummyData() {
@@ -4541,22 +4521,6 @@ class Invoice {
4541
4521
  tenantCode: 'tenantCode'
4542
4522
  }
4543
4523
  }
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
4524
  static get _classname() {
4561
4525
  return 'Invoice'
4562
4526
  }
@@ -4565,7 +4529,7 @@ class Invoice {
4565
4529
  }
4566
4530
 
4567
4531
  get isValid() {
4568
- return !!this.tenantCode
4532
+ return super.isValid
4569
4533
  }
4570
4534
  get cart() {
4571
4535
  return this._Cart.init(this._cart)
@@ -4638,7 +4602,9 @@ class Invoice {
4638
4602
  getAmount() {
4639
4603
  return this.amount
4640
4604
  }
4641
-
4605
+ getCode() {
4606
+ return this.invoiceCode
4607
+ }
4642
4608
  getCurrencyCode() {
4643
4609
  return this.amount ? this.amount.getCurrencyCode() : null
4644
4610
  }
@@ -4662,12 +4628,6 @@ class Invoice {
4662
4628
  }
4663
4629
  return this
4664
4630
  }
4665
-
4666
- setModified() {
4667
- this.modified = (new Date()).valueOf()
4668
- return this
4669
- }
4670
-
4671
4631
  setCompleted() {
4672
4632
  this.status.setCompleted()
4673
4633
  return this.setModified()
@@ -4681,12 +4641,8 @@ class Invoice {
4681
4641
  update(update) {
4682
4642
  Object.keys(update).forEach((key) => {
4683
4643
  if (invoice_updateAllowedProps.includes(key)) {
4684
- if (key === 'remarks') {
4685
- this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
4686
- } else if (key === 'amount') {
4644
+ if (key === 'amount') {
4687
4645
  this[key] = this._Amount.init(update[key])
4688
- } else if (key === 'metadata') {
4689
- this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
4690
4646
  } else if (key === 'issuer') {
4691
4647
  this[key] = this._Issuer.init(update[key])
4692
4648
  } else if (key === 'status') {
@@ -4696,7 +4652,7 @@ class Invoice {
4696
4652
  }
4697
4653
  }
4698
4654
  })
4699
- return this.setModified()
4655
+ return super.update(update)
4700
4656
  }
4701
4657
  }
4702
4658
 
@@ -4751,40 +4707,33 @@ class InvoiceRepo extends q_utilities_namespaceObject.Repo {
4751
4707
  ;// ./lib/models/paymentGateway/paymentGateway.js
4752
4708
 
4753
4709
 
4710
+
4754
4711
  const paymentGateway_updateAllowedProps = [
4755
- 'active',
4756
- 'deleted',
4757
4712
  'label',
4758
4713
  'logoUrl',
4759
4714
  'name',
4760
- 'owner',
4761
4715
  'sandbox',
4762
4716
  'setting'
4763
4717
  ]
4764
4718
 
4765
-
4766
- class PaymentGateway {
4719
+ class PaymentGateway extends q_utilities_namespaceObject.TenantAwareEntity {
4767
4720
  constructor(options = {}) {
4768
4721
  options = options || {}
4722
+ super(options)
4723
+
4769
4724
  const id = options._id || options.id
4770
4725
  this.id = paymentGateway_setId(id)
4771
4726
  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
4727
+
4776
4728
  this.hasWebhook = options.hasWebhook || false
4777
4729
  this.label = options.label
4778
4730
  this.logoUrl = options.logoUrl
4779
- this.modified = options.modified || (new Date()).valueOf()
4780
4731
  this.name = options.name || ''
4781
- this.owner = options.owner
4782
4732
  this.paymentGatewayCode = paymentGateway_setCode(options, 'paymentGatewayCode')
4783
4733
  this.paymentGatewayType = options.paymentGatewayType || 'PaymentGateway'
4784
4734
  this.paymentResultType = options.paymentResultType || 'PaymentResult'
4785
4735
  this.sandbox = options.sandbox || false
4786
4736
  this.setting = options.setting || null
4787
- this.tenantCode = options.tenantCode
4788
4737
  }
4789
4738
  static dummyData() {
4790
4739
  return {
@@ -4792,22 +4741,6 @@ class PaymentGateway {
4792
4741
  tenantCode: 'tenantCode'
4793
4742
  }
4794
4743
  }
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
4744
  static get _classname() {
4812
4745
  return 'PaymentGateway'
4813
4746
  }
@@ -4817,7 +4750,7 @@ class PaymentGateway {
4817
4750
 
4818
4751
  // getters
4819
4752
  get isValid() {
4820
- return !!this.name && !!this.tenantCode
4753
+ return super.isValid && !!this.name
4821
4754
  }
4822
4755
 
4823
4756
  // instance methods
@@ -4827,6 +4760,9 @@ class PaymentGateway {
4827
4760
  async getAppPayParams() {
4828
4761
  throw new Error(`${this._classname} subclass should implement getAppPayParams`)
4829
4762
  }
4763
+ getCode() {
4764
+ return this.paymentGatewayCode
4765
+ }
4830
4766
  async updatePayment() {
4831
4767
  throw new Error(`${this._classname} subclass should implement updatePayment`)
4832
4768
  }
@@ -4840,18 +4776,13 @@ class PaymentGateway {
4840
4776
  setCompletedRelatedStatus(status) {
4841
4777
  throw new Error(`${this.name} subclass should implement setCompletedRelatedStatus`)
4842
4778
  }
4843
-
4844
- setModified() {
4845
- this.modified = (new Date()).valueOf()
4846
- return this
4847
- }
4848
4779
  update(update) {
4849
4780
  Object.keys(update).forEach((key) => {
4850
4781
  if (paymentGateway_updateAllowedProps.includes(key)) {
4851
4782
  this[key] = update[key]
4852
4783
  }
4853
4784
  })
4854
- return this.setModified()
4785
+ return super.update(update)
4855
4786
  }
4856
4787
  }
4857
4788
 
@@ -4912,9 +4843,11 @@ const paymentResult_updateAllowedProps = [
4912
4843
  'result'
4913
4844
  ]
4914
4845
 
4915
- class PaymentResult {
4846
+ class PaymentResult extends q_utilities_namespaceObject.TenantAwareEntity {
4916
4847
  constructor(options = {}) {
4917
4848
  options = options || {}
4849
+ super(options)
4850
+
4918
4851
  const { _Transaction } = options._constructor || {}
4919
4852
  this._Transaction = _Transaction && (_Transaction._superclass === Transaction._superclass) ? _Transaction : Transaction
4920
4853
 
@@ -4923,20 +4856,12 @@ class PaymentResult {
4923
4856
 
4924
4857
  const id = options._id || options.id
4925
4858
  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
4859
+
4933
4860
  this.paymentResultCode = paymentResult_setCode(options, 'paymentResultCode')
4934
4861
  this.paymentResultType = options.paymentResultType || 'PaymentResult'
4935
- this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
4936
4862
  this.result = options.result
4937
4863
  this.resultRef = options.resultRef
4938
4864
  this.resultType = options.resultType
4939
- this.tenantCode = options.tenantCode
4940
4865
  // this.transaction = this._Transaction.init(options.transaction)
4941
4866
  this.transactionCode = options.transactionCode
4942
4867
  }
@@ -4951,22 +4876,6 @@ class PaymentResult {
4951
4876
  transactionCode: 'transactionCode'
4952
4877
  }
4953
4878
  }
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
4879
  static get _classname() {
4971
4880
  return 'PaymentResult'
4972
4881
  }
@@ -4976,7 +4885,7 @@ class PaymentResult {
4976
4885
 
4977
4886
  // getters
4978
4887
  get isValid() {
4979
- return !!this.resultType && !!this.tenantCode && !!this.transactionCode
4888
+ return super.isValid && !!this.resultType && !!this.transactionCode
4980
4889
  // return !!this.result && !!this.resultType && !!this.tenantCode
4981
4890
  }
4982
4891
  get amount() {
@@ -4986,7 +4895,7 @@ class PaymentResult {
4986
4895
  throw new Error(`${this._classname} subclass should implement get paymentMethod`)
4987
4896
  }
4988
4897
  get transaction() {
4989
- return this._transaction.init(this._transaction)
4898
+ return this._Transaction.init(this._transaction)
4990
4899
  }
4991
4900
 
4992
4901
  // instance methods
@@ -5002,71 +4911,288 @@ class PaymentResult {
5002
4911
  return this
5003
4912
  }
5004
4913
 
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
- )
4914
+ compareStatus(paymentResult) {
4915
+ throw new Error(`${this.paymentResultType} subclass should implement compareStatus`)
4916
+ }
4917
+ getCode() {
4918
+ return this.paymentResultCode
4919
+ }
4920
+ getPaidAmount() {
4921
+ throw new Error(`${this.paymentResultType} subclass should implement getPaidAmount`)
4922
+ }
4923
+ getPaidTimestamp() {
4924
+ throw new Error(
4925
+ `${this.paymentResultType} subclass should implement getPaidTimestamp in milliseconds`
4926
+ )
4927
+ }
4928
+ getPaymentCode() {
4929
+ throw new Error(`${this.paymentResultType} subclass should implement getPaymentCode`)
4930
+ }
4931
+ getTransactionStatus() {
4932
+ throw new Error(`${this.paymentResultType} subclass should implement getTransactionStatus`)
4933
+ }
4934
+ handlePayment(payment) {
4935
+ if (!this.isForThisPayment(payment)) {
4936
+ return { payment, err: new Error('the payment result is not for this payment') }
4937
+ }
4938
+ if (!this.isSameAmount(payment)) {
4939
+ return { payment, err: new Error('the amount was not matched') }
4940
+ }
4941
+ try {
4942
+ payment.settled()
4943
+ payment
4944
+ .setPaidAmount(this.getPaidAmount())
4945
+ .setPaidTimestamp(this.getPaidTimestamp())
4946
+ .setPaymentResultCode(this.paymentResultCode)
4947
+ return { payment, err: null }
4948
+ } catch (err) {
4949
+ return { payment, err }
4950
+ }
4951
+ }
4952
+ isForThisPayment(payment) {
4953
+ return this.getPaymentCode() === payment.paymentCode
4954
+ }
4955
+ isSameAmount(payment) {
4956
+ return this.getPaidAmount() === payment.getAmount()
4957
+ }
4958
+ isSuccess() {
4959
+ throw new Error(`${this.paymentResultType} subclass should implement isSuccess`)
4960
+ }
4961
+ setupMetadata() {
4962
+ const amount = this.amount
4963
+ const paymentMethod = this.paymentMethod
4964
+ q_utilities_namespaceObject.Metadata.addItem(this.metadata, 'AMOUNT', amount)
4965
+ q_utilities_namespaceObject.Metadata.addItem(this.metadata, 'PAYMENT_METHOD', paymentMethod)
4966
+ q_utilities_namespaceObject.KeyValueObject.addItem(this.remarks, 'amount', amount)
4967
+ q_utilities_namespaceObject.KeyValueObject.addItem(this.remarks, 'paymentMethod', paymentMethod)
4968
+ return this
4969
+ }
4970
+ setupRemarks() {
4971
+ return this.setupMetadata()
4972
+ }
4973
+ update(update) {
4974
+ Object.keys(update).forEach((key) => {
4975
+ if (paymentResult_updateAllowedProps.includes(key)) {
4976
+ this[key] = update[key]
4977
+ }
4978
+ })
4979
+ return super.update(update)
4980
+ }
4981
+ }
4982
+
4983
+ function paymentResult_setCode(options, key) {
4984
+ const copyOptions = options || {}
4985
+ if (copyOptions[key]) {
4986
+ return copyOptions[key]
4987
+ }
4988
+ return stringHelper.setCode()
4989
+ }
4990
+
4991
+ function paymentResult_setId(id) {
4992
+ if (id && typeof id.toString === 'function') {
4993
+ return id.toString()
4994
+ }
4995
+ return id
4996
+ }
4997
+
4998
+
4999
+
5000
+ ;// ./lib/models/paymentResult/paymentResultRepo.js
5001
+
5002
+
5003
+
5004
+ class PaymentResultRepo extends q_utilities_namespaceObject.Repo {
5005
+ constructor(options = {}) {
5006
+ options = options || {}
5007
+ super(options)
5008
+ const { _PaymentResult } = options._constructor || {}
5009
+ this._PaymentResult = _PaymentResult && (_PaymentResult._superclass === PaymentResult._superclass) ? _PaymentResult : PaymentResult
5010
+ }
5011
+ static get _classname() {
5012
+ return 'PaymentResultRepo'
5013
+ }
5014
+ init(options) {
5015
+ return this._PaymentResult.init(options)
5016
+ }
5017
+ }
5018
+
5019
+
5020
+
5021
+ ;// ./lib/models/paymentResult/index.js
5022
+
5023
+
5024
+
5025
+
5026
+
5027
+
5028
+ ;// ./lib/models/status/index.js
5029
+
5030
+
5031
+
5032
+
5033
+
5034
+ ;// ./lib/models/storeItem/storeItem.js
5035
+
5036
+
5037
+
5038
+
5039
+
5040
+ const storeItem_updateAllowedProps = [
5041
+ 'active',
5042
+ 'deleted',
5043
+ 'description',
5044
+ 'intangible',
5045
+ 'limitPercentage',
5046
+ 'lineOptions',
5047
+ 'maxPerWallet',
5048
+ 'name',
5049
+ 'originalStock',
5050
+ 'owner',
5051
+ 'productOptions',
5052
+ 'remarks',
5053
+ 'requiredStoreItemCode',
5054
+ 'stock'
5055
+ ]
5056
+
5057
+ class StoreItem {
5058
+ constructor(options = {}) {
5059
+ options = options || {}
5060
+ const { _ItemOption } = options._constructor || {}
5061
+ this._ItemOption = _ItemOption && (_ItemOption._superclass === ItemOption) ? _ItemOption : ItemOption
5062
+
5063
+ const id = options._id || options.id
5064
+ this.id = storeItem_setId(id)
5065
+ this._type = options._type || 'StoreItem'
5066
+ this.active = (typeof options.active !== 'undefined') ? !!options.active : true
5067
+ this.created = options.created || (new Date()).valueOf()
5068
+ this.creator = options.creator
5069
+ this.deleted = options.deleted || false
5070
+ this.description = options.description || ''
5071
+ this.intangible = options.intangible || false
5072
+ this.limitPercentage = options.limitPercentage || 100
5073
+ this.lineOptions = this._ItemOption.initOnlyValidFromArray(options.lineOptions)
5074
+ this.maxPerWallet = options.maxPerWallet || 1
5075
+ this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
5076
+ this.modified = options.modified || (new Date()).valueOf()
5077
+ this.name = options.name || ''
5078
+ this.originalStock = options.originalStock || 0
5079
+ this.owner = options.owner
5080
+ this.productCode = storeItem_setCode(options, 'productCode')
5081
+ this.productOptions = this._ItemOption.initOnlyValidFromArray(options.productOptions)
5082
+ this.requiredStoreItemCode = options.requiredStoreItemCode
5083
+ this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
5084
+ this.stock = options.stock || 0
5085
+ this.storeItemType = options.storeItemType || 'StoreItem'
5086
+ this.tenantCode = options.tenantCode
5087
+ }
5088
+
5089
+ // class method
5090
+ static dummyData() {
5091
+ return {
5092
+ name: 'badge',
5093
+ tenantCode: 'tenantCode'
5094
+ }
5095
+ }
5096
+ static init(options = {}) {
5097
+ if (options instanceof this) {
5098
+ return options
5099
+ }
5100
+ const instance = new this(options)
5101
+ return instance.isValid ? instance : null
5102
+ }
5103
+ static initFromArray(arr = []) {
5104
+ if (Array.isArray(arr)) {
5105
+ return arr.map((a) => this.init(a))
5106
+ }
5107
+ return []
5108
+ }
5109
+ static initOnlyValidFromArray(arr = []) {
5110
+ return this.initFromArray(arr).filter((i) => i)
5111
+ }
5112
+ static get _classname() {
5113
+ return 'StoreItem'
5114
+ }
5115
+ static get _superclass() {
5116
+ return 'StoreItem'
5117
+ }
5118
+
5119
+ // getters
5120
+ get isValid() {
5121
+ return !!this.tenantCode && !!this.name
5122
+ }
5123
+ get isReachedLimitPercentage() {
5124
+ return this.soldPercentage >= this.limitPercentage
5125
+ }
5126
+ get soldPercentage() {
5127
+ return ((this.originalStock - this.stock) / this.originalStock) * 100
5128
+ }
5129
+ get summary() {
5130
+ return {
5131
+ product: this,
5132
+ productCode: this.productCode,
5133
+ name: this.name,
5134
+ }
5135
+ }
5136
+
5137
+ // instance methods
5138
+ ableToHave(qty) {
5139
+ return this.maxPerWallet >= qty
5140
+ }
5141
+
5142
+ checkStoreItemItemOptions(itemOptionFillIns = []) {
5143
+ const copyItemOptionsFillIns = ItemOptionFillIn.getItemOptionFillInsByTarget({ itemOptionFillIns, target: 'StoreItem', targetCode: this.productCode })
5144
+ return copyItemOptionsFillIns.reduce((acc, fillIn) => {
5145
+ const key = fillIn.getKey()
5146
+ const itemOption = this.getStoreItemOptionByKey(key)
5147
+ if (!itemOption) {
5148
+ acc.errMsgs.push(`options of the product(${this.productCode}) does not contain key: "${key}"`)
5149
+ return acc
5150
+ }
5151
+ const isValid = itemOption.isValidFillInValue(fillIn.getValue())
5152
+ if (!isValid) {
5153
+ acc.errMsgs.push(`the product(${this.productCode}) option's(${key}) fillInValue is invalid`)
5154
+ }
5155
+ return acc
5156
+ }, { errMsgs: [] })
5015
5157
  }
5016
- getPaymentCode() {
5017
- throw new Error(`${this.paymentResultType} subclass should implement getPaymentCode`)
5158
+ getCode() {
5159
+ return this.productCode
5018
5160
  }
5019
- getTransactionStatus() {
5020
- throw new Error(`${this.paymentResultType} subclass should implement getTransactionStatus`)
5161
+ getMetadataValueByKey(key) {
5162
+ return q_utilities_namespaceObject.Metadata.getValueByKey(this.metadata || [], key)
5021
5163
  }
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 }
5164
+ getStoreItemOptionByKey(key) {
5165
+ const arr = this._ItemOption.getByKey(this.productOptions, key)
5166
+ if (arr.length === 1) {
5167
+ return arr[0]
5038
5168
  }
5169
+ return null
5039
5170
  }
5040
- isForThisPayment(payment) {
5041
- return this.getPaymentCode() === payment.paymentCode
5171
+ hasStock(qty) {
5172
+ return this.stock >= qty
5042
5173
  }
5043
- isSameAmount(payment) {
5044
- return this.getPaidAmount() === payment.getAmount()
5174
+ isQualified(data) {
5175
+ const rules = this.getMetadataValueByKey('RULES') || []
5176
+ return (rules.length === 0)
5177
+ ? true
5178
+ : rules.reduce((acc, r) => {
5179
+ return acc || (0,q_utilities_namespaceObject.getValidation)(r, data, storeItem_getDataByKey, q_utilities_namespaceObject.KeyValueObject)
5180
+ }, false)
5045
5181
  }
5046
- isSuccess() {
5047
- throw new Error(`${this.paymentResultType} subclass should implement isSuccess`)
5182
+ isTicket() {
5183
+ return false
5048
5184
  }
5049
5185
  setModified() {
5050
5186
  this.modified = (new Date()).valueOf()
5051
5187
  return this
5052
5188
  }
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
5189
  update(update) {
5066
5190
  Object.keys(update).forEach((key) => {
5067
- if (paymentResult_updateAllowedProps.includes(key)) {
5191
+ if (storeItem_updateAllowedProps.includes(key)) {
5068
5192
  if (key === 'metadata') {
5069
5193
  this[key] = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(update[key])
5194
+ } else if (key === 'productOptions') {
5195
+ this[key] = this._ItemOption.initOnlyValidFromArray(update[key])
5070
5196
  } else if (key === 'remarks') {
5071
5197
  this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(update[key])
5072
5198
  } else {
@@ -5078,58 +5204,35 @@ class PaymentResult {
5078
5204
  }
5079
5205
  }
5080
5206
 
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) {
5207
+ function storeItem_setId(id) {
5090
5208
  if (id && typeof id.toString === 'function') {
5091
5209
  return id.toString()
5092
5210
  }
5093
5211
  return id
5094
5212
  }
5095
5213
 
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)
5214
+ function storeItem_setCode(options, key) {
5215
+ const copyOptions = options || {}
5216
+ if (copyOptions[key]) {
5217
+ return copyOptions[key]
5114
5218
  }
5219
+ return stringHelper.setCode()
5115
5220
  }
5116
5221
 
5117
-
5118
-
5119
- ;// ./lib/models/paymentResult/index.js
5120
-
5121
-
5222
+ function storeItem_getDataByKey(key, data) {
5223
+ return (0,q_utilities_namespaceObject.getValueByKeys)(key.split('.'), data)
5224
+ }
5122
5225
 
5123
5226
 
5124
5227
 
5228
+ ;// ./lib/models/storeItem/index.js
5125
5229
 
5126
- ;// ./lib/models/status/index.js
5127
5230
 
5128
5231
 
5129
5232
 
5233
+ ;// ./lib/models/index.js
5130
5234
 
5131
5235
 
5132
- ;// ./lib/models/index.js
5133
5236
 
5134
5237
 
5135
5238
 
@@ -5261,6 +5364,34 @@ class Chain {
5261
5364
 
5262
5365
 
5263
5366
 
5367
+ ;// ./lib/helpers/calculateByCoupon/calculateCoupon.js
5368
+
5369
+ function calculateByCoupon({ coupon, price }) {
5370
+ const { couponDetails } = coupon
5371
+ if (!couponDetails) {
5372
+ return 0
5373
+ }
5374
+ const { type, item } = couponDetails
5375
+ if (item) {
5376
+ switch(type) {
5377
+ case ('Percentage'): {
5378
+ return _caculateByPercentage(price, couponDetails)
5379
+ }
5380
+ default: {
5381
+ return 0
5382
+ }
5383
+ }
5384
+ }
5385
+ }
5386
+
5387
+ function _caculateByPercentage(price, couponDetails) {
5388
+ const { value } = couponDetails
5389
+ return price.value * (value / 100)
5390
+ }
5391
+
5392
+
5393
+
5394
+
5264
5395
  ;// ./lib/eventManager/chains/helpers.js
5265
5396
 
5266
5397
 
@@ -5269,6 +5400,7 @@ class Chain {
5269
5400
 
5270
5401
 
5271
5402
 
5403
+
5272
5404
  ;// ./lib/eventManager/chains/chainCategoryLimit.js
5273
5405
 
5274
5406
 
@@ -5301,7 +5433,7 @@ class ChainCategoryLimit extends Chain {
5301
5433
  function groupCategory(categories = [], walletItems = []) {
5302
5434
  return categories.reduce((acc, category) => {
5303
5435
  const {
5304
- categoryCode, name, max, min, productCodes = [],
5436
+ categoryCode, codes, name, max, min, productCodes = [],
5305
5437
  } = category
5306
5438
  const filtered = walletItems.filter((w) => {
5307
5439
  if (w.status.cancelled !== null) {
@@ -5311,6 +5443,7 @@ function groupCategory(categories = [], walletItems = []) {
5311
5443
  })
5312
5444
  acc.push({
5313
5445
  categoryCode,
5446
+ codes,
5314
5447
  max,
5315
5448
  min,
5316
5449
  name,
@@ -5326,7 +5459,7 @@ function handleCategory(line, groupedCategory) {
5326
5459
  const { productsQty, updatedItem } = line
5327
5460
  // const productsQty = merchandise.getProductsQty(item.qty)
5328
5461
  Object.keys(productsQty).forEach((key) => {
5329
- const found = groupedCategory.find((g) => g.productCodes.includes(key))
5462
+ const found = groupedCategory.find((g) => g.productCodes.includes(key) && g.codes.includes(updatedItem.merchandiseCode))
5330
5463
  if (found) {
5331
5464
  const balance = found.max - (found.used + found.owned)
5332
5465
  if (balance === 0) {
@@ -5388,6 +5521,7 @@ class ChainGetPrice extends Chain {
5388
5521
  // }
5389
5522
  })
5390
5523
  cutEntitlements(lines, entitlements, this.currency.code)
5524
+ // useCoupons(lines, this.currency.code)
5391
5525
  // getAmount()
5392
5526
  await this.next(chainTarget)
5393
5527
  } catch (err) {
@@ -5604,6 +5738,13 @@ function getStrategiesByRestrictions(prices, line, user) {
5604
5738
  }
5605
5739
 
5606
5740
 
5741
+ // function useCoupons(lines, currencyCode) {
5742
+ // lines.forEach((line) => {
5743
+
5744
+ // })
5745
+ // }
5746
+
5747
+
5607
5748
 
5608
5749
  ;// ./lib/eventManager/chains/ChainGetPriceForGroup.js
5609
5750
 
@@ -5859,7 +6000,7 @@ class ChainMerchandiseLimit extends Chain {
5859
6000
  const stock = merchandise.getStock()
5860
6001
  if (stock === 0) {
5861
6002
  line.disabled = true
5862
- line.errors.push('Sold out.')
6003
+ line.errors.push('Full.')
5863
6004
  } else {
5864
6005
  const { qty } = updatedItem
5865
6006
  updatedItem.qty = qty > stock ? stock : qty
@@ -5904,7 +6045,7 @@ class ChainProductLimit extends Chain {
5904
6045
  // const newRest = balance - ordered
5905
6046
  if (balance === 0) {
5906
6047
  updatedItem.qty = 0
5907
- line.errors.push(`"${name}" is out of stock`)
6048
+ // line.errors.push(`"${name}" is out of stock`)
5908
6049
  } else {
5909
6050
  const ordered = (productQty * qty)
5910
6051
  const newBalance = balance - ordered
@@ -6048,22 +6189,141 @@ class ChainPurchaseOptions extends Chain {
6048
6189
  if (required && !value && !notFinishRequired) {
6049
6190
  notFinishRequired = true
6050
6191
  line.validated = false
6051
- line.errors.push('Need to fill in options.')
6192
+ line.errors.push('Please fill in the option(s).')
6052
6193
  }
6053
6194
  if (validated && !notFinishValidated) {
6054
6195
  notFinishValidated = true
6055
- line.errors.push('Has not validated options.')
6196
+ line.errors.push('Invalid option(s).')
6056
6197
  }
6057
6198
  })
6058
6199
  })
6059
6200
  })
6060
6201
  await this.next(chainTarget)
6061
6202
  } catch (err) {
6062
- chainTarget.addException('check product restriction fail', err.message)
6203
+ chainTarget.addException('Check product restriction failed.', err.message)
6204
+ this.exitChain()
6205
+ }
6206
+ }
6207
+ }
6208
+
6209
+
6210
+
6211
+ ;// ./lib/eventManager/chains/chainRelatedCoupons.js
6212
+
6213
+ // import { WalletItem } from '../../models/walletItem/index.js'
6214
+
6215
+ class ChainRelatedCoupons extends Chain {
6216
+ constructor(options = {}) {
6217
+ super(options)
6218
+ this.autoUseCoupon = options.autoUseCoupon || false
6219
+ this.currency = options.currency
6220
+ this.walletItems = options.walletItems
6221
+ }
6222
+
6223
+ async handleRequest(chainTarget) {
6224
+ try {
6225
+ const { lines, users } = chainTarget
6226
+ // const walletItems = WalletItem.initOnlyValidFromArray(this.walletItems)
6227
+ const couponWalletItems = this.walletItems.filter((i) => i.isCoupon)
6228
+ lines.forEach((line) => {
6229
+ _calculateAmountByCoupons({ line, currencyCode: this.currency.code })
6230
+ _updateRelatedCoupons(line, couponWalletItems, this.autoUseCoupon, this.currency.code)
6231
+ })
6232
+ lines.forEach((line) => {
6233
+ _getAvailableCoupons(line)
6234
+ })
6235
+ await this.next(chainTarget)
6236
+ } catch (err) {
6237
+ chainTarget.addException('calculate categories limit fail', err.message)
6063
6238
  this.exitChain()
6064
6239
  }
6065
6240
  }
6066
6241
  }
6242
+ function _calculateAmountByCoupons({ line, currencyCode }) {
6243
+ const { usedCoupons = {}, updatedItem } = line
6244
+ Object.keys(usedCoupons).forEach((key) => {
6245
+ usedCoupons[key].forEach((coupon) => {
6246
+ const obj = _calculateAmountByOneCoupon({ updatedItem, coupon, currencyCode })
6247
+ Object.assign(updatedItem, obj)
6248
+ })
6249
+ })
6250
+ }
6251
+
6252
+ function _calculateAmountByOneCoupon({ updatedItem, coupon, currencyCode }) {
6253
+ const { couponDetails, walletItemCode } = coupon
6254
+ if (!couponDetails) {
6255
+ return updatedItem
6256
+ }
6257
+ const { price, qty, discount, remarks, subTotal } = updatedItem
6258
+ const _discount = calculateByCoupon({ coupon, price })
6259
+ const discountValue = _discount + discount.value
6260
+ const subTotalValue = subTotal.value > _discount ? subTotal.value - _discount : 0
6261
+ const _usedCoupons = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(remarks, 'USED_ITEM_COUPONS') || []
6262
+ _usedCoupons.push(walletItemCode)
6263
+ return {
6264
+ ...updatedItem,
6265
+ discount: Amount.init({ value: discountValue, currencyCode }),
6266
+ remarks: q_utilities_namespaceObject.KeyValueObject.insertOrUpdateRecord(remarks, 'USED_ITEM_COUPONS', _usedCoupons ),
6267
+ subTotal: Amount.init({ value: subTotalValue, currencyCode })
6268
+ }
6269
+ }
6270
+
6271
+
6272
+ function _getAvailableCoupons(line) {
6273
+ const { relatedCoupons = [] } = line
6274
+ line.relatedCoupons = relatedCoupons.map((c) => ({
6275
+ ...c,
6276
+ availableCoupons: c.coupons.filter((_c) => (!_c.isOnHold))
6277
+ }))
6278
+ }
6279
+
6280
+ function _getRelatedCoupons(cartItemLine, couponWalletItems, autoUseCoupon, currencyCode) {
6281
+ const { merchandise, usedCoupons = {}, updatedItem = {} } = cartItemLine
6282
+ const relatedWalletItems = couponWalletItems.filter(
6283
+ item => item.isApplicableCoupon(merchandise) && item.isItemCoupon
6284
+ )
6285
+ // .sort((a, b) => (
6286
+ // b.couponDetails.value - a.couponDetails.value
6287
+ // ))
6288
+ return relatedWalletItems.reduce((acc, w) => {
6289
+ const productCode = w.product.productCode
6290
+ let exist = acc.find((i) => i.productCode === productCode)
6291
+ const isOnHold = w.isOnHold // max? || only use One Coupon?
6292
+ if (!exist) {
6293
+ exist = {
6294
+ coupons: [],
6295
+ product: w.product,
6296
+ productCode: productCode,
6297
+ usedQty: (usedCoupons[productCode] || []).length
6298
+ }
6299
+ acc.push(exist)
6300
+ }
6301
+ exist.coupons.push(w)
6302
+ const { qty: itemQty, subTotal } = updatedItem
6303
+ if (autoUseCoupon && !isOnHold && exist.usedQty < itemQty && subTotal.value > 0) {
6304
+ // use coupon
6305
+ w.setOnHold()
6306
+ usedCoupons[productCode] = [
6307
+ ...usedCoupons[productCode] || [],
6308
+ w
6309
+ ]
6310
+ const obj = _calculateAmountByOneCoupon({ updatedItem, currencyCode, coupon: w })
6311
+ Object.assign(updatedItem, obj)
6312
+ exist.usedQty = usedCoupons[productCode].length
6313
+ }
6314
+ return acc
6315
+ }, [])
6316
+ }
6317
+
6318
+
6319
+ function _updateRelatedCoupons(line, couponWalletItems, autoUseCoupon, currencyCode) {
6320
+ if (couponWalletItems.length > 0) {
6321
+ line.relatedCoupons = _getRelatedCoupons(line, couponWalletItems, autoUseCoupon, currencyCode)
6322
+ }
6323
+ }
6324
+
6325
+
6326
+
6067
6327
 
6068
6328
 
6069
6329
 
@@ -6079,6 +6339,7 @@ class ChainPurchaseOptions extends Chain {
6079
6339
 
6080
6340
 
6081
6341
 
6342
+
6082
6343
  ;// ./lib/helpers/corHelper/chainException.js
6083
6344
 
6084
6345
  class ChainException {
@@ -6340,6 +6601,7 @@ class ChainManagerFactory {
6340
6601
 
6341
6602
  function _calculateAmountChainsFactory(payload) {
6342
6603
  const {
6604
+ autoUseCoupon,
6343
6605
  categories,
6344
6606
  currency,
6345
6607
  dateTime,
@@ -6363,6 +6625,7 @@ function _calculateAmountChainsFactory(payload) {
6363
6625
  new ChainGetPrice({
6364
6626
  currency, dateTime, entitlements, merchandises
6365
6627
  }),
6628
+ new ChainRelatedCoupons({ currency, autoUseCoupon, walletItems }),
6366
6629
  ]
6367
6630
  }
6368
6631
 
@@ -6397,11 +6660,12 @@ function _calculateAmountChainsFactoryforGroup(payload) {
6397
6660
 
6398
6661
 
6399
6662
  ;// ./lib/helpers/adminSettle/adminSettle.js
6400
- function adminSettle({ component, invoice, payeeName, payeeAddress, payeeCountry, cb }) {
6663
+ function adminSettle({ component, eventRegistration, invoice, payeeName, payeeAddress, payeeCountry, cb }) {
6664
+ const _eventRegistration = eventRegistration || component.registration
6401
6665
  component.invoice = invoice
6402
6666
  component.adminSettleFormData = {
6403
6667
  ...invoice,
6404
- email: component.registration ? component.registration.getEmail() || '' : '',
6668
+ email: _eventRegistration ? _eventRegistration.getEmail() || '' : '',
6405
6669
  payeeName,
6406
6670
  payeeAddress,
6407
6671
  payeeCountry,
@@ -6504,6 +6768,11 @@ function getFakeClass() {
6504
6768
 
6505
6769
 
6506
6770
 
6771
+ ;// ./lib/helpers/calculateByCoupon/index.js
6772
+
6773
+
6774
+
6775
+
6507
6776
  ;// ./lib/helpers/corHelper/index.js
6508
6777
 
6509
6778
 
@@ -6511,6 +6780,150 @@ function getFakeClass() {
6511
6780
 
6512
6781
 
6513
6782
 
6783
+ ;// ./lib/helpers/getRolesChangesRelatedCouponsHelper/getRolesChangesRelatedCouponsHelper.js
6784
+ function getRolesChangesRelatedCouponsHelper({ newRoles, originalRoles }) {
6785
+ const couponFromNewRoles = _getCouponsByRoles(newRoles)
6786
+ const couponFromOriginalRoles = _getCouponsByRoles(originalRoles)
6787
+ const allKeys = new Set([
6788
+ ...Object.keys(couponFromNewRoles),
6789
+ ...Object.keys(couponFromOriginalRoles)
6790
+ ])
6791
+ return Array.from(allKeys).reduce((acc, key) => {
6792
+ const newValue = couponFromNewRoles[key] || 0;
6793
+ const originalValue = couponFromOriginalRoles[key] || 0;
6794
+ const delta = newValue - originalValue;
6795
+ if (delta !== 0) {
6796
+ acc.push({
6797
+ key,
6798
+ value: {
6799
+ delta,
6800
+ newValue,
6801
+ originalValue
6802
+ }
6803
+ });
6804
+ }
6805
+ return acc
6806
+ }, [])
6807
+ }
6808
+
6809
+
6810
+ function _getCouponsByRoles(roles) {
6811
+ return roles.reduce((acc, role) => {
6812
+ const couponCodes = role.getCouponCodes()
6813
+ couponCodes.forEach((c) => {
6814
+ const { key, value } = c
6815
+ acc[key] = acc[key] ? acc[key] + value : value
6816
+ })
6817
+ return acc
6818
+ }, {})
6819
+ }
6820
+
6821
+
6822
+
6823
+ ;// ./lib/helpers/couponManager/couponManager.js
6824
+
6825
+
6826
+
6827
+
6828
+ class CouponManager {
6829
+ constructor(options) {
6830
+ this.products = options.products || []
6831
+ this.walletItems = options.walletItems || []
6832
+ this.originalRoles = options.originalRoles || []
6833
+ this.newRoles = options.newRoles || []
6834
+ }
6835
+
6836
+ static init(options = {}) {
6837
+ if (options instanceof this) {
6838
+ return options
6839
+ }
6840
+ const instance = new this(options)
6841
+ return instance.isValid ? instance : null
6842
+ }
6843
+
6844
+ get isValid() {
6845
+ return !!this
6846
+ }
6847
+
6848
+ get couponProducts() {
6849
+ return this.products.filter((p) => p.isCoupon)
6850
+ }
6851
+
6852
+ get couponWalletItems() {
6853
+ return this.walletItems.filter((w) => w.isCoupon)
6854
+ }
6855
+
6856
+ get roleRelatedCoupons() {
6857
+ return getRolesChangesRelatedCouponsHelper({ newRoles: this.newRoles, originalRoles: this.originalRoles })
6858
+ }
6859
+
6860
+
6861
+ get couponItemList() {
6862
+ return this.couponProducts.map((p) => {
6863
+ const relatedWalletItems = this.walletItems.filter(
6864
+ item => item.productCode === p.productCode
6865
+ )
6866
+
6867
+ const usedCoupons = relatedWalletItems.filter(item => item.isUsed)
6868
+ usedCoupons.forEach((c) => {
6869
+ c.useForWalletItems = this.walletItems.filter((item) => (c.useFor || []).includes(item.walletItemCode)) // useFor
6870
+ })
6871
+
6872
+ const availableCoupons = relatedWalletItems.filter(item => !item.isAvailableCoupon)
6873
+
6874
+ const roleBase = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(this.roleRelatedCoupons, p.productCode) || {}
6875
+
6876
+ const remainingQuota = p.maxPerWallet - (usedCoupons.length + availableCoupons.length)
6877
+
6878
+ const { qty, remarks } = _handler({ product: p, availableCoupons, roleBase, remainingQuota })
6879
+
6880
+ return {
6881
+ product: p,
6882
+ usedCoupons,
6883
+ availableCoupons,
6884
+ alreadyHave: usedCoupons.length + availableCoupons.length,
6885
+ maxLimit: p.maxPerWallet,
6886
+ remainingQuota,
6887
+ qty,
6888
+ roleBase,
6889
+ remarks
6890
+ };
6891
+ })
6892
+ }
6893
+
6894
+ setNewRoles() {
6895
+ this.newRoles = newRoles
6896
+ }
6897
+
6898
+ }
6899
+
6900
+
6901
+
6902
+
6903
+ function _handler({ product, remainingQuota, availableCoupons, roleBase }) {
6904
+ const { delta = 0 } = roleBase
6905
+ const { maxPerWallet } = product
6906
+ let qty = delta
6907
+ const remarks = []
6908
+ if (delta > 0 && maxPerWallet && delta > remainingQuota) {
6909
+ qty = 0
6910
+ remarks.push(`max ${maxPerWallet}`)
6911
+ }
6912
+ if (delta < 0 && maxPerWallet && availableCoupons.length < delta) {
6913
+ qty = availableCoupons.length
6914
+ remarks.push(`only ${availableCoupons.length} could be cancelled`)
6915
+ }
6916
+ return {
6917
+ qty,
6918
+ remarks
6919
+ }
6920
+ }
6921
+
6922
+ ;// ./lib/helpers/couponManager/index.js
6923
+
6924
+
6925
+
6926
+
6514
6927
  ;// ./lib/helpers/dateHelper/handler/handler.js
6515
6928
  class Handler {
6516
6929
  constructor(date) {
@@ -6638,7 +7051,11 @@ function createDate(timestamp) {
6638
7051
  const mthIdx = Number(mthStr) - 1
6639
7052
  return new Date(timestamp.slice(0, 4), mthIdx, timestamp.slice(6, 8))
6640
7053
  }
6641
- throw new Error('timestamp does not meet the requirements')
7054
+ try {
7055
+ return new Date(timestamp)
7056
+ } catch (e) {
7057
+ throw new Error('timestamp does not meet the requirements')
7058
+ }
6642
7059
  }
6643
7060
 
6644
7061
  function convert(date, dateFormat) {
@@ -6907,6 +7324,8 @@ function isDescendingOrder({ arr = [], key }) {
6907
7324
 
6908
7325
 
6909
7326
 
7327
+
7328
+
6910
7329
  ;// ./lib/index.js
6911
7330
 
6912
7331
  const models = models_namespaceObject