Skip to content

Commit 3cc402d

Browse files
committed
PM-1155 - refactor code
1 parent 0b6a18d commit 3cc402d

26 files changed

+682
-644
lines changed

src/api/admin-winning/adminWinning.controller.ts renamed to src/api/admin/admin.controller.ts

+18-21
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,23 @@ import { TopcoderMembersService } from 'src/shared/topcoder/members.service';
2424
import { Role } from 'src/core/auth/auth.constants';
2525
import { Roles, User } from 'src/core/auth/decorators';
2626

27-
import { AdminWinningService } from './adminWinning.service';
28-
import { UserInfo } from 'src/dto/user.dto';
27+
import { UserInfo } from 'src/dto/user.type';
2928

30-
import {
31-
ResponseStatusType,
32-
ResponseDto,
33-
WinningAuditDto,
34-
WinningRequestDto,
35-
SearchWinningResult,
36-
WinningUpdateRequestDto,
37-
AuditPayoutDto,
38-
} from 'src/dto/adminWinning.dto';
39-
40-
@ApiTags('AdminWinning')
29+
import { AdminService } from './admin.service';
30+
import { ResponseDto, ResponseStatusType } from 'src/dto/api-response.dto';
31+
import { WinningAuditDto, AuditPayoutDto } from './dto/audit.dto';
32+
33+
import { WinningRequestDto, SearchWinningResult } from 'src/dto/winning.dto';
34+
import { WinningsRepository } from '../repository/winnings.repo';
35+
import { WinningUpdateRequestDto } from './dto/winnings.dto';
36+
37+
@ApiTags('AdminWinnings')
4138
@Controller('/admin')
4239
@ApiBearerAuth()
43-
export class AdminWinningController {
40+
export class AdminController {
4441
constructor(
45-
private readonly adminWinningService: AdminWinningService,
42+
private readonly adminService: AdminService,
43+
private readonly winningsRepo: WinningsRepository,
4644
private readonly tcMembersService: TopcoderMembersService,
4745
) {}
4846

@@ -65,7 +63,7 @@ export class AdminWinningController {
6563
async searchWinnings(
6664
@Body() body: WinningRequestDto,
6765
): Promise<ResponseDto<SearchWinningResult>> {
68-
const result = await this.adminWinningService.searchWinnings(body);
66+
const result = await this.winningsRepo.searchWinnings(body);
6967
if (result.error) {
7068
result.status = ResponseStatusType.ERROR;
7169
}
@@ -94,7 +92,7 @@ export class AdminWinningController {
9492
@Header('Content-Type', 'text/csv')
9593
@Header('Content-Disposition', 'attachment; filename="winnings.csv"')
9694
async exportWinnings(@Body() body: WinningRequestDto) {
97-
const result = await this.adminWinningService.searchWinnings({
95+
const result = await this.winningsRepo.searchWinnings({
9896
...body,
9997
limit: 999,
10098
});
@@ -172,7 +170,7 @@ export class AdminWinningController {
172170
);
173171
}
174172

175-
const result = await this.adminWinningService.updateWinnings(body, user.id);
173+
const result = await this.adminService.updateWinnings(body, user.id);
176174
if (result.error) {
177175
result.status = ResponseStatusType.ERROR;
178176
}
@@ -201,7 +199,7 @@ export class AdminWinningController {
201199
async getWinningAudit(
202200
@Param('winningID') winningId: string,
203201
): Promise<ResponseDto<WinningAuditDto[]>> {
204-
const result = await this.adminWinningService.getWinningAudit(winningId);
202+
const result = await this.adminService.getWinningAudit(winningId);
205203
if (result.error) {
206204
result.status = ResponseStatusType.ERROR;
207205
}
@@ -231,8 +229,7 @@ export class AdminWinningController {
231229
async getWinningAuditPayout(
232230
@Param('winningID') winningId: string,
233231
): Promise<ResponseDto<AuditPayoutDto[]>> {
234-
const result =
235-
await this.adminWinningService.getWinningAuditPayout(winningId);
232+
const result = await this.adminService.getWinningAuditPayout(winningId);
236233
if (result.error) {
237234
result.status = ResponseStatusType.ERROR;
238235
}

src/api/admin/admin.module.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Module } from '@nestjs/common';
2+
import { AdminController } from './admin.controller';
3+
import { AdminService } from './admin.service';
4+
import { TaxFormRepository } from '../repository/taxForm.repo';
5+
import { PaymentMethodRepository } from '../repository/paymentMethod.repo';
6+
import { WinningsRepository } from '../repository/winnings.repo';
7+
import { TopcoderModule } from 'src/shared/topcoder/topcoder.module';
8+
9+
@Module({
10+
imports: [TopcoderModule],
11+
controllers: [AdminController],
12+
providers: [
13+
AdminService,
14+
TaxFormRepository,
15+
PaymentMethodRepository,
16+
WinningsRepository,
17+
],
18+
})
19+
export class AdminModule {}

src/api/admin-winning/adminWinning.service.ts renamed to src/api/admin/admin.service.ts

+5-210
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,18 @@ import {
88
import { PrismaPromise } from '@prisma/client';
99
import { PrismaService } from 'src/shared/global/prisma.service';
1010

11-
import {
12-
DateFilterType,
13-
ResponseDto,
14-
WinningAuditDto,
15-
WinningRequestDto,
16-
SearchWinningResult,
17-
WinningUpdateRequestDto,
18-
PaymentStatus,
19-
AuditPayoutDto,
20-
WinningsCategory,
21-
} from 'src/dto/adminWinning.dto';
2211
import { TaxFormRepository } from '../repository/taxForm.repo';
2312
import { PaymentMethodRepository } from '../repository/paymentMethod.repo';
24-
25-
const ONE_DAY = 24 * 60 * 60 * 1000;
13+
import { ResponseDto } from 'src/dto/api-response.dto';
14+
import { PaymentStatus } from 'src/dto/payment.dto';
15+
import { WinningAuditDto, AuditPayoutDto } from './dto/audit.dto';
16+
import { WinningUpdateRequestDto } from './dto/winnings.dto';
2617

2718
/**
2819
* The admin winning service.
2920
*/
3021
@Injectable()
31-
export class AdminWinningService {
22+
export class AdminService {
3223
/**
3324
* Constructs the admin winning service with the given dependencies.
3425
* @param prisma the prisma service.
@@ -39,202 +30,6 @@ export class AdminWinningService {
3930
private readonly paymentMethodRepo: PaymentMethodRepository,
4031
) {}
4132

42-
/**
43-
* Search winnings with parameters
44-
* @param body the request body
45-
* @returns the Promise with response result
46-
*/
47-
async searchWinnings(
48-
body: WinningRequestDto,
49-
): Promise<ResponseDto<SearchWinningResult>> {
50-
const result = new ResponseDto<SearchWinningResult>();
51-
52-
try {
53-
let winnerIds: string[] | undefined;
54-
let externalIds: string[] | undefined;
55-
if (body.winnerId) {
56-
winnerIds = [body.winnerId];
57-
} else if (body.winnerIds) {
58-
winnerIds = [...body.winnerIds];
59-
} else if (body.externalIds?.length > 0) {
60-
externalIds = body.externalIds;
61-
}
62-
63-
const queryWhere = this.getQueryByWinnerId(body, winnerIds, externalIds);
64-
const orderBy = this.getOrderByWithWinnerId(
65-
body,
66-
!winnerIds && !!externalIds?.length,
67-
);
68-
69-
const [winnings, count] = await this.prisma.$transaction([
70-
this.prisma.winnings.findMany({
71-
...queryWhere,
72-
include: {
73-
payment: {
74-
where: {
75-
installment_number: 1,
76-
},
77-
orderBy: [
78-
{
79-
created_at: 'desc',
80-
},
81-
],
82-
},
83-
origin: true,
84-
},
85-
orderBy,
86-
skip: body.offset,
87-
take: body.limit,
88-
}),
89-
this.prisma.winnings.count({ where: queryWhere.where }),
90-
]);
91-
92-
result.data = {
93-
winnings: winnings.map((item) => ({
94-
id: item.winning_id,
95-
type: item.type,
96-
winnerId: item.winner_id,
97-
origin: item.origin?.origin_name,
98-
category: (item.category ?? '') as WinningsCategory,
99-
title: item.title as string,
100-
description: item.description as string,
101-
externalId: item.external_id as string,
102-
attributes: (item.attributes ?? {}) as object,
103-
details: item.payment?.map((paymentItem) => ({
104-
id: paymentItem.payment_id,
105-
netAmount: Number(paymentItem.net_amount),
106-
grossAmount: Number(paymentItem.gross_amount),
107-
totalAmount: Number(paymentItem.total_amount),
108-
installmentNumber: paymentItem.installment_number as number,
109-
datePaid: (paymentItem.date_paid ?? undefined) as Date,
110-
status: paymentItem.payment_status as PaymentStatus,
111-
currency: paymentItem.currency as string,
112-
releaseDate: paymentItem.release_date as Date,
113-
category: item.category as string,
114-
billingAccount: paymentItem.billing_account,
115-
})),
116-
createdAt: item.created_at as Date,
117-
updatedAt: (item.payment?.[0].date_paid ??
118-
item.payment?.[0].updated_at ??
119-
undefined) as Date,
120-
releaseDate: item.payment?.[0]?.release_date as Date,
121-
})),
122-
pagination: {
123-
totalItems: count,
124-
totalPages: Math.ceil(count / body.limit),
125-
pageSize: body.limit,
126-
currentPage: Math.ceil(body.offset / body.limit) + 1,
127-
},
128-
};
129-
// response.data = winnings as any
130-
} catch (error) {
131-
console.error('Searching winnings failed', error);
132-
const message = 'Searching winnings failed. ' + error;
133-
result.error = {
134-
code: HttpStatus.INTERNAL_SERVER_ERROR,
135-
message,
136-
};
137-
}
138-
139-
return result;
140-
}
141-
142-
private generateFilterDate(body: WinningRequestDto) {
143-
let filterDate: object | undefined;
144-
const currentDay = new Date(new Date().setHours(0, 0, 0, 0));
145-
switch (body.date) {
146-
case DateFilterType.LAST7DAYS:
147-
// eslint-disable-next-line no-case-declarations
148-
const last7days = new Date(currentDay.getTime() - 6 * ONE_DAY);
149-
filterDate = {
150-
gte: last7days,
151-
};
152-
break;
153-
case DateFilterType.LAST30DAYS:
154-
// eslint-disable-next-line no-case-declarations
155-
const last30days = new Date(currentDay.getTime() - 29 * ONE_DAY);
156-
filterDate = {
157-
gte: last30days,
158-
};
159-
break;
160-
case DateFilterType.ALL:
161-
filterDate = undefined;
162-
break;
163-
default:
164-
break;
165-
}
166-
return filterDate;
167-
}
168-
169-
private getQueryByWinnerId(
170-
body: WinningRequestDto,
171-
winnerIds: string[] | undefined,
172-
externalIds: string[] | undefined,
173-
) {
174-
const filterDate: object | undefined = this.generateFilterDate(body);
175-
176-
const query = {
177-
where: {
178-
winner_id: winnerIds
179-
? {
180-
in: winnerIds,
181-
}
182-
: undefined,
183-
external_id: externalIds
184-
? {
185-
in: body.externalIds,
186-
}
187-
: undefined,
188-
category: body.type
189-
? {
190-
equals: body.type,
191-
}
192-
: undefined,
193-
created_at: filterDate,
194-
payment: body.status
195-
? {
196-
some: {
197-
payment_status: {
198-
equals: body.status,
199-
},
200-
installment_number: {
201-
equals: 1,
202-
},
203-
},
204-
}
205-
: {
206-
some: {
207-
installment_number: {
208-
equals: 1,
209-
},
210-
},
211-
},
212-
},
213-
};
214-
215-
return query;
216-
}
217-
218-
private getOrderByWithWinnerId(
219-
body: WinningRequestDto,
220-
externalIds?: boolean,
221-
) {
222-
const orderBy: object = [
223-
{
224-
created_at: 'desc',
225-
},
226-
...(externalIds ? [{ external_id: 'asc' }] : []),
227-
];
228-
229-
if (body.sortBy && body.sortOrder) {
230-
orderBy[0] = {
231-
[body.sortBy]: body.sortOrder.toString(),
232-
};
233-
}
234-
235-
return orderBy;
236-
}
237-
23833
private getPaymentsByWinningsId(winningsId: string, paymentId?: string) {
23934
return this.prisma.payment.findMany({
24035
where: {

src/api/admin/dto/audit.dto.ts

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
3+
export class WinningAuditDto {
4+
@ApiProperty({
5+
description: 'The ID of the audit',
6+
example: '2ccba36d-8db7-49da-94c9-b6c5b7bf47fb',
7+
})
8+
id: string;
9+
10+
@ApiProperty({
11+
description: 'The ID of the winning',
12+
example: '2ccba36d-8db7-49da-94c9-b6c5b7bf47fc',
13+
})
14+
winningsId: string;
15+
16+
@ApiProperty({
17+
description: 'The ID of the user',
18+
example: '123',
19+
})
20+
userId: string;
21+
22+
@ApiProperty({
23+
description: 'The audit action',
24+
example: 'create payment',
25+
})
26+
action: string;
27+
28+
@ApiProperty({
29+
description: 'The audit note',
30+
example: 'note 01',
31+
})
32+
note: string | null;
33+
34+
@ApiProperty({
35+
description: 'The creation timestamp',
36+
example: '2023-10-01T00:00:00Z',
37+
})
38+
createdAt: Date;
39+
}
40+
41+
export class AuditPayoutDto {
42+
externalTransactionId: string;
43+
status: string;
44+
totalNetAmount: number;
45+
createdAt: Date;
46+
metadata: string;
47+
paymentMethodUsed: string;
48+
externalTransactionDetails: object;
49+
}

0 commit comments

Comments
 (0)