| @@ -9,6 +9,7 @@ import { RunnerTeam } from '../models/entities/RunnerTeam'; | ||||
| import { Scan } from '../models/entities/Scan'; | ||||
| import { User } from '../models/entities/User'; | ||||
| import { ResponseStats } from '../models/responses/ResponseStats'; | ||||
| import { ResponseStatsOrgnisation } from '../models/responses/ResponseStatsOrganisation'; | ||||
| import { ResponseStatsRunner } from '../models/responses/ResponseStatsRunner'; | ||||
| import { ResponseStatsTeam } from '../models/responses/ResponseStatsTeam'; | ||||
|  | ||||
| @@ -57,6 +58,14 @@ export class StatsController { | ||||
|         return responseRunners; | ||||
|     } | ||||
|  | ||||
|     @Get("/scans") | ||||
|     @UseBefore(StatsAuth) | ||||
|     @ResponseSchema(ResponseStatsRunner, { isArray: true }) | ||||
|     @OpenAPI({ description: "Returns the top ten fastest track times (with their runner and the runner's group).", security: [{ "StatsApiToken": [] }] }) | ||||
|     async getTopRunnersByTrackTime() { | ||||
|         throw new Error("Not implemented yet.") | ||||
|     } | ||||
|  | ||||
|     @Get("/teams/distance") | ||||
|     @UseBefore(StatsAuth) | ||||
|     @ResponseSchema(ResponseStatsTeam, { isArray: true }) | ||||
| @@ -89,13 +98,25 @@ export class StatsController { | ||||
|     @UseBefore(StatsAuth) | ||||
|     @OpenAPI({ description: "Returns the top ten organisations by distance.", security: [{ "StatsApiToken": [] }] }) | ||||
|     async getTopOrgsByDistance() { | ||||
|         throw new Error("Not implemented yet.") | ||||
|         let orgs = await getConnection().getRepository(RunnerOrganisation).find({ relations: ['runners', 'runners.scans', 'runners.distanceDonations', 'runners.scans.track', 'teams', 'teams.runners', 'teams.runners.scans', 'teams.runners.distanceDonations', 'teams.runners.scans.track'] }); | ||||
|         let topOrgs = orgs.sort((org1, org2) => org1.distance - org2.distance).slice(0, 9); | ||||
|         let responseOrgs: ResponseStatsOrgnisation[] = new Array<ResponseStatsOrgnisation>(); | ||||
|         topOrgs.forEach(org => { | ||||
|             responseOrgs.push(new ResponseStatsOrgnisation(org)); | ||||
|         }); | ||||
|         return responseOrgs; | ||||
|     } | ||||
|  | ||||
|     @Get("/organisations/donations") | ||||
|     @UseBefore(StatsAuth) | ||||
|     @OpenAPI({ description: "Returns the top ten organisations by donations.", security: [{ "StatsApiToken": [] }] }) | ||||
|     async getTopOrgsByDonations() { | ||||
|         throw new Error("Not implemented yet.") | ||||
|         let orgs = await getConnection().getRepository(RunnerOrganisation).find({ relations: ['runners', 'runners.scans', 'runners.distanceDonations', 'runners.scans.track', 'teams', 'teams.runners', 'teams.runners.scans', 'teams.runners.distanceDonations', 'teams.runners.scans.track'] }); | ||||
|         let topOrgs = orgs.sort((org1, org2) => org1.distanceDonationAmount - org2.distanceDonationAmount).slice(0, 9); | ||||
|         let responseOrgs: ResponseStatsOrgnisation[] = new Array<ResponseStatsOrgnisation>(); | ||||
|         topOrgs.forEach(org => { | ||||
|             responseOrgs.push(new ResponseStatsOrgnisation(org)); | ||||
|         }); | ||||
|         return responseOrgs; | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { IsOptional } from "class-validator"; | ||||
| import { IsInt, IsOptional } from "class-validator"; | ||||
| import { ChildEntity, ManyToOne, OneToMany } from "typeorm"; | ||||
| import { Address } from "./Address"; | ||||
| import { Runner } from './Runner'; | ||||
| import { RunnerGroup } from "./RunnerGroup"; | ||||
| import { RunnerTeam } from "./RunnerTeam"; | ||||
|  | ||||
| @@ -24,4 +25,32 @@ export class RunnerOrganisation extends RunnerGroup { | ||||
|    */ | ||||
|   @OneToMany(() => RunnerTeam, team => team.parentGroup, { nullable: true }) | ||||
|   teams: RunnerTeam[]; | ||||
|  | ||||
|   /** | ||||
|    * Returns all runners associated with this organisation (directly or indirectly via teams). | ||||
|    */ | ||||
|   public get allRunners(): Runner[] { | ||||
|     let returnRunners: Runner[] = new Array<Runner>(); | ||||
|     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); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										47
									
								
								src/models/responses/ResponseStatsOrganisation.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/models/responses/ResponseStatsOrganisation.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| import { | ||||
|     IsInt, | ||||
|  | ||||
|     IsString | ||||
| } from "class-validator"; | ||||
| import { RunnerOrganisation } from '../entities/RunnerOrganisation'; | ||||
|  | ||||
| /** | ||||
|  * Defines the org stats response. | ||||
|  * This differs from the normal org responce. | ||||
| */ | ||||
| export class ResponseStatsOrgnisation { | ||||
|     /** | ||||
|      * The orgs's id. | ||||
|      */ | ||||
|     @IsInt() | ||||
|     id: number; | ||||
|  | ||||
|     /** | ||||
|      * The orgs's name. | ||||
|      */ | ||||
|     @IsString() | ||||
|     name: string; | ||||
|  | ||||
|     /** | ||||
|      * The orgs's runner's currently ran distance in meters. | ||||
|      */ | ||||
|     @IsInt() | ||||
|     distance: number; | ||||
|  | ||||
|     /** | ||||
|      * The orgs's currently collected donations. | ||||
|      */ | ||||
|     @IsInt() | ||||
|     donationAmount: number; | ||||
|  | ||||
|     /** | ||||
|      * Creates a ResponseRunner object from a runner. | ||||
|      * @param runner The user the response shall be build for. | ||||
|      */ | ||||
|     public constructor(org: RunnerOrganisation) { | ||||
|         this.name = org.name; | ||||
|         this.id = org.id; | ||||
|         this.distance = org.distance; | ||||
|         this.donationAmount = org.distanceDonationAmount; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user