import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, QueryParam } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; import { DonationNotFoundError } from '../errors/DonationErrors'; import { DonorNotFoundError } from '../errors/DonorErrors'; import { RunnerNotFoundError } from '../errors/RunnerErrors'; import { CreateDistanceDonation } from '../models/actions/create/CreateDistanceDonation'; import { CreateFixedDonation } from '../models/actions/create/CreateFixedDonation'; import { DistanceDonation } from '../models/entities/DistanceDonation'; import { Donation } from '../models/entities/Donation'; import { FixedDonation } from '../models/entities/FixedDonation'; import { ResponseDistanceDonation } from '../models/responses/ResponseDistanceDonation'; import { ResponseDonation } from '../models/responses/ResponseDonation'; import { ResponseEmpty } from '../models/responses/ResponseEmpty'; @JsonController('/donations') @OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] }) export class DonationController { private donationRepository: Repository; private distanceDonationRepository: Repository; private fixedDonationRepository: Repository; /** * Gets the repository of this controller's model/entity. */ constructor() { this.donationRepository = getConnectionManager().get().getRepository(Donation); this.distanceDonationRepository = getConnectionManager().get().getRepository(DistanceDonation); this.fixedDonationRepository = getConnectionManager().get().getRepository(FixedDonation); } @Get() @Authorized("DONATION:GET") @ResponseSchema(ResponseDonation, { isArray: true }) @ResponseSchema(ResponseDistanceDonation, { isArray: true }) @OpenAPI({ description: 'Lists all donations (fixed or distance based) from all donors.
This includes the donations\'s runner\'s distance ran(if distance donation).' }) async getAll() { let responseDonations: ResponseDonation[] = new Array(); const donations = await this.donationRepository.find({ relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'] }); donations.forEach(donation => { responseDonations.push(donation.toResponse()); }); return responseDonations; } @Get('/:id') @Authorized("DONATION:GET") @ResponseSchema(ResponseDonation) @ResponseSchema(ResponseDistanceDonation) @ResponseSchema(DonationNotFoundError, { statusCode: 404 }) @OnUndefined(DonationNotFoundError) @OpenAPI({ description: 'Lists all information about the donation whose id got provided. This includes the donation\'s runner\'s distance ran (if distance donation).' }) async getOne(@Param('id') id: number) { let donation = await this.donationRepository.findOne({ id: id }, { relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'] }) if (!donation) { throw new DonationNotFoundError(); } return donation.toResponse(); } @Post('/fixed') @Authorized("DONATION:CREATE") @ResponseSchema(ResponseDonation) @ResponseSchema(DonorNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Create a fixed donation (not distance donation - use /donations/distance instead).
Please rmemember to provide the donation\'s donors\'s id and amount.' }) async postFixed(@Body({ validate: true }) createDonation: CreateFixedDonation) { let donation = await createDonation.toEntity(); donation = await this.fixedDonationRepository.save(donation); return (await this.donationRepository.findOne({ id: donation.id }, { relations: ['donor'] })).toResponse(); } @Post('/distance') @Authorized("DONATION:CREATE") @ResponseSchema(ResponseDistanceDonation) @ResponseSchema(DonorNotFoundError, { statusCode: 404 }) @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Create a distance donation (not fixed donation - use /donations/fixed instead).
Please rmemember to provide the donation\'s donors\'s and runner\s ids and amount per distance (kilometer).' }) async postDistance(@Body({ validate: true }) createDonation: CreateDistanceDonation) { let donation = await createDonation.toEntity(); donation = await this.distanceDonationRepository.save(donation); return (await this.donationRepository.findOne({ id: donation.id }, { relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'] })).toResponse(); } // @Put('/:id') // @Authorized("SCAN:UPDATE") // @ResponseSchema(ResponseScan) // @ResponseSchema(ScanNotFoundError, { statusCode: 404 }) // @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) // @ResponseSchema(ScanIdsNotMatchingError, { statusCode: 406 }) // @OpenAPI({ description: "Update the scan (not track scan use /scans/trackscans/:id instead) whose id you provided.
Please remember that ids can't be changed and distances must be positive." }) // async put(@Param('id') id: number, @Body({ validate: true }) scan: UpdateScan) { // let oldScan = await this.scanRepository.findOne({ id: id }); // if (!oldScan) { // throw new ScanNotFoundError(); // } // if (oldScan.id != scan.id) { // throw new ScanIdsNotMatchingError(); // } // await this.scanRepository.save(await scan.update(oldScan)); // return (await this.scanRepository.findOne({ id: id }, { relations: ['runner', 'track', 'runner.scans', 'runner.scans.track', 'card', 'station'] })).toResponse(); // } // @Put('/trackscans/:id') // @Authorized("SCAN:UPDATE") // @ResponseSchema(ResponseTrackScan) // @ResponseSchema(ScanNotFoundError, { statusCode: 404 }) // @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) // @ResponseSchema(ScanStationNotFoundError, { statusCode: 404 }) // @ResponseSchema(ScanIdsNotMatchingError, { statusCode: 406 }) // @OpenAPI({ description: 'Update the track scan (not "normal" scan use /scans/trackscans/:id instead) whose id you provided.
Please remember that only the validity, runner and track can be changed.' }) // async putTrackScan(@Param('id') id: number, @Body({ validate: true }) scan: UpdateTrackScan) { // let oldScan = await this.trackScanRepository.findOne({ id: id }); // if (!oldScan) { // throw new ScanNotFoundError(); // } // if (oldScan.id != scan.id) { // throw new ScanIdsNotMatchingError(); // } // await this.trackScanRepository.save(await scan.update(oldScan)); // return (await this.scanRepository.findOne({ id: id }, { relations: ['runner', 'track', 'runner.scans', 'runner.scans.track', 'card', 'station'] })).toResponse(); // } @Delete('/:id') @Authorized("DONATION:DELETE") @ResponseSchema(ResponseDonation) @ResponseSchema(ResponseDistanceDonation) @ResponseSchema(ResponseEmpty, { statusCode: 204 }) @OnUndefined(204) @OpenAPI({ description: 'Delete the donation whose id you provided.
If no donation with this id exists it will just return 204(no content).' }) async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { let donation = await this.donationRepository.findOne({ id: id }); if (!donation) { return null; } const responseScan = await this.donationRepository.findOne({ id: donation.id }, { relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'] }); await this.donationRepository.delete(donation); return responseScan.toResponse(); } }