Skip to content

Commit

Permalink
affiliate: Create endpoint to get donations with pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
sashko9807 committed Oct 24, 2023
1 parent 80711dd commit 4de21df
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 14 deletions.
16 changes: 7 additions & 9 deletions apps/api/src/affiliate/affiliate.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { BadRequestException, ConflictException, ForbiddenException } from '@nes
import { AffiliateStatusUpdateDto } from './dto/affiliate-status-update.dto'
import * as afCodeGenerator from './utils/affiliateCodeGenerator'
import { CreateAffiliateDonation } from './dto/create-affiliate-donation.dto'
import { CancelAffiliateDonation } from './dto/cancel-affiliate-donation.dto'

type PersonWithPayload = Prisma.PersonGetPayload<{ include: { company: true } }>
type AffiliateWithPayload = Prisma.AffiliateGetPayload<{
Expand Down Expand Up @@ -322,30 +321,29 @@ describe('AffiliateController', () => {
...donationResponseMock,
status: 'cancelled',
}
const donationDto: CancelAffiliateDonation = { donationId: donationResponseMock.id }
const affiliateDonationSpy = jest
.spyOn(donationService, 'getAffiliateDonationById')
.mockResolvedValue(donationResponseMock)
const updateDonationStatus = jest
.spyOn(donationService, 'update')
.mockResolvedValue(cancelledDonationResponse)
expect(await controller.cancelAffiliateDonation(affiliateCodeMock, donationDto)).toEqual(
cancelledDonationResponse,
)
expect(
await controller.cancelAffiliateDonation(affiliateCodeMock, donationResponseMock.id),
).toEqual(cancelledDonationResponse)
})
it('should throw error if donation status is succeeded', async () => {
const succeededDonationResponse: Donation = {
...donationResponseMock,
status: 'succeeded',
}
const donationDto: CancelAffiliateDonation = { donationId: donationResponseMock.id }

const affiliateDonationSpy = jest
.spyOn(donationService, 'getAffiliateDonationById')
.mockResolvedValue(succeededDonationResponse)
const updateDonationStatus = jest.spyOn(donationService, 'update')
expect(controller.cancelAffiliateDonation(affiliateCodeMock, donationDto)).rejects.toThrow(
new BadRequestException("Donation status can't be updated"),
)
expect(
controller.cancelAffiliateDonation(affiliateCodeMock, donationResponseMock.id),
).rejects.toThrow(new BadRequestException("Donation status can't be updated"))
expect(updateDonationStatus).not.toHaveBeenCalled()
})
})
Expand Down
23 changes: 21 additions & 2 deletions apps/api/src/affiliate/affiliate.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import {
Body,
ConflictException,
Controller,
DefaultValuePipe,
ForbiddenException,
Get,
NotFoundException,
Param,
ParseIntPipe,
Patch,
Post,
Query,
} from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger'
import { PersonService } from '../person/person.service'
Expand All @@ -20,6 +23,7 @@ import { CreateAffiliateDonation } from './dto/create-affiliate-donation.dto'
import { DonationsService } from '../donations/donations.service'
import { shouldAllowStatusChange } from '../donations/helpers/donation-status-updates'
import { affiliateCodeGenerator } from './utils/affiliateCodeGenerator'
import { DonationStatus } from '@prisma/client'

@Controller('affiliate')
@ApiTags('affiliate')
Expand Down Expand Up @@ -69,7 +73,7 @@ export class AffiliateController {
@Get(':affiliateCode')
@Public()
async affiliateSummary(@Param('affiliateCode') affilliateCode: string) {
return await this.affiliateService.findOneByCode(affilliateCode)
return await this.affiliateService.getAffiliateSummaryByCode(affilliateCode)
}

@Post(':affiliateCode/donation')
Expand All @@ -81,7 +85,6 @@ export class AffiliateController {
const affiliate = await this.affiliateService.findOneByCode(affiliateCode)
if (!affiliate || !affiliate.company || !affiliate.company.person)
throw new NotFoundException('Affiliate not found')

const affiliateDonationDto: CreateAffiliateDonation = {
...donation,
affiliateId: affiliate.id,
Expand All @@ -93,6 +96,22 @@ export class AffiliateController {
return await this.donationService.createAffiliateDonation(affiliateDonationDto)
}

@Get(':affiliateCode/donations')
@Public()
async getAffiliateDonations(
@Param('affiliateCode') affiliateCode: string,
@Query('status') status: DonationStatus | undefined,
@Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
@Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number,
) {
return await this.affiliateService.findAffiliateDonationsWithPagination(
affiliateCode,
status,
page,
limit,
)
}

@Patch(':affiliateCode/donations/:donationId/cancel')
@Public()
async cancelAffiliateDonation(
Expand Down
37 changes: 34 additions & 3 deletions apps/api/src/affiliate/affiliate.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Injectable } from '@nestjs/common'
import { PrismaService } from '../prisma/prisma.service'
import { AffiliateStatus } from '@prisma/client'
import { AffiliateStatus, DonationStatus } from '@prisma/client'

@Injectable()
export class AffiliateService {
constructor(private readonly prismaService: PrismaService) {}

async create(companyId: string) {
const affiliate = await this.prismaService.affiliate.create({
data: { companyId },
Expand All @@ -23,10 +22,42 @@ export class AffiliateService {
})
}

async findAffiliateDonationsWithPagination(
affiliateCode: string,
status: DonationStatus | undefined,
currentPage: number,
limit: number,
) {
return await this.prismaService.affiliate.findUnique({
where: { affiliateCode },
select: {
donations: {
orderBy: { createdAt: 'desc' },
where: { status },
take: limit,
skip: Number((currentPage - 1) * limit),
},
},
})
}

async getAffiliateSummaryByCode(affiliateCode: string) {
return await this.prismaService.affiliate.findUnique({
where: { affiliateCode },
include: {
donations: {
orderBy: { createdAt: 'desc' },
take: 10,
},
company: { select: { companyName: true, companyNumber: true, legalPersonName: true } },
},
})
}

async findOneByCode(affiliateCode: string) {
return await this.prismaService.affiliate.findUnique({
where: { affiliateCode },
include: { donations: true, company: { select: { person: true } } },
include: { company: { select: { person: true } } },
})
}

Expand Down

0 comments on commit 4de21df

Please sign in to comment.