From 795599fd388150a07c959cb3fbed6f676d3db790 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Fri, 4 Dec 2020 18:15:38 +0100 Subject: [PATCH] Working(tm) implementation of group and team deletion ref #13 --- src/controllers/RunnerController.ts | 8 ++--- .../RunnerOrganisationController.ts | 31 +++++++++++++------ src/controllers/RunnerTeamController.ts | 6 ++-- src/models/entities/RunnerGroup.ts | 7 +++-- src/models/entities/RunnerOrganisation.ts | 27 ++++++++++++++-- 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/controllers/RunnerController.ts b/src/controllers/RunnerController.ts index 798d3c6..124a062 100644 --- a/src/controllers/RunnerController.ts +++ b/src/controllers/RunnerController.ts @@ -1,10 +1,10 @@ -import { JsonController, Param, Body, Get, Post, Put, Delete, OnUndefined } from 'routing-controllers'; +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 { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; -import { Runner } from '../models/entities/Runner'; import { RunnerGroupNeededError, RunnerGroupNotFoundError, RunnerIdsNotMatchingError, RunnerNotFoundError, RunnerOnlyOneGroupAllowedError } from '../errors/RunnerErrors'; import { CreateRunner } from '../models/creation/CreateRunner'; +import { Runner } from '../models/entities/Runner'; @JsonController('/runners') @@ -76,7 +76,7 @@ export class RunnerController { @ResponseSchema(Runner) @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) @OpenAPI({ description: 'Delete a specified runner (if it exists).' }) - async remove(@Param('id') id: number) { + async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { let runner = await this.runnerRepository.findOne({ id: id }); if (!runner) { diff --git a/src/controllers/RunnerOrganisationController.ts b/src/controllers/RunnerOrganisationController.ts index 0bae97f..2ad2e25 100644 --- a/src/controllers/RunnerOrganisationController.ts +++ b/src/controllers/RunnerOrganisationController.ts @@ -4,7 +4,11 @@ import { getConnectionManager, Repository } from 'typeorm'; import { EntityFromBody } 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 { RunnerController } from './RunnerController'; +import { RunnerTeamController } from './RunnerTeamController'; @JsonController('/organisations') @@ -72,25 +76,34 @@ export class RunnerOrganisationController { @Delete('/:id') @ResponseSchema(RunnerOrganisation) @ResponseSchema(RunnerOrganisationNotFoundError, { statusCode: 404 }) + @ResponseSchema(RunnerOrganisationHasRunnersError, { statusCode: 406 }) + @ResponseSchema(RunnerOrganisationHasTeamsError, { statusCode: 406 }) @OpenAPI({ description: 'Delete a specified runnerOrganisation (if it exists).' }) - async remove(@Param('id') id: number, @QueryParam("force") force) { + async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { let runnerOrganisation = await this.runnerOrganisationRepository.findOne({ id: id }); if (!runnerOrganisation) { throw new RunnerOrganisationNotFoundError(); } - if (!force) { - if (runnerOrganisation.runners.length != 0) { - throw new RunnerOrganisationHasRunnersError(); - } + let runners: Runner[] = await runnerOrganisation.getRunners() - if (runnerOrganisation.teams.length != 0) { - throw new RunnerOrganisationHasTeamsError(); - } + if (!force && runners.length != 0) { + throw new RunnerOrganisationHasRunnersError(); } + const runnerController = new RunnerController() + await runners.forEach(async runner => { + await runnerController.remove(runner.id, true); + }); - //TODO: Delete runner and teams + let teams: RunnerTeam[] = await runnerOrganisation.getTeams() + if (!force && teams.length != 0) { + throw new RunnerOrganisationHasTeamsError(); + } + const teamController = new RunnerTeamController() + await teams.forEach(async team => { + await teamController.remove(team.id, true); + }); await this.runnerOrganisationRepository.delete(runnerOrganisation); return runnerOrganisation; diff --git a/src/controllers/RunnerTeamController.ts b/src/controllers/RunnerTeamController.ts index 466a9ff..ecbe9a2 100644 --- a/src/controllers/RunnerTeamController.ts +++ b/src/controllers/RunnerTeamController.ts @@ -76,7 +76,7 @@ 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) { + async remove(@Param('id') id: number, @QueryParam("force") force: boolean) { let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }); if (!runnerTeam) { @@ -84,16 +84,14 @@ export class RunnerTeamController { } let runners: Runner[] = await runnerTeam.getRunners() - if (!force) { if (runners.length != 0) { throw new RunnerTeamHasRunnersError(); } } - const runnerController = new RunnerController() runners.forEach(runner => { - runnerController.remove(runner.id) + runnerController.remove(runner.id, true) }); await this.runnerTeamRepository.delete(runnerTeam); diff --git a/src/models/entities/RunnerGroup.ts b/src/models/entities/RunnerGroup.ts index 8142754..2033d88 100644 --- a/src/models/entities/RunnerGroup.ts +++ b/src/models/entities/RunnerGroup.ts @@ -1,13 +1,12 @@ -import { PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, Entity, TableInheritance } from "typeorm"; import { IsInt, IsNotEmpty, IsOptional, - IsString, + IsString } from "class-validator"; +import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { GroupContact } from "./GroupContact"; import { Runner } from "./Runner"; -import { RunnerTeam } from "./RunnerTeam"; /** * Defines the runnerGroup interface. @@ -44,4 +43,6 @@ 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 f6e850e..bfdfe49 100644 --- a/src/models/entities/RunnerOrganisation.ts +++ b/src/models/entities/RunnerOrganisation.ts @@ -1,7 +1,8 @@ -import { Entity, Column, ManyToOne, OneToMany, ChildEntity } from "typeorm"; -import { IsOptional, } from "class-validator"; -import { RunnerGroup } from "./RunnerGroup"; +import { IsOptional } from "class-validator"; +import { ChildEntity, getConnectionManager, ManyToOne, OneToMany } from "typeorm"; import { Address } from "./Address"; +import { Runner } from './Runner'; +import { RunnerGroup } from "./RunnerGroup"; import { RunnerTeam } from "./RunnerTeam"; /** @@ -23,6 +24,26 @@ 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 }); }