153 lines
7.9 KiB
TypeScript
153 lines
7.9 KiB
TypeScript
import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers';
|
|
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
|
import { Repository, getConnectionManager } from 'typeorm';
|
|
import { DonationIdsNotMatchingError, 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 { UpdateDistanceDonation } from '../models/actions/update/UpdateDistanceDonation';
|
|
import { UpdateFixedDonation } from '../models/actions/update/UpdateFixedDonation';
|
|
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<Donation>;
|
|
private distanceDonationRepository: Repository<DistanceDonation>;
|
|
private fixedDonationRepository: Repository<FixedDonation>;
|
|
|
|
/**
|
|
* 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. <br> This includes the donations\'s runner\'s distance ran(if distance donation).' })
|
|
async getAll(@QueryParam("page", { required: false }) page: number, @QueryParam("page_size", { required: false }) page_size: number = 100) {
|
|
let responseDonations: ResponseDonation[] = new Array<ResponseDonation>();
|
|
let donations: Array<Donation>;
|
|
|
|
if (page != undefined) {
|
|
donations = await this.donationRepository.find({ relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'], skip: page * page_size, take: page_size });
|
|
} else {
|
|
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). <br> 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). <br> 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.distanceDonationRepository.findOne({ id: donation.id }, { relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'] })).toResponse();
|
|
}
|
|
|
|
@Put('/fixed/:id')
|
|
@Authorized("DONATION:UPDATE")
|
|
@ResponseSchema(ResponseDonation)
|
|
@ResponseSchema(DonationNotFoundError, { statusCode: 404 })
|
|
@ResponseSchema(DonorNotFoundError, { statusCode: 404 })
|
|
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
|
|
@ResponseSchema(DonationIdsNotMatchingError, { statusCode: 406 })
|
|
@OpenAPI({ description: "Update the fixed donation (not distance donation - use /donations/distance instead) whose id you provided. <br> Please remember that ids can't be changed and amounts must be positive." })
|
|
async putFixed(@Param('id') id: number, @Body({ validate: true }) donation: UpdateFixedDonation) {
|
|
let oldDonation = await this.fixedDonationRepository.findOne({ id: id });
|
|
|
|
if (!oldDonation) {
|
|
throw new DonationNotFoundError();
|
|
}
|
|
|
|
if (oldDonation.id != donation.id) {
|
|
throw new DonationIdsNotMatchingError();
|
|
}
|
|
|
|
await this.fixedDonationRepository.save(await donation.update(oldDonation));
|
|
return (await this.donationRepository.findOne({ id: donation.id }, { relations: ['donor'] })).toResponse();
|
|
}
|
|
|
|
@Put('/distance/:id')
|
|
@Authorized("DONATION:UPDATE")
|
|
@ResponseSchema(ResponseDonation)
|
|
@ResponseSchema(DonationNotFoundError, { statusCode: 404 })
|
|
@ResponseSchema(DonorNotFoundError, { statusCode: 404 })
|
|
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
|
|
@ResponseSchema(DonationIdsNotMatchingError, { statusCode: 406 })
|
|
@OpenAPI({ description: "Update the distance donation (not fixed donation - use /donations/fixed instead) whose id you provided. <br> Please remember that ids can't be changed and amountPerDistance must be positive." })
|
|
async putDistance(@Param('id') id: number, @Body({ validate: true }) donation: UpdateDistanceDonation) {
|
|
let oldDonation = await this.distanceDonationRepository.findOne({ id: id });
|
|
|
|
if (!oldDonation) {
|
|
throw new DonationNotFoundError();
|
|
}
|
|
|
|
if (oldDonation.id != donation.id) {
|
|
throw new DonationIdsNotMatchingError();
|
|
}
|
|
|
|
await this.distanceDonationRepository.save(await donation.update(oldDonation));
|
|
return (await this.distanceDonationRepository.findOne({ id: donation.id }, { relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'] })).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. <br> 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();
|
|
}
|
|
}
|