import { Controller, Get, Post, Patch, Delete, Body, Query, HttpCode, HttpStatus, Inject } from '@nestjs/common'; import { ApiTags, ApiResponse, ApiOperation } from '@nestjs/swagger'; import { RequireAuthenticatedUser } from '../auth/RequireAuthenticatedUser'; import { RequireRoles } from '../auth/RequireRoles'; import { RequireCapability } from '../policy/RequireCapability'; import { PaymentsService } from './PaymentsService'; import { CreatePaymentInput, CreatePaymentOutput, UpdatePaymentStatusInput, UpdatePaymentStatusOutput, GetPaymentsQuery, GetPaymentsOutput, GetMembershipFeesQuery, GetMembershipFeesOutput, UpsertMembershipFeeInput, UpsertMembershipFeeOutput, UpdateMemberPaymentInput, UpdateMemberPaymentOutput, GetPrizesQuery, GetPrizesOutput, CreatePrizeInput, CreatePrizeOutput, AwardPrizeInput, AwardPrizeOutput, DeletePrizeInput, DeletePrizeOutput, GetWalletQuery, GetWalletOutput, ProcessWalletTransactionInput, ProcessWalletTransactionOutput } from './dtos/PaymentsDto'; @ApiTags('payments') @RequireAuthenticatedUser() @RequireRoles('admin') @Controller('payments') export class PaymentsController { constructor(@Inject(PaymentsService) private readonly paymentsService: PaymentsService) {} @Get() @RequireCapability('payments.admin', 'view') @ApiOperation({ summary: 'Get payments based on filters' }) @ApiResponse({ status: 200, description: 'List of payments', type: GetPaymentsOutput }) async getPayments(@Query() query: GetPaymentsQuery): Promise { return this.paymentsService.getPayments(query); } @Post() @RequireCapability('payments.admin', 'mutate') @HttpCode(HttpStatus.CREATED) @ApiOperation({ summary: 'Create a new payment' }) @ApiResponse({ status: 201, description: 'Payment created', type: CreatePaymentOutput }) async createPayment(@Body() input: CreatePaymentInput): Promise { return this.paymentsService.createPayment(input); } @Patch('status') @RequireCapability('payments.admin', 'mutate') @ApiOperation({ summary: 'Update the status of a payment' }) @ApiResponse({ status: 200, description: 'Payment status updated', type: UpdatePaymentStatusOutput }) async updatePaymentStatus(@Body() input: UpdatePaymentStatusInput): Promise { return this.paymentsService.updatePaymentStatus(input); } @Get('membership-fees') @RequireCapability('payments.admin', 'view') @ApiOperation({ summary: 'Get membership fees and member payments' }) @ApiResponse({ status: 200, description: 'Membership fee configuration and member payments', type: GetMembershipFeesOutput }) async getMembershipFees(@Query() query: GetMembershipFeesQuery): Promise { return this.paymentsService.getMembershipFees(query); } @Post('membership-fees') @RequireCapability('payments.admin', 'mutate') @HttpCode(HttpStatus.CREATED) @ApiOperation({ summary: 'Create or update membership fee configuration' }) @ApiResponse({ status: 201, description: 'Membership fee configuration created or updated', type: UpsertMembershipFeeOutput }) async upsertMembershipFee(@Body() input: UpsertMembershipFeeInput): Promise { return this.paymentsService.upsertMembershipFee(input); } @Patch('membership-fees/member-payment') @RequireCapability('payments.admin', 'mutate') @ApiOperation({ summary: 'Record or update a member payment' }) @ApiResponse({ status: 200, description: 'Member payment recorded or updated', type: UpdateMemberPaymentOutput }) async updateMemberPayment(@Body() input: UpdateMemberPaymentInput): Promise { return this.paymentsService.updateMemberPayment(input); } @Get('prizes') @RequireCapability('payments.admin', 'view') @ApiOperation({ summary: 'Get prizes for a league or season' }) @ApiResponse({ status: 200, description: 'List of prizes', type: GetPrizesOutput }) async getPrizes(@Query() query: GetPrizesQuery): Promise { return this.paymentsService.getPrizes(query); } @Post('prizes') @RequireCapability('payments.admin', 'mutate') @HttpCode(HttpStatus.CREATED) @ApiOperation({ summary: 'Create a new prize' }) @ApiResponse({ status: 201, description: 'Prize created', type: CreatePrizeOutput }) async createPrize(@Body() input: CreatePrizeInput): Promise { return this.paymentsService.createPrize(input); } @Patch('prizes/award') @RequireCapability('payments.admin', 'mutate') @ApiOperation({ summary: 'Award a prize to a driver' }) @ApiResponse({ status: 200, description: 'Prize awarded', type: AwardPrizeOutput }) async awardPrize(@Body() input: AwardPrizeInput): Promise { return this.paymentsService.awardPrize(input); } @Delete('prizes') @RequireCapability('payments.admin', 'mutate') @ApiOperation({ summary: 'Delete a prize' }) @ApiResponse({ status: 200, description: 'Prize deleted', type: DeletePrizeOutput }) async deletePrize(@Query() query: DeletePrizeInput): Promise { return this.paymentsService.deletePrize(query); } @Get('wallets') @RequireCapability('payments.admin', 'view') @ApiOperation({ summary: 'Get wallet information and transactions' }) @ApiResponse({ status: 200, description: 'Wallet and transaction data', type: GetWalletOutput }) async getWallet(@Query() query: GetWalletQuery): Promise { return this.paymentsService.getWallet(query); } @Post('wallets/transactions') @RequireCapability('payments.admin', 'mutate') @HttpCode(HttpStatus.CREATED) @ApiOperation({ summary: 'Process a wallet transaction (deposit or withdrawal)' }) @ApiResponse({ status: 201, description: 'Wallet transaction processed', type: ProcessWalletTransactionOutput }) async processWalletTransaction(@Body() input: ProcessWalletTransactionInput): Promise { return this.paymentsService.processWalletTransaction(input); } }