refactor payments module

This commit is contained in:
2025-12-22 17:52:59 +01:00
parent 0828506c21
commit c90b2166c1
28 changed files with 524 additions and 268 deletions

View File

@@ -2,7 +2,39 @@ import { Test, TestingModule } from '@nestjs/testing';
import { vi } from 'vitest'; import { vi } from 'vitest';
import { PaymentsController } from './PaymentsController'; import { PaymentsController } from './PaymentsController';
import { PaymentsService } from './PaymentsService'; import { PaymentsService } from './PaymentsService';
import { GetPaymentsQuery, CreatePaymentInput, UpdatePaymentStatusInput, GetMembershipFeesQuery, UpsertMembershipFeeInput, UpdateMemberPaymentInput, GetPrizesQuery, CreatePrizeInput, AwardPrizeInput, DeletePrizeInput, GetWalletQuery, ProcessWalletTransactionInput } from './dtos/PaymentsDto'; import {
GetPaymentsQuery,
CreatePaymentInput,
UpdatePaymentStatusInput,
GetMembershipFeesQuery,
UpsertMembershipFeeInput,
UpdateMemberPaymentInput,
GetPrizesQuery,
CreatePrizeInput,
AwardPrizeInput,
DeletePrizeInput,
GetWalletQuery,
ProcessWalletTransactionInput,
PaymentType,
PayerType,
PaymentStatus,
MembershipFeeType,
MemberPaymentStatus,
PrizeType,
TransactionType,
GetPaymentsOutput,
CreatePaymentOutput,
UpdatePaymentStatusOutput,
GetMembershipFeesOutput,
UpsertMembershipFeeOutput,
UpdateMemberPaymentOutput,
GetPrizesOutput,
CreatePrizeOutput,
AwardPrizeOutput,
DeletePrizeOutput,
GetWalletOutput,
ProcessWalletTransactionOutput
} from './dtos/PaymentsDto';
describe('PaymentsController', () => { describe('PaymentsController', () => {
let controller: PaymentsController; let controller: PaymentsController;
@@ -38,9 +70,9 @@ describe('PaymentsController', () => {
describe('getPayments', () => { describe('getPayments', () => {
it('should return payments', async () => { it('should return payments', async () => {
const query: GetPaymentsQuery = { status: 'pending' }; const query: GetPaymentsQuery = { leagueId: 'league-123' };
const result = { payments: [] }; const result: GetPaymentsOutput = { payments: [] };
service.getPayments.mockResolvedValue({ viewModel: result } as any); service.getPayments.mockResolvedValue(result);
const response = await controller.getPayments(query); const response = await controller.getPayments(query);
@@ -51,9 +83,28 @@ describe('PaymentsController', () => {
describe('createPayment', () => { describe('createPayment', () => {
it('should create payment', async () => { it('should create payment', async () => {
const input: CreatePaymentInput = { amount: 100, type: 'membership_fee', payerId: 'payer-123', payerType: 'driver', leagueId: 'league-123' }; const input: CreatePaymentInput = {
const result = { payment: { id: 'pay-123' } }; amount: 100,
service.createPayment.mockResolvedValue({ viewModel: result } as any); type: PaymentType.MEMBERSHIP_FEE,
payerId: 'payer-123',
payerType: PayerType.DRIVER,
leagueId: 'league-123'
};
const result: CreatePaymentOutput = {
payment: {
id: 'pay-123',
type: PaymentType.MEMBERSHIP_FEE,
amount: 100,
platformFee: 5,
netAmount: 95,
payerId: 'payer-123',
payerType: PayerType.DRIVER,
leagueId: 'league-123',
status: PaymentStatus.PENDING,
createdAt: new Date()
}
};
service.createPayment.mockResolvedValue(result);
const response = await controller.createPayment(input); const response = await controller.createPayment(input);
@@ -64,9 +115,23 @@ describe('PaymentsController', () => {
describe('updatePaymentStatus', () => { describe('updatePaymentStatus', () => {
it('should update payment status', async () => { it('should update payment status', async () => {
const input: UpdatePaymentStatusInput = { paymentId: 'pay-123', status: 'completed' }; const input: UpdatePaymentStatusInput = { paymentId: 'pay-123', status: PaymentStatus.COMPLETED };
const result = { payment: { id: 'pay-123', status: 'completed' } }; const result: UpdatePaymentStatusOutput = {
service.updatePaymentStatus.mockResolvedValue({ viewModel: result } as any); payment: {
id: 'pay-123',
type: PaymentType.MEMBERSHIP_FEE,
amount: 100,
platformFee: 5,
netAmount: 95,
payerId: 'payer-123',
payerType: PayerType.DRIVER,
leagueId: 'league-123',
status: PaymentStatus.COMPLETED,
createdAt: new Date(),
completedAt: new Date()
}
};
service.updatePaymentStatus.mockResolvedValue(result);
const response = await controller.updatePaymentStatus(input); const response = await controller.updatePaymentStatus(input);
@@ -78,8 +143,19 @@ describe('PaymentsController', () => {
describe('getMembershipFees', () => { describe('getMembershipFees', () => {
it('should return membership fees', async () => { it('should return membership fees', async () => {
const query: GetMembershipFeesQuery = { leagueId: 'league-123' }; const query: GetMembershipFeesQuery = { leagueId: 'league-123' };
const result = { fees: [] }; const result: GetMembershipFeesOutput = {
service.getMembershipFees.mockResolvedValue({ viewModel: result } as any); fee: {
id: 'fee-123',
leagueId: 'league-123',
type: MembershipFeeType.MONTHLY,
amount: 50,
enabled: true,
createdAt: new Date(),
updatedAt: new Date()
},
payments: []
};
service.getMembershipFees.mockResolvedValue(result);
const response = await controller.getMembershipFees(query); const response = await controller.getMembershipFees(query);
@@ -90,9 +166,23 @@ describe('PaymentsController', () => {
describe('upsertMembershipFee', () => { describe('upsertMembershipFee', () => {
it('should upsert membership fee', async () => { it('should upsert membership fee', async () => {
const input: UpsertMembershipFeeInput = { leagueId: 'league-123', amount: 50 }; const input: UpsertMembershipFeeInput = {
const result = { feeId: 'fee-123' }; leagueId: 'league-123',
service.upsertMembershipFee.mockResolvedValue({ viewModel: result } as any); type: MembershipFeeType.MONTHLY,
amount: 50
};
const result: UpsertMembershipFeeOutput = {
fee: {
id: 'fee-123',
leagueId: 'league-123',
type: MembershipFeeType.MONTHLY,
amount: 50,
enabled: true,
createdAt: new Date(),
updatedAt: new Date()
}
};
service.upsertMembershipFee.mockResolvedValue(result);
const response = await controller.upsertMembershipFee(input); const response = await controller.upsertMembershipFee(input);
@@ -103,9 +193,25 @@ describe('PaymentsController', () => {
describe('updateMemberPayment', () => { describe('updateMemberPayment', () => {
it('should update member payment', async () => { it('should update member payment', async () => {
const input: UpdateMemberPaymentInput = { memberId: 'member-123', paymentId: 'pay-123' }; const input: UpdateMemberPaymentInput = {
const result = { success: true }; feeId: 'fee-123',
service.updateMemberPayment.mockResolvedValue({ viewModel: result } as any); driverId: 'driver-123',
status: MemberPaymentStatus.PAID
};
const result: UpdateMemberPaymentOutput = {
payment: {
id: 'mp-123',
feeId: 'fee-123',
driverId: 'driver-123',
amount: 50,
platformFee: 2.5,
netAmount: 47.5,
status: MemberPaymentStatus.PAID,
dueDate: new Date(),
paidAt: new Date()
}
};
service.updateMemberPayment.mockResolvedValue(result);
const response = await controller.updateMemberPayment(input); const response = await controller.updateMemberPayment(input);
@@ -117,8 +223,8 @@ describe('PaymentsController', () => {
describe('getPrizes', () => { describe('getPrizes', () => {
it('should return prizes', async () => { it('should return prizes', async () => {
const query: GetPrizesQuery = { leagueId: 'league-123' }; const query: GetPrizesQuery = { leagueId: 'league-123' };
const result = { prizes: [] }; const result: GetPrizesOutput = { prizes: [] };
service.getPrizes.mockResolvedValue({ viewModel: result } as any); service.getPrizes.mockResolvedValue(result);
const response = await controller.getPrizes(query); const response = await controller.getPrizes(query);
@@ -129,9 +235,28 @@ describe('PaymentsController', () => {
describe('createPrize', () => { describe('createPrize', () => {
it('should create prize', async () => { it('should create prize', async () => {
const input: CreatePrizeInput = { name: 'Prize', amount: 100 }; const input: CreatePrizeInput = {
const result = { prizeId: 'prize-123' }; leagueId: 'league-123',
service.createPrize.mockResolvedValue({ viewModel: result } as any); seasonId: 'season-123',
position: 1,
name: 'Champion',
amount: 1000,
type: PrizeType.CASH
};
const result: CreatePrizeOutput = {
prize: {
id: 'prize-123',
leagueId: 'league-123',
seasonId: 'season-123',
position: 1,
name: 'Champion',
amount: 1000,
type: PrizeType.CASH,
awarded: false,
createdAt: new Date()
}
};
service.createPrize.mockResolvedValue(result);
const response = await controller.createPrize(input); const response = await controller.createPrize(input);
@@ -143,8 +268,22 @@ describe('PaymentsController', () => {
describe('awardPrize', () => { describe('awardPrize', () => {
it('should award prize', async () => { it('should award prize', async () => {
const input: AwardPrizeInput = { prizeId: 'prize-123', driverId: 'driver-123' }; const input: AwardPrizeInput = { prizeId: 'prize-123', driverId: 'driver-123' };
const result = { success: true }; const result: AwardPrizeOutput = {
service.awardPrize.mockResolvedValue({ viewModel: result } as any); prize: {
id: 'prize-123',
leagueId: 'league-123',
seasonId: 'season-123',
position: 1,
name: 'Champion',
amount: 1000,
type: PrizeType.CASH,
awarded: true,
awardedTo: 'driver-123',
awardedAt: new Date(),
createdAt: new Date()
}
};
service.awardPrize.mockResolvedValue(result);
const response = await controller.awardPrize(input); const response = await controller.awardPrize(input);
@@ -156,8 +295,8 @@ describe('PaymentsController', () => {
describe('deletePrize', () => { describe('deletePrize', () => {
it('should delete prize', async () => { it('should delete prize', async () => {
const query: DeletePrizeInput = { prizeId: 'prize-123' }; const query: DeletePrizeInput = { prizeId: 'prize-123' };
const result = { success: true }; const result: DeletePrizeOutput = { success: true };
service.deletePrize.mockResolvedValue({ viewModel: result } as any); service.deletePrize.mockResolvedValue(result);
const response = await controller.deletePrize(query); const response = await controller.deletePrize(query);
@@ -168,9 +307,21 @@ describe('PaymentsController', () => {
describe('getWallet', () => { describe('getWallet', () => {
it('should return wallet', async () => { it('should return wallet', async () => {
const query: GetWalletQuery = { userId: 'user-123' }; const query: GetWalletQuery = { leagueId: 'league-123' };
const result = { balance: 100 }; const result: GetWalletOutput = {
service.getWallet.mockResolvedValue({ viewModel: result } as any); wallet: {
id: 'wallet-123',
leagueId: 'league-123',
balance: 100,
totalRevenue: 100,
totalPlatformFees: 5,
totalWithdrawn: 0,
currency: 'USD',
createdAt: new Date()
},
transactions: []
};
service.getWallet.mockResolvedValue(result);
const response = await controller.getWallet(query); const response = await controller.getWallet(query);
@@ -181,9 +332,33 @@ describe('PaymentsController', () => {
describe('processWalletTransaction', () => { describe('processWalletTransaction', () => {
it('should process wallet transaction', async () => { it('should process wallet transaction', async () => {
const input: ProcessWalletTransactionInput = { userId: 'user-123', amount: 50, type: 'deposit' }; const input: ProcessWalletTransactionInput = {
const result = { transactionId: 'tx-123' }; leagueId: 'league-123',
service.processWalletTransaction.mockResolvedValue({ viewModel: result } as any); amount: 50,
type: TransactionType.DEPOSIT,
description: 'Test deposit'
};
const result: ProcessWalletTransactionOutput = {
wallet: {
id: 'wallet-123',
leagueId: 'league-123',
balance: 150,
totalRevenue: 150,
totalPlatformFees: 7.5,
totalWithdrawn: 0,
currency: 'USD',
createdAt: new Date()
},
transaction: {
id: 'tx-123',
walletId: 'wallet-123',
type: TransactionType.DEPOSIT,
amount: 50,
description: 'Test deposit',
createdAt: new Date()
}
};
service.processWalletTransaction.mockResolvedValue(result);
const response = await controller.processWalletTransaction(input); const response = await controller.processWalletTransaction(input);

View File

@@ -34,8 +34,7 @@ export class PaymentsController {
@ApiOperation({ summary: 'Get membership fees and member payments' }) @ApiOperation({ summary: 'Get membership fees and member payments' })
@ApiResponse({ status: 200, description: 'Membership fee configuration and member payments', type: GetMembershipFeesOutput }) @ApiResponse({ status: 200, description: 'Membership fee configuration and member payments', type: GetMembershipFeesOutput })
async getMembershipFees(@Query() query: GetMembershipFeesQuery): Promise<GetMembershipFeesOutput> { async getMembershipFees(@Query() query: GetMembershipFeesQuery): Promise<GetMembershipFeesOutput> {
const presenter = await this.paymentsService.getMembershipFees(query); return this.paymentsService.getMembershipFees(query);
return presenter.viewModel;
} }
@Post('membership-fees') @Post('membership-fees')
@@ -43,23 +42,20 @@ export class PaymentsController {
@ApiOperation({ summary: 'Create or update membership fee configuration' }) @ApiOperation({ summary: 'Create or update membership fee configuration' })
@ApiResponse({ status: 201, description: 'Membership fee configuration created or updated', type: UpsertMembershipFeeOutput }) @ApiResponse({ status: 201, description: 'Membership fee configuration created or updated', type: UpsertMembershipFeeOutput })
async upsertMembershipFee(@Body() input: UpsertMembershipFeeInput): Promise<UpsertMembershipFeeOutput> { async upsertMembershipFee(@Body() input: UpsertMembershipFeeInput): Promise<UpsertMembershipFeeOutput> {
const presenter = await this.paymentsService.upsertMembershipFee(input); return this.paymentsService.upsertMembershipFee(input);
return presenter.viewModel;
} }
@Patch('membership-fees/member-payment') @Patch('membership-fees/member-payment')
@ApiOperation({ summary: 'Record or update a member payment' }) @ApiOperation({ summary: 'Record or update a member payment' })
@ApiResponse({ status: 200, description: 'Member payment recorded or updated', type: UpdateMemberPaymentOutput }) @ApiResponse({ status: 200, description: 'Member payment recorded or updated', type: UpdateMemberPaymentOutput })
async updateMemberPayment(@Body() input: UpdateMemberPaymentInput): Promise<UpdateMemberPaymentOutput> { async updateMemberPayment(@Body() input: UpdateMemberPaymentInput): Promise<UpdateMemberPaymentOutput> {
const presenter = await this.paymentsService.updateMemberPayment(input); return this.paymentsService.updateMemberPayment(input);
return presenter.viewModel;
} }
@Get('prizes') @Get('prizes')
@ApiOperation({ summary: 'Get prizes for a league or season' }) @ApiOperation({ summary: 'Get prizes for a league or season' })
@ApiResponse({ status: 200, description: 'List of prizes', type: GetPrizesOutput }) @ApiResponse({ status: 200, description: 'List of prizes', type: GetPrizesOutput })
async getPrizes(@Query() query: GetPrizesQuery): Promise<GetPrizesOutput> { async getPrizes(@Query() query: GetPrizesQuery): Promise<GetPrizesOutput> {
const presenter = await this.paymentsService.getPrizes(query); return this.paymentsService.getPrizes(query);
return presenter.viewModel;
} }
@Post('prizes') @Post('prizes')
@@ -67,31 +63,27 @@ export class PaymentsController {
@ApiOperation({ summary: 'Create a new prize' }) @ApiOperation({ summary: 'Create a new prize' })
@ApiResponse({ status: 201, description: 'Prize created', type: CreatePrizeOutput }) @ApiResponse({ status: 201, description: 'Prize created', type: CreatePrizeOutput })
async createPrize(@Body() input: CreatePrizeInput): Promise<CreatePrizeOutput> { async createPrize(@Body() input: CreatePrizeInput): Promise<CreatePrizeOutput> {
const presenter = await this.paymentsService.createPrize(input); return this.paymentsService.createPrize(input);
return presenter.viewModel;
} }
@Patch('prizes/award') @Patch('prizes/award')
@ApiOperation({ summary: 'Award a prize to a driver' }) @ApiOperation({ summary: 'Award a prize to a driver' })
@ApiResponse({ status: 200, description: 'Prize awarded', type: AwardPrizeOutput }) @ApiResponse({ status: 200, description: 'Prize awarded', type: AwardPrizeOutput })
async awardPrize(@Body() input: AwardPrizeInput): Promise<AwardPrizeOutput> { async awardPrize(@Body() input: AwardPrizeInput): Promise<AwardPrizeOutput> {
const presenter = await this.paymentsService.awardPrize(input); return this.paymentsService.awardPrize(input);
return presenter.viewModel;
} }
@Delete('prizes') @Delete('prizes')
@ApiOperation({ summary: 'Delete a prize' }) @ApiOperation({ summary: 'Delete a prize' })
@ApiResponse({ status: 200, description: 'Prize deleted', type: DeletePrizeOutput }) @ApiResponse({ status: 200, description: 'Prize deleted', type: DeletePrizeOutput })
async deletePrize(@Query() query: DeletePrizeInput): Promise<DeletePrizeOutput> { async deletePrize(@Query() query: DeletePrizeInput): Promise<DeletePrizeOutput> {
const presenter = await this.paymentsService.deletePrize(query); return this.paymentsService.deletePrize(query);
return presenter.viewModel;
} }
@Get('wallets') @Get('wallets')
@ApiOperation({ summary: 'Get wallet information and transactions' }) @ApiOperation({ summary: 'Get wallet information and transactions' })
@ApiResponse({ status: 200, description: 'Wallet and transaction data', type: GetWalletOutput }) @ApiResponse({ status: 200, description: 'Wallet and transaction data', type: GetWalletOutput })
async getWallet(@Query() query: GetWalletQuery): Promise<GetWalletOutput> { async getWallet(@Query() query: GetWalletQuery): Promise<GetWalletOutput> {
const presenter = await this.paymentsService.getWallet(query); return this.paymentsService.getWallet(query);
return presenter.viewModel;
} }
@Post('wallets/transactions') @Post('wallets/transactions')
@@ -99,7 +91,6 @@ export class PaymentsController {
@ApiOperation({ summary: 'Process a wallet transaction (deposit or withdrawal)' }) @ApiOperation({ summary: 'Process a wallet transaction (deposit or withdrawal)' })
@ApiResponse({ status: 201, description: 'Wallet transaction processed', type: ProcessWalletTransactionOutput }) @ApiResponse({ status: 201, description: 'Wallet transaction processed', type: ProcessWalletTransactionOutput })
async processWalletTransaction(@Body() input: ProcessWalletTransactionInput): Promise<ProcessWalletTransactionOutput> { async processWalletTransaction(@Body() input: ProcessWalletTransactionInput): Promise<ProcessWalletTransactionOutput> {
const presenter = await this.paymentsService.processWalletTransaction(input); return this.paymentsService.processWalletTransaction(input);
return presenter.viewModel;
} }
} }

View File

@@ -32,17 +32,23 @@ import { UpsertMembershipFeePresenter } from './presenters/UpsertMembershipFeePr
// DTOs // DTOs
import type { import type {
AwardPrizeInput, AwardPrizeInput,
AwardPrizeOutput,
CreatePaymentInput, CreatePaymentInput,
CreatePaymentOutput, CreatePaymentOutput,
CreatePrizeInput, CreatePrizeInput,
CreatePrizeOutput,
DeletePrizeInput, DeletePrizeInput,
DeletePrizeOutput,
GetMembershipFeesOutput, GetMembershipFeesOutput,
GetMembershipFeesQuery, GetMembershipFeesQuery,
GetPaymentsOutput, GetPaymentsOutput,
GetPaymentsQuery, GetPaymentsQuery,
GetPrizesOutput,
GetPrizesQuery, GetPrizesQuery,
GetWalletOutput,
GetWalletQuery, GetWalletQuery,
ProcessWalletTransactionInput, ProcessWalletTransactionInput,
ProcessWalletTransactionOutput,
UpdateMemberPaymentInput, UpdateMemberPaymentInput,
UpdateMemberPaymentOutput, UpdateMemberPaymentOutput,
UpdatePaymentStatusInput, UpdatePaymentStatusInput,
@@ -103,7 +109,7 @@ export class PaymentsService {
const result = await this.getPaymentsUseCase.execute(query); const result = await this.getPaymentsUseCase.execute(query);
if (result.isErr()) { if (result.isErr()) {
throw new Error(result.unwrapErr().details?.message ?? 'Failed to get payments'); throw new Error(result.unwrapErr().code ?? 'Failed to get payments');
} }
return this.getPaymentsPresenter.getResponseModel(); return this.getPaymentsPresenter.getResponseModel();
} }
@@ -113,7 +119,7 @@ export class PaymentsService {
const result = await this.createPaymentUseCase.execute(input); const result = await this.createPaymentUseCase.execute(input);
if (result.isErr()) { if (result.isErr()) {
throw new Error(result.unwrapErr().details?.message ?? 'Failed to create payment'); throw new Error(result.unwrapErr().code ?? 'Failed to create payment');
} }
return this.createPaymentPresenter.getResponseModel(); return this.createPaymentPresenter.getResponseModel();
} }
@@ -123,7 +129,7 @@ export class PaymentsService {
const result = await this.updatePaymentStatusUseCase.execute(input); const result = await this.updatePaymentStatusUseCase.execute(input);
if (result.isErr()) { if (result.isErr()) {
throw new Error(result.unwrapErr().details?.message ?? 'Failed to update payment status'); throw new Error(result.unwrapErr().code ?? 'Failed to update payment status');
} }
return this.updatePaymentStatusPresenter.getResponseModel(); return this.updatePaymentStatusPresenter.getResponseModel();
} }
@@ -133,9 +139,9 @@ export class PaymentsService {
const result = await this.getMembershipFeesUseCase.execute(query); const result = await this.getMembershipFeesUseCase.execute(query);
if (result.isErr()) { if (result.isErr()) {
throw new Error(result.unwrapErr().details?.message ?? 'Failed to get membership fees'); throw new Error(result.unwrapErr().code ?? 'Failed to get membership fees');
} }
return this.getMembershipFeesPresenter.getResponseModel(); return this.getMembershipFeesPresenter.viewModel;
} }
async upsertMembershipFee(input: UpsertMembershipFeeInput): Promise<UpsertMembershipFeeOutput> { async upsertMembershipFee(input: UpsertMembershipFeeInput): Promise<UpsertMembershipFeeOutput> {
@@ -143,9 +149,11 @@ export class PaymentsService {
const result = await this.upsertMembershipFeeUseCase.execute(input); const result = await this.upsertMembershipFeeUseCase.execute(input);
if (result.isErr()) { if (result.isErr()) {
throw new Error(result.unwrapErr().details?.message ?? 'Failed to upsert membership fee'); // Since UpsertMembershipFeeUseCase has never as error type, this should never happen
// but we keep the check for consistency
throw new Error('Failed to upsert membership fee');
} }
return this.upsertMembershipFeePresenter.getResponseModel(); return this.upsertMembershipFeePresenter.viewModel;
} }
async updateMemberPayment(input: UpdateMemberPaymentInput): Promise<UpdateMemberPaymentOutput> { async updateMemberPayment(input: UpdateMemberPaymentInput): Promise<UpdateMemberPaymentOutput> {
@@ -153,56 +161,56 @@ export class PaymentsService {
const result = await this.updateMemberPaymentUseCase.execute(input); const result = await this.updateMemberPaymentUseCase.execute(input);
if (result.isErr()) { if (result.isErr()) {
throw new Error(result.unwrapErr().details?.message ?? 'Failed to update member payment'); throw new Error(result.unwrapErr().code ?? 'Failed to update member payment');
} }
return this.updateMemberPaymentPresenter.getResponseModel(); return this.updateMemberPaymentPresenter.viewModel;
} }
async getPrizes(query: GetPrizesQuery): Promise<GetPrizesPresenter> { // TODO must return ResponseModel not Presenter async getPrizes(query: GetPrizesQuery): Promise<GetPrizesOutput> {
this.logger.debug('[PaymentsService] Getting prizes', { query }); this.logger.debug('[PaymentsService] Getting prizes', { query });
const presenter = new GetPrizesPresenter(); const input: { leagueId: string; seasonId?: string } = {
await this.getPrizesUseCase.execute({ leagueId: query.leagueId!, seasonId: query.seasonId }, presenter); leagueId: query.leagueId!,
return presenter; };
if (query.seasonId !== undefined) {
input.seasonId = query.seasonId;
}
await this.getPrizesUseCase.execute(input);
return this.getPrizesPresenter.viewModel;
} }
async createPrize(input: CreatePrizeInput): Promise<CreatePrizePresenter> { // TODO must return ResponseModel not Presenter async createPrize(input: CreatePrizeInput): Promise<CreatePrizeOutput> {
this.logger.debug('[PaymentsService] Creating prize', { input }); this.logger.debug('[PaymentsService] Creating prize', { input });
const presenter = new CreatePrizePresenter(); await this.createPrizeUseCase.execute(input);
await this.createPrizeUseCase.execute(input, presenter); return this.createPrizePresenter.viewModel;
return presenter;
} }
async awardPrize(input: AwardPrizeInput): Promise<AwardPrizePresenter> { // TODO must return ResponseModel not Presenter async awardPrize(input: AwardPrizeInput): Promise<AwardPrizeOutput> {
this.logger.debug('[PaymentsService] Awarding prize', { input }); this.logger.debug('[PaymentsService] Awarding prize', { input });
const presenter = new AwardPrizePresenter(); await this.awardPrizeUseCase.execute(input);
await this.awardPrizeUseCase.execute(input, presenter); return this.awardPrizePresenter.viewModel;
return presenter;
} }
async deletePrize(input: DeletePrizeInput): Promise<DeletePrizePresenter> { // TODO must return ResponseModel not Presenter async deletePrize(input: DeletePrizeInput): Promise<DeletePrizeOutput> {
this.logger.debug('[PaymentsService] Deleting prize', { input }); this.logger.debug('[PaymentsService] Deleting prize', { input });
const presenter = new DeletePrizePresenter(); await this.deletePrizeUseCase.execute(input);
await this.deletePrizeUseCase.execute(input, presenter); return this.deletePrizePresenter.viewModel;
return presenter;
} }
async getWallet(query: GetWalletQuery): Promise<GetWalletPresenter> { // TODO must return ResponseModel not Presenter async getWallet(query: GetWalletQuery): Promise<GetWalletOutput> {
this.logger.debug('[PaymentsService] Getting wallet', { query }); this.logger.debug('[PaymentsService] Getting wallet', { query });
const presenter = new GetWalletPresenter(); await this.getWalletUseCase.execute({ leagueId: query.leagueId! });
await this.getWalletUseCase.execute({ leagueId: query.leagueId! }, presenter); return this.getWalletPresenter.viewModel;
return presenter;
} }
async processWalletTransaction(input: ProcessWalletTransactionInput): Promise<ProcessWalletTransactionPresenter> { async processWalletTransaction(input: ProcessWalletTransactionInput): Promise<ProcessWalletTransactionOutput> {
this.logger.debug('[PaymentsService] Processing wallet transaction', { input }); this.logger.debug('[PaymentsService] Processing wallet transaction', { input });
const presenter = new ProcessWalletTransactionPresenter(); await this.processWalletTransactionUseCase.execute(input);
await this.processWalletTransactionUseCase.execute(input, presenter); return this.processWalletTransactionPresenter.viewModel;
return presenter;
} }
} }

View File

@@ -0,0 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsObject } from 'class-validator';
import { PrizeDto } from './PaymentsDto';
export class AwardPrizeResultDTO {
@ApiProperty({ type: PrizeDto })
@IsObject()
prize!: PrizeDto;
}

View File

@@ -6,23 +6,23 @@ import { PayerType } from './PayerType';
export class CreatePaymentInputDTO { export class CreatePaymentInputDTO {
@ApiProperty({ enum: PaymentType }) @ApiProperty({ enum: PaymentType })
@IsEnum(PaymentType) @IsEnum(PaymentType)
type: PaymentType; type!: PaymentType;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
payerId: string; payerId!: string;
@ApiProperty({ enum: PayerType }) @ApiProperty({ enum: PayerType })
@IsEnum(PayerType) @IsEnum(PayerType)
payerType: PayerType; payerType!: PayerType;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()

View File

@@ -3,5 +3,5 @@ import { PaymentDTO } from './PaymentDTO';
export class CreatePaymentOutputDTO { export class CreatePaymentOutputDTO {
@ApiProperty({ type: PaymentDTO }) @ApiProperty({ type: PaymentDTO })
payment: PaymentDTO; payment!: PaymentDTO;
} }

View File

@@ -0,0 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsObject } from 'class-validator';
import { PrizeDto } from './PaymentsDto';
export class CreatePrizeResultDTO {
@ApiProperty({ type: PrizeDto })
@IsObject()
prize!: PrizeDto;
}

View File

@@ -0,0 +1,8 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean } from 'class-validator';
export class DeletePrizeResultDTO {
@ApiProperty()
@IsBoolean()
success!: boolean;
}

View File

@@ -0,0 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsObject, IsArray } from 'class-validator';
import { MembershipFeeDto, MemberPaymentDto } from './PaymentsDto';
export class GetMembershipFeesResultDTO {
@ApiProperty({ type: MembershipFeeDto, nullable: true })
@IsObject()
fee!: MembershipFeeDto | null;
@ApiProperty({ type: [MemberPaymentDto] })
@IsArray()
payments!: MemberPaymentDto[];
}

View File

@@ -0,0 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsArray } from 'class-validator';
import { PrizeDto } from './PaymentsDto';
export class GetPrizesResultDTO {
@ApiProperty({ type: [PrizeDto] })
@IsArray()
prizes!: PrizeDto[];
}

View File

@@ -0,0 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsObject, IsArray } from 'class-validator';
import { WalletDto, TransactionDto } from './PaymentsDto';
export class GetWalletResultDTO {
@ApiProperty({ type: WalletDto })
@IsObject()
wallet!: WalletDto;
@ApiProperty({ type: [TransactionDto] })
@IsArray()
transactions!: TransactionDto[];
}

View File

@@ -7,35 +7,35 @@ import { PaymentStatus } from './PaymentStatus';
export class PaymentDTO { export class PaymentDTO {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
id: string; id!: string;
@ApiProperty({ enum: PaymentType }) @ApiProperty({ enum: PaymentType })
@IsEnum(PaymentType) @IsEnum(PaymentType)
type: PaymentType; type!: PaymentType;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
platformFee: number; platformFee!: number;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
netAmount: number; netAmount!: number;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
payerId: string; payerId!: string;
@ApiProperty({ enum: PayerType }) @ApiProperty({ enum: PayerType })
@IsEnum(PayerType) @IsEnum(PayerType)
payerType: PayerType; payerType!: PayerType;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -44,11 +44,11 @@ export class PaymentDTO {
@ApiProperty({ enum: PaymentStatus }) @ApiProperty({ enum: PaymentStatus })
@IsEnum(PaymentStatus) @IsEnum(PaymentStatus)
status: PaymentStatus; status!: PaymentStatus;
@ApiProperty() @ApiProperty()
@IsDate() @IsDate()
createdAt: Date; createdAt!: Date;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()

View File

@@ -21,35 +21,35 @@ export enum PaymentStatus {
export class PaymentDto { export class PaymentDto {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
id: string; id!: string;
@ApiProperty({ enum: PaymentType }) @ApiProperty({ enum: PaymentType })
@IsEnum(PaymentType) @IsEnum(PaymentType)
type: PaymentType; type!: PaymentType;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
platformFee: number; platformFee!: number;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
netAmount: number; netAmount!: number;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
payerId: string; payerId!: string;
@ApiProperty({ enum: PayerType }) @ApiProperty({ enum: PayerType })
@IsEnum(PayerType) @IsEnum(PayerType)
payerType: PayerType; payerType!: PayerType;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -58,11 +58,11 @@ export class PaymentDto {
@ApiProperty({ enum: PaymentStatus }) @ApiProperty({ enum: PaymentStatus })
@IsEnum(PaymentStatus) @IsEnum(PaymentStatus)
status: PaymentStatus; status!: PaymentStatus;
@ApiProperty() @ApiProperty()
@IsDate() @IsDate()
createdAt: Date; createdAt!: Date;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -73,23 +73,23 @@ export class PaymentDto {
export class CreatePaymentInput { export class CreatePaymentInput {
@ApiProperty({ enum: PaymentType }) @ApiProperty({ enum: PaymentType })
@IsEnum(PaymentType) @IsEnum(PaymentType)
type: PaymentType; type!: PaymentType;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
payerId: string; payerId!: string;
@ApiProperty({ enum: PayerType }) @ApiProperty({ enum: PayerType })
@IsEnum(PayerType) @IsEnum(PayerType)
payerType: PayerType; payerType!: PayerType;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -99,22 +99,22 @@ export class CreatePaymentInput {
export class CreatePaymentOutput { export class CreatePaymentOutput {
@ApiProperty({ type: PaymentDto }) @ApiProperty({ type: PaymentDto })
payment: PaymentDto; payment!: PaymentDto;
} }
export class UpdatePaymentStatusInput { export class UpdatePaymentStatusInput {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
paymentId: string; paymentId!: string;
@ApiProperty({ enum: PaymentStatus }) @ApiProperty({ enum: PaymentStatus })
@IsEnum(PaymentStatus) @IsEnum(PaymentStatus)
status: PaymentStatus; status!: PaymentStatus;
} }
export class UpdatePaymentStatusOutput { export class UpdatePaymentStatusOutput {
@ApiProperty({ type: PaymentDto }) @ApiProperty({ type: PaymentDto })
payment: PaymentDto; payment!: PaymentDto;
} }
export enum MembershipFeeType { export enum MembershipFeeType {
@@ -132,11 +132,11 @@ export enum MemberPaymentStatus {
export class MembershipFeeDto { export class MembershipFeeDto {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
id: string; id!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -145,57 +145,57 @@ export class MembershipFeeDto {
@ApiProperty({ enum: MembershipFeeType }) @ApiProperty({ enum: MembershipFeeType })
@IsEnum(MembershipFeeType) @IsEnum(MembershipFeeType)
type: MembershipFeeType; type!: MembershipFeeType;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty() @ApiProperty()
@IsBoolean() @IsBoolean()
enabled: boolean; enabled!: boolean;
@ApiProperty() @ApiProperty()
@IsDate() @IsDate()
createdAt: Date; createdAt!: Date;
@ApiProperty() @ApiProperty()
@IsDate() @IsDate()
updatedAt: Date; updatedAt!: Date;
} }
export class MemberPaymentDto { export class MemberPaymentDto {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
id: string; id!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
feeId: string; feeId!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
driverId: string; driverId!: string;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
platformFee: number; platformFee!: number;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
netAmount: number; netAmount!: number;
@ApiProperty({ enum: MemberPaymentStatus }) @ApiProperty({ enum: MemberPaymentStatus })
@IsEnum(MemberPaymentStatus) @IsEnum(MemberPaymentStatus)
status: MemberPaymentStatus; status!: MemberPaymentStatus;
@ApiProperty() @ApiProperty()
@IsDate() @IsDate()
dueDate: Date; dueDate!: Date;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -206,7 +206,7 @@ export class MemberPaymentDto {
export class GetMembershipFeesQuery { export class GetMembershipFeesQuery {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -216,16 +216,16 @@ export class GetMembershipFeesQuery {
export class GetMembershipFeesOutput { export class GetMembershipFeesOutput {
@ApiProperty({ type: MembershipFeeDto, nullable: true }) @ApiProperty({ type: MembershipFeeDto, nullable: true })
fee: MembershipFeeDto | null; fee!: MembershipFeeDto | null;
@ApiProperty({ type: [MemberPaymentDto] }) @ApiProperty({ type: [MemberPaymentDto] })
payments: MemberPaymentDto[]; payments!: MemberPaymentDto[];
} }
export class UpsertMembershipFeeInput { export class UpsertMembershipFeeInput {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -234,26 +234,26 @@ export class UpsertMembershipFeeInput {
@ApiProperty({ enum: MembershipFeeType }) @ApiProperty({ enum: MembershipFeeType })
@IsEnum(MembershipFeeType) @IsEnum(MembershipFeeType)
type: MembershipFeeType; type!: MembershipFeeType;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
} }
export class UpsertMembershipFeeOutput { export class UpsertMembershipFeeOutput {
@ApiProperty({ type: MembershipFeeDto }) @ApiProperty({ type: MembershipFeeDto })
fee: MembershipFeeDto; fee!: MembershipFeeDto;
} }
export class UpdateMemberPaymentInput { export class UpdateMemberPaymentInput {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
feeId: string; feeId!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
driverId: string; driverId!: string;
@ApiProperty({ required: false, enum: MemberPaymentStatus }) @ApiProperty({ required: false, enum: MemberPaymentStatus })
@IsOptional() @IsOptional()
@@ -268,7 +268,7 @@ export class UpdateMemberPaymentInput {
export class UpdateMemberPaymentOutput { export class UpdateMemberPaymentOutput {
@ApiProperty({ type: MemberPaymentDto }) @ApiProperty({ type: MemberPaymentDto })
payment: MemberPaymentDto; payment!: MemberPaymentDto;
} }
export class GetPaymentsQuery { export class GetPaymentsQuery {
@@ -290,7 +290,7 @@ export class GetPaymentsQuery {
export class GetPaymentsOutput { export class GetPaymentsOutput {
@ApiProperty({ type: [PaymentDto] }) @ApiProperty({ type: [PaymentDto] })
payments: PaymentDto[]; payments!: PaymentDto[];
} }
export enum PrizeType { export enum PrizeType {
@@ -302,31 +302,31 @@ export enum PrizeType {
export class PrizeDto { export class PrizeDto {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
id: string; id!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
seasonId: string; seasonId!: string;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
position: number; position!: number;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
name: string; name!: string;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty({ enum: PrizeType }) @ApiProperty({ enum: PrizeType })
@IsEnum(PrizeType) @IsEnum(PrizeType)
type: PrizeType; type!: PrizeType;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -335,7 +335,7 @@ export class PrizeDto {
@ApiProperty() @ApiProperty()
@IsBoolean() @IsBoolean()
awarded: boolean; awarded!: boolean;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -349,7 +349,7 @@ export class PrizeDto {
@ApiProperty() @ApiProperty()
@IsDate() @IsDate()
createdAt: Date; createdAt!: Date;
} }
export class GetPrizesQuery { export class GetPrizesQuery {
@@ -365,33 +365,33 @@ export class GetPrizesQuery {
export class GetPrizesOutput { export class GetPrizesOutput {
@ApiProperty({ type: [PrizeDto] }) @ApiProperty({ type: [PrizeDto] })
prizes: PrizeDto[]; prizes!: PrizeDto[];
} }
export class CreatePrizeInput { export class CreatePrizeInput {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
seasonId: string; seasonId!: string;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
position: number; position!: number;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
name: string; name!: string;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty({ enum: PrizeType }) @ApiProperty({ enum: PrizeType })
@IsEnum(PrizeType) @IsEnum(PrizeType)
type: PrizeType; type!: PrizeType;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -401,34 +401,34 @@ export class CreatePrizeInput {
export class CreatePrizeOutput { export class CreatePrizeOutput {
@ApiProperty({ type: PrizeDto }) @ApiProperty({ type: PrizeDto })
prize: PrizeDto; prize!: PrizeDto;
} }
export class AwardPrizeInput { export class AwardPrizeInput {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
prizeId: string; prizeId!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
driverId: string; driverId!: string;
} }
export class AwardPrizeOutput { export class AwardPrizeOutput {
@ApiProperty({ type: PrizeDto }) @ApiProperty({ type: PrizeDto })
prize: PrizeDto; prize!: PrizeDto;
} }
export class DeletePrizeInput { export class DeletePrizeInput {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
prizeId: string; prizeId!: string;
} }
export class DeletePrizeOutput { export class DeletePrizeOutput {
@ApiProperty() @ApiProperty()
@IsBoolean() @IsBoolean()
success: boolean; success!: boolean;
} }
export enum TransactionType { export enum TransactionType {
@@ -446,57 +446,57 @@ export enum ReferenceType {
export class WalletDto { export class WalletDto {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
id: string; id!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
balance: number; balance!: number;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
totalRevenue: number; totalRevenue!: number;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
totalPlatformFees: number; totalPlatformFees!: number;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
totalWithdrawn: number; totalWithdrawn!: number;
@ApiProperty() @ApiProperty()
@IsDate() @IsDate()
createdAt: Date; createdAt!: Date;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
currency: string; currency!: string;
} }
export class TransactionDto { export class TransactionDto {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
id: string; id!: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
walletId: string; walletId!: string;
@ApiProperty({ enum: TransactionType }) @ApiProperty({ enum: TransactionType })
@IsEnum(TransactionType) @IsEnum(TransactionType)
type: TransactionType; type!: TransactionType;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
description: string; description!: string;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -510,7 +510,7 @@ export class TransactionDto {
@ApiProperty() @ApiProperty()
@IsDate() @IsDate()
createdAt: Date; createdAt!: Date;
} }
export class GetWalletQuery { export class GetWalletQuery {
@@ -521,29 +521,29 @@ export class GetWalletQuery {
export class GetWalletOutput { export class GetWalletOutput {
@ApiProperty({ type: WalletDto }) @ApiProperty({ type: WalletDto })
wallet: WalletDto; wallet!: WalletDto;
@ApiProperty({ type: [TransactionDto] }) @ApiProperty({ type: [TransactionDto] })
transactions: TransactionDto[]; transactions!: TransactionDto[];
} }
export class ProcessWalletTransactionInput { export class ProcessWalletTransactionInput {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
leagueId: string; leagueId!: string;
@ApiProperty({ enum: TransactionType }) @ApiProperty({ enum: TransactionType })
@IsEnum(TransactionType) @IsEnum(TransactionType)
type: TransactionType; type!: TransactionType;
@ApiProperty() @ApiProperty()
@IsNumber() @IsNumber()
amount: number; amount!: number;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
description: string; description!: string;
@ApiProperty({ required: false }) @ApiProperty({ required: false })
@IsOptional() @IsOptional()
@@ -558,9 +558,8 @@ export class ProcessWalletTransactionInput {
export class ProcessWalletTransactionOutput { export class ProcessWalletTransactionOutput {
@ApiProperty({ type: WalletDto }) @ApiProperty({ type: WalletDto })
wallet: WalletDto; wallet!: WalletDto;
@ApiProperty({ type: TransactionDto }) @ApiProperty({ type: TransactionDto })
transaction: TransactionDto; transaction!: TransactionDto;
} }

View File

@@ -0,0 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsObject } from 'class-validator';
import { WalletDto, TransactionDto } from './PaymentsDto';
export class ProcessWalletTransactionResultDTO {
@ApiProperty({ type: WalletDto })
@IsObject()
wallet!: WalletDto;
@ApiProperty({ type: TransactionDto })
@IsObject()
transaction!: TransactionDto;
}

View File

@@ -0,0 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsObject } from 'class-validator';
import { MemberPaymentDto } from './PaymentsDto';
export class UpdateMemberPaymentResultDTO {
@ApiProperty({ type: MemberPaymentDto })
@IsObject()
payment!: MemberPaymentDto;
}

View File

@@ -5,9 +5,9 @@ import { PaymentStatus } from './PaymentStatus';
export class UpdatePaymentStatusInputDTO { export class UpdatePaymentStatusInputDTO {
@ApiProperty() @ApiProperty()
@IsString() @IsString()
paymentId: string; paymentId!: string;
@ApiProperty({ enum: PaymentStatus }) @ApiProperty({ enum: PaymentStatus })
@IsEnum(PaymentStatus) @IsEnum(PaymentStatus)
status: PaymentStatus; status!: PaymentStatus;
} }

View File

@@ -3,5 +3,5 @@ import { PaymentDTO } from './PaymentDTO';
export class UpdatePaymentStatusOutputDTO { export class UpdatePaymentStatusOutputDTO {
@ApiProperty({ type: PaymentDTO }) @ApiProperty({ type: PaymentDTO })
payment: PaymentDTO; payment!: PaymentDTO;
} }

View File

@@ -0,0 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsObject } from 'class-validator';
import { MembershipFeeDto } from './PaymentsDto';
export class UpsertMembershipFeeResultDTO {
@ApiProperty({ type: MembershipFeeDto })
@IsObject()
fee!: MembershipFeeDto;
}

View File

@@ -1,11 +1,10 @@
import type { import type { Presenter } from '@core/shared/presentation/Presenter';
IAwardPrizePresenter, import { AwardPrizeResultDTO } from '../dtos/AwardPrizeDTO';
AwardPrizeResultDTO,
AwardPrizeViewModel, export interface IAwardPrizePresenter extends Presenter<AwardPrizeResultDTO, AwardPrizeResultDTO> {}
} from '@core/payments/application/presenters/IAwardPrizePresenter';
export class AwardPrizePresenter implements IAwardPrizePresenter { export class AwardPrizePresenter implements IAwardPrizePresenter {
private result: AwardPrizeViewModel | null = null; private result: AwardPrizeResultDTO | null = null;
reset() { reset() {
this.result = null; this.result = null;
@@ -15,11 +14,11 @@ export class AwardPrizePresenter implements IAwardPrizePresenter {
this.result = dto; this.result = dto;
} }
getViewModel(): AwardPrizeViewModel | null { getResponseModel(): AwardPrizeResultDTO | null {
return this.result; return this.result;
} }
get viewModel(): AwardPrizeViewModel { get viewModel(): AwardPrizeResultDTO {
if (!this.result) throw new Error('Presenter not presented'); if (!this.result) throw new Error('Presenter not presented');
return this.result; return this.result;
} }

View File

@@ -1,11 +1,10 @@
import type { import type { Presenter } from '@core/shared/presentation/Presenter';
ICreatePrizePresenter, import { CreatePrizeResultDTO } from '../dtos/CreatePrizeDTO';
CreatePrizeResultDTO,
CreatePrizeViewModel, export interface ICreatePrizePresenter extends Presenter<CreatePrizeResultDTO, CreatePrizeResultDTO> {}
} from '@core/payments/application/presenters/ICreatePrizePresenter';
export class CreatePrizePresenter implements ICreatePrizePresenter { export class CreatePrizePresenter implements ICreatePrizePresenter {
private result: CreatePrizeViewModel | null = null; private result: CreatePrizeResultDTO | null = null;
reset() { reset() {
this.result = null; this.result = null;
@@ -15,11 +14,11 @@ export class CreatePrizePresenter implements ICreatePrizePresenter {
this.result = dto; this.result = dto;
} }
getViewModel(): CreatePrizeViewModel | null { getResponseModel(): CreatePrizeResultDTO | null {
return this.result; return this.result;
} }
get viewModel(): CreatePrizeViewModel { get viewModel(): CreatePrizeResultDTO {
if (!this.result) throw new Error('Presenter not presented'); if (!this.result) throw new Error('Presenter not presented');
return this.result; return this.result;
} }

View File

@@ -1,11 +1,10 @@
import type { import type { Presenter } from '@core/shared/presentation/Presenter';
IDeletePrizePresenter, import { DeletePrizeResultDTO } from '../dtos/DeletePrizeDTO';
DeletePrizeResultDTO,
DeletePrizeViewModel, export interface IDeletePrizePresenter extends Presenter<DeletePrizeResultDTO, DeletePrizeResultDTO> {}
} from '@core/payments/application/presenters/IDeletePrizePresenter';
export class DeletePrizePresenter implements IDeletePrizePresenter { export class DeletePrizePresenter implements IDeletePrizePresenter {
private result: DeletePrizeViewModel | null = null; private result: DeletePrizeResultDTO | null = null;
reset() { reset() {
this.result = null; this.result = null;
@@ -15,11 +14,11 @@ export class DeletePrizePresenter implements IDeletePrizePresenter {
this.result = dto; this.result = dto;
} }
getViewModel(): DeletePrizeViewModel | null { getResponseModel(): DeletePrizeResultDTO | null {
return this.result; return this.result;
} }
get viewModel(): DeletePrizeViewModel { get viewModel(): DeletePrizeResultDTO {
if (!this.result) throw new Error('Presenter not presented'); if (!this.result) throw new Error('Presenter not presented');
return this.result; return this.result;
} }

View File

@@ -1,11 +1,10 @@
import type { import type { Presenter } from '@core/shared/presentation/Presenter';
IGetMembershipFeesPresenter, import { GetMembershipFeesResultDTO } from '../dtos/GetMembershipFeesDTO';
GetMembershipFeesResultDTO,
GetMembershipFeesViewModel, export interface IGetMembershipFeesPresenter extends Presenter<GetMembershipFeesResultDTO, GetMembershipFeesResultDTO> {}
} from '@core/payments/application/presenters/IGetMembershipFeesPresenter';
export class GetMembershipFeesPresenter implements IGetMembershipFeesPresenter { export class GetMembershipFeesPresenter implements IGetMembershipFeesPresenter {
private result: GetMembershipFeesViewModel | null = null; private result: GetMembershipFeesResultDTO | null = null;
reset() { reset() {
this.result = null; this.result = null;
@@ -15,11 +14,11 @@ export class GetMembershipFeesPresenter implements IGetMembershipFeesPresenter {
this.result = dto; this.result = dto;
} }
getViewModel(): GetMembershipFeesViewModel | null { getResponseModel(): GetMembershipFeesResultDTO | null {
return this.result; return this.result;
} }
get viewModel(): GetMembershipFeesViewModel { get viewModel(): GetMembershipFeesResultDTO {
if (!this.result) throw new Error('Presenter not presented'); if (!this.result) throw new Error('Presenter not presented');
return this.result; return this.result;
} }

View File

@@ -28,7 +28,7 @@ export class GetPaymentsPresenter implements UseCaseOutputPort<GetPaymentsResult
}; };
} }
get responseModel(): GetPaymentsOutput { getResponseModel(): GetPaymentsOutput {
if (!this.responseModel) throw new Error('Presenter not presented'); if (!this.responseModel) throw new Error('Presenter not presented');
return this.responseModel; return this.responseModel;
} }

View File

@@ -1,11 +1,10 @@
import type { import type { Presenter } from '@core/shared/presentation/Presenter';
IGetPrizesPresenter, import { GetPrizesResultDTO } from '../dtos/GetPrizesDTO';
GetPrizesResultDTO,
GetPrizesViewModel, export interface IGetPrizesPresenter extends Presenter<GetPrizesResultDTO, GetPrizesResultDTO> {}
} from '@core/payments/application/presenters/IGetPrizesPresenter';
export class GetPrizesPresenter implements IGetPrizesPresenter { export class GetPrizesPresenter implements IGetPrizesPresenter {
private result: GetPrizesViewModel | null = null; private result: GetPrizesResultDTO | null = null;
reset() { reset() {
this.result = null; this.result = null;
@@ -15,11 +14,11 @@ export class GetPrizesPresenter implements IGetPrizesPresenter {
this.result = dto; this.result = dto;
} }
getViewModel(): GetPrizesViewModel | null { getResponseModel(): GetPrizesResultDTO | null {
return this.result; return this.result;
} }
get viewModel(): GetPrizesViewModel { get viewModel(): GetPrizesResultDTO {
if (!this.result) throw new Error('Presenter not presented'); if (!this.result) throw new Error('Presenter not presented');
return this.result; return this.result;
} }

View File

@@ -1,11 +1,10 @@
import type { import type { Presenter } from '@core/shared/presentation/Presenter';
IGetWalletPresenter, import { GetWalletResultDTO } from '../dtos/GetWalletDTO';
GetWalletResultDTO,
GetWalletViewModel, export interface IGetWalletPresenter extends Presenter<GetWalletResultDTO, GetWalletResultDTO> {}
} from '@core/payments/application/presenters/IGetWalletPresenter';
export class GetWalletPresenter implements IGetWalletPresenter { export class GetWalletPresenter implements IGetWalletPresenter {
private result: GetWalletViewModel | null = null; private result: GetWalletResultDTO | null = null;
reset() { reset() {
this.result = null; this.result = null;
@@ -15,11 +14,11 @@ export class GetWalletPresenter implements IGetWalletPresenter {
this.result = dto; this.result = dto;
} }
getViewModel(): GetWalletViewModel | null { getResponseModel(): GetWalletResultDTO | null {
return this.result; return this.result;
} }
get viewModel(): GetWalletViewModel { get viewModel(): GetWalletResultDTO {
if (!this.result) throw new Error('Presenter not presented'); if (!this.result) throw new Error('Presenter not presented');
return this.result; return this.result;
} }

View File

@@ -1,11 +1,10 @@
import type { import type { Presenter } from '@core/shared/presentation/Presenter';
IProcessWalletTransactionPresenter, import { ProcessWalletTransactionResultDTO } from '../dtos/ProcessWalletTransactionDTO';
ProcessWalletTransactionResultDTO,
ProcessWalletTransactionViewModel, export interface IProcessWalletTransactionPresenter extends Presenter<ProcessWalletTransactionResultDTO, ProcessWalletTransactionResultDTO> {}
} from '@core/payments/application/presenters/IProcessWalletTransactionPresenter';
export class ProcessWalletTransactionPresenter implements IProcessWalletTransactionPresenter { export class ProcessWalletTransactionPresenter implements IProcessWalletTransactionPresenter {
private result: ProcessWalletTransactionViewModel | null = null; private result: ProcessWalletTransactionResultDTO | null = null;
reset() { reset() {
this.result = null; this.result = null;
@@ -15,11 +14,11 @@ export class ProcessWalletTransactionPresenter implements IProcessWalletTransact
this.result = dto; this.result = dto;
} }
getViewModel(): ProcessWalletTransactionViewModel | null { getResponseModel(): ProcessWalletTransactionResultDTO | null {
return this.result; return this.result;
} }
get viewModel(): ProcessWalletTransactionViewModel { get viewModel(): ProcessWalletTransactionResultDTO {
if (!this.result) throw new Error('Presenter not presented'); if (!this.result) throw new Error('Presenter not presented');
return this.result; return this.result;
} }

View File

@@ -1,11 +1,10 @@
import type { import type { Presenter } from '@core/shared/presentation/Presenter';
IUpdateMemberPaymentPresenter, import { UpdateMemberPaymentResultDTO } from '../dtos/UpdateMemberPaymentDTO';
UpdateMemberPaymentResultDTO,
UpdateMemberPaymentViewModel, export interface IUpdateMemberPaymentPresenter extends Presenter<UpdateMemberPaymentResultDTO, UpdateMemberPaymentResultDTO> {}
} from '@core/payments/application/presenters/IUpdateMemberPaymentPresenter';
export class UpdateMemberPaymentPresenter implements IUpdateMemberPaymentPresenter { export class UpdateMemberPaymentPresenter implements IUpdateMemberPaymentPresenter {
private result: UpdateMemberPaymentViewModel | null = null; private result: UpdateMemberPaymentResultDTO | null = null;
reset() { reset() {
this.result = null; this.result = null;
@@ -15,11 +14,11 @@ export class UpdateMemberPaymentPresenter implements IUpdateMemberPaymentPresent
this.result = dto; this.result = dto;
} }
getViewModel(): UpdateMemberPaymentViewModel | null { getResponseModel(): UpdateMemberPaymentResultDTO | null {
return this.result; return this.result;
} }
get viewModel(): UpdateMemberPaymentViewModel { get viewModel(): UpdateMemberPaymentResultDTO {
if (!this.result) throw new Error('Presenter not presented'); if (!this.result) throw new Error('Presenter not presented');
return this.result; return this.result;
} }

View File

@@ -1,11 +1,10 @@
import type { import type { Presenter } from '@core/shared/presentation/Presenter';
IUpsertMembershipFeePresenter, import { UpsertMembershipFeeResultDTO } from '../dtos/UpsertMembershipFeeDTO';
UpsertMembershipFeeResultDTO,
UpsertMembershipFeeViewModel, export interface IUpsertMembershipFeePresenter extends Presenter<UpsertMembershipFeeResultDTO, UpsertMembershipFeeResultDTO> {}
} from '@core/payments/application/presenters/IUpsertMembershipFeePresenter';
export class UpsertMembershipFeePresenter implements IUpsertMembershipFeePresenter { export class UpsertMembershipFeePresenter implements IUpsertMembershipFeePresenter {
private result: UpsertMembershipFeeViewModel | null = null; private result: UpsertMembershipFeeResultDTO | null = null;
reset() { reset() {
this.result = null; this.result = null;
@@ -15,11 +14,11 @@ export class UpsertMembershipFeePresenter implements IUpsertMembershipFeePresent
this.result = dto; this.result = dto;
} }
getViewModel(): UpsertMembershipFeeViewModel | null { getResponseModel(): UpsertMembershipFeeResultDTO | null {
return this.result; return this.result;
} }
get viewModel(): UpsertMembershipFeeViewModel { get viewModel(): UpsertMembershipFeeResultDTO {
if (!this.result) throw new Error('Presenter not presented'); if (!this.result) throw new Error('Presenter not presented');
return this.result; return this.result;
} }