diff --git a/src/controllers/RunnerController.ts b/src/controllers/RunnerController.ts index 14658da..6508f67 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'; @@ -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') @@ -64,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(); @@ -82,14 +83,15 @@ 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) { - let runner = await this.runnerRepository.findOne({ id: id }); + 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) { 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 bed6eec..8cfef6a 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'; @@ -58,9 +56,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') @@ -88,39 +85,35 @@ 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) { + if (!organisation) { throw new RunnerOrganisationNotFoundError() } + 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 6103083..1b7627d 100644 --- a/src/controllers/RunnerTeamController.ts +++ b/src/controllers/RunnerTeamController.ts @@ -1,10 +1,9 @@ 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 { Runner } from '../models/entities/Runner'; import { RunnerTeam } from '../models/entities/RunnerTeam'; import { ResponseRunnerTeam } from '../models/responses/ResponseRunnerTeam'; import { RunnerController } from './RunnerController'; @@ -88,26 +87,22 @@ 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'] }); + 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(); - } - - 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) - }); + 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/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 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; } } diff --git a/src/errors/AddressErrors.ts b/src/errors/AddressErrors.ts new file mode 100644 index 0000000..c7ae8af --- /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 an 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..c5bf9c7 --- /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 an existing groupContact'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 de672d8..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 ParticipantOnlyOneAddressAllowedError extends NotAcceptableError { - @IsString() - name = "ParticipantOnlyOneAddressAllowedError" - - @IsString() - message = "Participant's can only have one address! \n You provided an id and address object.." -} - -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/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 1dfb68e..65736b1 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 an 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..73f43d0 --- /dev/null +++ b/src/models/creation/CreateGroupContact.ts @@ -0,0 +1,83 @@ +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'; + +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 + */ + @IsInt() + @IsOptional() + address?: 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 (!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 8436186..00c8783 100644 --- a/src/models/creation/CreateParticipant.ts +++ b/src/models/creation/CreateParticipant.ts @@ -1,8 +1,7 @@ -import { IsEmail, IsInt, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; +import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; import { getConnectionManager } from 'typeorm'; -import { ParticipantOnlyOneAddressAllowedError } from '../../errors/ParticipantErrors'; +import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors'; import { Address } from '../entities/Address'; -import { CreateAddress } from './CreateAddress'; export abstract class CreateParticipant { /** @@ -46,38 +45,27 @@ export abstract class CreateParticipant { email?: string; /** - * The new participant's address's id. - * Optional - please provide either addressId or address. + * The new participant's address. + * Must be of type number (address id), createAddress (new address) or address (existing address) + * Optional. */ @IsInt() @IsOptional() - addressId?: number; + address?: number; /** - * The new participant's address. - * Optional - please provide either addressId or address. - */ - @IsObject() - @IsOptional() - address?: CreateAddress; - - /** - * Creates a Participant entity from this. + * Get's this participant's address from this.address. */ 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 (!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; } } \ No newline at end of file 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 new file mode 100644 index 0000000..76552ac --- /dev/null +++ b/src/models/creation/CreateRunnerGroup.ts @@ -0,0 +1,37 @@ +import { IsInt, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { getConnectionManager } from 'typeorm'; +import { GroupContactNotFoundError, GroupContactWrongTypeError } from '../../errors/GroupContactErrors'; +import { GroupContact } from '../entities/GroupContact'; + +export abstract class CreateRunnerGroup { + /** + * The group's name. + */ + @IsNotEmpty() + @IsString() + name: string; + + /** + * The group's contact. + * Optional + */ + @IsInt() + @IsOptional() + contact?: number; + + /** + * Deals with the contact for groups this. + */ + public async getContact(): Promise { + if (this.contact === undefined) { + return null; + } + if (!isNaN(this.contact)) { + let address = await getConnectionManager().get().getRepository(GroupContact).findOne({ id: this.contact }); + if (!address) { throw new GroupContactNotFoundError; } + return address; + } + + throw new GroupContactWrongTypeError; + } +} \ No newline at end of file diff --git a/src/models/creation/CreateRunnerOrganisation.ts b/src/models/creation/CreateRunnerOrganisation.ts index ff4ec65..01c3732 100644 --- a/src/models/creation/CreateRunnerOrganisation.ts +++ b/src/models/creation/CreateRunnerOrganisation.ts @@ -1,13 +1,35 @@ -import { IsNotEmpty, IsString } 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 { CreateRunnerGroup } from './CreateRunnerGroup'; -export class CreateRunnerOrganisation { +export class CreateRunnerOrganisation extends CreateRunnerGroup { /** - * The Organisation's name. + * The new organisation's address. + * Must be of type number (address id), createAddress (new address) or address (existing address) + * Optional. */ - @IsString() - @IsNotEmpty() - name: string; + @IsInt() + @IsOptional() + address?: number; + + /** + * Creates a Participant entity from this. + */ + public async getAddress(): Promise
{ + if (this.address === undefined) { + return null; + } + 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 RunnerOrganisation entity from this. @@ -16,6 +38,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; } diff --git a/src/models/creation/CreateRunnerTeam.ts b/src/models/creation/CreateRunnerTeam.ts index 101a516..98429cb 100644 --- a/src/models/creation/CreateRunnerTeam.ts +++ b/src/models/creation/CreateRunnerTeam.ts @@ -1,23 +1,32 @@ -import { IsInt, IsNotEmpty, IsString } from 'class-validator'; +import { IsInt, 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; + + public async getParent(): Promise { + if (this.parentGroup === undefined) { + throw new RunnerTeamNeedsParentError(); + } + if (!isNaN(this.parentGroup)) { + let parentGroup = await getConnectionManager().get().getRepository(RunnerOrganisation).findOne({ id: this.parentGroup }); + if (!parentGroup) { throw new RunnerOrganisationNotFoundError();; } + return parentGroup; + } + + throw new RunnerOrganisationWrongTypeError; + } /** * Creates a RunnerTeam entity from this. @@ -26,10 +35,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; } 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/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 21cdcb4..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"; @@ -15,13 +14,6 @@ export class RunnerTeam extends RunnerGroup { * Optional */ @IsNotEmpty() - @ManyToOne(() => RunnerOrganisation, org => org.teams, { nullable: false }) + @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