@@ -6,16 +6,18 @@ import {
6
6
Logger ,
7
7
} from '@nestjs/common' ;
8
8
9
- import { PrismaPromise } from '@prisma/client' ;
9
+ import { Prisma } from '@prisma/client' ;
10
10
import { PrismaService } from 'src/shared/global/prisma.service' ;
11
11
import { PaymentsService } from 'src/shared/payments' ;
12
12
13
- import { TaxFormRepository } from '../repository/taxForm.repo' ;
14
- import { PaymentMethodRepository } from '../repository/paymentMethod.repo' ;
15
13
import { ResponseDto } from 'src/dto/api-response.dto' ;
16
14
import { PaymentStatus } from 'src/dto/payment.dto' ;
17
15
import { WinningAuditDto , AuditPayoutDto } from './dto/audit.dto' ;
18
16
import { WinningUpdateRequestDto } from './dto/winnings.dto' ;
17
+ import {
18
+ AdminPaymentUpdateData ,
19
+ TopcoderChallengesService ,
20
+ } from 'src/shared/topcoder/challenges.service' ;
19
21
20
22
/**
21
23
* The admin winning service.
@@ -30,11 +32,14 @@ export class AdminService {
30
32
*/
31
33
constructor (
32
34
private readonly prisma : PrismaService ,
33
- private readonly taxFormRepo : TaxFormRepository ,
34
- private readonly paymentMethodRepo : PaymentMethodRepository ,
35
35
private readonly paymentsService : PaymentsService ,
36
+ private readonly tcChallengesService : TopcoderChallengesService ,
36
37
) { }
37
38
39
+ private getWinningById ( winningId : string ) {
40
+ return this . prisma . winnings . findFirst ( { where : { winning_id : winningId } } ) ;
41
+ }
42
+
38
43
private getPaymentsByWinningsId ( winningsId : string , paymentId ?: string ) {
39
44
return this . prisma . payment . findMany ( {
40
45
where : {
@@ -79,7 +84,9 @@ export class AdminService {
79
84
releaseDate = await this . getPaymentReleaseDateByWinningsId ( winningsId ) ;
80
85
}
81
86
82
- const transactions : PrismaPromise < any > [ ] = [ ] ;
87
+ const transactions : ( (
88
+ tx : Prisma . TransactionClient ,
89
+ ) => Promise < unknown > ) [ ] = [ ] ;
83
90
const now = new Date ( ) . getTime ( ) ;
84
91
payments . forEach ( ( payment ) => {
85
92
if (
@@ -108,8 +115,8 @@ export class AdminService {
108
115
if ( sinceRelease < 12 ) {
109
116
errMessage = `Cannot put a processing payment back to owed, unless it's been processing for at least 12 hours. Currently it's only been ${ sinceRelease . toFixed ( 1 ) } hours` ;
110
117
} else {
111
- transactions . push (
112
- this . markPaymentReleaseAsFailedByWinningsId ( winningsId ) ,
118
+ transactions . push ( ( tx ) =>
119
+ this . markPaymentReleaseAsFailedByWinningsId ( winningsId , tx ) ,
113
120
) ;
114
121
}
115
122
} else {
@@ -137,30 +144,32 @@ export class AdminService {
137
144
throw new BadRequestException ( errMessage ) ;
138
145
}
139
146
140
- transactions . push (
147
+ transactions . push ( ( tx ) =>
141
148
this . updatePaymentStatus (
142
149
userId ,
143
150
winningsId ,
144
151
payment . payment_id ,
145
152
payment . payment_status ,
146
153
body . paymentStatus ,
147
- version ,
154
+ version ++ ,
155
+ tx ,
148
156
) ,
149
157
) ;
150
- version += 1 ;
158
+
151
159
paymentStatus = body . paymentStatus as PaymentStatus ;
152
160
153
161
if ( body . paymentStatus === PaymentStatus . OWED ) {
154
162
needsReconciliation = true ;
155
163
}
156
164
157
165
if ( payment . installment_number === 1 ) {
158
- transactions . push (
166
+ transactions . push ( ( tx ) =>
159
167
this . addAudit (
160
168
userId ,
161
169
winningsId ,
162
170
`Modified payment status from ${ payment . payment_status } to ${ body . paymentStatus } ` ,
163
171
body . auditNote ,
172
+ tx ,
164
173
) ,
165
174
) ;
166
175
}
@@ -186,24 +195,25 @@ export class AdminService {
186
195
) ;
187
196
}
188
197
189
- transactions . push (
198
+ transactions . push ( ( tx ) =>
190
199
this . updateReleaseDate (
191
200
userId ,
192
201
winningsId ,
193
202
payment . payment_id ,
194
203
newReleaseDate ,
195
- version ,
204
+ version ++ ,
205
+ tx ,
196
206
) ,
197
207
) ;
198
- version += 1 ;
199
208
200
209
if ( payment . installment_number === 1 ) {
201
- transactions . push (
210
+ transactions . push ( ( tx ) =>
202
211
this . addAudit (
203
212
userId ,
204
213
winningsId ,
205
214
`Modified release date from ${ payment . release_date ?. toISOString ( ) } to ${ newReleaseDate . toISOString ( ) } ` ,
206
215
body . auditNote ,
216
+ tx ,
207
217
) ,
208
218
) ;
209
219
}
@@ -218,7 +228,7 @@ export class AdminService {
218
228
) {
219
229
// ideally we should be maintaining the original split of the payment amount between installments - but we aren't really using splits anymore
220
230
if ( payment . installment_number === 1 ) {
221
- transactions . push (
231
+ transactions . push ( ( tx ) =>
222
232
this . updatePaymentAmount (
223
233
userId ,
224
234
winningsId ,
@@ -227,20 +237,22 @@ export class AdminService {
227
237
body . paymentAmount ,
228
238
body . paymentAmount ,
229
239
version ,
240
+ tx ,
230
241
) ,
231
242
) ;
232
243
233
- transactions . push (
244
+ transactions . push ( ( tx ) =>
234
245
this . addAudit (
235
246
userId ,
236
247
winningsId ,
237
248
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
238
249
`Modified payment amount from ${ payment . total_amount } to ${ body . paymentAmount . toFixed ( 2 ) } ` ,
239
250
body . auditNote ,
251
+ tx ,
240
252
) ,
241
253
) ;
242
254
} else {
243
- transactions . push (
255
+ transactions . push ( ( tx ) =>
244
256
this . updatePaymentAmount (
245
257
userId ,
246
258
winningsId ,
@@ -249,15 +261,43 @@ export class AdminService {
249
261
0 ,
250
262
body . paymentAmount ,
251
263
version ,
264
+ tx ,
252
265
) ,
253
266
) ;
254
267
}
255
268
}
256
269
} ) ;
257
270
258
- if ( transactions . length > 0 ) {
259
- await this . prisma . $transaction ( transactions ) ;
260
- }
271
+ transactions . push ( async ( ) => {
272
+ const winning = await this . getWinningById ( winningsId ) ;
273
+ if ( ! winning ) {
274
+ this . logger . error (
275
+ `Error updating legacy system for winning ${ winningsId } . Winning not found!` ,
276
+ ) ;
277
+ throw new Error (
278
+ `Error updating legacy system for winning ${ winningsId } . Winning not found!` ,
279
+ ) ;
280
+ }
281
+
282
+ const payoutData : AdminPaymentUpdateData = {
283
+ userId : + winning . winner_id ,
284
+ status : body . paymentStatus ,
285
+ amount : body . paymentAmount ,
286
+ releaseDate : body . releaseDate ,
287
+ } ;
288
+
289
+ await this . tcChallengesService . updateLegacyPayments (
290
+ winning . external_id as string ,
291
+ payoutData ,
292
+ ) ;
293
+ } ) ;
294
+
295
+ // Run all transaction tasks in a single prisma transaction
296
+ await this . prisma . $transaction ( async ( tx ) => {
297
+ for ( const transaction of transactions ) {
298
+ await transaction ( tx ) ;
299
+ }
300
+ } ) ;
261
301
262
302
if ( needsReconciliation ) {
263
303
const winning = await this . prisma . winnings . findFirst ( {
@@ -320,8 +360,11 @@ export class AdminService {
320
360
return paymentReleases ?. release_date ;
321
361
}
322
362
323
- private markPaymentReleaseAsFailedByWinningsId ( winningsId : string ) {
324
- return this . prisma . payment_releases . updateMany ( {
363
+ private markPaymentReleaseAsFailedByWinningsId (
364
+ winningsId : string ,
365
+ tx ?: Prisma . TransactionClient ,
366
+ ) {
367
+ return ( tx ?? this . prisma ) . payment_releases . updateMany ( {
325
368
where : {
326
369
payment_release_associations : {
327
370
some : {
@@ -346,19 +389,22 @@ export class AdminService {
346
389
oldPaymentStatus : string | null ,
347
390
newPaymentStatus : PaymentStatus ,
348
391
currentVersion : number ,
392
+ tx ?: Prisma . TransactionClient ,
349
393
) {
350
394
let setDatePaidNull = false ;
351
- if ( [
352
- PaymentStatus . PAID ,
353
- PaymentStatus . PROCESSING ,
354
- PaymentStatus . RETURNED ,
355
- PaymentStatus . FAILED ,
356
- ] . includes ( oldPaymentStatus as PaymentStatus ) &&
395
+ if (
396
+ [
397
+ PaymentStatus . PAID ,
398
+ PaymentStatus . PROCESSING ,
399
+ PaymentStatus . RETURNED ,
400
+ PaymentStatus . FAILED ,
401
+ ] . includes ( oldPaymentStatus as PaymentStatus ) &&
357
402
newPaymentStatus === PaymentStatus . OWED
358
403
) {
359
404
setDatePaidNull = true ;
360
405
}
361
- return this . prisma . payment . update ( {
406
+
407
+ return ( tx ?? this . prisma ) . payment . update ( {
362
408
where : {
363
409
payment_id : paymentId ,
364
410
winnings_id : winningsId ,
@@ -379,8 +425,9 @@ export class AdminService {
379
425
winningsId : string ,
380
426
action : string ,
381
427
auditNote ?: string ,
428
+ tx ?: Prisma . TransactionClient ,
382
429
) {
383
- return this . prisma . audit . create ( {
430
+ return ( tx ?? this . prisma ) . audit . create ( {
384
431
data : {
385
432
user_id : userId ,
386
433
winnings_id : winningsId ,
@@ -396,8 +443,9 @@ export class AdminService {
396
443
paymentId : string ,
397
444
newReleaseDate : Date ,
398
445
currentVersion : number ,
446
+ tx ?: Prisma . TransactionClient ,
399
447
) {
400
- return this . prisma . payment . update ( {
448
+ return ( tx ?? this . prisma ) . payment . update ( {
401
449
where : {
402
450
payment_id : paymentId ,
403
451
winnings_id : winningsId ,
@@ -427,8 +475,9 @@ export class AdminService {
427
475
grossAmount : number ,
428
476
totalAmount : number ,
429
477
currentVersion : number ,
478
+ tx ?: Prisma . TransactionClient ,
430
479
) {
431
- return this . prisma . payment . update ( {
480
+ return ( tx ?? this . prisma ) . payment . update ( {
432
481
where : {
433
482
payment_id : paymentId ,
434
483
winnings_id : winningsId ,
@@ -461,11 +510,12 @@ export class AdminService {
461
510
*/
462
511
async getWinningAudit (
463
512
winningId : string ,
513
+ tx ?: Prisma . TransactionClient ,
464
514
) : Promise < ResponseDto < WinningAuditDto [ ] > > {
465
515
const result = new ResponseDto < WinningAuditDto [ ] > ( ) ;
466
516
467
517
try {
468
- const audits = await this . prisma . audit . findMany ( {
518
+ const audits = await ( tx ?? this . prisma ) . audit . findMany ( {
469
519
where : {
470
520
winnings_id : {
471
521
equals : winningId ,
@@ -501,11 +551,14 @@ export class AdminService {
501
551
*/
502
552
async getWinningAuditPayout (
503
553
winningId : string ,
554
+ tx ?: Prisma . TransactionClient ,
504
555
) : Promise < ResponseDto < AuditPayoutDto [ ] > > {
505
556
const result = new ResponseDto < AuditPayoutDto [ ] > ( ) ;
506
557
507
558
try {
508
- const paymentReleases = await this . prisma . payment_releases . findMany ( {
559
+ const paymentReleases = await (
560
+ tx ?? this . prisma
561
+ ) . payment_releases . findMany ( {
509
562
where : {
510
563
payment_release_associations : {
511
564
some : {
0 commit comments