@questwork/q-store-model 0.1.38 → 0.1.39

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.
@@ -68,12 +68,16 @@ __webpack_require__.d(__webpack_exports__, {
68
68
  ItemOptionLocale: () => (/* reexport */ ItemOptionLocale),
69
69
  KeyValueObject: () => (/* reexport */ q_utilities_namespaceObject.KeyValueObject),
70
70
  Merchandise: () => (/* reexport */ Merchandise),
71
+ Order: () => (/* reexport */ Order),
72
+ OrderLine: () => (/* reexport */ OrderLine),
71
73
  PaymentGateway: () => (/* reexport */ PaymentGateway),
72
74
  PaymentResult: () => (/* reexport */ PaymentResult),
73
75
  Price: () => (/* reexport */ Price),
74
76
  PriceStrategy: () => (/* reexport */ PriceStrategy),
75
77
  Product: () => (/* reexport */ Product),
76
78
  Status: () => (/* reexport */ Status),
79
+ StatusQStore: () => (/* reexport */ StatusQStore),
80
+ StatusQStoreOrderLine: () => (/* reexport */ StatusQStoreOrderLine),
77
81
  StoreItem: () => (/* reexport */ StoreItem),
78
82
  Transaction: () => (/* reexport */ Transaction),
79
83
  WalletItem: () => (/* reexport */ WalletItem),
@@ -118,12 +122,16 @@ __webpack_require__.d(models_namespaceObject, {
118
122
  ItemOptionLocale: () => (ItemOptionLocale),
119
123
  KeyValueObject: () => (q_utilities_namespaceObject.KeyValueObject),
120
124
  Merchandise: () => (Merchandise),
125
+ Order: () => (Order),
126
+ OrderLine: () => (OrderLine),
121
127
  PaymentGateway: () => (PaymentGateway),
122
128
  PaymentResult: () => (PaymentResult),
123
129
  Price: () => (Price),
124
130
  PriceStrategy: () => (PriceStrategy),
125
131
  Product: () => (Product),
126
132
  Status: () => (Status),
133
+ StatusQStore: () => (StatusQStore),
134
+ StatusQStoreOrderLine: () => (StatusQStoreOrderLine),
127
135
  StoreItem: () => (StoreItem),
128
136
  Transaction: () => (Transaction),
129
137
  WalletItem: () => (WalletItem)
@@ -1015,7 +1023,7 @@ class QtyPerTransaction {
1015
1023
  constructor(options = {}) {
1016
1024
  options = options || {}
1017
1025
  this.max = options.max === null || options.max > 0 ? options.max : 1 // options.max || 1
1018
- this.min = options.min === null || options.min >= 0 ? options.min : 1
1026
+ this.min = options.min === null || options.min >= 0 ? options.min : 0
1019
1027
  }
1020
1028
  static init(options = {}) {
1021
1029
  if (options instanceof this) {
@@ -1069,8 +1077,10 @@ const priceStrategy_updateAllowedProps = [
1069
1077
  'amounts',
1070
1078
  'deductions',
1071
1079
  'discount',
1080
+ 'metadata',
1072
1081
  'name',
1073
1082
  'qtyPerTransaction',
1083
+ 'remarks'
1074
1084
  ]
1075
1085
 
1076
1086
  class PriceStrategy {
@@ -1084,6 +1094,7 @@ class PriceStrategy {
1084
1094
  this.amounts = this._Amount.initOnlyValidFromArray(options.amounts)
1085
1095
  this.deductions = this._Amount.initOnlyValidFromArray(options.deductions)
1086
1096
  this.discount = options.discount || 0
1097
+ this.metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(options.metadata)
1087
1098
  this.name = options.name
1088
1099
  // this.order = options.order || 1
1089
1100
  this.qtyPerTransaction = this._QtyPerTransaction.init(options.qtyPerTransaction)
@@ -1123,7 +1134,15 @@ class PriceStrategy {
1123
1134
 
1124
1135
  // getters
1125
1136
  get isValid() {
1126
- return this.amounts.length > 0 && !!this.name && !!this.qtyPerTransaction && (typeof this.discount === 'number' && this.discount >= 0 && this.discount <= 100)
1137
+ return this.amounts.length > 0 && (typeof this.discount === 'number' && this.discount >= 0 && this.discount <= 100)
1138
+ }
1139
+ get restrictions() {
1140
+ let _restrictions = []
1141
+ _restrictions = q_utilities_namespaceObject.Metadata.getValuesByKey(this.metadata, 'RESTRICTIONS')
1142
+ if (_restrictions.length === 0) {
1143
+ _restrictions = q_utilities_namespaceObject.KeyValueObject.getValuesByKey(this.remarks, 'restrictions')
1144
+ }
1145
+ return _restrictions[0] || []
1127
1146
  }
1128
1147
 
1129
1148
  // instance methods
@@ -1142,7 +1161,7 @@ class PriceStrategy {
1142
1161
  // return this.priceStrategyType === priceStrategyType
1143
1162
  // }
1144
1163
 
1145
- getAmount({ cartItems, currencyCode, qty }) {
1164
+ getAmount({ currencyCode, qty }) {
1146
1165
  const amount = this.getAmountByCurrencyCode(currencyCode)
1147
1166
  if (amount) {
1148
1167
  const { value } = amount
@@ -1174,7 +1193,7 @@ class PriceStrategy {
1174
1193
 
1175
1194
  deductionHasCurrencyCode(currencyCode) {
1176
1195
  if (this.deductions.length === 0) {
1177
- return false
1196
+ return true
1178
1197
  }
1179
1198
  const amount = this.getDeductionByCurrencyCode(currencyCode)
1180
1199
  return (amount !== null)
@@ -1201,11 +1220,10 @@ class PriceStrategy {
1201
1220
  }
1202
1221
 
1203
1222
  isMatchedRestrictions(payload = {}) {
1204
- const [restrictions = []] = q_utilities_namespaceObject.KeyValueObject.getValuesByKey(this.remarks, 'restrictions')
1205
- if (restrictions.length === 0) {
1223
+ if (this.restrictions.length === 0) {
1206
1224
  return true
1207
1225
  }
1208
- const res = restrictions.reduce((acc, restriction) => {
1226
+ const res = this.restrictions.reduce((acc, restriction) => {
1209
1227
  const { key, value = {} } = restriction
1210
1228
  acc = acc || matchAnd(key, value, payload)
1211
1229
  // Object.keys(value).forEach((path) => {
@@ -1214,10 +1232,10 @@ class PriceStrategy {
1214
1232
  // })
1215
1233
  return acc
1216
1234
  }, false)
1217
- return res
1235
+ return res || false
1218
1236
  }
1219
1237
 
1220
- iaValidQty(qty) {
1238
+ isQtyValid(qty) {
1221
1239
  if (this.qtyPerTransaction.min > qty) {
1222
1240
  return false
1223
1241
  }
@@ -1307,7 +1325,13 @@ function _match({ action, formulaValue, val }) {
1307
1325
  case '$gte':
1308
1326
  return val >= formulaValue
1309
1327
  case '$in':
1310
- return formulaValue.includes(val)
1328
+ if (Array.isArray(val)) {
1329
+ return !!val.find((e) => (formulaValue.includes(e)))
1330
+ }
1331
+ if (typeof val !== 'object') {
1332
+ return !!formulaValue.includes(val)
1333
+ }
1334
+ return false
1311
1335
  case '$includes':
1312
1336
  return val.includes(formulaValue)
1313
1337
  case '$keyValue':
@@ -1364,11 +1388,9 @@ class Price {
1364
1388
  this.dateBegin = options.dateBegin || (new Date()).valueOf()
1365
1389
  this.dateEnd = options.dateEnd || null
1366
1390
  this.modified = options.modified || (new Date()).valueOf()
1367
- this.name = options.name
1391
+ this.name = options.name || ''
1368
1392
  this.priceStrategies = this._PriceStrategy.initOnlyValidFromArray(options.priceStrategies)
1369
- // this.qtyPerTransaction = QtyPerTransaction.init(options.qtyPerTransaction)
1370
1393
  this.remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.remarks)
1371
- // this.roleCodes = options.roleCodes || []
1372
1394
  }
1373
1395
 
1374
1396
  // class method
@@ -1383,8 +1405,6 @@ class Price {
1383
1405
  dateBegin: new Date().valueOf(),
1384
1406
  dateEnd: new Date().valueOf() + 1,
1385
1407
  priceStrategies: [PriceStrategy.dummyData()],
1386
- // roles: []
1387
- // qtyPerTransaction: QtyPerTransaction.init()
1388
1408
  }
1389
1409
  }
1390
1410
  static init(options = {}) {
@@ -1425,12 +1445,8 @@ class Price {
1425
1445
 
1426
1446
 
1427
1447
  // getters
1428
- // get displayPricing() {
1429
- // const amount = this.getAmount(1)
1430
- // return `${amount.currency}: ${amount.value} (${this.name})`
1431
- // }
1432
1448
  get isValid() {
1433
- return !!this.name && this.priceStrategies.length > 0
1449
+ return this.priceStrategies.length > 0
1434
1450
  }
1435
1451
 
1436
1452
  // instance methods
@@ -1438,17 +1454,17 @@ class Price {
1438
1454
  getStrategies() {
1439
1455
  return this.priceStrategies ? this.priceStrategies : []
1440
1456
  }
1441
- getStrategiesByRestrictions(payload) {
1457
+ getStrategiesByRestrictions(payload) { // payload = { user: {} }
1442
1458
  return this.priceStrategies.filter((p) => p.isMatchedRestrictions(payload))
1443
1459
  }
1444
- getStrategiesByCurrencyAndQty(currency, qty) {
1445
- let priceStrategies = this.getStrategiesByCurrency(currency, this.priceStrategies)
1460
+ getStrategiesByCurrencyAndQty(currencyCode, qty) {
1461
+ let priceStrategies = this.getStrategiesByCurrencyCode(currencyCode, this.priceStrategies)
1446
1462
  priceStrategies = this.getStrategiesByQty(qty, priceStrategies)
1447
1463
  return priceStrategies
1448
1464
  }
1449
1465
  getStrategiesByCurrencyCode(currencyCode, priceStrategies) {
1450
- const copy = priceStrategies || this.priceStrategies
1451
- return copy.reduce((acc, priceStrategy) => {
1466
+ const _priceStrategies = priceStrategies || this.priceStrategies
1467
+ return _priceStrategies.reduce((acc, priceStrategy) => {
1452
1468
  if (priceStrategy.hasCurrencyCode(currencyCode) && priceStrategy.deductionHasCurrencyCode(currencyCode)) {
1453
1469
  acc.push(priceStrategy)
1454
1470
  }
@@ -1456,17 +1472,17 @@ class Price {
1456
1472
  }, [])
1457
1473
  }
1458
1474
  getStrategiesByQty(qty, priceStrategies) {
1459
- const copy = priceStrategies || this.priceStrategies
1460
- return copy.reduce((acc, priceStrategy) => {
1461
- if (priceStrategy.iaValidQty(qty)) {
1475
+ const _priceStrategies = priceStrategies || this.priceStrategies
1476
+ return _priceStrategies.reduce((acc, priceStrategy) => {
1477
+ if (priceStrategy.isQtyValid(qty)) {
1462
1478
  acc.push(priceStrategy)
1463
1479
  }
1464
1480
  return acc
1465
1481
  }, [])
1466
1482
  }
1467
1483
  isAvailableByDate(timestamp) {
1468
- const copyTimestamp = timestamp || (new Date()).valueOf()
1469
- if (copyTimestamp >= this.dateBegin && (copyTimestamp < this.dateEnd || this.dateEnd === null)) {
1484
+ const _timestamp = timestamp || (new Date()).valueOf()
1485
+ if (_timestamp >= this.dateBegin && (_timestamp < this.dateEnd || this.dateEnd === null)) {
1470
1486
  return true
1471
1487
  }
1472
1488
  return false
@@ -1628,6 +1644,9 @@ class Product extends q_utilities_namespaceObject.TenantAwareEntity {
1628
1644
  get isReachedLimitPercentage() {
1629
1645
  return this.soldPercentage >= this.limitPercentage
1630
1646
  }
1647
+ get isTotalCoupon() {
1648
+ return this.couponDetails ? this.couponDetails.total : false
1649
+ }
1631
1650
  get soldPercentage() {
1632
1651
  return ((this.originalStock - this.stock) / this.originalStock) * 100
1633
1652
  }
@@ -1677,7 +1696,10 @@ class Product extends q_utilities_namespaceObject.TenantAwareEntity {
1677
1696
  return this.stock >= qty
1678
1697
  }
1679
1698
  isApplicableCoupon(obj) {
1680
- const { merchandiseCodes = [] } = this.couponDetails || {}
1699
+ if (!this.couponDetails) {
1700
+ return false
1701
+ }
1702
+ const { merchandiseCodes = [] } = this.couponDetails
1681
1703
  return merchandiseCodes.length > 0 ? merchandiseCodes.includes(obj.merchandiseCode) : true
1682
1704
  }
1683
1705
  isQualified(data) {
@@ -1764,6 +1786,8 @@ class ProductRepo extends q_utilities_namespaceObject.Repo {
1764
1786
 
1765
1787
 
1766
1788
  const merchandise_updateAllowedProps = [
1789
+ 'allowEditQty',
1790
+ 'allowEditUnitPrice',
1767
1791
  'defaultCurrency',
1768
1792
  'description',
1769
1793
  'eventSessionCode',
@@ -1775,7 +1799,6 @@ const merchandise_updateAllowedProps = [
1775
1799
  'name',
1776
1800
  'onlyFor',
1777
1801
  'prices',
1778
- 'pricings',
1779
1802
  'priority',
1780
1803
  'productCodes',
1781
1804
  'sku',
@@ -1801,6 +1824,8 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
1801
1824
  const id = options._id || options.id
1802
1825
  this.id = merchandise_setId(id)
1803
1826
 
1827
+ this.allowEditQty = options.allowEditQty || false
1828
+ this.allowEditUnitPrice = options.allowEditUnitPrice || false
1804
1829
  this.defaultCurrency = options.defaultCurrency || 'HKD'
1805
1830
  this.description = options.description
1806
1831
  this.free = options.free || false
@@ -1809,7 +1834,7 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
1809
1834
  this.merchandiseCategoryCodes = options.merchandiseCategoryCodes || []
1810
1835
  this.merchandiseCode = merchandise_setCode(options, 'merchandiseCode')
1811
1836
  this.merchandiseOptions = initMerchandiseOptions(this, options)
1812
- this.merchandiseType = options.merchandiseType || 'merchandise'
1837
+ this.merchandiseType = options.merchandiseType || 'Merchandise'
1813
1838
  this.name = options.name || ''
1814
1839
  this.prices = this._Price.initOnlyValidFromArray(options.prices)
1815
1840
  this.productCodes = options.productCodes || []
@@ -1847,17 +1872,20 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
1847
1872
  // getters
1848
1873
  get afterEnd() {
1849
1874
  const dates = this.getBeginAndEndDates()
1850
- return dates.dateEnd > (new Date()).valueOf()
1875
+ return dates.dateEnd > Date.now()
1851
1876
  }
1852
1877
  get beforeBegin() {
1853
1878
  const dates = this.getBeginAndEndDates()
1854
- return dates.dateBegin <= (new Date()).valueOf()
1879
+ return dates.dateBegin <= Date.now()
1855
1880
  }
1856
1881
  get currentPrice() {
1882
+ if (this.free) {
1883
+ return null
1884
+ }
1885
+ const now = Date.now()
1857
1886
  const prices = this.prices.filter((p) => {
1858
- return p.isAvailableByDate()
1887
+ return p.isAvailableByDate(now)
1859
1888
  })
1860
- prices.push({dummy: true})
1861
1889
  if (prices.length === 1) {
1862
1890
  return prices[0]
1863
1891
  }
@@ -1881,7 +1909,7 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
1881
1909
  return this.deleted === true
1882
1910
  }
1883
1911
  get isAvailable() {
1884
- return this.isActive && this.isAvailableByDate
1912
+ return this.isActive && !this.isDeleted && this.hasStock && (this.free || this.currentPrice)
1885
1913
  }
1886
1914
  get isAvailableByDate() {
1887
1915
  return !this.afterEnd && !this.beforeBegin
@@ -1904,9 +1932,12 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
1904
1932
  get summary() {
1905
1933
  return {
1906
1934
  currentPrice: this.currentPrice,
1935
+ free: this.free,
1936
+ max: this.max,
1907
1937
  merchandise: this,
1908
1938
  merchandiseCode: this.merchandiseCode,
1909
1939
  name: this.name,
1940
+ stock: this.stock
1910
1941
  }
1911
1942
  }
1912
1943
 
@@ -1955,20 +1986,20 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
1955
1986
  qty,
1956
1987
  value: null
1957
1988
  }
1958
- const copyCurrency = currency || this.defaultCurrency
1989
+ const _currencyCode = currency || this.defaultCurrency
1959
1990
  const price = this.getPriceByTimeAndRoleCodes(dateTimestamp, roleCodes)
1960
1991
  if (!price) {
1961
1992
  obj.errorMessages.push("Can't get available price for you.")
1962
1993
  return obj
1963
1994
  }
1964
1995
  obj.price = price
1965
- const priceStrategies = price.getStrategiesByCurrencyAndQty(copyCurrency, qty)
1996
+ const priceStrategies = price.getStrategiesByCurrencyAndQty(_currencyCode, qty)
1966
1997
  if (priceStrategies.length === 0) {
1967
1998
  obj.errorMessages.push("Can't get available strategies from price.")
1968
1999
  return obj
1969
2000
  }
1970
2001
  const { convertedPriceStrategies, maxQty } = priceStrategies.reduce((acc, priceStrategy) => {
1971
- const strategy = priceStrategy.toCalculatorRule({ currency: copyCurrency, qty })
2002
+ const strategy = priceStrategy.toCalculatorRule({ currency: _currencyCode, qty })
1972
2003
  acc.convertedPriceStrategies.push(strategy)
1973
2004
  if (strategy.max === null) {
1974
2005
  acc.maxQty = null
@@ -2028,10 +2059,10 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
2028
2059
  info.unavailableMessages.push('No available price for you in this time.')
2029
2060
  }
2030
2061
  info.price = price // may be no need
2031
- const copyCurrency = currency || this.defaultCurrency
2062
+ const _currencyCode = currency || this.defaultCurrency
2032
2063
  // const currencyCode = currency.code
2033
- if (price && !price.hasCurrencyWithQty(copyCurrency, info.qty)) {
2034
- info.unavailableMessages.push(`The price not support currency '${copyCurrency}'.`)
2064
+ if (price.getStrategiesByCurrencyAndQty(_currencyCode, info.qty).length === 0) {
2065
+ info.unavailableMessages.push(`The price not support currency '${_currencyCode}'.`)
2035
2066
  }
2036
2067
  const { cartItemInfos, hasProblem } = this.getItemOptionInfos(cartItems)
2037
2068
  info.cartItemInfos = cartItemInfos
@@ -2044,35 +2075,45 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
2044
2075
  return info
2045
2076
  }
2046
2077
  getBeginAndEndDates() {
2047
- const dates = {
2078
+ const beginAndEnd = {
2048
2079
  dateBegin: null,
2049
2080
  dateEnd: null
2050
2081
  }
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
2082
+ return this.prices.reduce((acc, price) => {
2083
+ if (!acc.dateBegin || (price.dateBegin > acc.dateBegin)) {
2084
+ acc.dateBegin = price.dateBegin
2055
2085
  }
2056
2086
 
2057
- if (!acc.dateEnd || (pricing.dateEnd <= acc.dateEnd)) {
2058
- acc.dateEnd = pricing.dateEnd
2087
+ if (!acc.dateEnd || (price.dateEnd <= acc.dateEnd)) {
2088
+ acc.dateEnd = price.dateEnd
2059
2089
  }
2060
2090
  return acc
2061
- }, dates)
2091
+ }, beginAndEnd)
2062
2092
  }
2063
2093
  getCode() {
2064
2094
  return this.merchandiseCode
2065
2095
  }
2066
- getCurrentPrice() {
2067
- const timestamp = (new Date()).valueOf()
2068
- const prices = this.getPricesByTime(timestamp)
2096
+ getCurrentAmount({ currencyCode, payload, ignoreRestriction = fasle }) {
2097
+ if (!this.currentPrice) {
2098
+ return null
2099
+ }
2100
+ let priceStrategies = ignoreRestriction ? this.currentPrice.priceStrategies : this.currentPrice.getStrategiesByRestrictions(payload)
2101
+ priceStrategies = this.currentPrice.getStrategiesByCurrencyCode(currencyCode, priceStrategies)
2102
+ if (priceStrategies.length === 0) {
2103
+ return null
2104
+ }
2105
+ return priceStrategies[0].getAmountByCurrencyCode(currencyCode)
2106
+ }
2107
+ getCurrentPrice(timestamp) {
2108
+ const _timestamp = timestamp || Date.now()
2109
+ const prices = this.getPricesByTime(_timestamp)
2069
2110
  if (prices.length === 1) {
2070
2111
  return prices[0]
2071
2112
  }
2072
2113
  return null
2073
2114
  }
2074
2115
  getCurrentPriceByRoleCodes(roleCodes) {
2075
- const timestamp = (new Date()).valueOf()
2116
+ const timestamp = Date.now()
2076
2117
  let prices = this.getPricesByTime(timestamp)
2077
2118
  prices = Price.getPricesByRoleCodes(prices, roleCodes)
2078
2119
  if (prices.length === 1) {
@@ -2110,8 +2151,8 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
2110
2151
  return this.prices ? this.prices : []
2111
2152
  }
2112
2153
  getPricesByTime(timestamp) {
2113
- const copyDate = timestamp || (new Date()).valueOf()
2114
- return Price.getPricesByTime(this.prices, copyDate)
2154
+ const _timestamp = timestamp || Date.now()
2155
+ return Price.getPricesByTime(this.prices, _timestamp)
2115
2156
  }
2116
2157
  getPriceByTimeAndRoleCodes(timestamp, roleCodes) {
2117
2158
  let prices = this.getPricesByTime(timestamp)
@@ -2145,6 +2186,12 @@ class Merchandise extends q_utilities_namespaceObject.TenantAwareEntity {
2145
2186
  getStock() {
2146
2187
  return this.stock || 0
2147
2188
  }
2189
+ getSummary(options) {
2190
+ return {
2191
+ ...this.summary,
2192
+ currentAmount: this.getCurrentAmount(options)
2193
+ }
2194
+ }
2148
2195
 
2149
2196
  reachLimit(qty) {
2150
2197
  return this.max < qty
@@ -2705,9 +2752,21 @@ class Status {
2705
2752
  // this.cancelled = null
2706
2753
  // return this
2707
2754
  // }
2755
+ unSetAssigned() {
2756
+ this.assigned = null
2757
+ }
2758
+ unsetDelivered() {
2759
+ this.delivered = null
2760
+ }
2708
2761
  unSetOnHold() {
2709
2762
  this.onHold = null
2710
2763
  }
2764
+ unSetRefundRequested() {
2765
+ this.refundRequested = null
2766
+ }
2767
+ unsetUsed() {
2768
+ this.used = null
2769
+ }
2711
2770
  update(update) {
2712
2771
  Object.keys(update).forEach((key) => {
2713
2772
  if (!notUpdateAllowedProps.includes(key)) {
@@ -3194,6 +3253,7 @@ class CreditNoteLine extends q_utilities_namespaceObject.TenantAwareEntity {
3194
3253
  // this.deduction = this._Amount.init(options.deduction)
3195
3254
  this.description = options.description
3196
3255
  // this.discount = options.discount || 0
3256
+ this.handlingCharge = this._Amount.init(options.handlingCharge)
3197
3257
  this.qty = options.qty || 1
3198
3258
  // this.unitPrice = Amount.init(options.unitPrice)
3199
3259
  }
@@ -3317,11 +3377,12 @@ class CreditNote extends q_utilities_namespaceObject.TenantAwareEntity {
3317
3377
  const id = options._id || options.id
3318
3378
  this.id = creditNote_setId(id)
3319
3379
 
3320
- this.amount = this._Amount.init(options.amount)
3380
+ this.amount = this._Amount.init(options.amount) // refundAmount
3321
3381
  this.creditNoteCode = creditNote_setCode(options, 'creditNoteCode')
3322
3382
  this.creditNoteLines = this._CreditNoteLine.initOnlyValidFromArray(options.creditNoteLines)
3323
3383
  this.description = options.description
3324
3384
  this.invoiceCode = options.invoiceCode
3385
+ this.handlingCharge = this._Amount.init(options.handlingCharge)
3325
3386
  this.status = this._Status.init(options.status)
3326
3387
  }
3327
3388
 
@@ -3351,6 +3412,18 @@ class CreditNote extends q_utilities_namespaceObject.TenantAwareEntity {
3351
3412
  get isValid() {
3352
3413
  return super.isValid && !!this.invoiceCode
3353
3414
  }
3415
+
3416
+ get displayCreated() {
3417
+ return (0,q_utilities_namespaceObject.formatDate)(this.meta.created, 'YYYY/MM/DD hh:mm')
3418
+ }
3419
+
3420
+ get displayRefundedDate() {
3421
+ return (0,q_utilities_namespaceObject.formatDate)(this.meta.created, 'YYYY/MM/DD hh:mm')
3422
+ }
3423
+
3424
+ get refundedDetail() {
3425
+ return q_utilities_namespaceObject.KeyValueObject.foundValueByKey(this.metadata, 'REFUNDED_DETAIL') || {}
3426
+ }
3354
3427
  getCode() {
3355
3428
  return this.creditNoteCode
3356
3429
  }
@@ -3624,6 +3697,7 @@ const invoiceLine_updateAllowedProps = [
3624
3697
  'deduction',
3625
3698
  'description',
3626
3699
  'discount',
3700
+ 'note',
3627
3701
  'purchaseOptions',
3628
3702
  'qty',
3629
3703
  'unitPrice'
@@ -3652,7 +3726,9 @@ class InvoiceLine extends q_utilities_namespaceObject.TenantAwareEntity {
3652
3726
  this.discount = options.discount || 0
3653
3727
  this.invoiceCode = options.invoiceCode
3654
3728
  this.invoiceLineCode = invoiceLine_setCode(options, 'invoiceLineCode')
3729
+ this.invoiceLineType = options.invoiceLineType || 'InvoiceLine'
3655
3730
  this.merchandiseCode = options.merchandiseCode
3731
+ this.note = options.note
3656
3732
  this.purchaseOptions = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(options.purchaseOptions)
3657
3733
  this.qty = options.qty || 1
3658
3734
  this.status = this._Status.init(options.status)
@@ -3686,6 +3762,12 @@ class InvoiceLine extends q_utilities_namespaceObject.TenantAwareEntity {
3686
3762
  return this._Merchandise.init(this._merchandise)
3687
3763
  }
3688
3764
 
3765
+ get usedCoupons() {
3766
+ const usedItemCoupons = q_utilities_namespaceObject.KeyValueObject.getValueByKey(this.remarks, 'USED_ITEM_COUPONS') || []
3767
+ const usedTotalCoupons = q_utilities_namespaceObject.KeyValueObject.getValueByKey(this.remarks, 'USED_TOTAL_COUPONS') || []
3768
+ return [...usedItemCoupons, ...usedTotalCoupons]
3769
+ }
3770
+
3689
3771
  // instance methods
3690
3772
  getPurchaseOptionValue(options) {
3691
3773
  const { delimiter, key, tag } = options || {}
@@ -3817,6 +3899,7 @@ class Issuer {
3817
3899
 
3818
3900
 
3819
3901
 
3902
+
3820
3903
  // import { Transaction } from '../transaction/index.js'
3821
3904
 
3822
3905
  const walletItem_updateAllowedProps = [
@@ -3878,6 +3961,9 @@ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
3878
3961
  get isAssigned() {
3879
3962
  return this.status.isAssigned
3880
3963
  }
3964
+ get isAvailable() {
3965
+ return this.isInWallet && (!this.isUsed || !this.isDelivered)
3966
+ }
3881
3967
  get isAvailableCoupon() {
3882
3968
  return this.isCoupon && !this.isCancelled && !this.isUsed
3883
3969
  }
@@ -3897,7 +3983,7 @@ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
3897
3983
  return this.status.isDelivered
3898
3984
  }
3899
3985
  get isInWallet() {
3900
- return !this.isCancelled && !this.isRefundRequested
3986
+ return !this.isCancelled && !this.isRejected && !this.isRefunded && !this.isRefundRequested
3901
3987
  }
3902
3988
  get isItemCoupon() {
3903
3989
  return this.product ? this.product.isItemCoupon : false
@@ -3907,7 +3993,7 @@ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
3907
3993
  }
3908
3994
  get isOwned() {
3909
3995
  return (
3910
- !this.isCancelled && !this.isRejected && !this.isRefunded
3996
+ this.isInWallet
3911
3997
  && (
3912
3998
  (this.isPaid && !this.isAssigned && !this.isConfirmed)
3913
3999
  || (this.isWaived && !this.isAssigned && !this.isConfirmed)
@@ -3940,6 +4026,9 @@ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
3940
4026
  get isSubmitted() {
3941
4027
  return this.status.isSubmitted
3942
4028
  }
4029
+ get isTotalCoupon() {
4030
+ return this.product ? this.product.isTotalCoupon : false
4031
+ }
3943
4032
  get isUsed() {
3944
4033
  return this.status.isUsed
3945
4034
  }
@@ -3950,9 +4039,35 @@ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
3950
4039
  get couponDetails() {
3951
4040
  return this.product ? this.product.couponDetails : null
3952
4041
  }
4042
+
4043
+ get displayPurchaseOptions() {
4044
+ return this.purchaseOptions.length > 0
4045
+ ? this.purchaseOptions.reduce((acc, purchaseOption) => {
4046
+ const { value } = purchaseOption
4047
+ return acc += value.reduce((_acc, item) => {
4048
+ const { label, value } = item
4049
+ return _acc += `<div><span>${label}: </span><span>${value}</span></div>`
4050
+ }, '')
4051
+ }, '')
4052
+ : ''
4053
+ }
4054
+
4055
+ get lastRefundRejectedDetail() {
4056
+ return Array.isArray(this.refundRejectedHistory) && this.refundRejectedHistory.length > 0 ? this.refundRejectedHistory[this.refundRejectedHistory.length - 1] : null
4057
+ }
4058
+
3953
4059
  get product() {
3954
4060
  return this._Product.init(this._product)
3955
4061
  }
4062
+ get refundedDetail() {
4063
+ return q_utilities_namespaceObject.Metadata.getValueByKey(this.metadata, 'REFUNDED_DETAIL') || {}
4064
+ }
4065
+ get refundRejectedHistory() {
4066
+ return q_utilities_namespaceObject.Metadata.getValueByKey(this.metadata, 'REFUND_REJECTED_HISTORY') || {}
4067
+ }
4068
+ get refundRequestedDetail() {
4069
+ return q_utilities_namespaceObject.Metadata.getValueByKey(this.metadata, 'REFUND_REQUESTED_DETAIL') || {}
4070
+ }
3956
4071
  get tenant() {
3957
4072
  return this._tenant
3958
4073
  }
@@ -4005,6 +4120,10 @@ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
4005
4120
  this.status.setAssigned(value)
4006
4121
  return this
4007
4122
  }
4123
+ setCancelled(value) {
4124
+ this.status.setCancelled(value)
4125
+ return this
4126
+ }
4008
4127
  setConfirmed(value) {
4009
4128
  this.status.setConfirmed(value)
4010
4129
  return this
@@ -4038,6 +4157,33 @@ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
4038
4157
  this.status.setRejected()
4039
4158
  return this
4040
4159
  }
4160
+ setRefunded(obj) {
4161
+ if (!this.status.cancelled) {
4162
+ this.setCancelled()
4163
+ }
4164
+ const timestamp = this.status.cancelled + 1
4165
+ this.metadata = q_utilities_namespaceObject.Metadata.insertOrUpdateRecord(this.metadata, 'REFUNDED_DETAIL', obj)
4166
+ this.status.setRefunded(timestamp)
4167
+ return this
4168
+ }
4169
+ setRefundRequested(obj) {
4170
+ this.metadata = q_utilities_namespaceObject.Metadata.insertOrUpdateRecord(this.metadata, 'REFUND_REQUESTED_DETAIL', obj)
4171
+ this.status.setRefundRequested()
4172
+ return this
4173
+ }
4174
+
4175
+ setRefundRejected(datail) {
4176
+ const last = this.status.refundRequested
4177
+ this.unSetRefundRequested()
4178
+ const history = q_utilities_namespaceObject.Metadata.foundValueByKey(this.metadata, 'REFUND_REJECTED_HISTORY') || []
4179
+ history.push({
4180
+ ...datail,
4181
+ refundRequested: last,
4182
+ created: (new Date()).valueOf(),
4183
+ })
4184
+ this.metadata = q_utilities_namespaceObject.Metadata.insertOrUpdateRecord(this.metadata, 'REFUND_REJECTED_HISTORY', history)
4185
+ }
4186
+
4041
4187
  setShared() {
4042
4188
  this.status.setShared()
4043
4189
  return this
@@ -4072,10 +4218,45 @@ class WalletItem extends q_utilities_namespaceObject.TenantAwareEntity {
4072
4218
  // walletItemCode: this.walletItemCode
4073
4219
  // }
4074
4220
  // }
4221
+ updatePurchaseOptions(purchaseOptions) {
4222
+ const { purchaseOptions: _purchaseOptions } = this
4223
+ const history = q_utilities_namespaceObject.Metadata.foundValueByKey(this.metadata, 'PURCHASE_OPTION_HISTORY') || []
4224
+ history.push({
4225
+ purchaseOptions: external_lodash_namespaceObject.cloneDeep(_purchaseOptions),
4226
+ created: (new Date()).valueOf(),
4227
+ })
4228
+ this.metadata = q_utilities_namespaceObject.Metadata.insertOrUpdateRecord(this.metadata, 'PURCHASE_OPTION_HISTORY', history)
4229
+ _purchaseOptions.forEach((_purchaseOption) => {
4230
+ const { key, value } = _purchaseOption
4231
+ const { value: updatedValue } = purchaseOptions.find((i) => i.key === key)
4232
+ value.forEach((i, idx) => {
4233
+ Object.assign(i, updatedValue[idx])
4234
+ })
4235
+ })
4236
+ return this
4237
+ }
4238
+ unSetAssigned() {
4239
+ this.status.unSetAssigned()
4240
+ return this
4241
+ }
4242
+ unsetDelivered() {
4243
+ this.status.unsetDelivered()
4244
+ return this
4245
+ }
4075
4246
  unSetOnHold() {
4076
4247
  this.status.unSetOnHold()
4077
4248
  return this
4078
4249
  }
4250
+
4251
+ unSetRefundRequested() {
4252
+ this.status.unSetRefundRequested()
4253
+ return this
4254
+ }
4255
+ unsetUsed() {
4256
+ this.status.unsetUsed()
4257
+ return this
4258
+ }
4259
+
4079
4260
  update(update) {
4080
4261
  Object.keys(update).forEach((key) => {
4081
4262
  if (walletItem_updateAllowedProps.includes(key)) {
@@ -4155,8 +4336,9 @@ class Transaction extends q_utilities_namespaceObject.TenantAwareEntity {
4155
4336
  options = options || {}
4156
4337
  super(options)
4157
4338
 
4158
- const { _Amount, _Status, _WalletItem } = options._constructor || {}
4339
+ const { _Amount, _PaymentResultFactory, _Status, _WalletItem } = options._constructor || {}
4159
4340
  this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
4341
+ this._PaymentResultFactory = _PaymentResultFactory
4160
4342
  this._Status = _Status && (_Status._superclass === Status._superclass) ? _Status : Status
4161
4343
  this._WalletItem = _WalletItem && (_WalletItem._superclass === WalletItem._superclass) ? _WalletItem : WalletItem
4162
4344
 
@@ -4199,6 +4381,9 @@ class Transaction extends q_utilities_namespaceObject.TenantAwareEntity {
4199
4381
  get isValid() {
4200
4382
  return super.isValid
4201
4383
  }
4384
+ get billedAmount() {
4385
+ return this.amount?.displayAmount()
4386
+ }
4202
4387
  get isActive() {
4203
4388
  return this.active === true
4204
4389
  }
@@ -4252,6 +4437,25 @@ class Transaction extends q_utilities_namespaceObject.TenantAwareEntity {
4252
4437
  get isWaived() {
4253
4438
  return this.status.isWaived
4254
4439
  }
4440
+ get paymentResults() {
4441
+ return this._PaymentResultFactory.initOnlyValidFromArray(this._paymentResults || [])
4442
+ }
4443
+ get paymentResultAmounts() {
4444
+ return this.paymentResults.filter((p) => {
4445
+ return p.isSuccess()
4446
+ }).map((p) => {
4447
+ return {
4448
+ billedAmount: p.billedAmount,
4449
+ paidTimestamp: p.getPaidTimestamp(),
4450
+ paymentMethod: p.paymentMethod,
4451
+ paymentResultCode: p.paymentResultCode,
4452
+ receivedAmount: p.receivedAmount
4453
+ }
4454
+ })
4455
+ }
4456
+ get successedPaymentResult() {
4457
+ return this.paymentResults.find((p) => (p.isSuccess()))
4458
+ }
4255
4459
  get walletItems() {
4256
4460
  return this._WalletItem.initOnlyValidFromArray(this._walletItems)
4257
4461
  }
@@ -4511,6 +4715,7 @@ class Invoice extends q_utilities_namespaceObject.TenantAwareEntity {
4511
4715
  this.invoiceCode = invoice_setCode(options, 'invoiceCode')
4512
4716
  this.invoiceDate = options.invoiceDate || (new Date()).valueOf()
4513
4717
  this.invoiceNumber = options.invoiceNumber
4718
+ this.invoiceType = options.invoiceType || 'Invoice'
4514
4719
  this.issuer = this._Issuer.init(options.issuer)
4515
4720
  this.revisionNumber = options.revisionNumber || 1
4516
4721
  this.status = this._Status.init(options.status)
@@ -4704,196 +4909,711 @@ class InvoiceRepo extends q_utilities_namespaceObject.Repo {
4704
4909
  ;// ./lib/models/keyValueObject/index.js
4705
4910
 
4706
4911
 
4707
- ;// ./lib/models/paymentGateway/paymentGateway.js
4708
-
4912
+ ;// ./lib/models/statusQStore/statusQStore.js
4709
4913
 
4710
4914
 
4711
- const paymentGateway_updateAllowedProps = [
4712
- 'label',
4713
- 'logoUrl',
4714
- 'name',
4715
- 'sandbox',
4716
- 'setting'
4717
- ]
4915
+ const statusQStore_notUpdateAllowedProps = (/* unused pure expression or super */ null && ([
4916
+ ]))
4718
4917
 
4719
- class PaymentGateway extends q_utilities_namespaceObject.TenantAwareEntity {
4720
- constructor(options = {}) {
4918
+ class StatusQStore extends q_utilities_namespaceObject.Status {
4919
+ constructor(options) {
4721
4920
  options = options || {}
4722
4921
  super(options)
4723
4922
 
4724
- const id = options._id || options.id
4725
- this.id = paymentGateway_setId(id)
4726
- this._type = options._type || 'PaymentGateway'
4727
-
4728
- this.hasWebhook = options.hasWebhook || false
4729
- this.label = options.label
4730
- this.logoUrl = options.logoUrl
4731
- this.name = options.name || ''
4732
- this.paymentGatewayCode = paymentGateway_setCode(options, 'paymentGatewayCode')
4733
- this.paymentGatewayType = options.paymentGatewayType || 'PaymentGateway'
4734
- this.paymentResultType = options.paymentResultType || 'PaymentResult'
4735
- this.sandbox = options.sandbox || false
4736
- this.setting = options.setting || null
4737
- }
4738
- static dummyData() {
4739
- return {
4740
- name: 'name',
4741
- tenantCode: 'tenantCode'
4742
- }
4923
+ this.cancelled = this._ActionRecord.init(options.cancelled)
4924
+ this.completed = this._ActionRecord.init(options.completed)
4925
+ this.confirmed = this._ActionRecord.init(options.confirmed)
4926
+ this.deleted = this._ActionRecord.init(options.deleted)
4927
+ this.terminated = this._ActionRecord.init(options.terminated)
4743
4928
  }
4929
+
4744
4930
  static get _classname() {
4745
- return 'PaymentGateway'
4931
+ return 'StatusQStore'
4746
4932
  }
4747
- static get _superclass() {
4748
- return 'PaymentGateway'
4933
+ get _classname() {
4934
+ return 'StatusQStore'
4749
4935
  }
4750
-
4751
- // getters
4752
- get isValid() {
4753
- return super.isValid && !!this.name
4936
+ get isCancelled() {
4937
+ return this.cancelled?.timestamp > 0
4754
4938
  }
4755
-
4756
- // instance methods
4757
- async createPayment() {
4758
- throw new Error(`${this._classname} subclass should implement createPayment`)
4939
+ get isCompleted() {
4940
+ return this.completed?.timestamp > 0
4759
4941
  }
4760
- async getAppPayParams() {
4761
- throw new Error(`${this._classname} subclass should implement getAppPayParams`)
4942
+ get isConfirmed() {
4943
+ return this.confirmed?.timestamp > 0
4762
4944
  }
4763
- getCode() {
4764
- return this.paymentGatewayCode
4945
+ get isDeleted() {
4946
+ return this.deleted?.timestamp > 0
4765
4947
  }
4766
- async updatePayment() {
4767
- throw new Error(`${this._classname} subclass should implement updatePayment`)
4948
+ get isTerminated() {
4949
+ return this.terminated?.timestamp > 0
4768
4950
  }
4769
- async query() {
4770
- throw new Error(`${this._classname} subclass should implement query`)
4951
+ get isValid() {
4952
+ return super.isValid
4771
4953
  }
4772
- async submit() {
4773
- throw new Error(`${this._classname} subclass should implement submit`)
4954
+ setCancelled(value, actorCode) {
4955
+ return this.setValue(value, actorCode, 'cancelled')
4774
4956
  }
4775
-
4776
- setCompletedRelatedStatus(status) {
4777
- throw new Error(`${this.name} subclass should implement setCompletedRelatedStatus`)
4957
+ setCompleted(value, actorCode) {
4958
+ return this.setValue(value, actorCode, 'completed')
4778
4959
  }
4779
- update(update) {
4780
- Object.keys(update).forEach((key) => {
4781
- if (paymentGateway_updateAllowedProps.includes(key)) {
4782
- this[key] = update[key]
4783
- }
4784
- })
4785
- return super.update(update)
4960
+ setConfirmed(value, actorCode) {
4961
+ return this.setValue(value, actorCode, 'confirmed')
4786
4962
  }
4787
- }
4788
-
4789
- function paymentGateway_setCode(options, key) {
4790
- const copyOptions = options || {}
4791
- if (copyOptions[key]) {
4792
- return copyOptions[key]
4963
+ setDeleted(value, actorCode) {
4964
+ return this.setValue(value, actorCode, 'deleted')
4793
4965
  }
4794
- return stringHelper.setCode()
4795
- }
4796
-
4797
- function paymentGateway_setId(id) {
4798
- if (id && typeof id.toString === 'function') {
4799
- return id.toString()
4966
+ setTerminated(value, actorCode) {
4967
+ return this.setValue(value, actorCode, 'terminated')
4800
4968
  }
4801
- return id
4969
+ // update(update) {
4970
+ // Object.keys(update).forEach((key) => {
4971
+ // if (!notUpdateAllowedProps.includes(key)) {
4972
+ // this[key] = this[key] instanceof this._ActionRecord ? this[key].update(update[key]) : this._ActionRecord.init(update[key])
4973
+ // }
4974
+ // })
4975
+ // return super.update(update)
4976
+ // }
4802
4977
  }
4803
4978
 
4979
+ ;// ./lib/models/statusQStore/statusQStoreOrderLine.js
4804
4980
 
4805
4981
 
4806
- ;// ./lib/models/paymentGateway/paymentGatewayRepo.js
4807
-
4808
-
4982
+ const statusQStoreOrderLine_notUpdateAllowedProps = (/* unused pure expression or super */ null && ([
4983
+ ]))
4809
4984
 
4810
- class PaymentGatewayRepo extends q_utilities_namespaceObject.Repo {
4811
- constructor(options = {}) {
4985
+ class StatusQStoreOrderLine extends StatusQStore {
4986
+ constructor(options) {
4812
4987
  options = options || {}
4813
4988
  super(options)
4814
- const { _PaymentGateway } = options._constructor || {}
4815
- this._PaymentGateway = _PaymentGateway && (_PaymentGateway._superclass === PaymentGateway._superclass) ? _PaymentGateway : PaymentGateway
4989
+
4990
+ this.expired = this._ActionRecord.init(options.expired)
4991
+ this.invalid = this._ActionRecord.init(options.invalid)
4816
4992
  }
4993
+
4817
4994
  static get _classname() {
4818
- return 'PaymentGatewayRepo'
4995
+ return 'StatusQStoreOrderLine'
4819
4996
  }
4820
- init(options) {
4821
- return this._PaymentGateway.init(options)
4997
+ get _classname() {
4998
+ return 'StatusQStoreOrderLine'
4999
+ }
5000
+ get isExpired() {
5001
+ return this.expired?.timestamp > Date.now()
5002
+ }
5003
+ get isInvalid() {
5004
+ return this.invalid?.timestamp > Date.now()
5005
+ }
5006
+ get isValid() {
5007
+ return super.isValid
5008
+ }
5009
+ setExpired(value, actorCode) {
5010
+ return this.setValue(value, actorCode, 'expired')
4822
5011
  }
5012
+ setInvalid(value, actorCode) {
5013
+ return this.setValue(value, actorCode, 'invalid')
5014
+ }
5015
+ // update(update) {
5016
+ // Object.keys(update).forEach((key) => {
5017
+ // if (!notUpdateAllowedProps.includes(key)) {
5018
+ // this[key] = this[key] instanceof this._ActionRecord ? this[key].update(update[key]) : this._ActionRecord.init(update[key])
5019
+ // }
5020
+ // })
5021
+ // return super.update(update)
5022
+ // }
4823
5023
  }
4824
5024
 
5025
+ ;// ./lib/models/statusQStore/index.js
4825
5026
 
4826
5027
 
4827
- ;// ./lib/models/paymentGateway/index.js
4828
-
4829
5028
 
4830
5029
 
4831
5030
 
5031
+ ;// ./lib/models/orderLine/orderLine.js
4832
5032
 
5033
+ // import { Amount, Merchandise, Status, stringHelper } from '@questwork/q-store-model'
4833
5034
 
4834
- ;// ./lib/models/paymentResult/paymentResult.js
4835
5035
 
4836
5036
 
4837
5037
 
5038
+ // import { OrderService } from '../orderService/index.js'
4838
5039
 
4839
- const paymentResult_updateAllowedProps = [
4840
- 'active',
4841
- 'deleted',
4842
- 'remarks',
4843
- 'result'
5040
+ const orderLine_updateAllowedProps = [
5041
+ 'amount',
5042
+ 'deduction',
5043
+ 'discount',
5044
+ 'note',
5045
+ 'unitPrice',
5046
+ // 'purchaseOptions',
5047
+ 'status',
5048
+ // 'orderLineCode',
5049
+ // 'merchandiseCode',
5050
+ 'waived',
5051
+ 'qty'
4844
5052
  ]
4845
5053
 
4846
- class PaymentResult extends q_utilities_namespaceObject.TenantAwareEntity {
4847
- constructor(options = {}) {
5054
+ class OrderLine extends q_utilities_namespaceObject.TenantAwareEntity {
5055
+ constructor(options) {
4848
5056
  options = options || {}
4849
5057
  super(options)
4850
5058
 
4851
- const { _Transaction } = options._constructor || {}
4852
- this._Transaction = _Transaction && (_Transaction._superclass === Transaction._superclass) ? _Transaction : Transaction
5059
+ const { _Amount, _Merchandise, _Order, _OrderService, _Status } = options._constructor || {}
5060
+ this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
5061
+ this._Merchandise = _Merchandise && (_Merchandise._superclass === Merchandise._superclass) ? _Merchandise : Merchandise
5062
+ this._Order = _Order && (_Order._superclass === Order._superclass) ? _Order : Order
5063
+ // this._OrderService = _OrderService && (_OrderService._superclass === OrderService._superclass) ? _OrderService : OrderService
5064
+ this._Status = _Status && (_Status._superclass === StatusQStoreOrderLine._superclass) ? _Status : StatusQStoreOrderLine
4853
5065
 
4854
- this._transaction = options._transaction
4855
- this._type = options._type || 'PaymentResult'
5066
+ this._merchandise = options._merchandise
5067
+ this._order = options._order
5068
+ // this._orderService = options._orderService
4856
5069
 
4857
5070
  const id = options._id || options.id
4858
- this.id = paymentResult_setId(id)
4859
-
4860
- this.paymentResultCode = paymentResult_setCode(options, 'paymentResultCode')
4861
- this.paymentResultType = options.paymentResultType || 'PaymentResult'
4862
- this.result = options.result
4863
- this.resultRef = options.resultRef
4864
- this.resultType = options.resultType
4865
- // this.transaction = this._Transaction.init(options.transaction)
4866
- this.transactionCode = options.transactionCode
5071
+ this.id = orderLine_setId(id)
5072
+ this._type = options._type || 'OrderLine'
5073
+ this.amount = this._Amount.init(options.amount)
5074
+ this.deduction = this._Amount.init(options.deduction)
5075
+ this.discount = options.discount || 0
5076
+ this.note = options.note
5077
+ this.unitPrice = this._Amount.init(options.unitPrice)
5078
+ // this.purchaseOptions = KeyValueObject.initOnlyValidFromArray(options.purchaseOptions)
5079
+ this.status = this._Status.init(options.status)
5080
+ this.orderCode = options.orderCode
5081
+ this.orderLineCode = options.orderLineCode
5082
+ this.orderLineType = 'OrderLine'
5083
+ this.merchandiseCode = options.merchandiseCode
5084
+ this.waived = options.waived || 0
5085
+ this.qty = options.qty || 1
4867
5086
  }
4868
5087
 
4869
- // class method
4870
5088
  static dummyData() {
4871
5089
  return {
4872
- paymentResultType: 'PaymentResult',
4873
- result: { id: 'resultId' },
4874
- resultType: 'resultType',
4875
- tenantCode: 'tenantCode',
4876
- transactionCode: 'transactionCode'
5090
+ amount: Amount.dummyData(),
5091
+ orderCode: 'orderCode',
5092
+ tenantCode: 'tenantCode'
4877
5093
  }
4878
5094
  }
5095
+
4879
5096
  static get _classname() {
4880
- return 'PaymentResult'
5097
+ return 'OrderLine'
4881
5098
  }
5099
+
4882
5100
  static get _superclass() {
4883
- return 'PaymentResult'
5101
+ return 'OrderLine'
4884
5102
  }
4885
5103
 
4886
- // getters
4887
- get isValid() {
4888
- return super.isValid && !!this.resultType && !!this.transactionCode
4889
- // return !!this.result && !!this.resultType && !!this.tenantCode
5104
+ get isCompleted() {
5105
+ return this.status.isCompleted
4890
5106
  }
4891
- get amount() {
5107
+
5108
+ get isProcessing() {
5109
+ return this.status.isProcessing
5110
+ }
5111
+
5112
+ get isTerminated() {
5113
+ return this.status.isTerminated
5114
+ }
5115
+
5116
+ get isValid() {
5117
+ return super.isValid && !!this.merchandiseCode
5118
+ }
5119
+
5120
+ get order() {
5121
+ return this._Order.init(this._order)
5122
+ }
5123
+
5124
+ get merchandise() {
5125
+ return this._Merchandise.init(this._merchandise)
5126
+ }
5127
+
5128
+ allowCancel() {
5129
+ return this.status.allowCancel()
5130
+ }
5131
+
5132
+ createInvoiceLine() {
5133
+ return {
5134
+ invoiceLineType: 'InvoiceLine',
5135
+ amount: this.amount,
5136
+ unitPrice: this.unitPrice,
5137
+ deduction: this.deduction,
5138
+ discount: this.discount,
5139
+ qty: this.qty,
5140
+ merchandiseCode: this.merchandiseCode,
5141
+ metadata: this.metadata,
5142
+ note: this.note,
5143
+ purchaseOptions: this.purchaseOptions,
5144
+ remarks: this.remarks,
5145
+ waived: this.waived,
5146
+ owner: this.owner,
5147
+ tenantCode: this.tenantCode,
5148
+ }
5149
+ }
5150
+
5151
+ getAmount() {
5152
+ return this.amount
5153
+ }
5154
+
5155
+ toCaculateAmountItem() {
5156
+ return {
5157
+ merchandiseCode: this.merchandiseCode,
5158
+ qty: this.qty,
5159
+ price: this.unitPrice,
5160
+ discount: this.discount,
5161
+ subTotal: this.amount,
5162
+ priceStrategy: null,
5163
+ purchaseOptions: this.purchaseOptions || [],
5164
+ remarks: this.remarks,
5165
+ waived: this.waived
5166
+ }
5167
+ }
5168
+
5169
+ getCurrencyCode() {
5170
+ return this.amount ? this.amount.getCurrencyCode() : null
5171
+ }
5172
+
5173
+ setCompleted(value, actorCode) {
5174
+ this.status.setCompleted(value, actorCode)
5175
+ return this.setModified()
5176
+ }
5177
+
5178
+ setQty(qty) {
5179
+ if (typeof qty === 'number' && qty > 0) {
5180
+ this.qty = qty
5181
+ this.setModified()
5182
+ }
5183
+ return this.qty
5184
+ }
5185
+
5186
+ settle(service) {
5187
+ if (!service) {
5188
+ return this
5189
+ }
5190
+
5191
+ if (service.end) {
5192
+ this.setCompleted()
5193
+ }
5194
+
5195
+ return this
5196
+ }
5197
+
5198
+ // setCompleted() {
5199
+ // this.status.setCompleted()
5200
+ // return this.setModified()
5201
+ // }
5202
+
5203
+ setCancelled() {
5204
+ this.status.setCancelled()
5205
+ return this.setModified()
5206
+ }
5207
+
5208
+ setProcessing() {
5209
+ this.status.setProcessing()
5210
+ return this.setModified()
5211
+ }
5212
+
5213
+ setTerminated() {
5214
+ this.status.setTerminated()
5215
+ return this.setModified()
5216
+ }
5217
+
5218
+ setWaived() {
5219
+ this.status.setWaived()
5220
+ return this.setModified()
5221
+ }
5222
+
5223
+ update(obj) {
5224
+ Object.keys(obj).forEach((key) => {
5225
+ if (orderLine_updateAllowedProps.includes(key)) {
5226
+ if (key === 'purchaseOptions') {
5227
+ this[key] = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(obj[key])
5228
+ } else if (key === 'amount' || key === 'deduction' || key === 'unitPrice') {
5229
+ this[key] = this[key] instanceof this._Amount ? this[key].update(obj[key]) : this._Amount.init(obj[key])
5230
+ } else if (key === 'status') {
5231
+ this[key] = this[key] instanceof this._Status ? this[key].update(obj[key]) : this._Status.init(obj[key])
5232
+ } else {
5233
+ this[key] = obj[key]
5234
+ }
5235
+ }
5236
+ })
5237
+ return super.update(obj)
5238
+ }
5239
+ }
5240
+
5241
+ // function setCode(options, key) {
5242
+ // const copyOptions = options || {}
5243
+ // if (copyOptions[key]) {
5244
+ // return copyOptions[key]
5245
+ // }
5246
+ // return stringHelper.setCode()
5247
+ // }
5248
+
5249
+ function orderLine_setId(id) {
5250
+ if (id && typeof id.toString === 'function') {
5251
+ return id.toString()
5252
+ }
5253
+ return id
5254
+ }
5255
+
5256
+
5257
+
5258
+ ;// ./lib/models/orderLine/index.js
5259
+
5260
+
5261
+
5262
+
5263
+ ;// ./lib/models/order/order.js
5264
+
5265
+ // import { Amount, Status, stringHelper } from '@questwork/q-store-model'
5266
+
5267
+
5268
+
5269
+ // import { Status } from '../status/index.js'
5270
+ // import { stringHelper } from '../../helpers/stringHelper/index.js'
5271
+
5272
+ const order_updateAllowedProps = [
5273
+ 'amount',
5274
+ // 'orderNumber',
5275
+ // 'revisionNumber',
5276
+ 'status',
5277
+ 'name',
5278
+ ]
5279
+
5280
+ class Order extends q_utilities_namespaceObject.TenantAwareEntity {
5281
+ constructor(options) {
5282
+ options = options || {}
5283
+ super(options)
5284
+
5285
+ const { _Amount, _OrderLine, _Status } = options._constructor || {}
5286
+ this._Amount = _Amount && (_Amount._superclass === Amount._superclass) ? _Amount : Amount
5287
+ this._OrderLine = _OrderLine && (_OrderLine._superclass === OrderLine._superclass) ? _OrderLine : OrderLine
5288
+ this._Status = _Status && (_Status._superclass === StatusQStore._superclass) ? _Status : StatusQStore
5289
+
5290
+ this._orderLines = options._orderLines
5291
+
5292
+ const id = options._id || options.id
5293
+ this.id = order_setId(id)
5294
+ this._type = options._type || 'Order'
5295
+ this.amount = this._Amount.init(options.amount)
5296
+ this.orderCode = options.orderCode
5297
+ // this.orderNumber = options.orderNumber
5298
+ this.orderType = 'Order'
5299
+ // this.revisionNumber = options.revisionNumber || 1
5300
+ this.status = this._Status.init(options.status)
5301
+ this.name = options.name
5302
+ }
5303
+
5304
+ static dummyData() {
5305
+ return {
5306
+ tenantCode: 'tenantCode'
5307
+ }
5308
+ }
5309
+
5310
+ static get _classname() {
5311
+ return 'Order'
5312
+ }
5313
+
5314
+ static get _superclass() {
5315
+ return 'Order'
5316
+ }
5317
+
5318
+ // get isValid() {
5319
+ // return super.isValid
5320
+ // }
5321
+
5322
+ get isCompleted() {
5323
+ return this.status.isCompleted
5324
+ }
5325
+
5326
+ get isProcessing() {
5327
+ return this.status.isProcessing
5328
+ }
5329
+
5330
+ get isTerminated() {
5331
+ return this.status.isTerminated
5332
+ }
5333
+
5334
+ get orderLines() {
5335
+ return this._OrderLine.initOnlyValidFromArray(this._orderLines || [])
5336
+ }
5337
+
5338
+ getAmount() {
5339
+ return this.amount
5340
+ }
5341
+
5342
+ getCurrencyCode() {
5343
+ return this.amount ? this.amount.getCurrencyCode() : null
5344
+ }
5345
+
5346
+ getFullOrderNumber(delimiter = '.') {
5347
+ return `${this.orderNumber}${delimiter}${this.revisionNumber}`
5348
+ }
5349
+
5350
+ increaseRevisionNumber() {
5351
+ this.revisionNumber += 1
5352
+ return this
5353
+ }
5354
+
5355
+ setCompleted() {
5356
+ this.status.setCompleted()
5357
+ return this.setModified()
5358
+ }
5359
+
5360
+ setCancelled() {
5361
+ this.status.setCancelled()
5362
+ return this.setModified()
5363
+ }
5364
+
5365
+ setProcessing() {
5366
+ this.status.setProcessing()
5367
+ return this.setModified()
5368
+ }
5369
+
5370
+ setTerminated() {
5371
+ this.status.setTerminated()
5372
+ return this.setModified()
5373
+ }
5374
+
5375
+ setWaived() {
5376
+ this.status.setWaived()
5377
+ return this.setModified()
5378
+ }
5379
+
5380
+ update(obj) {
5381
+ Object.keys(obj).forEach((key) => {
5382
+ if (order_updateAllowedProps.includes(key)) {
5383
+ if (key === 'amount') {
5384
+ this[key] = this.amount instanceof this._Amount ? this.amount.update(obj[key]) : this._Amount.init(obj[key])
5385
+ } else if (key === 'status') {
5386
+ this[key] = this.status instanceof this._Status ? this.status.update(obj[key]) : this._Status.init(obj[key])
5387
+ } else {
5388
+ this[key] = obj[key]
5389
+ }
5390
+ }
5391
+ })
5392
+ return super.update(obj)
5393
+ }
5394
+ }
5395
+
5396
+ // function setCode(options, key) {
5397
+ // const copyOptions = options || {}
5398
+ // if (copyOptions[key]) {
5399
+ // return copyOptions[key]
5400
+ // }
5401
+ // return stringHelper.setCode()
5402
+ // }
5403
+
5404
+ function order_setId(id) {
5405
+ if (id && typeof id.toString === 'function') {
5406
+ return id.toString()
5407
+ }
5408
+ return id
5409
+ }
5410
+
5411
+
5412
+
5413
+ ;// ./lib/models/order/index.js
5414
+
5415
+
5416
+
5417
+
5418
+ ;// ./lib/models/paymentGateway/paymentGateway.js
5419
+
5420
+
5421
+
5422
+ const paymentGateway_updateAllowedProps = [
5423
+ 'label',
5424
+ 'logoUrl',
5425
+ 'name',
5426
+ 'sandbox',
5427
+ 'setting'
5428
+ ]
5429
+
5430
+ class PaymentGateway extends q_utilities_namespaceObject.TenantAwareEntity {
5431
+ constructor(options = {}) {
5432
+ options = options || {}
5433
+ super(options)
5434
+
5435
+ const id = options._id || options.id
5436
+ this.id = paymentGateway_setId(id)
5437
+ this._type = options._type || 'PaymentGateway'
5438
+
5439
+ this.hasWebhook = options.hasWebhook || false
5440
+ this.label = options.label
5441
+ this.logoUrl = options.logoUrl
5442
+ this.name = options.name || ''
5443
+ this.paymentGatewayCode = paymentGateway_setCode(options, 'paymentGatewayCode')
5444
+ this.paymentGatewayType = options.paymentGatewayType || 'PaymentGateway'
5445
+ this.paymentResultType = options.paymentResultType || 'PaymentResult'
5446
+ this.sandbox = options.sandbox || false
5447
+ this.setting = options.setting || null
5448
+ }
5449
+ static dummyData() {
5450
+ return {
5451
+ name: 'name',
5452
+ tenantCode: 'tenantCode'
5453
+ }
5454
+ }
5455
+ static get _classname() {
5456
+ return 'PaymentGateway'
5457
+ }
5458
+ static get _superclass() {
5459
+ return 'PaymentGateway'
5460
+ }
5461
+
5462
+ // getters
5463
+ get isValid() {
5464
+ return super.isValid && !!this.name
5465
+ }
5466
+
5467
+ // instance methods
5468
+ async createPayment() {
5469
+ throw new Error(`${this._classname} subclass should implement createPayment`)
5470
+ }
5471
+ async getAppPayParams() {
5472
+ throw new Error(`${this._classname} subclass should implement getAppPayParams`)
5473
+ }
5474
+ getCode() {
5475
+ return this.paymentGatewayCode
5476
+ }
5477
+ async updatePayment() {
5478
+ throw new Error(`${this._classname} subclass should implement updatePayment`)
5479
+ }
5480
+ async query() {
5481
+ throw new Error(`${this._classname} subclass should implement query`)
5482
+ }
5483
+ async submit() {
5484
+ throw new Error(`${this._classname} subclass should implement submit`)
5485
+ }
5486
+
5487
+ setCompletedRelatedStatus(status) {
5488
+ throw new Error(`${this.name} subclass should implement setCompletedRelatedStatus`)
5489
+ }
5490
+ update(update) {
5491
+ Object.keys(update).forEach((key) => {
5492
+ if (paymentGateway_updateAllowedProps.includes(key)) {
5493
+ this[key] = update[key]
5494
+ }
5495
+ })
5496
+ return super.update(update)
5497
+ }
5498
+ }
5499
+
5500
+ function paymentGateway_setCode(options, key) {
5501
+ const copyOptions = options || {}
5502
+ if (copyOptions[key]) {
5503
+ return copyOptions[key]
5504
+ }
5505
+ return stringHelper.setCode()
5506
+ }
5507
+
5508
+ function paymentGateway_setId(id) {
5509
+ if (id && typeof id.toString === 'function') {
5510
+ return id.toString()
5511
+ }
5512
+ return id
5513
+ }
5514
+
5515
+
5516
+
5517
+ ;// ./lib/models/paymentGateway/paymentGatewayRepo.js
5518
+
5519
+
5520
+
5521
+ class PaymentGatewayRepo extends q_utilities_namespaceObject.Repo {
5522
+ constructor(options = {}) {
5523
+ options = options || {}
5524
+ super(options)
5525
+ const { _PaymentGateway } = options._constructor || {}
5526
+ this._PaymentGateway = _PaymentGateway && (_PaymentGateway._superclass === PaymentGateway._superclass) ? _PaymentGateway : PaymentGateway
5527
+ }
5528
+ static get _classname() {
5529
+ return 'PaymentGatewayRepo'
5530
+ }
5531
+ init(options) {
5532
+ return this._PaymentGateway.init(options)
5533
+ }
5534
+ }
5535
+
5536
+
5537
+
5538
+ ;// ./lib/models/paymentGateway/index.js
5539
+
5540
+
5541
+
5542
+
5543
+
5544
+
5545
+ ;// ./lib/models/paymentResult/paymentResult.js
5546
+
5547
+
5548
+
5549
+
5550
+ const paymentResult_updateAllowedProps = [
5551
+ 'active',
5552
+ 'deleted',
5553
+ 'remarks',
5554
+ 'result'
5555
+ ]
5556
+
5557
+ class PaymentResult extends q_utilities_namespaceObject.TenantAwareEntity {
5558
+ constructor(options = {}) {
5559
+ options = options || {}
5560
+ super(options)
5561
+
5562
+ const { _Transaction } = options._constructor || {}
5563
+ this._Transaction = _Transaction && (_Transaction._superclass === Transaction._superclass) ? _Transaction : Transaction
5564
+
5565
+ this._transaction = options._transaction
5566
+ this._type = options._type || 'PaymentResult'
5567
+
5568
+ const id = options._id || options.id
5569
+ this.id = paymentResult_setId(id)
5570
+
5571
+ this.paymentResultCode = paymentResult_setCode(options, 'paymentResultCode')
5572
+ this.paymentResultType = options.paymentResultType || 'PaymentResult'
5573
+ this.result = options.result
5574
+ this.resultRef = options.resultRef
5575
+ this.resultType = options.resultType
5576
+ // this.transaction = this._Transaction.init(options.transaction)
5577
+ this.transactionCode = options.transactionCode
5578
+ }
5579
+
5580
+ // class method
5581
+ static dummyData() {
5582
+ return {
5583
+ paymentResultType: 'PaymentResult',
5584
+ result: { id: 'resultId' },
5585
+ resultType: 'resultType',
5586
+ tenantCode: 'tenantCode',
5587
+ transactionCode: 'transactionCode'
5588
+ }
5589
+ }
5590
+ static get _classname() {
5591
+ return 'PaymentResult'
5592
+ }
5593
+ static get _superclass() {
5594
+ return 'PaymentResult'
5595
+ }
5596
+
5597
+ // getters
5598
+ get isValid() {
5599
+ return super.isValid && !!this.resultType && !!this.transactionCode
5600
+ // return !!this.result && !!this.resultType && !!this.tenantCode
5601
+ }
5602
+ get amount() {
4892
5603
  throw new Error(`${this._classname} subclass should implement get amount`)
4893
5604
  }
5605
+ get billedAmount() {
5606
+ throw new Error(`${this._classname} subclass should implement get billedAmount`)
5607
+ }
4894
5608
  get paymentMethod() {
4895
5609
  throw new Error(`${this._classname} subclass should implement get paymentMethod`)
4896
5610
  }
5611
+ get receivedAmount() {
5612
+ throw new Error(`${this._classname} subclass should implement get receivedAmount`)
5613
+ }
5614
+ get resultStatus() {
5615
+ throw new Error(`${this._classname} subclass should implement get resultStatus`)
5616
+ }
4897
5617
  get transaction() {
4898
5618
  return this._Transaction.init(this._transaction)
4899
5619
  }
@@ -4903,11 +5623,11 @@ class PaymentResult extends q_utilities_namespaceObject.TenantAwareEntity {
4903
5623
  // throw new Error(`${this.paymentResultType} subclass should implement getPaymentId`)
4904
5624
  // }
4905
5625
  addMetadata(key, value) {
4906
- q_utilities_namespaceObject.Metadata.addItem(this.metadata, key, value)
5626
+ this.metadata = q_utilities_namespaceObject.Metadata.insertOrUpdateRecord(this.metadata, key, value)
4907
5627
  return this
4908
5628
  }
4909
5629
  addRemark(key, value) {
4910
- q_utilities_namespaceObject.KeyValueObject.addItem(this.remarks, key, value)
5630
+ this.remarks = q_utilities_namespaceObject.KeyValueObject.insertOrUpdateRecord(this.remarks, key, value)
4911
5631
  return this
4912
5632
  }
4913
5633
 
@@ -4961,10 +5681,10 @@ class PaymentResult extends q_utilities_namespaceObject.TenantAwareEntity {
4961
5681
  setupMetadata() {
4962
5682
  const amount = this.amount
4963
5683
  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)
5684
+ this.metadata = q_utilities_namespaceObject.Metadata.insertOrUpdateRecord(this.metadata, 'AMOUNT', amount)
5685
+ this.metadata = q_utilities_namespaceObject.Metadata.insertOrUpdateRecord(this.metadata, 'PAYMENT_METHOD', paymentMethod)
5686
+ this.remarks = q_utilities_namespaceObject.KeyValueObject.insertOrUpdateRecord(this.remarks, 'amount', amount)
5687
+ this.remarks = q_utilities_namespaceObject.KeyValueObject.insertOrUpdateRecord(this.remarks, 'paymentMethod', paymentMethod)
4968
5688
  return this
4969
5689
  }
4970
5690
  setupRemarks() {
@@ -5249,6 +5969,9 @@ function storeItem_getDataByKey(key, data) {
5249
5969
 
5250
5970
 
5251
5971
 
5972
+
5973
+
5974
+
5252
5975
 
5253
5976
 
5254
5977
 
@@ -5366,7 +6089,8 @@ class Chain {
5366
6089
 
5367
6090
  ;// ./lib/helpers/calculateByCoupon/calculateCoupon.js
5368
6091
 
5369
- function calculateByCoupon({ coupon, price }) {
6092
+
6093
+ function calculateByCoupon({ coupon, price, currencyCode }) {
5370
6094
  const { couponDetails } = coupon
5371
6095
  if (!couponDetails) {
5372
6096
  return 0
@@ -5374,8 +6098,11 @@ function calculateByCoupon({ coupon, price }) {
5374
6098
  const { type, item } = couponDetails
5375
6099
  if (item) {
5376
6100
  switch(type) {
6101
+ case ('Deduction'): {
6102
+ return _caculateByDeduction({ price, couponDetails, currencyCode })
6103
+ }
5377
6104
  case ('Percentage'): {
5378
- return _caculateByPercentage(price, couponDetails)
6105
+ return _caculateByPercentage({ price, couponDetails })
5379
6106
  }
5380
6107
  default: {
5381
6108
  return 0
@@ -5384,7 +6111,11 @@ function calculateByCoupon({ coupon, price }) {
5384
6111
  }
5385
6112
  }
5386
6113
 
5387
- function _caculateByPercentage(price, couponDetails) {
6114
+ function _caculateByDeduction({ price, couponDetails, currencyCode }) {
6115
+ const { value } = couponDetails
6116
+ return q_utilities_namespaceObject.KeyValueObject.foundValueByKey(value, currencyCode)
6117
+ }
6118
+ function _caculateByPercentage({ price, couponDetails }) {
5388
6119
  const { value } = couponDetails
5389
6120
  return price.value * (value / 100)
5390
6121
  }
@@ -5392,6 +6123,11 @@ function _caculateByPercentage(price, couponDetails) {
5392
6123
 
5393
6124
 
5394
6125
 
6126
+ ;// ./lib/helpers/calculateByCoupon/index.js
6127
+
6128
+
6129
+
6130
+
5395
6131
  ;// ./lib/eventManager/chains/helpers.js
5396
6132
 
5397
6133
 
@@ -5566,6 +6302,10 @@ function cutEntitlements(lines, entitlements = [], currencyCode) {
5566
6302
  const subTotal = Amount.init({ value, currencyCode })
5567
6303
  const discountValue = ((price ? price.value : 0) * restQty) - (subTotal ? subTotal.value : 0) + ((price ? price.value : 0) * waived)
5568
6304
  const discount = Amount.init({ value: discountValue, currencyCode })
6305
+ let remarks = q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray([...(updatedItem.remarks || [])])
6306
+ remarks = q_utilities_namespaceObject.KeyValueObject.updateOrInsertRecord(remarks, 'entitlements', entitlementsRemarkValue)
6307
+ let metadata = q_utilities_namespaceObject.Metadata.initOnlyValidFromArray([...(updatedItem.metadata || [])])
6308
+ metadata = q_utilities_namespaceObject.Metadata.updateOrInsertRecord(metadata, 'entitlements', entitlementsRemarkValue)
5569
6309
  const obj = {
5570
6310
  merchandiseCode,
5571
6311
  price,
@@ -5573,7 +6313,9 @@ function cutEntitlements(lines, entitlements = [], currencyCode) {
5573
6313
  subTotal,
5574
6314
  qty,
5575
6315
  waived,
5576
- remarks: [{ key: 'entitlements', value: entitlementsRemarkValue }],
6316
+ // remarks: [{ key: 'entitlements', value: entitlementsRemarkValue }],
6317
+ remarks,
6318
+ metadata,
5577
6319
  priceStrategies,
5578
6320
  priceStrategy: strategy
5579
6321
  }
@@ -5667,7 +6409,7 @@ function getAmount(priceStrategies, currencyCode, line) {
5667
6409
  const discount = Amount.init({ value: discountValue, currencyCode })
5668
6410
  return {
5669
6411
  merchandiseCode,
5670
- remarks: [],
6412
+ // remarks: [],
5671
6413
  price,
5672
6414
  discount,
5673
6415
  subTotal,
@@ -5720,14 +6462,18 @@ function getPricesByTime(line, dateTime) {
5720
6462
  }
5721
6463
 
5722
6464
  function getStrategiesByRestrictions(prices, line, user) {
5723
- if (prices.length === 0) {
5724
- return []
5725
- }
6465
+ // if (prices.length === 0) {
6466
+ // return []
6467
+ // }
5726
6468
  const { updatedItem } = line
5727
- const priceStrategies = prices.reduce((acc, price) => {
5728
- const strategies = price.getStrategiesByRestrictions({ user })
5729
- return acc.concat(strategies)
5730
- }, [])
6469
+ let priceStrategies = []
6470
+ if (prices.length !== 0) {
6471
+ priceStrategies = prices.reduce((acc, price) => {
6472
+ const strategies = price.getStrategiesByRestrictions({ user })
6473
+ return acc.concat(strategies)
6474
+ }, [])
6475
+ }
6476
+
5731
6477
  if (priceStrategies.length === 0) {
5732
6478
  updatedItem.qty = 0
5733
6479
  line.available = false
@@ -5814,6 +6560,10 @@ function ChainGetPriceForGroup_cutEntitlements(lines, entitlements = [], currenc
5814
6560
  const subTotal = Amount.init({ value, currencyCode })
5815
6561
  const discountValue = (price.value * restQty) - subTotal.value + (price.value * waived)
5816
6562
  const discount = Amount.init({ value: discountValue, currencyCode })
6563
+ let remarks = KeyValueObject.initOnlyValidFromArray([...(updatedItem.remarks || [])])
6564
+ remarks = KeyValueObject.updateOrInsertRecord(remarks, 'entitlements', entitlementsRemarkValue)
6565
+ let metadata = Metadata.initOnlyValidFromArray([...(updatedItem.metadata || [])])
6566
+ metadata = Metadata.updateOrInsertRecord(metadata, 'entitlements', entitlementsRemarkValue)
5817
6567
  const obj = {
5818
6568
  merchandiseCode,
5819
6569
  price,
@@ -5821,7 +6571,9 @@ function ChainGetPriceForGroup_cutEntitlements(lines, entitlements = [], currenc
5821
6571
  subTotal,
5822
6572
  qty,
5823
6573
  waived,
5824
- remarks: [{ key: 'entitlements', value: entitlementsRemarkValue }],
6574
+ // remarks: [{ key: 'entitlements', value: entitlementsRemarkValue }],
6575
+ remarks,
6576
+ metadata,
5825
6577
  priceStrategies,
5826
6578
  priceStrategy: strategy
5827
6579
  }
@@ -5876,7 +6628,7 @@ function ChainGetPriceForGroup_getAmount(priceStrategies, currencyCode, line) {
5876
6628
  const discount = Amount.init({ value: discountValue, currencyCode })
5877
6629
  return {
5878
6630
  merchandiseCode,
5879
- remarks: [],
6631
+ // remarks: [],
5880
6632
  price,
5881
6633
  discount,
5882
6634
  subTotal,
@@ -5961,7 +6713,8 @@ class ChainInitLines extends Chain {
5961
6713
  line.updatedItem = {
5962
6714
  ...item,
5963
6715
  waived: 0,
5964
- remarks: [],
6716
+ remarks: q_utilities_namespaceObject.KeyValueObject.initOnlyValidFromArray(item.remarks),
6717
+ metadata: q_utilities_namespaceObject.Metadata.initOnlyValidFromArray(item.metadata),
5965
6718
  price: Amount.init(item.price),
5966
6719
  discount: Amount.init(item.discount),
5967
6720
  subTotal: Amount.init(item.subTotal),
@@ -6016,6 +6769,61 @@ class ChainMerchandiseLimit extends Chain {
6016
6769
 
6017
6770
 
6018
6771
 
6772
+ ;// ./lib/eventManager/chains/chainPriceAdjustment.js
6773
+
6774
+
6775
+ class ChainPriceAdjustment extends Chain {
6776
+ constructor(options = {}) {
6777
+ super(options)
6778
+ this.currency = options.currency
6779
+ }
6780
+
6781
+ async handleRequest(chainTarget) {
6782
+ try {
6783
+ const { lines } = chainTarget
6784
+
6785
+ // for item coupon
6786
+ lines.forEach((line) => {
6787
+ _calculate({ line, currency: this.currency })
6788
+ })
6789
+ await this.next(chainTarget)
6790
+ } catch (err) {
6791
+ chainTarget.addException('handle related coupons fail', err.message)
6792
+ this.exitChain()
6793
+ }
6794
+ }
6795
+ }
6796
+
6797
+ function _calculate({ line, currency }) {
6798
+ const { updatedItem } = line
6799
+ const { price, qty, discount, purchaseOptions, remarks, subTotal } = updatedItem
6800
+ if (purchaseOptions.length === 0 || updatedItem.qty === 0) {
6801
+ return
6802
+ }
6803
+ const priceAdjustment = _findPriceAdjustmentValue(purchaseOptions)
6804
+ if (!priceAdjustment) {
6805
+ return
6806
+ }
6807
+ const subTotalValue = subTotal.value + priceAdjustment * (currency.factor || 1)
6808
+ const obj = {
6809
+ subTotal: Amount.init({ value: subTotalValue, currencyCode: currency.code })
6810
+ }
6811
+ Object.assign(updatedItem, obj)
6812
+ }
6813
+
6814
+ function _findPriceAdjustmentValue(dataArray) {
6815
+ for (const obj of dataArray) {
6816
+ const priceAdjustment = obj.value?.find(item => item.key === 'priceAdjustment')
6817
+ if (priceAdjustment) {
6818
+ return Number(priceAdjustment.value)
6819
+ }
6820
+ }
6821
+ return null
6822
+ }
6823
+
6824
+
6825
+
6826
+
6019
6827
  ;// ./lib/eventManager/chains/chainProductLimit.js
6020
6828
 
6021
6829
 
@@ -6210,7 +7018,6 @@ class ChainPurchaseOptions extends Chain {
6210
7018
 
6211
7019
  ;// ./lib/eventManager/chains/chainRelatedCoupons.js
6212
7020
 
6213
- // import { WalletItem } from '../../models/walletItem/index.js'
6214
7021
 
6215
7022
  class ChainRelatedCoupons extends Chain {
6216
7023
  constructor(options = {}) {
@@ -6222,40 +7029,143 @@ class ChainRelatedCoupons extends Chain {
6222
7029
 
6223
7030
  async handleRequest(chainTarget) {
6224
7031
  try {
6225
- const { lines, users } = chainTarget
6226
- // const walletItems = WalletItem.initOnlyValidFromArray(this.walletItems)
7032
+ const { lines, relatedTotalCoupons = [], users } = chainTarget
6227
7033
  const couponWalletItems = this.walletItems.filter((i) => i.isCoupon)
7034
+ // for item coupon
6228
7035
  lines.forEach((line) => {
6229
- _calculateAmountByCoupons({ line, currencyCode: this.currency.code })
6230
- _updateRelatedCoupons(line, couponWalletItems, this.autoUseCoupon, this.currency.code)
7036
+ _calculateAmountByItemCoupons({ line, currencyCode: this.currency.code })
7037
+ _updateRelatedItemCoupons(line, couponWalletItems, this.autoUseCoupon, this.currency.code)
6231
7038
  })
6232
7039
  lines.forEach((line) => {
6233
- _getAvailableCoupons(line)
7040
+ _getAvailableItemCoupons(line)
6234
7041
  })
7042
+ // for total ptice coupon
7043
+ _calculateAmountByTotalCoupons({ lines, currencyCode: this.currency.code, relatedTotalCoupons })
7044
+ _autoUsedTotalCoupons({ lines, autoUseCoupon: this.autoUseCoupon, currencyCode: this.currency.code, relatedTotalCoupons})
6235
7045
  await this.next(chainTarget)
6236
7046
  } catch (err) {
6237
- chainTarget.addException('calculate categories limit fail', err.message)
7047
+ chainTarget.addException('handle related coupons fail', err.message)
6238
7048
  this.exitChain()
6239
7049
  }
6240
7050
  }
6241
7051
  }
6242
- function _calculateAmountByCoupons({ line, currencyCode }) {
7052
+
7053
+
7054
+ function _autoUsedTotalCoupons({ lines, autoUseCoupon, currencyCode, relatedTotalCoupons }) {
7055
+ if (autoUseCoupon) {
7056
+ relatedTotalCoupons.forEach((item) => {
7057
+ const obj = _autoUsedTotalCoupon(item, lines, currencyCode)
7058
+ Object.assign(item, obj)
7059
+ })
7060
+ }
7061
+ }
7062
+
7063
+
7064
+ function _autoUsedTotalCoupon(item, lines, currencyCode) {
7065
+ const { availableCoupons, usedCoupons, product } = item
7066
+ if (availableCoupons.length > 0) {
7067
+ const availableLines = lines.filter((line) => (product.isApplicableCoupon(line.merchandise)))
7068
+ const total = availableLines.reduce((acc, l) => {
7069
+ const { updatedItem = {} } = l
7070
+ const { subTotal = {} } = updatedItem
7071
+ if (subTotal && subTotal.value) {
7072
+ acc += subTotal.value
7073
+ }
7074
+ return acc
7075
+ }, 0)
7076
+ if (total > 0) {
7077
+ const [coupon] = availableCoupons.splice(0, 1)
7078
+ coupon.setOnHold()
7079
+ usedCoupons.push(coupon)
7080
+ _calculateAmountByOneTotalCoupon({ lines, currencyCode, coupon })
7081
+ return _autoUsedTotalCoupon(item, lines, currencyCode)
7082
+ }
7083
+ }
7084
+ return item
7085
+ }
7086
+
7087
+ function _calculateAmountByItemCoupons({ line, currencyCode }) {
6243
7088
  const { usedCoupons = {}, updatedItem } = line
6244
7089
  Object.keys(usedCoupons).forEach((key) => {
6245
7090
  usedCoupons[key].forEach((coupon) => {
6246
- const obj = _calculateAmountByOneCoupon({ updatedItem, coupon, currencyCode })
7091
+ const obj = _calculateAmountByOneItemCoupon({ updatedItem, coupon, currencyCode })
6247
7092
  Object.assign(updatedItem, obj)
6248
7093
  })
6249
7094
  })
6250
7095
  }
6251
7096
 
6252
- function _calculateAmountByOneCoupon({ updatedItem, coupon, currencyCode }) {
7097
+ function _calculateAmountByTotalCoupons({ lines, currencyCode, relatedTotalCoupons }) {
7098
+ relatedTotalCoupons.forEach((i) => {
7099
+ const { usedCoupons } = i
7100
+ usedCoupons.forEach((coupon) => {
7101
+ _calculateAmountByOneTotalCoupon({ lines, currencyCode, coupon })
7102
+ })
7103
+ })
7104
+ }
7105
+
7106
+ function _calculateAmountByOneTotalCoupon({ lines, currencyCode, coupon }) {
7107
+ const availableLines = lines.filter((line) => (coupon.isApplicableCoupon(line.merchandise)))
7108
+ // const qty = availableLines.reduce((acc, i) => (acc += i.updatedItem.qty), 0)
7109
+ const totalPrice = availableLines.reduce((acc, i) => {
7110
+ const { price = {}, qty } = i.updatedItem || {}
7111
+ return acc += price.value * qty
7112
+ }, 0)
7113
+ const { couponDetails, walletItemCode } = coupon
7114
+ if (couponDetails) {
7115
+ const { type, total } = couponDetails
7116
+ const { value } = couponDetails
7117
+ switch(type) {
7118
+ case ('Deduction'): {
7119
+ const _discount = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(value, currencyCode)
7120
+ availableLines.forEach((line) => {
7121
+ const { updatedItem } = line
7122
+ const { price, qty, discount, remarks, subTotal } = updatedItem
7123
+ const discountValue = _discount * (price.value * qty / totalPrice) + discount.value
7124
+ const subTotalValue = subTotal.value > _discount ? subTotal.value - _discount : 0
7125
+ const _usedCoupons = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(remarks, 'USED_TOTAL_COUPONS') || []
7126
+ _usedCoupons.push(walletItemCode)
7127
+ const obj = {
7128
+ discount: Amount.init({ value: discountValue, currencyCode }),
7129
+ remarks: q_utilities_namespaceObject.KeyValueObject.insertOrUpdateRecord(remarks, 'USED_TOTAL_COUPONS', _usedCoupons ),
7130
+ subTotal: Amount.init({ value: subTotalValue, currencyCode })
7131
+ }
7132
+ Object.assign(updatedItem, obj)
7133
+ })
7134
+ break
7135
+ }
7136
+ case ('Percentage'): {
7137
+ availableLines.forEach((line) => {
7138
+ const { updatedItem } = line
7139
+ const { price, qty, discount, remarks, subTotal } = updatedItem
7140
+ const _discount = price.value * (value / 100) * qty
7141
+ const discountValue = _discount + discount.value
7142
+ const subTotalValue = subTotal.value > _discount ? subTotal.value - _discount : 0
7143
+ const _usedCoupons = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(remarks, 'USED_TOTAL_COUPONS') || []
7144
+ _usedCoupons.push(walletItemCode)
7145
+ const obj = {
7146
+ discount: Amount.init({ value: discountValue, currencyCode }),
7147
+ remarks: q_utilities_namespaceObject.KeyValueObject.insertOrUpdateRecord(remarks, 'USED_TOTAL_COUPONS', _usedCoupons ),
7148
+ subTotal: Amount.init({ value: subTotalValue, currencyCode })
7149
+ }
7150
+ Object.assign(updatedItem, obj)
7151
+ })
7152
+ break
7153
+ }
7154
+ default: {
7155
+
7156
+ }
7157
+ }
7158
+ }
7159
+
7160
+ }
7161
+
7162
+ function _calculateAmountByOneItemCoupon({ updatedItem, coupon, currencyCode }) {
6253
7163
  const { couponDetails, walletItemCode } = coupon
6254
7164
  if (!couponDetails) {
6255
7165
  return updatedItem
6256
7166
  }
6257
7167
  const { price, qty, discount, remarks, subTotal } = updatedItem
6258
- const _discount = calculateByCoupon({ coupon, price })
7168
+ const _discount = calculateByCoupon({ coupon, price, currencyCode })
6259
7169
  const discountValue = _discount + discount.value
6260
7170
  const subTotalValue = subTotal.value > _discount ? subTotal.value - _discount : 0
6261
7171
  const _usedCoupons = q_utilities_namespaceObject.KeyValueObject.foundValueByKey(remarks, 'USED_ITEM_COUPONS') || []
@@ -6269,7 +7179,7 @@ function _calculateAmountByOneCoupon({ updatedItem, coupon, currencyCode }) {
6269
7179
  }
6270
7180
 
6271
7181
 
6272
- function _getAvailableCoupons(line) {
7182
+ function _getAvailableItemCoupons(line) {
6273
7183
  const { relatedCoupons = [] } = line
6274
7184
  line.relatedCoupons = relatedCoupons.map((c) => ({
6275
7185
  ...c,
@@ -6277,7 +7187,7 @@ function _getAvailableCoupons(line) {
6277
7187
  }))
6278
7188
  }
6279
7189
 
6280
- function _getRelatedCoupons(cartItemLine, couponWalletItems, autoUseCoupon, currencyCode) {
7190
+ function _getRelatedItemCoupons(cartItemLine, couponWalletItems, autoUseCoupon, currencyCode) {
6281
7191
  const { merchandise, usedCoupons = {}, updatedItem = {} } = cartItemLine
6282
7192
  const relatedWalletItems = couponWalletItems.filter(
6283
7193
  item => item.isApplicableCoupon(merchandise) && item.isItemCoupon
@@ -6307,7 +7217,7 @@ function _getRelatedCoupons(cartItemLine, couponWalletItems, autoUseCoupon, curr
6307
7217
  ...usedCoupons[productCode] || [],
6308
7218
  w
6309
7219
  ]
6310
- const obj = _calculateAmountByOneCoupon({ updatedItem, currencyCode, coupon: w })
7220
+ const obj = _calculateAmountByOneItemCoupon({ updatedItem, currencyCode, coupon: w })
6311
7221
  Object.assign(updatedItem, obj)
6312
7222
  exist.usedQty = usedCoupons[productCode].length
6313
7223
  }
@@ -6316,9 +7226,9 @@ function _getRelatedCoupons(cartItemLine, couponWalletItems, autoUseCoupon, curr
6316
7226
  }
6317
7227
 
6318
7228
 
6319
- function _updateRelatedCoupons(line, couponWalletItems, autoUseCoupon, currencyCode) {
7229
+ function _updateRelatedItemCoupons(line, couponWalletItems, autoUseCoupon, currencyCode) {
6320
7230
  if (couponWalletItems.length > 0) {
6321
- line.relatedCoupons = _getRelatedCoupons(line, couponWalletItems, autoUseCoupon, currencyCode)
7231
+ line.relatedCoupons = _getRelatedItemCoupons(line, couponWalletItems, autoUseCoupon, currencyCode)
6322
7232
  }
6323
7233
  }
6324
7234
 
@@ -6340,6 +7250,7 @@ function _updateRelatedCoupons(line, couponWalletItems, autoUseCoupon, currencyC
6340
7250
 
6341
7251
 
6342
7252
 
7253
+
6343
7254
  ;// ./lib/helpers/corHelper/chainException.js
6344
7255
 
6345
7256
  class ChainException {
@@ -6448,12 +7359,15 @@ class ChainTargetCalculateAmount extends ChainTarget {
6448
7359
  constructor(options = {}) {
6449
7360
  super(options)
6450
7361
  this.lines = options.lines
7362
+ this.relatedTotalCoupons = options.relatedTotalCoupons
6451
7363
  this.user = options.user
6452
7364
  }
6453
7365
 
6454
7366
  getResult() {
6455
7367
  return {
6456
- lines: this.lines
7368
+ lines: this.lines,
7369
+ relatedTotalCoupons: this.relatedTotalCoupons
7370
+
6457
7371
  }
6458
7372
  }
6459
7373
  }
@@ -6589,10 +7503,11 @@ class ChainManagerFactory {
6589
7503
  static calculateAmount({ chains = [], payload = {}, serviceAppName }) {
6590
7504
  const {
6591
7505
  lines,
7506
+ relatedTotalCoupons,
6592
7507
  user,
6593
7508
  } = payload
6594
7509
  // const chains = _calculateAmountChainsFactory(payload)
6595
- const chainTarget = new ChainTargetCalculateAmount({ lines, user })
7510
+ const chainTarget = new ChainTargetCalculateAmount({ lines, relatedTotalCoupons, user })
6596
7511
  const chainManager = new ChainManager({ chainTarget })
6597
7512
  chainManager.createChains({ chains })
6598
7513
  return chainManager
@@ -6626,6 +7541,7 @@ function _calculateAmountChainsFactory(payload) {
6626
7541
  currency, dateTime, entitlements, merchandises
6627
7542
  }),
6628
7543
  new ChainRelatedCoupons({ currency, autoUseCoupon, walletItems }),
7544
+ new ChainPriceAdjustment({ currency }),
6629
7545
  ]
6630
7546
  }
6631
7547
 
@@ -6660,11 +7576,12 @@ function _calculateAmountChainsFactoryforGroup(payload) {
6660
7576
 
6661
7577
 
6662
7578
  ;// ./lib/helpers/adminSettle/adminSettle.js
6663
- function adminSettle({ component, eventRegistration, invoice, payeeName, payeeAddress, payeeCountry, cb }) {
7579
+ function adminSettle({ adminSettleFormData = {}, component, eventRegistration, invoice, payeeName, payeeAddress, payeeCountry, cb }) {
6664
7580
  const _eventRegistration = eventRegistration || component.registration
6665
7581
  component.invoice = invoice
6666
7582
  component.adminSettleFormData = {
6667
7583
  ...invoice,
7584
+ ...adminSettleFormData,
6668
7585
  email: _eventRegistration ? _eventRegistration.getEmail() || '' : '',
6669
7586
  payeeName,
6670
7587
  payeeAddress,
@@ -6768,11 +7685,6 @@ function getFakeClass() {
6768
7685
 
6769
7686
 
6770
7687
 
6771
- ;// ./lib/helpers/calculateByCoupon/index.js
6772
-
6773
-
6774
-
6775
-
6776
7688
  ;// ./lib/helpers/corHelper/index.js
6777
7689
 
6778
7690
 
@@ -7087,6 +7999,7 @@ function convert(date, dateFormat) {
7087
7999
 
7088
8000
 
7089
8001
 
8002
+ let _config = null
7090
8003
  let _isAdmin = null
7091
8004
  let _label = {}
7092
8005
  let orderList_self = null
@@ -7137,6 +8050,17 @@ function actionBuilder(row, header, qRow) {
7137
8050
  label: _label.ADMIN_SETTLE,
7138
8051
  onClick: orderList_self.onOrderListAction('adminSettle')
7139
8052
  })
8053
+ if (_config && _config.allowWaived) {
8054
+ actions.push({
8055
+ css: {
8056
+ element: '__button'
8057
+ },
8058
+ icon: 'fa fa-edit',
8059
+ label: _label.WAIVED,
8060
+ onClick: orderList_self.onOrderListAction('waived')
8061
+ })
8062
+ }
8063
+
7140
8064
  }
7141
8065
  actions.push({
7142
8066
  css: {
@@ -7235,9 +8159,10 @@ function handlerHeaders(defaultHeaders) {
7235
8159
  }
7236
8160
 
7237
8161
  function handlerOrderList({
7238
- component, merchandises, invoices, defaultHeaders, isAdmin, label = {}
8162
+ component, config, merchandises, invoices, defaultHeaders, isAdmin, label = {}
7239
8163
  }) {
7240
8164
  orderList_self = component
8165
+ _config = config
7241
8166
  _isAdmin = isAdmin
7242
8167
  _label = label.button || {}
7243
8168
  const orderList = qListArr(merchandises, invoices)