From 5d7d80d2e75e0cdf68eea458b97610e6e2322087 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Fri, 4 Dec 2020 22:58:34 +0100 Subject: [PATCH 01/10] A step towards inheritance for the create* objects relating to runner groups ref #13 --- src/models/creation/CreateRunnerGroup.ts | 30 ++++++++++++ .../creation/CreateRunnerOrganisation.ts | 48 ++++++++++++++++--- 2 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 src/models/creation/CreateRunnerGroup.ts diff --git a/src/models/creation/CreateRunnerGroup.ts b/src/models/creation/CreateRunnerGroup.ts new file mode 100644 index 0000000..33cb5a9 --- /dev/null +++ b/src/models/creation/CreateRunnerGroup.ts @@ -0,0 +1,30 @@ +import { IsNotEmpty, IsObject, IsOptional, IsString } from 'class-validator'; +import { GroupContact } from '../entities/GroupContact'; + +export abstract class CreateRunnerGroup { + /** + * The group's name. + */ + @IsNotEmpty() + @IsString() + name: string; + + /** + * The group's contact. + * Optional + */ + @IsObject() + @IsOptional() + contact?: GroupContact; + + /** + * Deals with the contact for groups this. + */ + public async getContact(): Promise { + let newGroupContact: GroupContact; + + //TODO: + + return newGroupContact; + } +} \ No newline at end of file diff --git a/src/models/creation/CreateRunnerOrganisation.ts b/src/models/creation/CreateRunnerOrganisation.ts index ff4ec65..b90162d 100644 --- a/src/models/creation/CreateRunnerOrganisation.ts +++ b/src/models/creation/CreateRunnerOrganisation.ts @@ -1,13 +1,47 @@ -import { IsNotEmpty, IsString } from 'class-validator'; +import { IsInt, IsObject, IsOptional } from 'class-validator'; +import { getConnectionManager } from 'typeorm'; +import { ParticipantOnlyOneAddressAllowedError } from '../../errors/ParticipantErrors'; +import { Address } from '../entities/Address'; import { RunnerOrganisation } from '../entities/RunnerOrganisation'; +import { CreateAddress } from './CreateAddress'; +import { CreateRunnerGroup } from './CreateRunnerGroup'; -export class CreateRunnerOrganisation { +export class CreateRunnerOrganisation extends CreateRunnerGroup { /** - * The Organisation's name. + * The new participant's address's id. + * Optional - please provide either addressId or address. */ - @IsString() - @IsNotEmpty() - name: string; + @IsInt() + @IsOptional() + addressId?: number; + + /** + * The new participant's address. + * Optional - please provide either addressId or address. + */ + @IsObject() + @IsOptional() + address?: CreateAddress; + + /** + * Creates a Participant entity from this. + */ + public async getAddress(): Promise
{ + let address: Address; + + if (this.addressId !== undefined && this.address !== undefined) { + throw new ParticipantOnlyOneAddressAllowedError + } + if (this.addressId === undefined && this.address === undefined) { + return null; + } + + if (this.addressId) { + return await getConnectionManager().get().getRepository(Address).findOne({ id: this.addressId }); + } + + return this.address.toAddress(); + } /** * Creates a RunnerOrganisation entity from this. @@ -16,6 +50,8 @@ export class CreateRunnerOrganisation { let newRunnerOrganisation: RunnerOrganisation = new RunnerOrganisation(); newRunnerOrganisation.name = this.name; + newRunnerOrganisation.contact = await this.getContact(); + newRunnerOrganisation.address = await this.getAddress(); return newRunnerOrganisation; } From aca13f730865e3660bdc14574af71d1ccfd7e5ad Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 5 Dec 2020 10:59:15 +0100 Subject: [PATCH 02/10] Fixed bugs concerning posts ref #13 --- src/controllers/RunnerController.ts | 3 ++- src/controllers/RunnerOrganisationController.ts | 3 +-- src/models/entities/DistanceDonation.ts | 12 ++---------- src/models/entities/Runner.ts | 17 +++++------------ src/models/entities/RunnerTeam.ts | 2 +- 5 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/controllers/RunnerController.ts b/src/controllers/RunnerController.ts index 14658da..96853cc 100644 --- a/src/controllers/RunnerController.ts +++ b/src/controllers/RunnerController.ts @@ -55,7 +55,8 @@ export class RunnerController { return error; } - return new ResponseRunner(await this.runnerRepository.save(runner)); + runner = await this.runnerRepository.save(runner) + return new ResponseRunner(await this.runnerRepository.findOne(runner, { relations: ['scans', 'group'] })); } @Put('/:id') diff --git a/src/controllers/RunnerOrganisationController.ts b/src/controllers/RunnerOrganisationController.ts index bed6eec..451a6e7 100644 --- a/src/controllers/RunnerOrganisationController.ts +++ b/src/controllers/RunnerOrganisationController.ts @@ -58,9 +58,8 @@ export class RunnerOrganisationController { } runnerOrganisation = await this.runnerOrganisationRepository.save(runnerOrganisation); - runnerOrganisation = await this.runnerOrganisationRepository.findOne(runnerOrganisation, { relations: ['address', 'contact', 'teams'] }); - return new ResponseRunnerOrganisation(runnerOrganisation); + return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(runnerOrganisation, { relations: ['address', 'contact', 'teams'] })); } @Put('/:id') diff --git a/src/models/entities/DistanceDonation.ts b/src/models/entities/DistanceDonation.ts index 9051849..3103865 100644 --- a/src/models/entities/DistanceDonation.ts +++ b/src/models/entities/DistanceDonation.ts @@ -28,18 +28,10 @@ export class DistanceDonation extends Donation { * The donation's amount in cents (or whatever your currency's smallest unit is.). * The exact implementation may differ for each type of donation. */ - @IsInt() - public get amount() { - return this.getAmount(); - } - - /** - * The function that calculates the amount based on the runner object's distance. - */ - public async getAmount(): Promise { + public get amount(): number { let calculatedAmount = -1; try { - calculatedAmount = this.amountPerDistance * await this.runner.distance(); + calculatedAmount = this.amountPerDistance * this.runner.distance; } catch (error) { throw error; } diff --git a/src/models/entities/Runner.ts b/src/models/entities/Runner.ts index 5454f64..6f4033a 100644 --- a/src/models/entities/Runner.ts +++ b/src/models/entities/Runner.ts @@ -1,5 +1,5 @@ import { IsInt, IsNotEmpty } from "class-validator"; -import { ChildEntity, getConnectionManager, ManyToOne, OneToMany } from "typeorm"; +import { ChildEntity, ManyToOne, OneToMany } from "typeorm"; import { DistanceDonation } from "./DistanceDonation"; import { Participant } from "./Participant"; import { RunnerCard } from "./RunnerCard"; @@ -36,25 +36,18 @@ export class Runner extends Participant { @OneToMany(() => Scan, scan => scan.runner, { nullable: true }) scans: Scan[]; - /** - * Returns all scans associated with this runner. - */ - public async getScans(): Promise { - return await getConnectionManager().get().getRepository(Scan).find({ runner: this }); - } - /** * Returns all valid scans associated with this runner. */ - public async getValidScans(): Promise { - return (await this.getScans()).filter(scan => { scan.valid === true }); + public get validScans(): Scan[] { + return this.scans.filter(scan => { scan.valid === true }); } /** * Returns the total distance ran by this runner. */ @IsInt() - public async distance(): Promise { - return await (await this.getValidScans()).reduce((sum, current) => sum + current.distance, 0); + public get distance(): number { + return this.validScans.reduce((sum, current) => sum + current.distance, 0); } } \ No newline at end of file diff --git a/src/models/entities/RunnerTeam.ts b/src/models/entities/RunnerTeam.ts index 21cdcb4..44a047a 100644 --- a/src/models/entities/RunnerTeam.ts +++ b/src/models/entities/RunnerTeam.ts @@ -15,7 +15,7 @@ export class RunnerTeam extends RunnerGroup { * Optional */ @IsNotEmpty() - @ManyToOne(() => RunnerOrganisation, org => org.teams, { nullable: false }) + @ManyToOne(() => RunnerOrganisation, org => org.teams, { nullable: true }) parentGroup?: RunnerOrganisation; /** From 9c63a34fe13ffed8e35371c42617a43814f7d16c Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 5 Dec 2020 11:36:33 +0100 Subject: [PATCH 03/10] Little bugfix ref #13 --- src/controllers/RunnerController.ts | 2 +- src/controllers/RunnerTeamController.ts | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/controllers/RunnerController.ts b/src/controllers/RunnerController.ts index 96853cc..0c49bea 100644 --- a/src/controllers/RunnerController.ts +++ b/src/controllers/RunnerController.ts @@ -84,7 +84,7 @@ export class RunnerController { @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Delete a specified runner (if it exists).' }) async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { - let runner = await this.runnerRepository.findOne({ id: id }); + const runner = await this.runnerRepository.findOne({ id: id }); if (!runner) { throw new RunnerNotFoundError(); diff --git a/src/controllers/RunnerTeamController.ts b/src/controllers/RunnerTeamController.ts index 6103083..8abc0ff 100644 --- a/src/controllers/RunnerTeamController.ts +++ b/src/controllers/RunnerTeamController.ts @@ -4,7 +4,6 @@ import { getConnectionManager, Repository } from 'typeorm'; import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; import { RunnerTeamHasRunnersError, RunnerTeamIdsNotMatchingError, RunnerTeamNotFoundError } from '../errors/RunnerTeamErrors'; import { CreateRunnerTeam } from '../models/creation/CreateRunnerTeam'; -import { Runner } from '../models/entities/Runner'; import { RunnerTeam } from '../models/entities/RunnerTeam'; import { ResponseRunnerTeam } from '../models/responses/ResponseRunnerTeam'; import { RunnerController } from './RunnerController'; @@ -89,21 +88,20 @@ export class RunnerTeamController { @ResponseSchema(RunnerTeamHasRunnersError, { statusCode: 406 }) @OpenAPI({ description: 'Delete a specified runnerTeam (if it exists).' }) async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { - let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact'] }); + let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact', 'runners'] }); if (!runnerTeam) { throw new RunnerTeamNotFoundError(); } - let runners: Runner[] = await runnerTeam.getRunners() if (!force) { - if (runners.length != 0) { + if (runnerTeam.runners.length != 0) { throw new RunnerTeamHasRunnersError(); } } const runnerController = new RunnerController() - runners.forEach(runner => { - runnerController.remove(runner.id, true) + await runnerTeam.runners.forEach(async runner => { + await runnerController.remove(runner.id, true); }); const responseTeam = new ResponseRunnerTeam(runnerTeam); From 45675b06994d6754fa0106f46353b48041aaba13 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 5 Dec 2020 12:15:51 +0100 Subject: [PATCH 04/10] All things deletion for runner* now are clean af and cascadeing ref #13 --- src/controllers/RunnerController.ts | 10 ++--- .../RunnerOrganisationController.ts | 41 +++++++++---------- src/controllers/RunnerTeamController.ts | 14 +++---- src/models/entities/RunnerGroup.ts | 2 - src/models/entities/RunnerOrganisation.ts | 26 +----------- src/models/entities/RunnerTeam.ts | 10 +---- 6 files changed, 33 insertions(+), 70 deletions(-) diff --git a/src/controllers/RunnerController.ts b/src/controllers/RunnerController.ts index 0c49bea..026b4a6 100644 --- a/src/controllers/RunnerController.ts +++ b/src/controllers/RunnerController.ts @@ -1,7 +1,7 @@ import { 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 { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { RunnerGroupNeededError, RunnerGroupNotFoundError, RunnerIdsNotMatchingError, RunnerNotFoundError, RunnerOnlyOneGroupAllowedError } from '../errors/RunnerErrors'; import { CreateRunner } from '../models/creation/CreateRunner'; import { Runner } from '../models/entities/Runner'; @@ -65,7 +65,7 @@ export class RunnerController { @ResponseSchema(RunnerIdsNotMatchingError, { statusCode: 406 }) @OpenAPI({ description: "Update a runner object (id can't be changed)." }) async put(@Param('id') id: number, @EntityFromBody() runner: Runner) { - let oldRunner = await this.runnerRepository.findOne({ id: id }); + let oldRunner = await this.runnerRepository.findOne({ id: id }, { relations: ['scans', 'group'] }); if (!oldRunner) { throw new RunnerNotFoundError(); @@ -83,14 +83,14 @@ export class RunnerController { @ResponseSchema(ResponseRunner) @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Delete a specified runner (if it exists).' }) - async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { - const runner = await this.runnerRepository.findOne({ id: id }); + async remove(@EntityFromParam('id') runner: Runner, @QueryParam("force") force: boolean) { + const responseRunner = await this.runnerRepository.findOne(runner, { relations: ['scans', 'group'] }); if (!runner) { throw new RunnerNotFoundError(); } await this.runnerRepository.delete(runner); - return new ResponseRunner(runner); + return new ResponseRunner(responseRunner); } } diff --git a/src/controllers/RunnerOrganisationController.ts b/src/controllers/RunnerOrganisationController.ts index 451a6e7..127cb55 100644 --- a/src/controllers/RunnerOrganisationController.ts +++ b/src/controllers/RunnerOrganisationController.ts @@ -1,12 +1,10 @@ import { 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 { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { RunnerOrganisationHasRunnersError, RunnerOrganisationHasTeamsError, RunnerOrganisationIdsNotMatchingError, RunnerOrganisationNotFoundError } from '../errors/RunnerOrganisationErrors'; import { CreateRunnerOrganisation } from '../models/creation/CreateRunnerOrganisation'; -import { Runner } from '../models/entities/Runner'; import { RunnerOrganisation } from '../models/entities/RunnerOrganisation'; -import { RunnerTeam } from '../models/entities/RunnerTeam'; import { ResponseRunnerOrganisation } from '../models/responses/ResponseRunnerOrganisation'; import { RunnerController } from './RunnerController'; import { RunnerTeamController } from './RunnerTeamController'; @@ -87,39 +85,38 @@ export class RunnerOrganisationController { @Delete('/:id') @ResponseSchema(ResponseRunnerOrganisation) @ResponseSchema(RunnerOrganisationNotFoundError, { statusCode: 404 }) + @ResponseSchema(RunnerOrganisationHasTeamsError, { statusCode: 406 }) @ResponseSchema(RunnerOrganisationHasRunnersError, { statusCode: 406 }) @OpenAPI({ description: 'Delete a specified runnerOrganisation (if it exists).' }) - async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { - let runnerOrganisation = await this.runnerOrganisationRepository.findOne({ id: id }, { relations: ['address', 'contact', 'teams'] }); + async remove(@EntityFromParam('id') organisation: RunnerOrganisation, @QueryParam("force") force: boolean) { + let runnerOrganisation = await this.runnerOrganisationRepository.findOne(organisation, { relations: ['address', 'contact', 'runners', 'teams'] }); if (!runnerOrganisation) { throw new RunnerOrganisationNotFoundError(); } - let runners: Runner[] = await runnerOrganisation.getRunners() if (!force) { - if (runners.length != 0) { - throw new RunnerOrganisationHasRunnersError(); - } - } - const runnerController = new RunnerController() - runners.forEach(runner => { - runnerController.remove(runner.id, true) - }); - - let teams: RunnerTeam[] = await runnerOrganisation.getTeams() - if (!force) { - if (teams.length != 0) { + if (runnerOrganisation.teams.length != 0) { throw new RunnerOrganisationHasTeamsError(); } } const teamController = new RunnerTeamController() - teams.forEach(team => { - teamController.remove(team.id, true) - }); + for (let team of runnerOrganisation.teams) { + await teamController.remove(team, true); + } + + if (!force) { + if (runnerOrganisation.runners.length != 0) { + throw new RunnerOrganisationHasRunnersError(); + } + } + const runnerController = new RunnerController() + for (let runner of runnerOrganisation.runners) { + await runnerController.remove(runner, true); + } const responseOrganisation = new ResponseRunnerOrganisation(runnerOrganisation); - await this.runnerOrganisationRepository.delete({ id: runnerOrganisation.id }); + await this.runnerOrganisationRepository.delete(organisation); return responseOrganisation; } } diff --git a/src/controllers/RunnerTeamController.ts b/src/controllers/RunnerTeamController.ts index 8abc0ff..b0061b5 100644 --- a/src/controllers/RunnerTeamController.ts +++ b/src/controllers/RunnerTeamController.ts @@ -1,7 +1,7 @@ import { 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 { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { RunnerTeamHasRunnersError, RunnerTeamIdsNotMatchingError, RunnerTeamNotFoundError } from '../errors/RunnerTeamErrors'; import { CreateRunnerTeam } from '../models/creation/CreateRunnerTeam'; import { RunnerTeam } from '../models/entities/RunnerTeam'; @@ -87,8 +87,8 @@ export class RunnerTeamController { @ResponseSchema(RunnerTeamNotFoundError, { statusCode: 404 }) @ResponseSchema(RunnerTeamHasRunnersError, { statusCode: 406 }) @OpenAPI({ description: 'Delete a specified runnerTeam (if it exists).' }) - async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { - let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact', 'runners'] }); + async remove(@EntityFromParam('id') team: RunnerTeam, @QueryParam("force") force: boolean) { + let runnerTeam = await this.runnerTeamRepository.findOne(team, { relations: ['parentGroup', 'contact', 'runners'] }); if (!runnerTeam) { throw new RunnerTeamNotFoundError(); @@ -100,12 +100,12 @@ export class RunnerTeamController { } } const runnerController = new RunnerController() - await runnerTeam.runners.forEach(async runner => { - await runnerController.remove(runner.id, true); - }); + for (let runner of runnerTeam.runners) { + await runnerController.remove(runner, true); + } const responseTeam = new ResponseRunnerTeam(runnerTeam); - await this.runnerTeamRepository.delete({ id: runnerTeam.id }); + await this.runnerTeamRepository.delete(team); return responseTeam; } } diff --git a/src/models/entities/RunnerGroup.ts b/src/models/entities/RunnerGroup.ts index c042384..a2bd585 100644 --- a/src/models/entities/RunnerGroup.ts +++ b/src/models/entities/RunnerGroup.ts @@ -42,6 +42,4 @@ export abstract class RunnerGroup { */ @OneToMany(() => Runner, runner => runner.group, { nullable: true }) runners: Runner[]; - - public abstract getRunners(); } \ No newline at end of file diff --git a/src/models/entities/RunnerOrganisation.ts b/src/models/entities/RunnerOrganisation.ts index bfdfe49..28b90d8 100644 --- a/src/models/entities/RunnerOrganisation.ts +++ b/src/models/entities/RunnerOrganisation.ts @@ -1,7 +1,6 @@ import { IsOptional } from "class-validator"; -import { ChildEntity, getConnectionManager, ManyToOne, OneToMany } from "typeorm"; +import { ChildEntity, ManyToOne, OneToMany } from "typeorm"; import { Address } from "./Address"; -import { Runner } from './Runner'; import { RunnerGroup } from "./RunnerGroup"; import { RunnerTeam } from "./RunnerTeam"; @@ -24,27 +23,4 @@ export class RunnerOrganisation extends RunnerGroup { */ @OneToMany(() => RunnerTeam, team => team.parentGroup, { nullable: true }) teams: RunnerTeam[]; - - - /** - * Returns all runners associated with this organisation or it's teams. - */ - public async getRunners() { - let runners: Runner[] = new Array(); - const teams = await this.getTeams(); - - await teams.forEach(async team => { - runners.push(... await team.getRunners()); - }); - await runners.push(... await getConnectionManager().get().getRepository(Runner).find({ group: this })); - - return runners; - } - - /** - * Returns all teams associated with this organisation. - */ - public async getTeams() { - return await getConnectionManager().get().getRepository(RunnerTeam).find({ parentGroup: this }); - } } \ No newline at end of file diff --git a/src/models/entities/RunnerTeam.ts b/src/models/entities/RunnerTeam.ts index 44a047a..bcae3fd 100644 --- a/src/models/entities/RunnerTeam.ts +++ b/src/models/entities/RunnerTeam.ts @@ -1,6 +1,5 @@ import { IsNotEmpty } from "class-validator"; -import { ChildEntity, getConnectionManager, ManyToOne } from "typeorm"; -import { Runner } from './Runner'; +import { ChildEntity, ManyToOne } from "typeorm"; import { RunnerGroup } from "./RunnerGroup"; import { RunnerOrganisation } from "./RunnerOrganisation"; @@ -17,11 +16,4 @@ export class RunnerTeam extends RunnerGroup { @IsNotEmpty() @ManyToOne(() => RunnerOrganisation, org => org.teams, { nullable: true }) parentGroup?: RunnerOrganisation; - - /** - * Returns all runners associated with this team. - */ - public async getRunners() { - return await getConnectionManager().get().getRepository(Runner).find({ group: this }); - } } \ No newline at end of file From 179add80f480cd10f2951d8f7077164da840d4d0 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 5 Dec 2020 12:18:24 +0100 Subject: [PATCH 05/10] Now throwing errors even faster ref #13 --- src/controllers/RunnerController.ts | 1 + src/controllers/RunnerOrganisationController.ts | 5 +---- src/controllers/RunnerTeamController.ts | 5 +---- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/controllers/RunnerController.ts b/src/controllers/RunnerController.ts index 026b4a6..6508f67 100644 --- a/src/controllers/RunnerController.ts +++ b/src/controllers/RunnerController.ts @@ -84,6 +84,7 @@ export class RunnerController { @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Delete a specified runner (if it exists).' }) async remove(@EntityFromParam('id') runner: Runner, @QueryParam("force") force: boolean) { + if (!runner) { throw new RunnerNotFoundError(); } const responseRunner = await this.runnerRepository.findOne(runner, { relations: ['scans', 'group'] }); if (!runner) { diff --git a/src/controllers/RunnerOrganisationController.ts b/src/controllers/RunnerOrganisationController.ts index 127cb55..8cfef6a 100644 --- a/src/controllers/RunnerOrganisationController.ts +++ b/src/controllers/RunnerOrganisationController.ts @@ -89,12 +89,9 @@ export class RunnerOrganisationController { @ResponseSchema(RunnerOrganisationHasRunnersError, { statusCode: 406 }) @OpenAPI({ description: 'Delete a specified runnerOrganisation (if it exists).' }) async remove(@EntityFromParam('id') organisation: RunnerOrganisation, @QueryParam("force") force: boolean) { + if (!organisation) { throw new RunnerOrganisationNotFoundError() } let runnerOrganisation = await this.runnerOrganisationRepository.findOne(organisation, { relations: ['address', 'contact', 'runners', 'teams'] }); - if (!runnerOrganisation) { - throw new RunnerOrganisationNotFoundError(); - } - if (!force) { if (runnerOrganisation.teams.length != 0) { throw new RunnerOrganisationHasTeamsError(); diff --git a/src/controllers/RunnerTeamController.ts b/src/controllers/RunnerTeamController.ts index b0061b5..1b7627d 100644 --- a/src/controllers/RunnerTeamController.ts +++ b/src/controllers/RunnerTeamController.ts @@ -88,12 +88,9 @@ export class RunnerTeamController { @ResponseSchema(RunnerTeamHasRunnersError, { statusCode: 406 }) @OpenAPI({ description: 'Delete a specified runnerTeam (if it exists).' }) async remove(@EntityFromParam('id') team: RunnerTeam, @QueryParam("force") force: boolean) { + if (!team) { throw new RunnerTeamNotFoundError(); } let runnerTeam = await this.runnerTeamRepository.findOne(team, { relations: ['parentGroup', 'contact', 'runners'] }); - if (!runnerTeam) { - throw new RunnerTeamNotFoundError(); - } - if (!force) { if (runnerTeam.runners.length != 0) { throw new RunnerTeamHasRunnersError(); From 0e3cf07b9147f32cf3da40e764fea19fb1f52c58 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 5 Dec 2020 12:21:47 +0100 Subject: [PATCH 06/10] TrackController now also deletes based on a entityfromparam ref #13 --- src/controllers/TrackController.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/controllers/TrackController.ts b/src/controllers/TrackController.ts index ae451be..02370fc 100644 --- a/src/controllers/TrackController.ts +++ b/src/controllers/TrackController.ts @@ -1,7 +1,7 @@ import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; -import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { TrackIdsNotMatchingError, TrackNotFoundError } from "../errors/TrackErrors"; import { CreateTrack } from '../models/creation/CreateTrack'; import { Track } from '../models/entities/Track'; @@ -74,14 +74,10 @@ export class TrackController { @ResponseSchema(ResponseTrack) @ResponseSchema(TrackNotFoundError, { statusCode: 404 }) @OpenAPI({ description: "Delete a specified track (if it exists)." }) - async remove(@Param('id') id: number) { - let track = await this.trackRepository.findOne({ id: id }); - - if (!track) { - throw new TrackNotFoundError(); - } + async remove(@EntityFromParam('id') track: Track) { + if (!track) { throw new TrackNotFoundError(); } await this.trackRepository.delete(track); return new ResponseTrack(track); } -} +} \ No newline at end of file From 8870b26ce63d6294567863c76d9dcfccd18e681d Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 5 Dec 2020 12:24:38 +0100 Subject: [PATCH 07/10] Deletes now work based on EntityFromParam ref #14 --- src/controllers/UserController.ts | 12 +++++------- src/controllers/UserGroupController.ts | 12 +++++------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/controllers/UserController.ts b/src/controllers/UserController.ts index dbc4d3a..01e743e 100644 --- a/src/controllers/UserController.ts +++ b/src/controllers/UserController.ts @@ -1,7 +1,7 @@ import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; -import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { UserGroupNotFoundError, UserIdsNotMatchingError, UserNotFoundError } from '../errors/UserErrors'; import { CreateUser } from '../models/creation/CreateUser'; import { User } from '../models/entities/User'; @@ -73,14 +73,12 @@ export class UserController { @ResponseSchema(User) @ResponseSchema(UserNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Delete a specified runner (if it exists).' }) - async remove(@Param('id') id: number) { - let runner = await this.userRepository.findOne({ id: id }); - - if (!runner) { + async remove(@EntityFromParam('id') user: User) { + if (!user) { throw new UserNotFoundError(); } - await this.userRepository.delete(runner); - return runner; + await this.userRepository.delete(user); + return user; } } diff --git a/src/controllers/UserGroupController.ts b/src/controllers/UserGroupController.ts index fb158ed..c937f36 100644 --- a/src/controllers/UserGroupController.ts +++ b/src/controllers/UserGroupController.ts @@ -1,7 +1,7 @@ import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; -import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; +import { EntityFromBody, EntityFromParam } from 'typeorm-routing-controllers-extensions'; import { UserGroupIdsNotMatchingError, UserGroupNotFoundError } from '../errors/UserGroupErrors'; import { CreateUserGroup } from '../models/creation/CreateUserGroup'; import { UserGroup } from '../models/entities/UserGroup'; @@ -73,14 +73,12 @@ export class UserGroupController { @ResponseSchema(UserGroup) @ResponseSchema(UserGroupNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Delete a specified usergroup (if it exists).' }) - async remove(@Param('id') id: number) { - let userGroup = await this.userGroupsRepository.findOne({ id: id }); - - if (!userGroup) { + async remove(@EntityFromParam('id') group: UserGroup) { + if (!group) { throw new UserGroupNotFoundError(); } - await this.userGroupsRepository.delete(userGroup); - return userGroup; + await this.userGroupsRepository.delete(group); + return group; } } From 975d30e411c580d8c6a7e6c87f7d0187b97070f1 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 5 Dec 2020 12:39:11 +0100 Subject: [PATCH 08/10] Smoothed out the participant creation process regarting addresses ref #13 --- src/errors/ParticipantErrors.ts | 6 ++-- src/models/creation/CreateParticipant.ts | 40 ++++++++++-------------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/errors/ParticipantErrors.ts b/src/errors/ParticipantErrors.ts index de672d8..97c5412 100644 --- a/src/errors/ParticipantErrors.ts +++ b/src/errors/ParticipantErrors.ts @@ -1,12 +1,12 @@ import { IsString } from 'class-validator'; import { NotAcceptableError, NotFoundError } from 'routing-controllers'; -export class ParticipantOnlyOneAddressAllowedError extends NotAcceptableError { +export class ParticipantAddressWrongTypeError extends NotAcceptableError { @IsString() - name = "ParticipantOnlyOneAddressAllowedError" + name = "ParticipantAddressWrongTypeError" @IsString() - message = "Participant's can only have one address! \n You provided an id and address object.." + message = "The participant's address must be either a existing address, new address or a existing adress's id. \n You provided a object of another type." } export class ParticipantAddressNotFoundError extends NotFoundError { diff --git a/src/models/creation/CreateParticipant.ts b/src/models/creation/CreateParticipant.ts index 8436186..c70cf56 100644 --- a/src/models/creation/CreateParticipant.ts +++ b/src/models/creation/CreateParticipant.ts @@ -1,6 +1,6 @@ -import { IsEmail, IsInt, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; import { getConnectionManager } from 'typeorm'; -import { ParticipantOnlyOneAddressAllowedError } from '../../errors/ParticipantErrors'; +import { ParticipantAddressNotFoundError, ParticipantAddressWrongTypeError } from '../../errors/ParticipantErrors'; import { Address } from '../entities/Address'; import { CreateAddress } from './CreateAddress'; @@ -45,39 +45,33 @@ export abstract class CreateParticipant { @IsEmail() email?: string; - /** - * The new participant's address's id. - * Optional - please provide either addressId or address. - */ - @IsInt() - @IsOptional() - addressId?: number; - /** * The new participant's address. - * Optional - please provide either addressId or address. + * Must be of type number (address id), createAddress (new address) or address (existing address) + * Optional. */ @IsObject() - @IsOptional() - address?: CreateAddress; + address?: number | CreateAddress | Address; /** * Creates a Participant entity from this. */ public async getAddress(): Promise
{ - let address: Address; - - if (this.addressId !== undefined && this.address !== undefined) { - throw new ParticipantOnlyOneAddressAllowedError - } - if (this.addressId === undefined && this.address === undefined) { + if (this.address === undefined) { return null; } - - if (this.addressId) { - return await getConnectionManager().get().getRepository(Address).findOne({ id: this.addressId }); + if (this.address! instanceof Address) { + return this.address; + } + if (this.address! instanceof CreateAddress) { + return this.address.toAddress(); + } + if (!isNaN(this.address)) { + let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address }); + if (!address) { throw new ParticipantAddressNotFoundError; } + return address; } - return this.address.toAddress(); + throw new ParticipantAddressWrongTypeError; } } \ No newline at end of file From 4352910d54a74773499704070f35adb95e542ff6 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 5 Dec 2020 15:50:28 +0100 Subject: [PATCH 09/10] More dynamic creation of objects ref #13 --- src/errors/AddressErrors.ts | 18 ++++ src/errors/GroupContactErrors.ts | 18 ++++ src/errors/ParticipantErrors.ts | 18 ---- src/errors/RunnerOrganisationErrors.ts | 10 ++- src/errors/RunnerTeamErrors.ts | 12 +++ src/models/creation/CreateGroupContact.ts | 89 +++++++++++++++++++ src/models/creation/CreateParticipant.ts | 8 +- src/models/creation/CreateRunnerGroup.ts | 24 +++-- .../creation/CreateRunnerOrganisation.ts | 42 ++++----- src/models/creation/CreateRunnerTeam.ts | 40 +++++---- 10 files changed, 212 insertions(+), 67 deletions(-) create mode 100644 src/errors/AddressErrors.ts create mode 100644 src/errors/GroupContactErrors.ts delete mode 100644 src/errors/ParticipantErrors.ts create mode 100644 src/models/creation/CreateGroupContact.ts diff --git a/src/errors/AddressErrors.ts b/src/errors/AddressErrors.ts new file mode 100644 index 0000000..c655032 --- /dev/null +++ b/src/errors/AddressErrors.ts @@ -0,0 +1,18 @@ +import { IsString } from 'class-validator'; +import { NotAcceptableError, NotFoundError } from 'routing-controllers'; + +export class AddressWrongTypeError extends NotAcceptableError { + @IsString() + name = "AddressWrongTypeError" + + @IsString() + message = "The address must be either a existing address, new address or a existing adress's id. \n You provided a object of another type." +} + +export class AddressNotFoundError extends NotFoundError { + @IsString() + name = "AddressNotFoundError" + + @IsString() + message = "The address you provided couldn't be located in the system. \n Please check your request." +} \ No newline at end of file diff --git a/src/errors/GroupContactErrors.ts b/src/errors/GroupContactErrors.ts new file mode 100644 index 0000000..503fa47 --- /dev/null +++ b/src/errors/GroupContactErrors.ts @@ -0,0 +1,18 @@ +import { IsString } from 'class-validator'; +import { NotAcceptableError, NotFoundError } from 'routing-controllers'; + +export class GroupContactWrongTypeError extends NotAcceptableError { + @IsString() + name = "GroupContactWrongTypeError" + + @IsString() + message = "The groupContact must be either a existing groupContact, new groupContact or a existing adress's id. \n You provided a object of another type." +} + +export class GroupContactNotFoundError extends NotFoundError { + @IsString() + name = "GroupContactNotFoundError" + + @IsString() + message = "The groupContact you provided couldn't be located in the system. \n Please check your request." +} \ No newline at end of file diff --git a/src/errors/ParticipantErrors.ts b/src/errors/ParticipantErrors.ts deleted file mode 100644 index 97c5412..0000000 --- a/src/errors/ParticipantErrors.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { IsString } from 'class-validator'; -import { NotAcceptableError, NotFoundError } from 'routing-controllers'; - -export class ParticipantAddressWrongTypeError extends NotAcceptableError { - @IsString() - name = "ParticipantAddressWrongTypeError" - - @IsString() - message = "The participant's address must be either a existing address, new address or a existing adress's id. \n You provided a object of another type." -} - -export class ParticipantAddressNotFoundError extends NotFoundError { - @IsString() - name = "ParticipantAddressNotFoundError" - - @IsString() - message = "The address you provided couldn't be located in the system. \n Please check your request." -} \ No newline at end of file diff --git a/src/errors/RunnerOrganisationErrors.ts b/src/errors/RunnerOrganisationErrors.ts index 1dfb68e..9c0e6c3 100644 --- a/src/errors/RunnerOrganisationErrors.ts +++ b/src/errors/RunnerOrganisationErrors.ts @@ -48,4 +48,12 @@ export class RunnerOrganisationHasTeamsError extends NotAcceptableError { @IsString() message = "This organisation still has teams associated with it. \n If you want to delete this organisation with all it's runners and teams ass `?force` to your query." -} \ No newline at end of file +} + +export class RunnerOrganisationWrongTypeError extends NotAcceptableError { + @IsString() + name = "RunnerOrganisationWrongTypeError" + + @IsString() + message = "The runner organisation must be either a existing organisation, new organisation or a existing organisation's id. \n You provided a object of another type." +} diff --git a/src/errors/RunnerTeamErrors.ts b/src/errors/RunnerTeamErrors.ts index a482c26..33fbea5 100644 --- a/src/errors/RunnerTeamErrors.ts +++ b/src/errors/RunnerTeamErrors.ts @@ -36,4 +36,16 @@ export class RunnerTeamHasRunnersError extends NotAcceptableError { @IsString() message = "This team still has runners associated with it. \n If you want to delete this team with all it's runners and teams ass `?force` to your query." +} + +/** + * Error to throw when a team still has runners associated. + * Implemented this waysto work with the json-schema conversion for openapi. + */ +export class RunnerTeamNeedsParentError extends NotAcceptableError { + @IsString() + name = "RunnerTeamNeedsParentError" + + @IsString() + message = "You provided no runner organisation as this team's parent group." } \ No newline at end of file diff --git a/src/models/creation/CreateGroupContact.ts b/src/models/creation/CreateGroupContact.ts new file mode 100644 index 0000000..21b42d5 --- /dev/null +++ b/src/models/creation/CreateGroupContact.ts @@ -0,0 +1,89 @@ +import { IsEmail, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; +import { getConnectionManager } from 'typeorm'; +import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors'; +import { Address } from '../entities/Address'; +import { GroupContact } from '../entities/GroupContact'; +import { CreateAddress } from './CreateAddress'; + +export class CreateGroupContact { + /** + * The contact's first name. + */ + @IsNotEmpty() + @IsString() + firstname: string; + + /** + * The contact's middle name. + * Optional + */ + @IsOptional() + @IsString() + middlename?: string; + + /** + * The contact's last name. + */ + @IsNotEmpty() + @IsString() + lastname: string; + + /** + * The contact's address. + * Optional + */ + @IsOptional() + address?: Address | CreateAddress | number; + + /** + * The contact's phone number. + * Optional + */ + @IsOptional() + @IsPhoneNumber("DE") + phone?: string; + + /** + * The contact's email address. + * Optional + */ + @IsOptional() + @IsEmail() + email?: string; + + /** + * Get's this participant's address from this.address. + */ + public async getAddress(): Promise
{ + if (this.address === undefined) { + return null; + } + if (this.address! instanceof Address) { + return this.address; + } + if (this.address! instanceof CreateAddress) { + return this.address.toAddress(); + } + if (!isNaN(this.address)) { + let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address }); + if (!address) { throw new AddressNotFoundError; } + return address; + } + + throw new AddressWrongTypeError; + } + + /** + * Creates a Address object based on this. + */ + public async toGroupContact(): Promise { + let contact: GroupContact = new GroupContact(); + contact.firstname = this.firstname; + contact.middlename = this.middlename; + contact.lastname = this.lastname; + contact.email = this.email; + contact.phone = this.phone; + contact.address = await this.getAddress(); + return null; + } +} \ No newline at end of file diff --git a/src/models/creation/CreateParticipant.ts b/src/models/creation/CreateParticipant.ts index c70cf56..87472ed 100644 --- a/src/models/creation/CreateParticipant.ts +++ b/src/models/creation/CreateParticipant.ts @@ -1,6 +1,6 @@ import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; import { getConnectionManager } from 'typeorm'; -import { ParticipantAddressNotFoundError, ParticipantAddressWrongTypeError } from '../../errors/ParticipantErrors'; +import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors'; import { Address } from '../entities/Address'; import { CreateAddress } from './CreateAddress'; @@ -54,7 +54,7 @@ export abstract class CreateParticipant { address?: number | CreateAddress | Address; /** - * Creates a Participant entity from this. + * Get's this participant's address from this.address. */ public async getAddress(): Promise
{ if (this.address === undefined) { @@ -68,10 +68,10 @@ export abstract class CreateParticipant { } if (!isNaN(this.address)) { let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address }); - if (!address) { throw new ParticipantAddressNotFoundError; } + if (!address) { throw new AddressNotFoundError; } return address; } - throw new ParticipantAddressWrongTypeError; + throw new AddressWrongTypeError; } } \ No newline at end of file diff --git a/src/models/creation/CreateRunnerGroup.ts b/src/models/creation/CreateRunnerGroup.ts index 33cb5a9..20a5dab 100644 --- a/src/models/creation/CreateRunnerGroup.ts +++ b/src/models/creation/CreateRunnerGroup.ts @@ -1,5 +1,8 @@ import { IsNotEmpty, IsObject, IsOptional, IsString } from 'class-validator'; +import { getConnectionManager } from 'typeorm'; +import { GroupContactNotFoundError, GroupContactWrongTypeError } from '../../errors/GroupContactErrors'; import { GroupContact } from '../entities/GroupContact'; +import { CreateGroupContact } from './CreateGroupContact'; export abstract class CreateRunnerGroup { /** @@ -15,16 +18,27 @@ export abstract class CreateRunnerGroup { */ @IsObject() @IsOptional() - contact?: GroupContact; + contact?: number | CreateGroupContact | GroupContact; /** * Deals with the contact for groups this. */ public async getContact(): Promise { - let newGroupContact: GroupContact; + if (this.contact === undefined) { + return null; + } + if (this.contact! instanceof GroupContact) { + return this.contact; + } + if (this.contact! instanceof CreateGroupContact) { + return this.contact.toGroupContact(); + } + if (!isNaN(this.contact)) { + let address = await getConnectionManager().get().getRepository(GroupContact).findOne({ id: this.contact }); + if (!address) { throw new GroupContactNotFoundError; } + return address; + } - //TODO: - - return newGroupContact; + throw new GroupContactWrongTypeError; } } \ No newline at end of file diff --git a/src/models/creation/CreateRunnerOrganisation.ts b/src/models/creation/CreateRunnerOrganisation.ts index b90162d..6e40e60 100644 --- a/src/models/creation/CreateRunnerOrganisation.ts +++ b/src/models/creation/CreateRunnerOrganisation.ts @@ -1,6 +1,6 @@ -import { IsInt, IsObject, IsOptional } from 'class-validator'; +import { IsObject } from 'class-validator'; import { getConnectionManager } from 'typeorm'; -import { ParticipantOnlyOneAddressAllowedError } from '../../errors/ParticipantErrors'; +import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors'; import { Address } from '../entities/Address'; import { RunnerOrganisation } from '../entities/RunnerOrganisation'; import { CreateAddress } from './CreateAddress'; @@ -8,39 +8,33 @@ import { CreateRunnerGroup } from './CreateRunnerGroup'; export class CreateRunnerOrganisation extends CreateRunnerGroup { /** - * The new participant's address's id. - * Optional - please provide either addressId or address. - */ - @IsInt() - @IsOptional() - addressId?: number; - - /** - * The new participant's address. - * Optional - please provide either addressId or address. + * The new organisation's address. + * Must be of type number (address id), createAddress (new address) or address (existing address) + * Optional. */ @IsObject() - @IsOptional() - address?: CreateAddress; + address?: number | CreateAddress | Address; /** * Creates a Participant entity from this. */ public async getAddress(): Promise
{ - let address: Address; - - if (this.addressId !== undefined && this.address !== undefined) { - throw new ParticipantOnlyOneAddressAllowedError - } - if (this.addressId === undefined && this.address === undefined) { + if (this.address === undefined) { return null; } - - if (this.addressId) { - return await getConnectionManager().get().getRepository(Address).findOne({ id: this.addressId }); + if (this.address! instanceof Address) { + return this.address; + } + if (this.address! instanceof CreateAddress) { + return this.address.toAddress(); + } + if (!isNaN(this.address)) { + let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address }); + if (!address) { throw new AddressNotFoundError; } + return address; } - return this.address.toAddress(); + throw new AddressWrongTypeError; } /** diff --git a/src/models/creation/CreateRunnerTeam.ts b/src/models/creation/CreateRunnerTeam.ts index 101a516..341a765 100644 --- a/src/models/creation/CreateRunnerTeam.ts +++ b/src/models/creation/CreateRunnerTeam.ts @@ -1,23 +1,35 @@ -import { IsInt, IsNotEmpty, IsString } from 'class-validator'; +import { IsNotEmpty } from 'class-validator'; import { getConnectionManager } from 'typeorm'; -import { RunnerOrganisationNotFoundError } from '../../errors/RunnerOrganisationErrors'; +import { RunnerOrganisationNotFoundError, RunnerOrganisationWrongTypeError } from '../../errors/RunnerOrganisationErrors'; +import { RunnerTeamNeedsParentError } from '../../errors/RunnerTeamErrors'; import { RunnerOrganisation } from '../entities/RunnerOrganisation'; import { RunnerTeam } from '../entities/RunnerTeam'; +import { CreateRunnerGroup } from './CreateRunnerGroup'; -export class CreateRunnerTeam { - /** - * The teams's name. - */ - @IsString() - @IsNotEmpty() - name: string; +export class CreateRunnerTeam extends CreateRunnerGroup { /** * The team's parent group (organisation). */ - @IsInt() @IsNotEmpty() - parentId: number + parentGroup: number | RunnerOrganisation + + public async getParent(): Promise { + if (this.parentGroup === undefined) { + throw new RunnerTeamNeedsParentError(); + } + if (this.parentGroup! instanceof RunnerOrganisation) { + return this.parentGroup; + } + if (!isNaN(this.parentGroup)) { + let parentGroup = await getConnectionManager().get().getRepository(RunnerOrganisation).findOne({ id: this.parentGroup }); + if (!parentGroup) { throw new RunnerOrganisationNotFoundError();; } + return parentGroup; + } + console.log(this.parentGroup); + + throw new RunnerOrganisationWrongTypeError; + } /** * Creates a RunnerTeam entity from this. @@ -26,10 +38,8 @@ export class CreateRunnerTeam { let newRunnerTeam: RunnerTeam = new RunnerTeam(); newRunnerTeam.name = this.name; - newRunnerTeam.parentGroup = await getConnectionManager().get().getRepository(RunnerOrganisation).findOne({ id: this.parentId }); - if (!newRunnerTeam.parentGroup) { - throw new RunnerOrganisationNotFoundError(); - } + newRunnerTeam.parentGroup = await this.getParent(); + newRunnerTeam.contact = await this.getContact() return newRunnerTeam; } From 65b2399eaa83ae97a8ade0f4eef5a17f15773fcb Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 5 Dec 2020 17:04:22 +0100 Subject: [PATCH 10/10] Reverted to id based relation setter ref #13 --- src/errors/AddressErrors.ts | 2 +- src/errors/GroupContactErrors.ts | 2 +- src/errors/RunnerErrors.ts | 4 +- src/errors/RunnerOrganisationErrors.ts | 2 +- src/models/creation/CreateGroupContact.ts | 12 ++---- src/models/creation/CreateParticipant.ts | 14 ++----- src/models/creation/CreateRunner.ts | 41 ++++++------------- src/models/creation/CreateRunnerGroup.ts | 13 ++---- .../creation/CreateRunnerOrganisation.ts | 14 ++----- src/models/creation/CreateRunnerTeam.ts | 9 ++-- 10 files changed, 34 insertions(+), 79 deletions(-) diff --git a/src/errors/AddressErrors.ts b/src/errors/AddressErrors.ts index c655032..c7ae8af 100644 --- a/src/errors/AddressErrors.ts +++ b/src/errors/AddressErrors.ts @@ -6,7 +6,7 @@ export class AddressWrongTypeError extends NotAcceptableError { name = "AddressWrongTypeError" @IsString() - message = "The address must be either a existing address, new address or a existing adress's id. \n You provided a object of another type." + message = "The address must be an existing adress's id. \n You provided a object of another type." } export class AddressNotFoundError extends NotFoundError { diff --git a/src/errors/GroupContactErrors.ts b/src/errors/GroupContactErrors.ts index 503fa47..c5bf9c7 100644 --- a/src/errors/GroupContactErrors.ts +++ b/src/errors/GroupContactErrors.ts @@ -6,7 +6,7 @@ export class GroupContactWrongTypeError extends NotAcceptableError { name = "GroupContactWrongTypeError" @IsString() - message = "The groupContact must be either a existing groupContact, new groupContact or a existing adress's id. \n You provided a object of another type." + message = "The groupContact must be an existing groupContact's id. \n You provided a object of another type." } export class GroupContactNotFoundError extends NotFoundError { diff --git a/src/errors/RunnerErrors.ts b/src/errors/RunnerErrors.ts index 0be6419..8250d17 100644 --- a/src/errors/RunnerErrors.ts +++ b/src/errors/RunnerErrors.ts @@ -1,5 +1,5 @@ -import { JsonController, Param, Body, Get, Post, Put, Delete, NotFoundError, OnUndefined, NotAcceptableError } from 'routing-controllers'; -import { IsInt, IsNotEmpty, IsPositive, IsString } from 'class-validator'; +import { IsString } from 'class-validator'; +import { NotAcceptableError, NotFoundError } from 'routing-controllers'; /** * Error to throw when a runner couldn't be found. diff --git a/src/errors/RunnerOrganisationErrors.ts b/src/errors/RunnerOrganisationErrors.ts index 9c0e6c3..65736b1 100644 --- a/src/errors/RunnerOrganisationErrors.ts +++ b/src/errors/RunnerOrganisationErrors.ts @@ -55,5 +55,5 @@ export class RunnerOrganisationWrongTypeError extends NotAcceptableError { name = "RunnerOrganisationWrongTypeError" @IsString() - message = "The runner organisation must be either a existing organisation, new organisation or a existing organisation's id. \n You provided a object of another type." + message = "The runner organisation must be an existing organisation's id. \n You provided a object of another type." } diff --git a/src/models/creation/CreateGroupContact.ts b/src/models/creation/CreateGroupContact.ts index 21b42d5..73f43d0 100644 --- a/src/models/creation/CreateGroupContact.ts +++ b/src/models/creation/CreateGroupContact.ts @@ -1,9 +1,8 @@ -import { IsEmail, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; +import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; import { getConnectionManager } from 'typeorm'; import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors'; import { Address } from '../entities/Address'; import { GroupContact } from '../entities/GroupContact'; -import { CreateAddress } from './CreateAddress'; export class CreateGroupContact { /** @@ -32,8 +31,9 @@ export class CreateGroupContact { * The contact's address. * Optional */ + @IsInt() @IsOptional() - address?: Address | CreateAddress | number; + address?: number; /** * The contact's phone number. @@ -58,12 +58,6 @@ export class CreateGroupContact { if (this.address === undefined) { return null; } - if (this.address! instanceof Address) { - return this.address; - } - if (this.address! instanceof CreateAddress) { - return this.address.toAddress(); - } if (!isNaN(this.address)) { let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address }); if (!address) { throw new AddressNotFoundError; } diff --git a/src/models/creation/CreateParticipant.ts b/src/models/creation/CreateParticipant.ts index 87472ed..00c8783 100644 --- a/src/models/creation/CreateParticipant.ts +++ b/src/models/creation/CreateParticipant.ts @@ -1,8 +1,7 @@ -import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; +import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; import { getConnectionManager } from 'typeorm'; import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors'; import { Address } from '../entities/Address'; -import { CreateAddress } from './CreateAddress'; export abstract class CreateParticipant { /** @@ -50,8 +49,9 @@ export abstract class CreateParticipant { * Must be of type number (address id), createAddress (new address) or address (existing address) * Optional. */ - @IsObject() - address?: number | CreateAddress | Address; + @IsInt() + @IsOptional() + address?: number; /** * Get's this participant's address from this.address. @@ -60,12 +60,6 @@ export abstract class CreateParticipant { if (this.address === undefined) { return null; } - if (this.address! instanceof Address) { - return this.address; - } - if (this.address! instanceof CreateAddress) { - return this.address.toAddress(); - } if (!isNaN(this.address)) { let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address }); if (!address) { throw new AddressNotFoundError; } diff --git a/src/models/creation/CreateRunner.ts b/src/models/creation/CreateRunner.ts index b34ec9d..4e5f3e9 100644 --- a/src/models/creation/CreateRunner.ts +++ b/src/models/creation/CreateRunner.ts @@ -1,10 +1,10 @@ -import { IsInt, IsOptional } from 'class-validator'; +import { IsInt } from 'class-validator'; import { getConnectionManager } from 'typeorm'; -import { RunnerGroupNeededError, RunnerGroupNotFoundError, RunnerOnlyOneGroupAllowedError } from '../../errors/RunnerErrors'; +import { RunnerGroupNotFoundError } from '../../errors/RunnerErrors'; +import { RunnerOrganisationWrongTypeError } from '../../errors/RunnerOrganisationErrors'; +import { RunnerTeamNeedsParentError } from '../../errors/RunnerTeamErrors'; import { Runner } from '../entities/Runner'; import { RunnerGroup } from '../entities/RunnerGroup'; -import { RunnerOrganisation } from '../entities/RunnerOrganisation'; -import { RunnerTeam } from '../entities/RunnerTeam'; import { CreateParticipant } from './CreateParticipant'; export class CreateRunner extends CreateParticipant { @@ -14,16 +14,7 @@ export class CreateRunner extends CreateParticipant { * Either provide this or his organisation's id. */ @IsInt() - @IsOptional() - teamId?: number; - - /** - * The new runner's organisation's id. - * Either provide this or his teams's id. - */ - @IsInt() - @IsOptional() - orgId?: number; + group: number; /** * Creates a Runner entity from this. @@ -46,23 +37,15 @@ export class CreateRunner extends CreateParticipant { * Manages all the different ways a group can be provided. */ public async getGroup(): Promise { - let group: RunnerGroup; - if (this.teamId !== undefined && this.orgId !== undefined) { - throw new RunnerOnlyOneGroupAllowedError(); + if (this.group === undefined) { + throw new RunnerTeamNeedsParentError(); } - if (this.teamId === undefined && this.orgId === undefined) { - throw new RunnerGroupNeededError(); + if (!isNaN(this.group)) { + let group = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: this.group }); + if (!group) { throw new RunnerGroupNotFoundError; } + return group; } - if (this.teamId) { - group = await getConnectionManager().get().getRepository(RunnerTeam).findOne({ id: this.teamId }); - } - if (this.orgId) { - group = await getConnectionManager().get().getRepository(RunnerOrganisation).findOne({ id: this.orgId }); - } - if (!group) { - throw new RunnerGroupNotFoundError(); - } - return group; + throw new RunnerOrganisationWrongTypeError; } } \ No newline at end of file diff --git a/src/models/creation/CreateRunnerGroup.ts b/src/models/creation/CreateRunnerGroup.ts index 20a5dab..76552ac 100644 --- a/src/models/creation/CreateRunnerGroup.ts +++ b/src/models/creation/CreateRunnerGroup.ts @@ -1,8 +1,7 @@ -import { IsNotEmpty, IsObject, IsOptional, IsString } from 'class-validator'; +import { IsInt, IsNotEmpty, IsOptional, IsString } from 'class-validator'; import { getConnectionManager } from 'typeorm'; import { GroupContactNotFoundError, GroupContactWrongTypeError } from '../../errors/GroupContactErrors'; import { GroupContact } from '../entities/GroupContact'; -import { CreateGroupContact } from './CreateGroupContact'; export abstract class CreateRunnerGroup { /** @@ -16,9 +15,9 @@ export abstract class CreateRunnerGroup { * The group's contact. * Optional */ - @IsObject() + @IsInt() @IsOptional() - contact?: number | CreateGroupContact | GroupContact; + contact?: number; /** * Deals with the contact for groups this. @@ -27,12 +26,6 @@ export abstract class CreateRunnerGroup { if (this.contact === undefined) { return null; } - if (this.contact! instanceof GroupContact) { - return this.contact; - } - if (this.contact! instanceof CreateGroupContact) { - return this.contact.toGroupContact(); - } if (!isNaN(this.contact)) { let address = await getConnectionManager().get().getRepository(GroupContact).findOne({ id: this.contact }); if (!address) { throw new GroupContactNotFoundError; } diff --git a/src/models/creation/CreateRunnerOrganisation.ts b/src/models/creation/CreateRunnerOrganisation.ts index 6e40e60..01c3732 100644 --- a/src/models/creation/CreateRunnerOrganisation.ts +++ b/src/models/creation/CreateRunnerOrganisation.ts @@ -1,9 +1,8 @@ -import { IsObject } from 'class-validator'; +import { IsInt, IsOptional } from 'class-validator'; import { getConnectionManager } from 'typeorm'; import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors'; import { Address } from '../entities/Address'; import { RunnerOrganisation } from '../entities/RunnerOrganisation'; -import { CreateAddress } from './CreateAddress'; import { CreateRunnerGroup } from './CreateRunnerGroup'; export class CreateRunnerOrganisation extends CreateRunnerGroup { @@ -12,8 +11,9 @@ export class CreateRunnerOrganisation extends CreateRunnerGroup { * Must be of type number (address id), createAddress (new address) or address (existing address) * Optional. */ - @IsObject() - address?: number | CreateAddress | Address; + @IsInt() + @IsOptional() + address?: number; /** * Creates a Participant entity from this. @@ -22,12 +22,6 @@ export class CreateRunnerOrganisation extends CreateRunnerGroup { if (this.address === undefined) { return null; } - if (this.address! instanceof Address) { - return this.address; - } - if (this.address! instanceof CreateAddress) { - return this.address.toAddress(); - } if (!isNaN(this.address)) { let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address }); if (!address) { throw new AddressNotFoundError; } diff --git a/src/models/creation/CreateRunnerTeam.ts b/src/models/creation/CreateRunnerTeam.ts index 341a765..98429cb 100644 --- a/src/models/creation/CreateRunnerTeam.ts +++ b/src/models/creation/CreateRunnerTeam.ts @@ -1,4 +1,4 @@ -import { IsNotEmpty } from 'class-validator'; +import { IsInt, IsNotEmpty } from 'class-validator'; import { getConnectionManager } from 'typeorm'; import { RunnerOrganisationNotFoundError, RunnerOrganisationWrongTypeError } from '../../errors/RunnerOrganisationErrors'; import { RunnerTeamNeedsParentError } from '../../errors/RunnerTeamErrors'; @@ -11,22 +11,19 @@ export class CreateRunnerTeam extends CreateRunnerGroup { /** * The team's parent group (organisation). */ + @IsInt() @IsNotEmpty() - parentGroup: number | RunnerOrganisation + parentGroup: number; public async getParent(): Promise { if (this.parentGroup === undefined) { throw new RunnerTeamNeedsParentError(); } - if (this.parentGroup! instanceof RunnerOrganisation) { - return this.parentGroup; - } if (!isNaN(this.parentGroup)) { let parentGroup = await getConnectionManager().get().getRepository(RunnerOrganisation).findOne({ id: this.parentGroup }); if (!parentGroup) { throw new RunnerOrganisationNotFoundError();; } return parentGroup; } - console.log(this.parentGroup); throw new RunnerOrganisationWrongTypeError; }