shufflecom-calculations 1.12.18 → 1.12.21

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.
@@ -18,7 +18,7 @@ describe('VipBonusUtils', () => {
18
18
  const expiryPerOccurrence = 5 * 60;
19
19
  const firstOccurrenceActivationPeriod = 5;
20
20
  const occurrence = 4;
21
- const bonusClaims: VipBonusIssuanceModel[] = []
21
+ const bonusClaims: VipBonusIssuanceModel[] = [];
22
22
 
23
23
  const vipBonus: VipBonusPartial = {
24
24
  type: VipBonusType.RELOADED,
@@ -28,56 +28,63 @@ describe('VipBonusUtils', () => {
28
28
  occurrence,
29
29
  cancelledAt: null,
30
30
  createdAt: startDate.toISOString(),
31
- endAt: startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence * occurrence, 'seconds').toISOString(),
31
+ endAt: startDate
32
+ .add(firstOccurrenceActivationPeriod, 'hours')
33
+ .add(expiryPerOccurrence * occurrence, 'seconds')
34
+ .toISOString(),
32
35
  bonusClaims,
33
36
  firstOccurrenceActivationPeriod,
34
37
  expiryPerOccurrence,
35
- }
38
+ };
36
39
 
37
- let timeNow = startDate
40
+ let timeNow = startDate;
38
41
  mockdatetime(timeNow.toDate());
39
42
 
40
- let issuances = deriveBonusIssuances(vipBonus)
43
+ let issuances = deriveBonusIssuances(vipBonus);
41
44
 
42
- let firstIssuance = issuances[0]
43
- expect(firstIssuance.expiryDate).toEqual(startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString())
44
- expect(firstIssuance.availableDate).toEqual(startDate.toISOString())
45
- expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM)
46
-
47
- let secondIssuance = issuances[1]
48
- expect(secondIssuance.expiryDate).toBeUndefined()
49
- expect(secondIssuance.availableDate).toBeUndefined()
50
- expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED)
45
+ let firstIssuance = issuances[0];
46
+ expect(firstIssuance.expiryDate).toEqual(
47
+ startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString(),
48
+ );
49
+ expect(firstIssuance.availableDate).toEqual(startDate.toISOString());
50
+ expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM);
51
51
 
52
+ let secondIssuance = issuances[1];
53
+ expect(secondIssuance.expiryDate).toBeUndefined();
54
+ expect(secondIssuance.availableDate).toBeUndefined();
55
+ expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
52
56
 
53
57
  // first claim before the activation period ends
54
- timeNow = startDate.add(firstOccurrenceActivationPeriod / 2, 'hours')
55
- mockdatetime(timeNow.toDate())
58
+ timeNow = startDate.add(firstOccurrenceActivationPeriod / 2, 'hours');
59
+ mockdatetime(timeNow.toDate());
56
60
 
57
61
  bonusClaims.push({
58
62
  currency: Currency.BTC,
63
+ amount: '10',
59
64
  bonusAmountUsd: BigNumber(bonusAmountUsd).dividedBy(occurrence).toString(),
60
65
  occurrenceIndex: 1,
61
66
  createdAt: timeNow.toISOString(),
62
- })
63
-
64
- vipBonus.bonusClaims = bonusClaims
67
+ });
65
68
 
66
- issuances = deriveBonusIssuances(vipBonus)
69
+ vipBonus.bonusClaims = bonusClaims;
67
70
 
68
- firstIssuance = issuances[0]
69
- expect(firstIssuance.expiryDate).toEqual(startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString())
70
- expect(firstIssuance.availableDate).toEqual(startDate.toISOString())
71
- expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED)
71
+ issuances = deriveBonusIssuances(vipBonus);
72
72
 
73
- secondIssuance = issuances[1]
74
- expect(secondIssuance.expiryDate).toEqual(timeNow.add(cadence + expiryPerOccurrence, 'seconds').toISOString())
75
- expect(secondIssuance.availableDate).toEqual(timeNow.add(cadence, 'seconds').toISOString())
76
- expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED)
77
- expect(secondIssuance.currency).toEqual(Currency.BTC)
73
+ firstIssuance = issuances[0];
74
+ expect(firstIssuance.expiryDate).toEqual(
75
+ startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString(),
76
+ );
77
+ expect(firstIssuance.availableDate).toEqual(startDate.toISOString());
78
+ expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED);
79
+ expect(firstIssuance.amount).toEqual('10');
78
80
 
79
-
80
- })
81
+ secondIssuance = issuances[1];
82
+ expect(secondIssuance.expiryDate).toEqual(timeNow.add(cadence + expiryPerOccurrence, 'seconds').toISOString());
83
+ expect(secondIssuance.availableDate).toEqual(timeNow.add(cadence, 'seconds').toISOString());
84
+ expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
85
+ expect(secondIssuance.currency).toEqual(Currency.BTC);
86
+ expect(secondIssuance.amount).toEqual(undefined);
87
+ });
81
88
 
82
89
  it('should derive bonus issuance status correctly (first claim after activation period)', () => {
83
90
  const bonusAmountUsd = '100';
@@ -86,7 +93,7 @@ describe('VipBonusUtils', () => {
86
93
  const expiryPerOccurrence = 20 * 60;
87
94
  const firstOccurrenceActivationPeriod = 5;
88
95
  const occurrence = 4;
89
- const bonusClaims: VipBonusIssuanceModel[] = []
96
+ const bonusClaims: VipBonusIssuanceModel[] = [];
90
97
 
91
98
  const vipBonus: VipBonusPartial = {
92
99
  type: VipBonusType.RELOADED,
@@ -96,54 +103,85 @@ describe('VipBonusUtils', () => {
96
103
  occurrence,
97
104
  cancelledAt: null,
98
105
  createdAt: startDate.toISOString(),
99
- endAt: startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence * occurrence, 'seconds').toISOString(),
106
+ endAt: startDate
107
+ .add(firstOccurrenceActivationPeriod, 'hours')
108
+ .add(expiryPerOccurrence * occurrence, 'seconds')
109
+ .toISOString(),
100
110
  bonusClaims,
101
111
  firstOccurrenceActivationPeriod,
102
112
  expiryPerOccurrence,
103
- }
113
+ };
104
114
 
105
- let timeNow = startDate
115
+ let timeNow = startDate;
106
116
  mockdatetime(timeNow.toDate());
107
117
 
108
- let issuances = deriveBonusIssuances(vipBonus)
118
+ let issuances = deriveBonusIssuances(vipBonus);
109
119
 
110
- let firstIssuance = issuances[0]
111
- expect(firstIssuance.expiryDate).toEqual(startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString())
112
- expect(firstIssuance.availableDate).toEqual(startDate.toISOString())
113
- expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM)
114
-
115
- let secondIssuance = issuances[1]
116
- expect(secondIssuance.expiryDate).toBeUndefined()
117
- expect(secondIssuance.availableDate).toBeUndefined()
118
- expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED)
120
+ let firstIssuance = issuances[0];
121
+ expect(firstIssuance.expiryDate).toEqual(
122
+ startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString(),
123
+ );
124
+ expect(firstIssuance.availableDate).toEqual(startDate.toISOString());
125
+ expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM);
119
126
 
127
+ let secondIssuance = issuances[1];
128
+ expect(secondIssuance.expiryDate).toBeUndefined();
129
+ expect(secondIssuance.availableDate).toBeUndefined();
130
+ expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
120
131
 
121
132
  // first claim after the activation period ends
122
- timeNow = startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence / 2, 'seconds')
123
- const activationTime = startDate.add(firstOccurrenceActivationPeriod, 'hours')
124
- mockdatetime(timeNow.toDate())
133
+ timeNow = startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence / 2, 'seconds');
134
+ const activationTime = startDate.add(firstOccurrenceActivationPeriod, 'hours');
135
+ mockdatetime(timeNow.toDate());
125
136
 
126
137
  bonusClaims.push({
127
138
  currency: Currency.BTC,
139
+ amount: '10',
128
140
  bonusAmountUsd: BigNumber(bonusAmountUsd).dividedBy(occurrence).toString(),
129
141
  occurrenceIndex: 1,
130
142
  createdAt: timeNow.toISOString(),
131
- })
132
-
133
- vipBonus.bonusClaims = bonusClaims
134
-
135
- issuances = deriveBonusIssuances(vipBonus)
136
- firstIssuance = issuances[0]
137
- expect(firstIssuance.expiryDate).toEqual(startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString())
138
- expect(firstIssuance.availableDate).toEqual(startDate.toISOString())
139
- expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED)
143
+ });
140
144
 
141
- secondIssuance = issuances[1]
142
- expect(secondIssuance.expiryDate).toEqual(activationTime.add(cadence + expiryPerOccurrence, 'seconds').toISOString())
143
- expect(secondIssuance.availableDate).toEqual(activationTime.add(cadence, 'seconds').toISOString())
144
- expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM)
145
- expect(secondIssuance.currency).toEqual(Currency.BTC)
146
- })
145
+ vipBonus.bonusClaims = bonusClaims;
146
+
147
+ issuances = deriveBonusIssuances(vipBonus);
148
+ firstIssuance = issuances[0];
149
+ expect(firstIssuance.expiryDate).toEqual(
150
+ startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'seconds').toISOString(),
151
+ );
152
+ expect(firstIssuance.availableDate).toEqual(startDate.toISOString());
153
+ expect(firstIssuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED);
154
+ expect(firstIssuance.amount).toEqual('10');
155
+
156
+ secondIssuance = issuances[1];
157
+ expect(secondIssuance.expiryDate).toEqual(activationTime.add(cadence + expiryPerOccurrence, 'seconds').toISOString());
158
+ expect(secondIssuance.availableDate).toEqual(activationTime.add(cadence, 'seconds').toISOString());
159
+ expect(secondIssuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM);
160
+ expect(secondIssuance.currency).toEqual(Currency.BTC);
161
+ expect(secondIssuance.amount).toEqual(undefined);
162
+
163
+ timeNow = startDate.add(firstOccurrenceActivationPeriod, 'hours').add(cadence + 1, 'seconds');
164
+ mockdatetime(timeNow.toDate());
165
+ const bonusClaimNotInOrder = [
166
+ {
167
+ currency: Currency.BTC,
168
+ bonusAmountUsd: BigNumber(bonusAmountUsd).dividedBy(occurrence).toString(),
169
+ occurrenceIndex: 2,
170
+ createdAt: timeNow.toISOString(),
171
+ },
172
+ bonusClaims[0],
173
+ ];
174
+
175
+ vipBonus.bonusClaims = bonusClaimNotInOrder;
176
+ issuances = deriveBonusIssuances(vipBonus);
177
+ firstIssuance = issuances[0];
178
+ expect(firstIssuance.createdAt).toEqual(
179
+ startDate
180
+ .add(firstOccurrenceActivationPeriod, 'hours')
181
+ .add(expiryPerOccurrence / 2, 'seconds')
182
+ .toISOString(),
183
+ );
184
+ });
147
185
 
148
186
  it('should update bonus issuance status correctly sequential vip reload', () => {
149
187
  const vipBonusId = uuidv4();
@@ -156,15 +194,22 @@ describe('VipBonusUtils', () => {
156
194
  const firstOccurrenceActivationPeriod = 0;
157
195
  const occurrence = 10;
158
196
  const claimed = [2, 3];
159
- const activationTime = dayjs(startDate)
197
+ const activationTime = dayjs(startDate);
160
198
 
161
- const issuances = range(1, occurrence + 1).map((occurrenceIndex) => ({
199
+ const issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
162
200
  vipBonusId,
163
201
  userId,
164
202
  currency,
165
203
  bonusAmountUsd,
166
204
  occurrenceIndex,
167
- expiryDate: getReloadExpiryDate(activationTime, cadence, expiryPerOccurrence, occurrenceIndex, startDate, firstOccurrenceActivationPeriod)?.toISOString(),
205
+ expiryDate: getReloadExpiryDate(
206
+ activationTime,
207
+ cadence,
208
+ expiryPerOccurrence,
209
+ occurrenceIndex,
210
+ startDate,
211
+ firstOccurrenceActivationPeriod,
212
+ )?.toISOString(),
168
213
  availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
169
214
  status: claimed.includes(occurrenceIndex) ? VipBonusIssuanceStatus.CLAIMED : null,
170
215
  createdAt: startDate.toISOString(),
@@ -175,7 +220,7 @@ describe('VipBonusUtils', () => {
175
220
 
176
221
  // fast forward into reward 3 claiming interval
177
222
  mockdatetime(startDate.add(cadence * fastForward + 1, 'seconds').toDate());
178
- let updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, null, dayjs()));
223
+ let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
179
224
 
180
225
  updatedStatusList.forEach((issuance, index) => {
181
226
  if (claimed.includes(index + 1)) {
@@ -190,7 +235,7 @@ describe('VipBonusUtils', () => {
190
235
  // fast forward into reward 6 claiming interval
191
236
  fastForward = 5;
192
237
  mockdatetime(startDate.add(cadence * fastForward, 'seconds').toDate());
193
- updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, null, dayjs()));
238
+ updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
194
239
 
195
240
  updatedStatusList.forEach((issuance, index) => {
196
241
  if (claimed.includes(index + 1)) {
@@ -216,27 +261,41 @@ describe('VipBonusUtils', () => {
216
261
  const firstOccurrenceActivationPeriod = 10;
217
262
  const occurrence = 10;
218
263
  let activationTime: Dayjs | null = null; // first one not claimed yet
219
-
220
- let issuances = range(1, occurrence + 1).map((occurrenceIndex) => ({
264
+
265
+ let issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
221
266
  vipBonusId,
222
267
  userId,
223
268
  currency,
224
269
  bonusAmountUsd,
225
270
  occurrenceIndex,
226
- expiryDate: getReloadExpiryDate(activationTime, cadence, expiryPerOccurrence, occurrenceIndex, startDate, firstOccurrenceActivationPeriod)?.toISOString(),
271
+ expiryDate: getReloadExpiryDate(
272
+ activationTime,
273
+ cadence,
274
+ expiryPerOccurrence,
275
+ occurrenceIndex,
276
+ startDate,
277
+ firstOccurrenceActivationPeriod,
278
+ )?.toISOString(),
227
279
  availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
228
280
  status: null as VipBonusIssuanceStatus | null,
229
281
  createdAt: startDate.toISOString(),
230
282
  expiryPerOccurrence,
231
283
  firstOccurrenceActivationPeriod,
232
- }))
284
+ }));
233
285
 
234
286
  // fast forward within first occurrence activation period
235
287
  mockdatetime(startDate.add(firstOccurrenceActivationPeriod / 2, 'hours').toDate());
236
288
  // first issuance has to recalculate based on current time
237
- issuances[0].expiryDate = getReloadExpiryDate(activationTime, cadence, expiryPerOccurrence, 1, startDate, firstOccurrenceActivationPeriod)?.toISOString()
289
+ issuances[0].expiryDate = getReloadExpiryDate(
290
+ activationTime,
291
+ cadence,
292
+ expiryPerOccurrence,
293
+ 1,
294
+ startDate,
295
+ firstOccurrenceActivationPeriod,
296
+ )?.toISOString();
238
297
 
239
- let updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, null, dayjs()));
298
+ let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
240
299
 
241
300
  updatedStatusList.forEach((issuance, index) => {
242
301
  if (index + 1 === 1) {
@@ -244,39 +303,63 @@ describe('VipBonusUtils', () => {
244
303
  } else {
245
304
  expect(issuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
246
305
  }
247
- })
306
+ });
248
307
 
249
308
  // fast forward after first occurrence activation period
250
- mockdatetime(startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence / 2, 'seconds').toDate());
251
- issuances[0].expiryDate = getReloadExpiryDate(activationTime, cadence, expiryPerOccurrence, 1, startDate, firstOccurrenceActivationPeriod)?.toISOString()
252
- updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, null, dayjs()));
309
+ mockdatetime(
310
+ startDate
311
+ .add(firstOccurrenceActivationPeriod, 'hours')
312
+ .add(expiryPerOccurrence / 2, 'seconds')
313
+ .toDate(),
314
+ );
315
+ issuances[0].expiryDate = getReloadExpiryDate(
316
+ activationTime,
317
+ cadence,
318
+ expiryPerOccurrence,
319
+ 1,
320
+ startDate,
321
+ firstOccurrenceActivationPeriod,
322
+ )?.toISOString();
323
+ updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
253
324
 
254
325
  updatedStatusList.forEach((issuance, index) => {
255
- if (index + 1 === 1) {
326
+ if (index + 1 === 1) {
256
327
  expect(issuance.status).toEqual(VipBonusIssuanceStatus.PENDING_CLAIM);
257
328
  } else {
258
329
  expect(issuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
259
330
  }
260
- })
331
+ });
261
332
 
262
333
  // fast forward after expiry
263
- mockdatetime(startDate.add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence + 1, 'seconds').toDate());
264
- activationTime = dayjs(startDate).add(firstOccurrenceActivationPeriod, 'hours')
265
- issuances = range(1, occurrence + 1).map((occurrenceIndex) => ({
334
+ mockdatetime(
335
+ startDate
336
+ .add(firstOccurrenceActivationPeriod, 'hours')
337
+ .add(expiryPerOccurrence + 1, 'seconds')
338
+ .toDate(),
339
+ );
340
+ activationTime = dayjs(startDate).add(firstOccurrenceActivationPeriod, 'hours');
341
+ issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
266
342
  vipBonusId,
267
343
  userId,
268
344
  currency,
269
345
  bonusAmountUsd,
270
346
  occurrenceIndex,
271
- expiryDate: getReloadExpiryDate(activationTime, cadence, expiryPerOccurrence, occurrenceIndex, startDate, firstOccurrenceActivationPeriod)?.toISOString(),
347
+ expiryDate: getReloadExpiryDate(
348
+ activationTime,
349
+ cadence,
350
+ expiryPerOccurrence,
351
+ occurrenceIndex,
352
+ startDate,
353
+ firstOccurrenceActivationPeriod,
354
+ )?.toISOString(),
272
355
  availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
273
356
  status: null as VipBonusIssuanceStatus | null,
274
357
  createdAt: startDate.toISOString(),
275
358
  expiryPerOccurrence,
276
359
  firstOccurrenceActivationPeriod,
277
- }))
360
+ }));
278
361
 
279
- updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, null, dayjs()));
362
+ updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
280
363
 
281
364
  updatedStatusList.forEach((issuance, index) => {
282
365
  if (index + 1 === 1) {
@@ -284,8 +367,8 @@ describe('VipBonusUtils', () => {
284
367
  } else {
285
368
  expect(issuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
286
369
  }
287
- })
288
- })
370
+ });
371
+ });
289
372
 
290
373
  it('should update bonus issuance status correctly for independent vip reload (overlapping vip reloads)', () => {
291
374
  const vipBonusId = uuidv4();
@@ -298,15 +381,22 @@ describe('VipBonusUtils', () => {
298
381
  const firstOccurrenceActivationPeriod = 10;
299
382
  const occurrence = 10;
300
383
  const claimed = [1];
301
- const activationTime = dayjs(startDate).add(5, 'hours') // user claimed within first occurrence activation period
384
+ const activationTime = dayjs(startDate).add(5, 'hours'); // user claimed within first occurrence activation period
302
385
 
303
- const issuances = range(1, occurrence + 1).map((occurrenceIndex) => ({
386
+ const issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
304
387
  vipBonusId,
305
388
  userId,
306
389
  currency,
307
390
  bonusAmountUsd,
308
391
  occurrenceIndex,
309
- expiryDate: getReloadExpiryDate(activationTime, cadence, expiryPerOccurrence, occurrenceIndex, startDate, firstOccurrenceActivationPeriod)?.toISOString(),
392
+ expiryDate: getReloadExpiryDate(
393
+ activationTime,
394
+ cadence,
395
+ expiryPerOccurrence,
396
+ occurrenceIndex,
397
+ startDate,
398
+ firstOccurrenceActivationPeriod,
399
+ )?.toISOString(),
310
400
  availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
311
401
  status: claimed.includes(occurrenceIndex) ? VipBonusIssuanceStatus.CLAIMED : null,
312
402
  createdAt: startDate.toISOString(),
@@ -318,9 +408,9 @@ describe('VipBonusUtils', () => {
318
408
 
319
409
  // fast forward into reward 3 claiming interval
320
410
  mockdatetime(activationTime.add(cadence * fastForward + 1, 'seconds').toDate());
321
- let updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, null, dayjs()));
411
+ let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
322
412
 
323
- let pendingClaims = [2, 3]
413
+ let pendingClaims = [2, 3];
324
414
  updatedStatusList.forEach((issuance, index) => {
325
415
  if (claimed.includes(index + 1)) {
326
416
  expect(issuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED);
@@ -331,14 +421,14 @@ describe('VipBonusUtils', () => {
331
421
  }
332
422
  });
333
423
 
334
- fastForward = 7
424
+ fastForward = 7;
335
425
 
336
426
  // fast forward into reward 8 just after expiry
337
427
  mockdatetime(activationTime.add(cadence * fastForward + expiryPerOccurrence + 1, 'seconds').toDate());
338
- updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, null, dayjs()));
428
+ updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
339
429
 
340
- pendingClaims = [9, 10]
341
- let expired = [ 2, 3, 4, 5, 6, 7, 8]
430
+ pendingClaims = [9, 10];
431
+ const expired = [2, 3, 4, 5, 6, 7, 8];
342
432
  updatedStatusList.forEach((issuance, index) => {
343
433
  if (claimed.includes(index + 1)) {
344
434
  expect(issuance.status).toEqual(VipBonusIssuanceStatus.CLAIMED);
@@ -349,8 +439,8 @@ describe('VipBonusUtils', () => {
349
439
  } else {
350
440
  expect(issuance.status).toEqual(VipBonusIssuanceStatus.SCHEDULED);
351
441
  }
352
- })
353
- })
442
+ });
443
+ });
354
444
 
355
445
  it('should update bonus issuance status correctly for independent vip reload (no overlapping vip reloads', () => {
356
446
  const vipBonusId = uuidv4();
@@ -364,26 +454,33 @@ describe('VipBonusUtils', () => {
364
454
  const occurrence = 10;
365
455
  const claimed = [2, 3];
366
456
  const activationTime = dayjs(startDate).add(firstOccurrenceActivationPeriod, 'hours');
367
-
368
- const issuances = range(1, occurrence + 1).map((occurrenceIndex) => ({
457
+
458
+ const issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
369
459
  vipBonusId,
370
460
  userId,
371
461
  currency,
372
462
  bonusAmountUsd,
373
463
  occurrenceIndex,
374
- expiryDate: getReloadExpiryDate(activationTime, cadence, expiryPerOccurrence, occurrenceIndex, startDate, firstOccurrenceActivationPeriod)?.toISOString(),
464
+ expiryDate: getReloadExpiryDate(
465
+ activationTime,
466
+ cadence,
467
+ expiryPerOccurrence,
468
+ occurrenceIndex,
469
+ startDate,
470
+ firstOccurrenceActivationPeriod,
471
+ )?.toISOString(),
375
472
  availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
376
473
  status: claimed.includes(occurrenceIndex) ? VipBonusIssuanceStatus.CLAIMED : null,
377
474
  createdAt: startDate.toISOString(),
378
475
  expiryPerOccurrence,
379
476
  firstOccurrenceActivationPeriod,
380
- }))
477
+ }));
381
478
 
382
479
  let fastForward = 2;
383
- let pendingClaims = [4, 5, 6, 7, 8, 9, 10]
480
+ let pendingClaims = [4, 5, 6, 7, 8, 9, 10];
384
481
  // fast forward into reward 3 claiming interval
385
482
  mockdatetime(activationTime.add(cadence * fastForward + 1, 'seconds').toDate());
386
- let updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, null, dayjs()));
483
+ let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
387
484
 
388
485
  updatedStatusList.forEach((issuance, index) => {
389
486
  if (claimed.includes(index + 1)) {
@@ -393,14 +490,14 @@ describe('VipBonusUtils', () => {
393
490
  } else {
394
491
  expect(issuance.status).toEqual(VipBonusIssuanceStatus.EXPIRED);
395
492
  }
396
- })
493
+ });
397
494
 
398
- fastForward = 7
399
- pendingClaims = [9, 10]
495
+ fastForward = 7;
496
+ pendingClaims = [9, 10];
400
497
 
401
498
  // fast forward into reward 8 just after expiry
402
499
  mockdatetime(activationTime.add(cadence * fastForward + expiryPerOccurrence + 1, 'seconds').toDate());
403
- updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, null, dayjs()));
500
+ updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, null, dayjs()));
404
501
 
405
502
  updatedStatusList.forEach((issuance, index) => {
406
503
  if (claimed.includes(index + 1)) {
@@ -410,9 +507,9 @@ describe('VipBonusUtils', () => {
410
507
  } else {
411
508
  expect(issuance.status).toEqual(VipBonusIssuanceStatus.EXPIRED);
412
509
  }
413
- })
414
- })
415
-
510
+ });
511
+ });
512
+
416
513
  it('should update bonus issuance status correctly with cancelledAt', () => {
417
514
  const vipBonusId = uuidv4();
418
515
  const userId = uuidv4();
@@ -428,15 +525,22 @@ describe('VipBonusUtils', () => {
428
525
  const cancelledAt = dayjs(startDate)
429
526
  .add(cadence * (cancelledIndex - 1), 'seconds')
430
527
  .toDate();
431
- const activationTime = dayjs(startDate)
528
+ const activationTime = dayjs(startDate);
432
529
 
433
- const issuances = range(1, occurrence + 1).map((occurrenceIndex) => ({
530
+ const issuances = range(1, occurrence + 1).map(occurrenceIndex => ({
434
531
  vipBonusId,
435
532
  userId,
436
533
  currency,
437
534
  bonusAmountUsd,
438
535
  occurrenceIndex,
439
- expiryDate: getReloadExpiryDate(activationTime, cadence, expiryPerOccurrence, occurrenceIndex, startDate, firstOccurrenceActivationPeriod)?.toISOString(),
536
+ expiryDate: getReloadExpiryDate(
537
+ activationTime,
538
+ cadence,
539
+ expiryPerOccurrence,
540
+ occurrenceIndex,
541
+ startDate,
542
+ firstOccurrenceActivationPeriod,
543
+ )?.toISOString(),
440
544
  availableDate: getReloadAvailableDate(activationTime, cadence, occurrenceIndex, startDate)?.toISOString(),
441
545
  status: claimed.includes(occurrenceIndex) ? VipBonusIssuanceStatus.CLAIMED : null,
442
546
  createdAt: startDate.toISOString(),
@@ -447,7 +551,7 @@ describe('VipBonusUtils', () => {
447
551
  // fast forward into reward 7 claiming interval
448
552
  let fastForward = 6;
449
553
  mockdatetime(startDate.add(cadence * fastForward, 'seconds').toDate());
450
- let updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, cancelledAt, dayjs()));
554
+ let updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, cancelledAt, dayjs()));
451
555
 
452
556
  updatedStatusList.forEach((issuance, index) => {
453
557
  if (claimed.includes(index + 1)) {
@@ -464,7 +568,7 @@ describe('VipBonusUtils', () => {
464
568
  // fast forward into reward 8 claiming interval
465
569
  fastForward = 7;
466
570
  mockdatetime(startDate.add(cadence * fastForward, 'seconds').toDate());
467
- updatedStatusList = issuances.map((issuance) => updateBonusIssuanceStatus(issuance, cancelledAt, dayjs()));
571
+ updatedStatusList = issuances.map(issuance => updateBonusIssuanceStatus(issuance, cancelledAt, dayjs()));
468
572
 
469
573
  updatedStatusList.forEach((issuance, index) => {
470
574
  if (claimed.includes(index + 1)) {
@@ -21,19 +21,26 @@ export function getReloadAvailableDate(activationTime: Dayjs | null, cadence: nu
21
21
  return activationTime.add(cadence * (index - 1), 'second').toDate();
22
22
  }
23
23
 
24
- export function getReloadExpiryDate(activationTime: Dayjs | null, cadence: number, expiryPerOccurrence: number, index: number, createdAt: Dayjs, firstOccurrenceActivationPeriod: number) {
24
+ export function getReloadExpiryDate(
25
+ activationTime: Dayjs | null,
26
+ cadence: number,
27
+ expiryPerOccurrence: number,
28
+ index: number,
29
+ createdAt: Dayjs,
30
+ firstOccurrenceActivationPeriod: number,
31
+ ) {
25
32
  const availableDate = getReloadAvailableDate(activationTime, cadence, index, createdAt);
26
33
 
27
34
  if (index === 1) {
28
35
  return dayjs(createdAt).add(firstOccurrenceActivationPeriod, 'hours').add(expiryPerOccurrence, 'second').toDate();
29
36
  }
30
-
37
+
31
38
  if (!availableDate) {
32
- return null
39
+ return null;
33
40
  }
34
41
 
35
42
  const result = dayjs(availableDate).add(expiryPerOccurrence, 'second').toDate();
36
- return result
43
+ return result;
37
44
  }
38
45
 
39
46
  export function deriveBonusIssuances(vipBonus: VipBonusPartial) {
@@ -42,7 +49,7 @@ export function deriveBonusIssuances(vipBonus: VipBonusPartial) {
42
49
  const bonusCreatedAt = dayjs(vipBonus.createdAt);
43
50
  const now = dayjs();
44
51
 
45
- const firstClaim = claims?.find((claim) => claim.occurrenceIndex == 1);
52
+ const firstClaim = claims?.find(claim => claim.occurrenceIndex == 1);
46
53
  let activationTime: Dayjs | null = null;
47
54
  const maxBonusActivationTime = bonusCreatedAt.add(vipBonus.firstOccurrenceActivationPeriod ?? 0, 'hours');
48
55
 
@@ -52,11 +59,18 @@ export function deriveBonusIssuances(vipBonus: VipBonusPartial) {
52
59
  activationTime = maxBonusActivationTime;
53
60
  }
54
61
 
55
- return range(1, vipBonus.occurrence + 1).map((occurrenceIndex) => {
56
- const claim = claims?.find((claim) => claim.occurrenceIndex == occurrenceIndex);
62
+ return range(1, vipBonus.occurrence + 1).map(occurrenceIndex => {
63
+ const claim = claims?.find(claim => claim.occurrenceIndex == occurrenceIndex);
57
64
  const expiryDate =
58
65
  vipBonus.type === VipBonusType.RELOADED
59
- ? getReloadExpiryDate(activationTime, vipBonus.cadence!, vipBonus.expiryPerOccurrence ?? 0, occurrenceIndex, bonusCreatedAt, vipBonus.firstOccurrenceActivationPeriod ?? 0)?.toISOString()
66
+ ? getReloadExpiryDate(
67
+ activationTime,
68
+ vipBonus.cadence!,
69
+ vipBonus.expiryPerOccurrence ?? 0,
70
+ occurrenceIndex,
71
+ bonusCreatedAt,
72
+ vipBonus.firstOccurrenceActivationPeriod ?? 0,
73
+ )?.toISOString()
60
74
  : vipBonus.endAt;
61
75
  const availableDate =
62
76
  vipBonus.type === VipBonusType.RELOADED
@@ -65,18 +79,16 @@ export function deriveBonusIssuances(vipBonus: VipBonusPartial) {
65
79
  return updateBonusIssuanceStatus(
66
80
  {
67
81
  currency,
68
- bonusAmountUsd: new BigNumber(vipBonus.bonusAmountUsd)
69
- .dividedBy(vipBonus.occurrence)
70
- .decimalPlaces(8, BigNumber.ROUND_DOWN)
71
- .toFixed(),
82
+ amount: claim?.amount,
83
+ bonusAmountUsd: new BigNumber(vipBonus.bonusAmountUsd).dividedBy(vipBonus.occurrence).decimalPlaces(8, BigNumber.ROUND_DOWN).toFixed(),
72
84
  occurrenceIndex,
73
85
  expiryDate,
74
86
  availableDate,
75
87
  status: claim ? VipBonusIssuanceStatus.CLAIMED : null,
76
- createdAt: vipBonus.bonusClaims?.[occurrenceIndex - 1]?.createdAt
88
+ createdAt: claim?.createdAt,
77
89
  },
78
90
  vipBonus.cancelledAt ? new Date(vipBonus.cancelledAt) : null,
79
- now
91
+ now,
80
92
  );
81
93
  });
82
94
  }