Skip to content

Commit d7cf709

Browse files
authored
Merge pull request #54 from topcoder-platform/PM-1237_withdraw-memo
Pm 1237 withdraw memo
2 parents a0cccb6 + 02d96a4 commit d7cf709

File tree

5 files changed

+54
-6
lines changed

5 files changed

+54
-6
lines changed
Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,39 @@
11
import { ApiProperty } from '@nestjs/swagger';
2-
import { ArrayNotEmpty, IsArray, IsNotEmpty, IsUUID } from 'class-validator';
2+
import {
3+
ArrayNotEmpty,
4+
IsArray,
5+
IsNotEmpty,
6+
IsOptional,
7+
IsString,
8+
IsUUID,
9+
MaxLength,
10+
} from 'class-validator';
11+
import { ENV_CONFIG } from 'src/config';
312

4-
export class WithdrawRequestDto {
13+
export class WithdrawRequestDtoBase {
514
@ApiProperty({
615
description: 'The ID of the winnings to withdraw',
716
example: ['3fa85f64-5717-4562-b3fc-2c963f66afa6'],
817
})
918
@IsArray()
1019
@ArrayNotEmpty()
11-
@IsUUID('4',{ each: true })
20+
@IsUUID('4', { each: true })
1221
@IsNotEmpty({ each: true })
1322
winningsIds: string[];
1423
}
24+
25+
export class WithdrawRequestDtoWithMemo extends WithdrawRequestDtoBase {
26+
@ApiProperty({
27+
description:
28+
'A short note (30 chars max) which that will show up on your bank statement',
29+
example: 'Topcoder payment for week 05/17',
30+
})
31+
@IsString()
32+
@IsOptional()
33+
@MaxLength(30)
34+
memo?: string;
35+
}
36+
37+
export const WithdrawRequestDto = ENV_CONFIG.ACCEPT_CUSTOM_PAYMENTS_MEMO
38+
? WithdrawRequestDtoWithMemo
39+
: WithdrawRequestDtoBase;

src/api/withdrawal/withdrawal.controller.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export class WithdrawalController {
4646
@HttpCode(HttpStatus.OK)
4747
async doWithdraw(
4848
@User() user: UserInfo,
49+
// @ts-expect-error: Suppress error for 'WithdrawRequestDto' being used as a type
4950
@Body() body: WithdrawRequestDto,
5051
): Promise<ResponseDto<string>> {
5152
const result = new ResponseDto<string>();
@@ -55,6 +56,7 @@ export class WithdrawalController {
5556
user.id,
5657
user.handle,
5758
body.winningsIds,
59+
body.memo,
5860
);
5961
result.status = ResponseStatusType.SUCCESS;
6062
return result;

src/api/withdrawal/withdrawal.service.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,12 @@ export class WithdrawalService {
151151
}
152152
}
153153

154-
async withdraw(userId: string, userHandle: string, winningsIds: string[]) {
154+
async withdraw(
155+
userId: string,
156+
userHandle: string,
157+
winningsIds: string[],
158+
paymentMemo?: string,
159+
) {
155160
this.logger.log('Processing withdrawal request');
156161
const hasActiveTaxForm = await this.taxFormRepo.hasActiveTaxForm(userId);
157162

@@ -206,6 +211,7 @@ export class WithdrawalService {
206211
paymentBatch.id,
207212
totalAmount,
208213
paymentRelease.payment_release_id,
214+
paymentMemo,
209215
);
210216

211217
await this.updateDbReleaseRecord(tx, paymentRelease, trolleyPayment.id);

src/config/config.env.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { IsInt, IsOptional, IsString } from 'class-validator';
1+
import { Transform } from 'class-transformer';
2+
import { IsBoolean, IsInt, IsOptional, IsString } from 'class-validator';
23

34
export class ConfigEnv {
45
@IsString()
@@ -54,4 +55,17 @@ export class ConfigEnv {
5455
@IsInt()
5556
@IsOptional()
5657
TROLLEY_MINIMUM_PAYMENT_AMOUNT: number = 0;
58+
59+
@IsBoolean()
60+
@IsOptional()
61+
@Transform(({ value }) => {
62+
if (typeof value === 'boolean') return value;
63+
64+
if (typeof value === 'string') {
65+
return value.toLowerCase() === 'true';
66+
}
67+
68+
return false;
69+
})
70+
ACCEPT_CUSTOM_PAYMENTS_MEMO;
5771
}

src/shared/global/trolley.service.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,15 @@ export class TrolleyService {
110110
paymentBatchId: string,
111111
totalAmount: number,
112112
transactionId: string,
113+
paymentMemo?: string,
113114
) {
114115
const paymentPayload = {
115116
recipient: {
116117
id: recipientId,
117118
},
118119
sourceAmount: totalAmount.toString(),
119120
sourceCurrency: 'USD',
120-
memo: 'Topcoder payment',
121+
memo: paymentMemo ?? 'Topcoder payment',
121122
externalId: transactionId,
122123
};
123124

0 commit comments

Comments
 (0)