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