import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; import { DonorHasDonationsError, DonorIdsNotMatchingError, DonorNotFoundError } from '../errors/DonorErrors'; import { CreateDonor } from '../models/actions/create/CreateDonor'; import { UpdateDonor } from '../models/actions/update/UpdateDonor'; import { Donor } from '../models/entities/Donor'; import { ResponseDonor } from '../models/responses/ResponseDonor'; import { ResponseEmpty } from '../models/responses/ResponseEmpty'; import { DonationController } from './DonationController'; @JsonController('/donors') @OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] }) export class DonorController { private donorRepository: Repository; /** * Gets the repository of this controller's model/entity. */ constructor() { this.donorRepository = getConnectionManager().get().getRepository(Donor); } @Get() @Authorized("DONOR:GET") @ResponseSchema(ResponseDonor, { isArray: true }) @OpenAPI({ description: 'Lists all donor.
This includes the donor\'s current donation amount.' }) async getAll() { let responseDonors: ResponseDonor[] = new Array(); const donors = await this.donorRepository.find({ relations: ['donations', 'donations.runner', 'donations.runner.scans', 'donations.runner.scans.track'] }); donors.forEach(donor => { responseDonors.push(new ResponseDonor(donor)); }); return responseDonors; } @Get('/:id') @Authorized("DONOR:GET") @ResponseSchema(ResponseDonor) @ResponseSchema(DonorNotFoundError, { statusCode: 404 }) @OnUndefined(DonorNotFoundError) @OpenAPI({ description: 'Lists all information about the donor whose id got provided.
This includes the donor\'s current donation amount.' }) async getOne(@Param('id') id: number) { let donor = await this.donorRepository.findOne({ id: id }, { relations: ['donations', 'donations.runner', 'donations.runner.scans', 'donations.runner.scans.track'] }) if (!donor) { throw new DonorNotFoundError(); } return new ResponseDonor(donor); } @Post() @Authorized("DONOR:CREATE") @ResponseSchema(ResponseDonor) @OpenAPI({ description: 'Create a new donor.' }) async post(@Body({ validate: true }) createRunner: CreateDonor) { let donor; try { donor = await createRunner.toEntity(); } catch (error) { throw error; } donor = await this.donorRepository.save(donor) return new ResponseDonor(await this.donorRepository.findOne(donor, { relations: ['donations', 'donations.runner', 'donations.runner.scans', 'donations.runner.scans.track'] })); } @Put('/:id') @Authorized("DONOR:UPDATE") @ResponseSchema(ResponseDonor) @ResponseSchema(DonorNotFoundError, { statusCode: 404 }) @ResponseSchema(DonorIdsNotMatchingError, { statusCode: 406 }) @OpenAPI({ description: "Update the donor whose id you provided.
Please remember that ids can't be changed." }) async put(@Param('id') id: number, @Body({ validate: true }) donor: UpdateDonor) { let oldDonor = await this.donorRepository.findOne({ id: id }); if (!oldDonor) { throw new DonorNotFoundError(); } if (oldDonor.id != donor.id) { throw new DonorIdsNotMatchingError(); } await this.donorRepository.save(await donor.update(oldDonor)); return new ResponseDonor(await this.donorRepository.findOne({ id: id }, { relations: ['donations', 'donations.runner', 'donations.runner.scans', 'donations.runner.scans.track'] })); } @Delete('/:id') @Authorized("DONOR:DELETE") @ResponseSchema(ResponseDonor) @ResponseSchema(ResponseEmpty, { statusCode: 204 }) @OnUndefined(204) @OpenAPI({ description: 'Delete the donor whose id you provided.
If no donor with this id exists it will just return 204(no content).
If the donor still has donations associated this will fail, please provide the query param ?force=true to delete the donor with all associated donations.' }) async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { let donor = await this.donorRepository.findOne({ id: id }); if (!donor) { return null; } const responseDonor = await this.donorRepository.findOne(donor, { relations: ['donations', 'donations.runner', 'donations.runner.scans', 'donations.runner.scans.track'] }); if (!donor) { throw new DonorNotFoundError(); } const donorDonations = (await this.donorRepository.findOne({ id: donor.id }, { relations: ["donations"] })).donations; if (donorDonations.length > 0 && !force) { throw new DonorHasDonationsError(); } const donationController = new DonationController(); for (let donation of donorDonations) { await donationController.remove(donation.id, force); } await this.donorRepository.delete(donor); return new ResponseDonor(responseDonor); } }