@positivegrid/pg-mongoose-schema 27.8.4 → 28.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.js +34 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/models/banks.d.ts +3 -0
  5. package/dist/models/banks.js +33 -0
  6. package/dist/models/banks.js.map +1 -0
  7. package/dist/models/device.d.ts +3 -0
  8. package/dist/models/device.js +48 -0
  9. package/dist/models/device.js.map +1 -0
  10. package/dist/models/featuredList.d.ts +3 -0
  11. package/dist/models/featuredList.js +70 -0
  12. package/dist/models/featuredList.js.map +1 -0
  13. package/dist/models/hardware.d.ts +3 -0
  14. package/dist/models/hardware.js +213 -0
  15. package/dist/models/hardware.js.map +1 -0
  16. package/dist/models/homeConfig.d.ts +3 -0
  17. package/dist/models/homeConfig.js +38 -0
  18. package/dist/models/homeConfig.js.map +1 -0
  19. package/dist/models/oauth.d.ts +3 -0
  20. package/dist/models/oauth.js +48 -0
  21. package/dist/models/oauth.js.map +1 -0
  22. package/dist/models/partner.d.ts +3 -0
  23. package/dist/models/partner.js +165 -0
  24. package/dist/models/partner.js.map +1 -0
  25. package/dist/models/payment.d.ts +3 -0
  26. package/dist/models/payment.js +859 -0
  27. package/dist/models/payment.js.map +1 -0
  28. package/dist/models/pgConfig.d.ts +3 -0
  29. package/dist/models/pgConfig.js +64 -0
  30. package/dist/models/pgConfig.js.map +1 -0
  31. package/dist/models/preset.d.ts +3 -0
  32. package/dist/models/preset.js +802 -0
  33. package/dist/models/preset.js.map +1 -0
  34. package/dist/models/promotion.d.ts +3 -0
  35. package/dist/models/promotion.js +585 -0
  36. package/dist/models/promotion.js.map +1 -0
  37. package/dist/models/redeem.d.ts +3 -0
  38. package/dist/models/redeem.js +26 -0
  39. package/dist/models/redeem.js.map +1 -0
  40. package/dist/models/toneTheme.d.ts +3 -0
  41. package/dist/models/toneTheme.js +29 -0
  42. package/dist/models/toneTheme.js.map +1 -0
  43. package/dist/models/toneThemeFeaturedList.d.ts +3 -0
  44. package/dist/models/toneThemeFeaturedList.js +18 -0
  45. package/dist/models/toneThemeFeaturedList.js.map +1 -0
  46. package/dist/models/user.d.ts +3 -0
  47. package/dist/models/user.js +565 -0
  48. package/dist/models/user.js.map +1 -0
  49. package/dist/models/userTrack.d.ts +3 -0
  50. package/dist/models/userTrack.js +82 -0
  51. package/dist/models/userTrack.js.map +1 -0
  52. package/dist/types/banks.types.d.ts +25 -0
  53. package/dist/types/banks.types.js +3 -0
  54. package/dist/types/banks.types.js.map +1 -0
  55. package/dist/types/device.types.d.ts +41 -0
  56. package/dist/types/device.types.js +3 -0
  57. package/dist/types/device.types.js.map +1 -0
  58. package/dist/types/featuredList.types.d.ts +32 -0
  59. package/dist/types/featuredList.types.js +3 -0
  60. package/dist/types/featuredList.types.js.map +1 -0
  61. package/dist/types/hardware.types.d.ts +123 -0
  62. package/dist/types/hardware.types.js +3 -0
  63. package/dist/types/hardware.types.js.map +1 -0
  64. package/dist/types/homeConfig.types.d.ts +24 -0
  65. package/dist/types/homeConfig.types.js +3 -0
  66. package/dist/types/homeConfig.types.js.map +1 -0
  67. package/dist/types/index.d.ts +17 -0
  68. package/dist/types/index.js +34 -0
  69. package/dist/types/index.js.map +1 -0
  70. package/dist/types/oauth.types.d.ts +38 -0
  71. package/dist/types/oauth.types.js +3 -0
  72. package/dist/types/oauth.types.js.map +1 -0
  73. package/dist/types/partner.types.d.ts +91 -0
  74. package/dist/types/partner.types.js +3 -0
  75. package/dist/types/partner.types.js.map +1 -0
  76. package/dist/types/payment.types.d.ts +304 -0
  77. package/dist/types/payment.types.js +3 -0
  78. package/dist/types/payment.types.js.map +1 -0
  79. package/dist/types/pgConfig.types.d.ts +35 -0
  80. package/dist/types/pgConfig.types.js +3 -0
  81. package/dist/types/pgConfig.types.js.map +1 -0
  82. package/dist/types/preset.types.d.ts +110 -0
  83. package/dist/types/preset.types.js +3 -0
  84. package/dist/types/preset.types.js.map +1 -0
  85. package/dist/types/promotion.types.d.ts +282 -0
  86. package/dist/types/promotion.types.js +3 -0
  87. package/dist/types/promotion.types.js.map +1 -0
  88. package/dist/types/redeem.types.d.ts +16 -0
  89. package/dist/types/redeem.types.js +3 -0
  90. package/dist/types/redeem.types.js.map +1 -0
  91. package/dist/types/toneTheme.types.d.ts +16 -0
  92. package/dist/types/toneTheme.types.js +3 -0
  93. package/dist/types/toneTheme.types.js.map +1 -0
  94. package/dist/types/toneThemeFeaturedList.types.d.ts +9 -0
  95. package/dist/types/toneThemeFeaturedList.types.js +3 -0
  96. package/dist/types/toneThemeFeaturedList.types.js.map +1 -0
  97. package/dist/types/user.types.d.ts +166 -0
  98. package/dist/types/user.types.js +6 -0
  99. package/dist/types/user.types.js.map +1 -0
  100. package/dist/types/userTrack.types.d.ts +39 -0
  101. package/dist/types/userTrack.types.js +12 -0
  102. package/dist/types/userTrack.types.js.map +1 -0
  103. package/package.json +38 -12
  104. package/index.js +0 -28
  105. package/models/banks.js +0 -42
  106. package/models/device.js +0 -51
  107. package/models/featuredList.js +0 -91
  108. package/models/hardware.js +0 -256
  109. package/models/homeConfig.js +0 -86
  110. package/models/oauth.js +0 -52
  111. package/models/partner.js +0 -265
  112. package/models/payment.js +0 -899
  113. package/models/pgConfig.js +0 -88
  114. package/models/preset.js +0 -845
  115. package/models/promotion.js +0 -590
  116. package/models/redeem.js +0 -26
  117. package/models/toneTheme.js +0 -78
  118. package/models/toneThemeFeaturedList.js +0 -49
  119. package/models/user.js +0 -639
  120. package/models/userTrack.js +0 -107
package/models/payment.js DELETED
@@ -1,899 +0,0 @@
1
- 'use strict'
2
-
3
- const _ = require('lodash')
4
- const isSubset = require('is-subset')
5
- const moment = require('moment')
6
- const mongooseLeanVirtuals = require('mongoose-lean-virtuals')
7
- const debug = require('debug')('model:payment')
8
-
9
- // Support OEM redeem to license type
10
- const OEM_FOCUSRITE_SUPPORT_LICENSE = [
11
- { support_type: { product_name: 'live', type: 'lite' }, display_name: 'LE' },
12
- { support_type: { product_name: 'bias', type: 'lite' }, display_name: 'LE' },
13
- { support_type: { product_name: 'amp2', type: 'lite' }, display_name: 'LE' }
14
- ]
15
- const OEM_APOGEE_SUPPORT_LICENSE = [
16
- { support_type: { product_name: 'live', type: 'lite' }, display_name: 'BIAS FX JAM' }
17
- ]
18
- const OEM_PROSONUS_SUPPORT_LICENSE = [
19
- { support_type: { product_name: 'fx2', type: 'lite' }, display_name: 'BIAS FX 2 LE' }
20
- ]
21
-
22
- const _oemMetaToLicenseName = function (redeemMeta) {
23
- let ret
24
- switch (redeemMeta['OEM_Name']) {
25
- case 'focusrite':
26
- ret = _.find(OEM_FOCUSRITE_SUPPORT_LICENSE, (o) => { return isSubset(redeemMeta, o.support_type) })
27
- break
28
- case 'Apogee':
29
- ret = _.find(OEM_APOGEE_SUPPORT_LICENSE, (o) => { return isSubset(redeemMeta, o.support_type) })
30
- break
31
- case 'ProSonus':
32
- ret = _.find(OEM_PROSONUS_SUPPORT_LICENSE, (o) => { return isSubset(redeemMeta, o.support_type) })
33
- break
34
- default:
35
- debug('ERROR:_oemMetaToLicenseName %o', redeemMeta)
36
- return null
37
- }
38
- return (!ret) ? null : { 'oem_name': redeemMeta['OEM_Name'], 'license_name': ret.display_name }
39
- }
40
-
41
- module.exports = (mongoose) => {
42
- const Schema = mongoose.Schema
43
- const ObjectId = Schema.Types.ObjectId
44
-
45
- const ProductSchema = new Schema({
46
- sku: { type: String, required: true, unique: true },
47
- name: { type: String, required: true }, // jamup/bias(AMP1)/live(FX1)/amp2/fx2/pedal/proseries
48
- display_name: { type: String, required: true },
49
- description: { type: String, required: true },
50
- price: { type: Number, default: 0, required: true },
51
- product_type: { type: Number, default: 0, required: true }, // 0:license, 1:pack, 2: dummy, 3: Partner, 4: IAP, 5: redeem(upgrade), 6: hardware
52
- status: { type: Number, default: 1, required: true }, // 0:offline, 1:online, 2:delete
53
- quota: { type: Number, default: 1, required: true },
54
- addition: { type: Number, required: true }, // 0:professional, 1:demo, 2: standard, 3: lite, 4: elite, 5: test
55
- version: { type: String, required: true },
56
- max_purchase: { type: Number },
57
- can_upgrade_addition: { type: Boolean },
58
- can_free_trial: { type: Boolean, default: false },
59
- upgrade: {
60
- to: { type: ObjectId },
61
- price: { type: Number },
62
- description: { type: String }
63
- }, // Remove in the future
64
- upgrade_metadata: [{
65
- to: { type: ObjectId },
66
- price: { type: Number },
67
- description: { type: String }
68
- }],
69
- discount: { type: Schema.Types.Mixed }, // Remove in the future
70
- gift_list: { type: [ObjectId], default: () => { return null } },
71
- require_list: { type: Schema.Types.Mixed, default: null },
72
- require_one_list: [{ type: ObjectId, ref: 'Product' }],
73
- require_one_bundles: [{ type: ObjectId, ref: 'Bundle' }],
74
- free_upgrade_list: [{
75
- has: { type: ObjectId },
76
- to: { type: ObjectId }
77
- }],
78
- remap_product_sku: { type: String },
79
- extra_payment_fields: { type: Schema.Types.Mixed },
80
- created_on: { type: Date, default: Date.now },
81
- updated_on: { type: Date, default: Date.now }
82
- }, { collection: 'jamup_product', toJSON: { virtuals: true }, toObject: { virtuals: true } })
83
- ProductSchema.index({ sku: 1 }, { unique: true })
84
-
85
- const LicenseSchema = new Schema({
86
- user_id: { type: ObjectId, ref: 'User', required: true },
87
- product_id: { type: ObjectId, ref: 'Product', required: true },
88
- bc_order_id: { type: Number, default: null },
89
- bc_coupon: { type: [String], default: () => { return null } },
90
- quota: { type: Number, default: 0 },
91
- from_redeem: { type: String, default: null },
92
- redeem_id: { type: ObjectId, ref: 'RedeemCode' },
93
- from_bundle: { type: ObjectId, ref: 'Bundle', default: null },
94
- from_hardware: { type: ObjectId, ref: 'hardware_activation_record', default: null },
95
- from_gift: { type: ObjectId, ref: 'License', default: null },
96
- from_guest: { type: ObjectId, ref: 'GuestCheckout', default: null },
97
- from_remap: { type: ObjectId, ref: 'Product' },
98
- from_free_trial: { type: ObjectId, ref: 'FreeTrial', default: null },
99
- upgrade_to: { type: ObjectId, ref: 'License', default: null }, // Upgrade from which license
100
- price_amount: { type: Number, default: null },
101
- due_date: { type: Date, default: null },
102
- iap_device_id: { type: String, default: null }, // confirm before remove
103
- iap_source: { type: String, default: null },
104
- metadata: { type: String, default: null }, // Remove in the future
105
- custom_metadata: { type: Schema.Types.Mixed, default: null },
106
- status: { type: Number, default: 1 }, // 1:normal/2:delete/3:refund/4:trial
107
- created_on: { type: Date, default: Date.now },
108
- updated_on: { type: Date, default: Date.now }
109
- }, { collection: 'jamup_license' })
110
- LicenseSchema.index({ iap_device_id: 1, user_id: 1, product_id: 1, status: 1 })
111
- LicenseSchema.index({ user_id: 1, product_id: 1, status: 1, iap_source: 1 })
112
- LicenseSchema.index({ from_redeem: 1, user_id: 1 })
113
- LicenseSchema.index({ user_id: 1, status: 1, due_date: 1, from_free_trial: 1 })
114
- LicenseSchema.set('toJSON', {
115
- virtuals: true,
116
- transform(_doc, ret) {
117
- if (ret.from_free_trial && ret.from_free_trial !== null) {
118
- ret.free_trial_meta = {
119
- is_free_trial: true,
120
- start_date: ret.created_on,
121
- end_date: ret.due_date,
122
- }
123
- } else {
124
- ret.free_trial_meta = null;
125
- }
126
- return ret
127
- }
128
- })
129
- LicenseSchema.set('toObject', {
130
- virtuals: true,
131
- transform(_doc, ret) {
132
- if (ret.from_free_trial && ret.from_free_trial !== null) {
133
- ret.free_trial_meta = {
134
- is_free_trial: true,
135
- start_date: ret.created_on,
136
- end_date: ret.due_date,
137
- }
138
- } else {
139
- ret.free_trial_meta = null;
140
- }
141
- return ret;
142
- }
143
- })
144
-
145
- const LicenseUpgradeMetaSchema = new Schema({
146
- bc_cart_id: { type: String, required: true },
147
- user_id: { type: ObjectId, ref: 'auth_user', required: true },
148
- upgrade_from: { type: ObjectId, ref: 'jamup_product', default: null, required: true },
149
- upgrade_to: { type: ObjectId, ref: 'jamup_product', default: null, required: true },
150
- upgrade_bundle_from: [{ type: ObjectId, ref: 'jamup_product' }],
151
- upgrade_bundle_to: { type: ObjectId, ref: 'jamup_bundle', default: null },
152
- status: { type: Number, default: 0 }, // 0:ReceiveOrder/1:OrderCompleted
153
- created_on: { type: Date, default: Date.now }
154
- }, { collection: 'license_upgrade_meta' })
155
- LicenseUpgradeMetaSchema.index({ bc_cart_id: 1, user_id: 1, upgrade_to: 1, upgrade_from: 1 })
156
- LicenseUpgradeMetaSchema.index({ bc_cart_id: 1, user_id: 1, upgrade_bundle_to: 1 })
157
- LicenseUpgradeMetaSchema.static({
158
- saveUpgradeOrder: async function (bcCartId, userId, upgradeFromProductId, upgradeToProductId) {
159
- try {
160
- const self = this
161
- return await self.findOneAndUpdate({
162
- bc_cart_id: bcCartId,
163
- user_id: userId,
164
- upgrade_from: upgradeFromProductId,
165
- upgrade_to: upgradeToProductId
166
- }, {
167
- '$set': {
168
- bc_cart_id: bcCartId,
169
- user_id: userId,
170
- upgrade_from: upgradeFromProductId,
171
- upgrade_to: upgradeToProductId,
172
- status: 0,
173
- created_on: new Date()
174
- }
175
- }, { upsert: true }).exec()
176
- } catch (err) {
177
- debug('ERR:saveUpgradeOrder:%o', err)
178
- throw err
179
- }
180
- },
181
- saveBundleUpgradeOrder: async function (bcCartId, userId, userOwnedProductIds, upgradeToBundleId) {
182
- try {
183
- const self = this
184
- return await self.findOneAndUpdate({
185
- bc_cart_id: bcCartId,
186
- user_id: userId,
187
- upgrade_bundle_to: upgradeToBundleId
188
- }, {
189
- '$set': {
190
- bc_cart_id: bcCartId,
191
- user_id: userId,
192
- upgrade_bundle_to: upgradeToBundleId,
193
- upgrade_bundle_from: userOwnedProductIds,
194
- status: 0,
195
- created_on: new Date()
196
- }
197
- }, { upsert: true }).exec()
198
- } catch (err) {
199
- debug('ERR:saveBundleUpgradeOrder:%o', err)
200
- throw err
201
- }
202
- },
203
- updateLicenseUpgradeStatusIfExist: async function (bcCartId, userId, targetProductId) {
204
- try {
205
- const self = this
206
- const ret = await self
207
- .aggregate()
208
- .match({
209
- bc_cart_id: bcCartId,
210
- user_id: userId,
211
- upgrade_to: targetProductId
212
- })
213
- .lookup({
214
- from: 'auth_user',
215
- localField: 'user_id',
216
- foreignField: '_id',
217
- as: 'user'
218
- })
219
- .unwind('user')
220
- .lookup({
221
- from: 'jamup_product',
222
- localField: 'upgrade_from',
223
- foreignField: '_id',
224
- as: 'from'
225
- })
226
- .unwind('from')
227
- .lookup({
228
- from: 'jamup_product',
229
- localField: 'upgrade_to',
230
- foreignField: '_id',
231
- as: 'to'
232
- })
233
- .unwind('to')
234
- .exec()
235
-
236
- debug('INFO:updateLicenseUpgradeStatusIfExist:%o:%o:%o:%o', ret, bcCartId, userId, targetProductId)
237
- if (ret.length === 1) {
238
- await self.findOneAndUpdate({
239
- bc_cart_id: bcCartId,
240
- user_id: userId,
241
- upgrade_to: targetProductId
242
- }, {
243
- '$set': {
244
- status: 1
245
- }
246
- }).exec()
247
- return ret[0]
248
- } else {
249
- return true
250
- }
251
- } catch (err) {
252
- debug('ERR:updateLicenseUpgradeStatusIfExist:%o', err)
253
- throw err
254
- }
255
- },
256
- updateBundleUpgradeStatusIfExist: async function (bcCartId, userId, targetBundleId) {
257
- try {
258
- const self = this
259
- const ret = await self.findOne({
260
- bc_cart_id: bcCartId,
261
- user_id: userId,
262
- upgrade_bundle_to: targetBundleId
263
- }).exec()
264
-
265
- debug('INFO:updateLicenseUpgradeStatusIfExist:%o:%o:%o:%o', ret, bcCartId, userId, targetBundleId)
266
- if (ret) {
267
- await self.findOneAndUpdate({
268
- bc_cart_id: bcCartId,
269
- user_id: userId,
270
- upgrade_bundle_to: targetBundleId
271
- }, {
272
- '$set': {
273
- status: 1
274
- }
275
- }).exec()
276
- }
277
-
278
- return true
279
- } catch (err) {
280
- debug('ERR:updateBundleUpgradeStatusIfExist:%o', err)
281
- throw err
282
- }
283
- }
284
- })
285
-
286
-
287
- let BundleSchema = new Schema({
288
- name: { type: String, required: true },
289
- display_name: { type: String, required: true },
290
- display_detail: { type: String, default: null },
291
- description: { type: Array, required: true },
292
- price: { type: Number, default: 0, required: true },
293
- sku: { type: String, default: null },
294
- products: [{ type: ObjectId, ref: 'Product' }], // Array of product Id
295
- validate_list: [{ type: ObjectId, ref: 'Product' }], // Verify does user can purchase bundle or not
296
- discount: { type: Schema.Types.Mixed },
297
- partial_purchase: [{
298
- product_id: { type: Schema.Types.Mixed },
299
- exclude_product_ids: [{ type: ObjectId, ref: 'Product' }], // only works when discount_type == 'exclude'
300
- discount_price: { type: Number },
301
- discount_type: { type: String } // amount, max, exclude
302
- }],
303
- require_list: { type: Schema.Types.Mixed, default: null },
304
- require_one_list: { type: Schema.Types.Mixed, default: null },
305
- extra_payment_fields: { type: Schema.Types.Mixed, default: null },
306
- status: { type: Number, default: 1, required: true }, // 0:offline, 1:online, 2:delete
307
- created_on: { type: Date, default: Date.now },
308
- updated_on: { type: Date, default: Date.now }
309
- }, { collection: 'jamup_bundle', toJSON: { virtuals: true }, toObject: { virtuals: true } })
310
-
311
- let DiscountSchema = new Schema({
312
- own_product: { type: ObjectId, ref: 'Product', required: true },
313
- discount_product: { type: ObjectId, ref: 'Product' },
314
- discount_bundle: { type: ObjectId, ref: 'Bundle' },
315
- discount_type: { type: String, required: true }, // amount, percent, overwrite
316
- discount_amount: { type: Number, required: true },
317
- start_date: { type: Date, default: null },
318
- end_date: { type: Date, default: null },
319
- status: { type: Boolean, default: true },
320
- created_on: { type: Date, default: Date.now }
321
- }, { collection: 'jamup_discount', toJSON: { virtuals: true }, toObject: { virtuals: true } })
322
-
323
- const EduDomainSchema = new Schema({
324
- domain: { type: String, required: true },
325
- name: { type: String, required: true },
326
- status: { type: Number, default: 1 }
327
- }, { collection: 'edu_domain' })
328
- EduDomainSchema.index({ domain: 1 }, { unique: true })
329
-
330
- const EduUserSchema = new Schema({
331
- edu_domain_id: { type: ObjectId, ref: 'edu_domain', required: false },
332
- user_id: { type: ObjectId, ref: 'auth_user', required: true },
333
- edu_email: { type: String, required: true },
334
- verify_token: { type: String, default: null },
335
- university_field: { type: String, default: null },
336
- coupon: { type: String, default: null },
337
- status: { type: Number, default: 0, required: true }, // 0:pending/1:verified-and-delivery
338
- created_on: { type: Date, default: Date.now, required: true }
339
- }, { collection: 'edu_user' })
340
-
341
- const GuestCheckoutSchema = new Schema({
342
- email: { type: String, required: true },
343
- status: { type: Number, default: 1, required: true }, // 1:Wait for Binding/2: Bind to target account/3: Error/4: Refund
344
- bc_order_id: { type: Number, default: null },
345
- user_id: { type: ObjectId, ref: 'User', default: null },
346
- purchased_items: [{
347
- sku: { type: String, required: true },
348
- number: { type: Number, default: 1, required: true }
349
- }],
350
- store_code: { type: String },
351
- created_on: { type: Date, default: Date.now, required: true },
352
- updated_on: { type: Date, default: Date.now, required: true }
353
- }, { collection: 'pg_guest_checkout' })
354
- GuestCheckoutSchema.index({ email: 1, bc_order_id: 1 }, { unique: true })
355
-
356
- // additional_purchase.rule:
357
- // "has": Buyer need to own the main product
358
- // "1to1": Additional purchase and main product should be 1:1
359
- // -----
360
- // additional_purchase.discount_type:
361
- // "amount"/"percent"
362
- const AdditionalPurchaseSchema = new Schema({
363
- main_product_sku: [{ type: String, required: true }],
364
- rule: { type: String, default: 'has' }, //1by1/purchasable/licensePurchasable
365
- category: { type: String, default: null },
366
- multiplier: { type: Number, default: 1 },
367
- additional_purchase: {
368
- sku: { type: String, required: true },
369
- disount_type: { type: String, default: 'amount' },
370
- disount_price: { type: Number, required: true }
371
- },
372
- include_country: [{type: String}],
373
- exclude_country: [{type: String}],
374
- status: { type: Number, default: 1 },
375
- created_on: { type: Date, default: Date.now }
376
- }, { collection: 'additional_purchase_meta' })
377
- AdditionalPurchaseSchema.index({ main_product_sku: 1 })
378
- AdditionalPurchaseSchema.index({ 'additional_purchase.sku': 1 })
379
- AdditionalPurchaseSchema.index({ 'include_country': 1 })
380
- AdditionalPurchaseSchema.index({ 'exclude_country': 1 })
381
- AdditionalPurchaseSchema.static({
382
- canPurchaseAdditional: async function (ownedSku, additionalSku) {
383
- if (!_.isArray(ownedSku) || !_.isArray(additionalSku)) {
384
- throw new Error('Invalid parameter format!')
385
- }
386
-
387
- const additionalPurchaseData = await this.find({
388
- 'additional_purchase.sku': { $in: additionalSku },
389
- status: 1
390
- }).exec()
391
- if (additionalPurchaseData.length <= 0) {
392
- return true
393
- }
394
-
395
- let canPurchase = false
396
- _.forEach(additionalPurchaseData, addition => {
397
- if (addition.rule === 'has') {
398
- const compare = _.difference(ownedSku, addition.main_product_sku)
399
- if (compare.length < ownedSku.length) {
400
- canPurchase = true
401
- }
402
- }
403
- })
404
-
405
- return canPurchase
406
- },
407
- verifyAdditionalPurchase: async function (skus) {
408
- const hasAdditionalPurchase = await this.find({
409
- 'additional_purchase.sku': { $in: skus },
410
- status: 1
411
- }).lean().exec()
412
- if (hasAdditionalPurchase.length <= 0) {
413
- return true
414
- }
415
-
416
- // All matching additional purchase should fit the rule
417
- let hasFulfill = true
418
- _.forEach(hasAdditionalPurchase, addition => {
419
- if (addition.rule === 'has') {
420
- const mainSkus = addition.main_product_sku
421
- const compare = _.difference(mainSkus, skus)
422
- if (compare.length >= mainSkus.length) {
423
- hasFulfill = false
424
- }
425
- }
426
- })
427
-
428
- return hasFulfill
429
- }
430
- })
431
-
432
- const CnSalesMetaSchema = new Schema({
433
- product_id: { type: ObjectId, ref: 'Product', required: true },
434
- status: { type: Number, default: 1, required: true }, // 1: active/2: inactive
435
- price: { type: Number, required: true },
436
- discount: { type: Number, default: null },
437
- gift: { type: [ObjectId], default: () => { return null } },
438
- date: { type: Date, default: Date.now }
439
- }, { collection: 'cn_sales_meta' })
440
- CnSalesMetaSchema.static({
441
- getAllSaleItems: async function (query = {}) {
442
- try {
443
- const queryCondition = (_.isObject(query) && _.isEmpty(query)) ? { status: 1 } : query
444
- const result = await this.aggregate()
445
- .match(queryCondition)
446
- .lookup({
447
- 'from': 'jamup_product',
448
- 'localField': 'product_id',
449
- 'foreignField': '_id',
450
- 'as': 'product'
451
- })
452
- .unwind('$product')
453
- .project({
454
- project_id: 1,
455
- price: 1,
456
- discount: 1,
457
- cn_price: {
458
- '$cond': {
459
- if: { '$ne': ['$discount', null] },
460
- then: { '$multiply': ['$discount', 7] },
461
- else: { '$multiply': ['$price', 7] }
462
- }
463
- },
464
- date: 1,
465
- product: {
466
- _id: 1,
467
- name: 1,
468
- display_name: 1,
469
- sku: 1
470
- }
471
- })
472
- .exec()
473
- return result
474
- } catch (err) {
475
- debug('ERR:getAllSaleItems:%o', err)
476
- throw err
477
- }
478
- }
479
- })
480
-
481
- const CnCouponSchema = new Schema({
482
- code: { type: String, unique: true, required: true },
483
- user_id: { type: ObjectId, ref: 'auth_user', required: false },
484
- stripe_order_id: { type: String, required: false }, // This is for CN only; Stripe is used; Only written when multiple_use = False
485
- multiple_use: { type: Boolean, required: false },
486
- value: {
487
- type: Number,
488
- required: function () { return !this.ratio }
489
- },
490
- ratio: {
491
- type: Number,
492
- required: function () { return !this.value }
493
- },
494
- type: { type: Number, default: 1, required: true }, // 1:normal/2:allowPromotion
495
- status: { type: Number, default: 1, required: true }, // 1:valid/2:used
496
- created_on: { type: Date, default: Date.now },
497
- expired_on: { type: Date, required: false }
498
- }, { collection: 'cn_coupon' })
499
- CnCouponSchema.static({
500
- createCoupon: async function ({ value, user }) {
501
- const generateCnCouponCode = async function () {
502
- const code = 'PGCN' + Math.random().toString(36).substr(2, 10).toUpperCase()
503
- if (await this.findOne({ code }).exec()) {
504
- return generateCnCouponCode()
505
- }
506
- return code
507
- }.bind(this)
508
- try {
509
- if (!value) {
510
- throw new Error('No value provided')
511
- }
512
- const result = await this.create({
513
- code: generateCnCouponCode(),
514
- user_id: user ? user._id : null,
515
- value
516
- })
517
- return result
518
- } catch (err) {
519
- debug('ERR:CnCoupon:createCoupon:%o', err)
520
- throw err
521
- }
522
- },
523
- findCoupon: async function (code) {
524
- const result = await this.findOne({
525
- code,
526
- stripe_order_id: { '$exists': false },
527
- '$or': [
528
- { expired_on: { '$gte': new Date() } },
529
- { expired_on: null },
530
- { expired_on: { '$exists': false } }
531
- ]
532
- }).exec()
533
- return result
534
- }
535
- })
536
- CnCouponSchema.methods.calculateFinalPrice = function (price) {
537
- return this.value ? price - this.value : parseFloat(price * this.ratio).toPrecision(4)
538
- }
539
- CnCouponSchema.methods.calculateDeducted = function (price) {
540
- return this.value ? this.value : price - parseFloat(price * this.ratio).toPrecision(4)
541
- }
542
- CnCouponSchema.methods.consumeCoupon = async function ({ orderId }) {
543
- if (!this.multiple_use) {
544
- this.stripe_order_id = orderId
545
- return this.save()
546
- }
547
- }
548
-
549
-
550
- const BcCartUpdateStatusSchema = new Schema({
551
- bc_cart_id: { type: String, required: true },
552
- cart_item_id: { type: String, required: true },
553
- status: { type: Number, default: 1 }, //1:process/2:finish/3:error
554
- created_on: { type: Date, default: Date.now }
555
- }, { collection: 'bc_cart_update_status' })
556
- BcCartUpdateStatusSchema.static({
557
- initCartUpdate: async function (cartId, itemId) {
558
- return this.findOneAndUpdate({
559
- bc_cart_id: cartId,
560
- cart_item_id: itemId
561
- }, {
562
- $set: {
563
- bc_cart_id: cartId,
564
- cart_item_id: itemId,
565
- status: 1,
566
- created_on: new Date()
567
- }
568
- }, { upsert: true }).exec()
569
- },
570
- finishCartUpdate: async function (cartId, itemId) {
571
- return this.findOneAndUpdate({
572
- bc_cart_id: cartId,
573
- cart_item_id: itemId
574
- }, {
575
- $set: {
576
- status: 2
577
- }
578
- }).exec()
579
- },
580
- handleCartUpdateError: async function (cartId, itemId) {
581
- return this.findOneAndUpdate({
582
- bc_cart_id: cartId,
583
- cart_item_id: itemId
584
- }, {
585
- $set: {
586
- status: 3
587
- }
588
- }).exec()
589
- }
590
- })
591
-
592
- const PgUserOrderSchema = new mongoose.Schema({
593
- orderId: { type: Number, required: true },
594
- customerId: { type: Number },
595
- statusId: { type: Number },
596
- country: { type: String },
597
- totalPrice: { type: Number },
598
- purchaseItems: [{
599
- sku: { type: String },
600
- name: { type: String },
601
- quantity: { type: Number },
602
- price: { type: Number }
603
- }],
604
- orderData: { type: Schema.Types.Mixed },
605
- createdAt: { type: Date, default: Date.now },
606
- updatedAt: { type: Date, default: Date.now }
607
- }, { collection: 'pg_user_orders' })
608
- PgUserOrderSchema.index({ orderId: 1 })
609
- PgUserOrderSchema.index({
610
- statusId: 1,
611
- 'purchaseItems.sku': 1
612
- })
613
-
614
- ProductSchema.static({
615
- getProductsByCondition: function (condition, cb) {
616
- var query = condition || {}
617
- this.find(query).sort({ created_on: -1 }).exec(cb)
618
- },
619
- createProduct: function (data, cb) {
620
- this.create(data, function (err, product) {
621
- cb(err, product)
622
- })
623
- }
624
- })
625
-
626
- LicenseSchema.static({
627
- hasLicenseOrNot: function (userId, productId, cb) {
628
- this.findOne({
629
- user_id: userId,
630
- product_id: productId,
631
- status: 1
632
- }, function (err, license) {
633
- if (err) {
634
- return cb(err)
635
- } else if (license) {
636
- return cb(new Error('User already owned this license'))
637
- } else {
638
- return cb(null)
639
- }
640
- })
641
- },
642
- hasLicensePromise: async function (userID, productID) {
643
- const hasProduct = await this.findOne({
644
- user_id: userID,
645
- product_id: productID,
646
- status: 1,
647
- '$or': [{ 'due_date': null }, { 'due_date': { $gt: new Date() } }]
648
- }).exec()
649
- return (hasProduct)
650
- },
651
- getLicenseByRedeem: function (redeem, cb) {
652
- this.find({ from_redeem: redeem }).sort({ created_on: -1 }).exec(cb)
653
- },
654
- getLicenseByRedeemPromise: async function (redeem, userID) {
655
- const output = await this.find({ from_redeem: redeem, user_id: mongoose.Types.ObjectId(userID) })
656
- .sort({ created_on: -1 })
657
- .populate('product_id')
658
- .exec()
659
- return output
660
- },
661
- // Include normal & trial licenses
662
- getUserLicense: function (query, cb) {
663
- if (!_.isObject(query)) {
664
- return cb(Error('Given query params should be a object'))
665
- }
666
-
667
- const queryObj = _.assign({}, query, {
668
- status: { '$in': [1, 4] },
669
- '$or': [{ 'due_date': null }, { 'due_date': { $gt: new Date() } }]
670
- })
671
-
672
- this.find(queryObj)
673
- .sort({ created_on: -1 })
674
- .populate('product_id', 'id name price product_type status version addition extra_payment_fields')
675
- .exec(function (err, licenses) {
676
- if (err) return cb(err)
677
- if (Array.isArray(licenses) === false) return cb(new Error('Invalid data format'))
678
-
679
- let result = []
680
- licenses.forEach((item) => {
681
- if (item.product_id) {
682
- result.push(item)
683
- } else {
684
- debug('getUserLicense:Invalid', item)
685
- }
686
- })
687
-
688
- debug('getUserLicense:Return', result)
689
- return cb(null, result)
690
- })
691
- },
692
- // Include normal & trial licenses
693
- getUserLicensePromise: async function (query) {
694
- try {
695
- if (!_.isObject(query)) {
696
- throw new Error('Given query params should be a object')
697
- }
698
-
699
- const queryObj = _.assign({}, query, {
700
- status: { '$in': [1, 4] },
701
- '$or': [{ 'due_date': null }, { 'due_date': { $gt: new Date() } }]
702
- })
703
-
704
- const licenseData = await this.find(queryObj)
705
- .sort({ created_on: -1 })
706
- .populate('product_id', 'id name price product_type status version addition extra_payment_fields')
707
- .exec()
708
-
709
- if (!_.isArray(licenseData)) {
710
- throw new Error('Invalid license data')
711
- }
712
-
713
- let result = []
714
- licenseData.forEach(item => {
715
- if (item.product_id) {
716
- result.push(item)
717
- } else {
718
- debug('getUserLicense:Invalid', item)
719
- }
720
- })
721
-
722
- debug('getUserLicense:Return', result)
723
- return result
724
- } catch (err) {
725
- throw err
726
- }
727
- },
728
- // Include normal & trial licenses
729
- getUserPurchase: function (query, productType, cb) {
730
- if (!_.isObject(query)) {
731
- return cb(Error('Given query params should be a object'))
732
- }
733
-
734
- let populateProductList = (productType === 'pack')
735
- ? 'id name product_type display_name extra_payment_fields created_on'
736
- : 'id name price product_type display_name status version addition'
737
-
738
- const queryObj = _.assign({}, query, {
739
- status: { '$in': [1, 4] },
740
- '$or': [{ 'due_date': null }, { 'due_date': { $gt: new Date() } }]
741
- })
742
-
743
- this.find(queryObj)
744
- .sort({ created_on: -1 })
745
- .populate('product_id', populateProductList)
746
- .exec(cb)
747
- },
748
- // Include normal & trial licenses
749
- getUserPurchasePromise: async function (query, productType, opts) {
750
- try {
751
- if (!_.isObject(query)) {
752
- throw new Error('Given query params should be a object')
753
- }
754
-
755
- let populateProductList = (productType === 'pack')
756
- ? 'id name sku product_type display_name extra_payment_fields created_on'
757
- : 'id name sku product_type display_name addition created_on'
758
-
759
- const freeTrialQuery = (productType === 'free_trial')
760
- ? { $and: [{ from_free_trial: { $ne: null } }, { from_free_trial: { $exists: true } }] }
761
- : { $or: [{ from_free_trial: null }, { from_free_trial: { $exists: false } }] }
762
-
763
- // Always check license status & due_date
764
- const queryObj = _.assign({}, {
765
- status: { '$in': [1, 4] },
766
- '$or': [{ 'due_date': null }, { 'due_date': { $gt: new Date() } }]
767
- }, freeTrialQuery, query)
768
- debug('getUserPurchasePromise %o', queryObj)
769
-
770
- const result = (_.has(opts, 'isLean') && opts.isLean === true)
771
- ? await this.find(queryObj)
772
- .sort({ created_on: -1 })
773
- .populate('product_id', populateProductList)
774
- .lean({ virtuals: true })
775
- .exec()
776
- : await this.find(queryObj)
777
- .sort({ created_on: -1 })
778
- .populate('product_id', populateProductList)
779
- .exec()
780
-
781
- debug('getUserPurchasePromise %o', result)
782
- return result
783
- } catch (err) {
784
- throw err
785
- }
786
- },
787
- getUserIapLicenses: async function (userId, iapIds) {
788
- try {
789
- return this.aggregate([
790
- {
791
- '$match': {
792
- 'user_id': userId,
793
- 'product_id': { '$in': iapIds },
794
- 'status': 1,
795
- '$or': [{ 'due_date': null }, { 'due_date': { $gt: new Date() } }]
796
- }
797
- },
798
- {
799
- '$lookup': {
800
- 'from': 'jamup_product',
801
- 'localField': 'product_id',
802
- 'foreignField': '_id',
803
- 'as': 'product'
804
- }
805
- },
806
- { '$unwind': '$product' },
807
- {
808
- '$project': {
809
- 'main_product': '$product.extra_payment_fields.main_product',
810
- 'iap_id': '$product.extra_payment_fields.iap_id',
811
- 'category': '$product.extra_payment_fields.category',
812
- 'display_name': '$product.display_name',
813
- 'user_id': '$user_id',
814
- 'source': '$iap_source',
815
- 'created_on': '$created_on'
816
- }
817
- }
818
- ]).exec()
819
- } catch (err) {
820
- debug('ERR:getUserIapLicenses %o', err)
821
- throw err
822
- }
823
- },
824
- createTrialLicense: async function (data) {
825
- try {
826
- if (!_.has(data, 'due_date') || !moment(data.due_date).isValid()) {
827
- throw new Error('Invalid trail license format!')
828
- }
829
-
830
- const ret = await this.create(_.assign({}, data, {
831
- 'status': 4,
832
- 'due_date': moment(data.due_date).toDate()
833
- }))
834
- return ret
835
- } catch (err) {
836
- debug('ERR:createTrialLicense:%o', err)
837
- throw err
838
- }
839
- },
840
- createLicense: function (data, cb) {
841
- var that = this
842
- that.create(data, function (err, license) {
843
- if (err) return cb(err)
844
-
845
- that.findById(license.id).populate('product_id').exec(cb)
846
- })
847
- },
848
- createLicensePromise: async function (data) {
849
- try {
850
- const newLicense = await this.create(data)
851
- return await this.findById(newLicense.id).populate('product_id').exec()
852
- } catch (err) {
853
- debug('ERR:createLicensePromise:%o', err)
854
- throw err
855
- }
856
- },
857
- removeLicense: function (licenseID) {
858
- return this
859
- .findOneAndUpdate({ _id: licenseID }, { $set: { status: 2 } })
860
- .exec()
861
- }
862
- })
863
- ProductSchema.virtual('id').get(function () {
864
- return this._id.toHexString()
865
- })
866
-
867
- LicenseSchema.virtual('id').get(function () {
868
- return this._id.toHexString()
869
- })
870
- LicenseSchema.virtual('product').get(function () {
871
- return this.product_id
872
- })
873
- LicenseSchema.virtual('oem').get(function () {
874
- return (this.custom_metadata && this.custom_metadata['OEM_Name'])
875
- ? _oemMetaToLicenseName(this.custom_metadata)
876
- : null
877
- })
878
- BundleSchema.virtual('id').get(function () {
879
- return this._id.toHexString()
880
- })
881
- DiscountSchema.virtual('id').get(function () {
882
- return this._id.toHexString()
883
- })
884
- LicenseSchema.plugin(mongooseLeanVirtuals)
885
-
886
- mongoose.model('Product', ProductSchema)
887
- mongoose.model('License', LicenseSchema)
888
- mongoose.model('LicenseUpgradeMeta', LicenseUpgradeMetaSchema)
889
- mongoose.model('Bundle', BundleSchema)
890
- mongoose.model('Discount', DiscountSchema)
891
- mongoose.model('EduDomain', EduDomainSchema)
892
- mongoose.model('EduUser', EduUserSchema)
893
- mongoose.model('GuestCheckout', GuestCheckoutSchema)
894
- mongoose.model('CnCoupon', CnCouponSchema)
895
- mongoose.model('CnSalesMeta', CnSalesMetaSchema)
896
- mongoose.model('AdditionalPurchase', AdditionalPurchaseSchema)
897
- mongoose.model('BcCartUpdateStatus', BcCartUpdateStatusSchema)
898
- mongoose.model('UserOrder', PgUserOrderSchema)
899
- }