import { IsInt, IsOptional, IsString } from "class-validator"; import { ChildEntity, Column, OneToMany } from "typeorm"; import { ResponseRunnerOrganisation } from '../responses/ResponseRunnerOrganisation'; import { Address } from './Address'; import { Runner } from './Runner'; import { RunnerGroup } from "./RunnerGroup"; import { RunnerTeam } from "./RunnerTeam"; /** * Defines the RunnerOrganisation entity. * This usually is a school, club or company. */ @ChildEntity() export class RunnerOrganisation extends RunnerGroup { /** * The organizations's address. */ @IsOptional() @Column(type => Address) address?: Address; /** * The organization's teams. * Used to link teams to a organization. */ @OneToMany(() => RunnerTeam, team => team.parentGroup, { nullable: true }) teams: RunnerTeam[]; /** * The organization's api key for self-service registration. * The api key can be used for the /runners/register/:token endpoint. * Is has to be base64 encoded if used via the api (to keep url-safety). */ @Column({ nullable: true, unique: true }) @IsString() @IsOptional() key?: string; /** * Returns all runners associated with this organization (directly or indirectly via teams). */ public get allRunners(): Runner[] { let returnRunners: Runner[] = new Array(); returnRunners.push(...this.runners); for (let team of this.teams) { returnRunners.push(...team.runners) } return returnRunners; } /** * Returns the total distance ran by this group's runners based on all their valid scans. */ @IsInt() public get distance(): number { return this.allRunners.reduce((sum, current) => sum + current.distance, 0); } /** * Returns the total donations a runner has collected based on his linked donations and distance ran. */ @IsInt() public get distanceDonationAmount(): number { return this.allRunners.reduce((sum, current) => sum + current.distanceDonationAmount, 0); } /** * Turns this entity into it's response class. */ public toResponse(): ResponseRunnerOrganisation { return new ResponseRunnerOrganisation(this); } }