Compare commits

..

16 Commits

Author SHA1 Message Date
057a8ee699 🚀Bumped version to v1.1.3
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-10 13:38:14 +02:00
8d9418635d feat(orgs): Also resolve child-teams' distances and add them to org total 2023-05-10 13:37:54 +02:00
f2832a2dae fix(orgs): Removed unused log 2023-05-10 13:36:05 +02:00
0d21596e2b 🚀Bumped version to v1.1.2
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-10 13:16:33 +02:00
245827e9c6 feat(groups): Resolve the total group distance on group get single (aka get org and get team) 2023-05-10 13:15:59 +02:00
4608a36df6 chore(package): Formatting 2023-05-10 13:15:21 +02:00
cb1305aa77 🚀Bumped version to v1.1.1
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 18:10:52 +02:00
12a9ae2493 feat(donors): Resolve donations with donors via pagination 2023-04-19 18:10:26 +02:00
b9fe9f1c24 🚀Bumped version to v1.1.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 15:48:16 +02:00
b25b0db760 Added hints 2023-04-19 15:47:54 +02:00
fe59e3a557 Added average donation per distance to stats 2023-04-19 15:46:50 +02:00
42c23a5883 Formatting 2023-04-19 15:45:34 +02:00
6ee5328dbc Added calls to controller 2023-04-19 15:41:49 +02:00
6f39ac42da feat(stats): Added donation count and donor count to stats 2023-04-19 15:41:43 +02:00
301f334674 🚀Bumped version to v1.0.1
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 20:09:58 +02:00
fcee3909f4 fix(pagination) page=0 resulted in false thx JS 2023-04-18 20:09:44 +02:00
22 changed files with 108 additions and 22 deletions

View File

@@ -2,8 +2,49 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC. All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [v1.0.0](https://git.odit.services/lfk/backend/compare/v0.15.4...v1.0.0) #### [v1.1.3](https://git.odit.services/lfk/backend/compare/v1.1.2...v1.1.3)
- feat(orgs): Also resolve child-teams' distances and add them to org total [`8d94186`](https://git.odit.services/lfk/backend/commit/8d9418635d3e381c0f55a2521a3334ba497c169a)
- fix(orgs): Removed unused log [`f2832a2`](https://git.odit.services/lfk/backend/commit/f2832a2daecc7bc7bbee4d4fceeab8db194730cf)
#### [v1.1.2](https://git.odit.services/lfk/backend/compare/v1.1.1...v1.1.2)
> 10 May 2023
- 🚀Bumped version to v1.1.2 [`0d21596`](https://git.odit.services/lfk/backend/commit/0d21596e2b64a99258d4925ae2ad627d5cdbd984)
- feat(groups): Resolve the total group distance on group get single (aka get org and get team) [`245827e`](https://git.odit.services/lfk/backend/commit/245827e9c659cf76183dc33ab253becc22ddf032)
- chore(package): Formatting [`4608a36`](https://git.odit.services/lfk/backend/commit/4608a36df6b187520ca0c331b8dce615205257be)
#### [v1.1.1](https://git.odit.services/lfk/backend/compare/v1.1.0...v1.1.1)
> 19 April 2023
- feat(donors): Resolve donations with donors via pagination [`12a9ae2`](https://git.odit.services/lfk/backend/commit/12a9ae24933117acb3ff9815a7d72abca5eea7a7)
- 🚀Bumped version to v1.1.1 [`cb1305a`](https://git.odit.services/lfk/backend/commit/cb1305aa77c36aa9d7900f09e7413bc6d45f2c89)
#### [v1.1.0](https://git.odit.services/lfk/backend/compare/v1.0.1...v1.1.0)
> 19 April 2023
- feat(stats): Added donation count and donor count to stats [`6f39ac4`](https://git.odit.services/lfk/backend/commit/6f39ac42dafc2a589bbb2256b0417f3e774ae174)
- 🚀Bumped version to v1.1.0 [`b9fe9f1`](https://git.odit.services/lfk/backend/commit/b9fe9f1c24653b91255a6dbbdc32c30b1b411eeb)
- Added average donation per distance to stats [`fe59e3a`](https://git.odit.services/lfk/backend/commit/fe59e3a557903cf555d4c50098e935c49ca1fac4)
- Added hints [`b25b0db`](https://git.odit.services/lfk/backend/commit/b25b0db76071ef8d50cc60e950a399dc060a2a9f)
- Added calls to controller [`6ee5328`](https://git.odit.services/lfk/backend/commit/6ee5328dbc404603d19db3a5173ae4def560a9c9)
- Formatting [`42c23a5`](https://git.odit.services/lfk/backend/commit/42c23a5883dacda4e0147842d448b3ad35b197b1)
#### [v1.0.1](https://git.odit.services/lfk/backend/compare/v1.0.0...v1.0.1)
> 18 April 2023
- fix(pagination) page=0 resulted in false thx JS [`fcee390`](https://git.odit.services/lfk/backend/commit/fcee3909f4c4664115cc7ecb94f30e0dd8e78ce0)
- 🚀Bumped version to v1.0.1 [`301f334`](https://git.odit.services/lfk/backend/commit/301f33467489a8533bdac11fbd10efd1b791f5e3)
### [v1.0.0](https://git.odit.services/lfk/backend/compare/v0.15.4...v1.0.0)
> 18 April 2023
- 🚀Bumped version to v1.0.0 [`f0e20e4`](https://git.odit.services/lfk/backend/commit/f0e20e413014fe446c97754d2765cdad92c2cc3b)
- Merge pull request 'feature/205-pagination' (#206) from feature/205-pagination into dev [`80de188`](https://git.odit.services/lfk/backend/commit/80de188565523d642407612272432ef07672b890) - Merge pull request 'feature/205-pagination' (#206) from feature/205-pagination into dev [`80de188`](https://git.odit.services/lfk/backend/commit/80de188565523d642407612272432ef07672b890)
- Added pagination for runner orgs [`538622a`](https://git.odit.services/lfk/backend/commit/538622aa1841e27256f304e15b4204c2f6d24d76) - Added pagination for runner orgs [`538622a`](https://git.odit.services/lfk/backend/commit/538622aa1841e27256f304e15b4204c2f6d24d76)
- RunnerTeam Pagination [`0fa663a`](https://git.odit.services/lfk/backend/commit/0fa663a34104d438dd8fc9ab02458fdf289329f8) - RunnerTeam Pagination [`0fa663a`](https://git.odit.services/lfk/backend/commit/0fa663a34104d438dd8fc9ab02458fdf289329f8)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-backend", "name": "@odit/lfk-backend",
"version": "1.0.0", "version": "1.1.3",
"main": "src/app.ts", "main": "src/app.ts",
"repository": "https://git.odit.services/lfk/backend", "repository": "https://git.odit.services/lfk/backend",
"engines": { "engines": {

View File

@@ -40,7 +40,7 @@ export class DonationController {
let responseDonations: ResponseDonation[] = new Array<ResponseDonation>(); let responseDonations: ResponseDonation[] = new Array<ResponseDonation>();
let donations: Array<Donation>; let donations: Array<Donation>;
if (page) { if (page != undefined) {
donations = await this.donationRepository.find({ relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'], skip: page * page_size, take: page_size }); donations = await this.donationRepository.find({ relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'], skip: page * page_size, take: page_size });
} else { } else {
donations = await this.donationRepository.find({ relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'] }); donations = await this.donationRepository.find({ relations: ['runner', 'donor', 'runner.scans', 'runner.scans.track'] });

View File

@@ -29,7 +29,7 @@ export class DonorController {
let responseDonors: ResponseDonor[] = new Array<ResponseDonor>(); let responseDonors: ResponseDonor[] = new Array<ResponseDonor>();
let donors: Array<Donor>; let donors: Array<Donor>;
if (page) { if (page != undefined) {
donors = await this.donorRepository.find({ relations: ['donations', 'donations.runner', 'donations.runner.scans', 'donations.runner.scans.track'], skip: page * page_size, take: page_size }); donors = await this.donorRepository.find({ relations: ['donations', 'donations.runner', 'donations.runner.scans', 'donations.runner.scans.track'], skip: page * page_size, take: page_size });
} else { } else {
donors = await this.donorRepository.find({ relations: ['donations', 'donations.runner', 'donations.runner.scans', 'donations.runner.scans.track'] }); donors = await this.donorRepository.find({ relations: ['donations', 'donations.runner', 'donations.runner.scans', 'donations.runner.scans.track'] });

View File

@@ -30,7 +30,7 @@ export class GroupContactController {
let responseContacts: ResponseGroupContact[] = new Array<ResponseGroupContact>(); let responseContacts: ResponseGroupContact[] = new Array<ResponseGroupContact>();
let contacts: Array<GroupContact>; let contacts: Array<GroupContact>;
if (page) { if (page != undefined) {
contacts = await this.contactRepository.find({ relations: ['groups', 'groups.parentGroup'], skip: page * page_size, take: page_size }); contacts = await this.contactRepository.find({ relations: ['groups', 'groups.parentGroup'], skip: page * page_size, take: page_size });
} else { } else {
contacts = await this.contactRepository.find({ relations: ['groups', 'groups.parentGroup'] }); contacts = await this.contactRepository.find({ relations: ['groups', 'groups.parentGroup'] });

View File

@@ -31,7 +31,7 @@ export class PermissionController {
let responsePermissions: ResponsePermission[] = new Array<ResponsePermission>(); let responsePermissions: ResponsePermission[] = new Array<ResponsePermission>();
let permissions: Array<Permission>; let permissions: Array<Permission>;
if (page) { if (page != undefined) {
permissions = await this.permissionRepository.find({ relations: ['principal'], skip: page * page_size, take: page_size }); permissions = await this.permissionRepository.find({ relations: ['principal'], skip: page * page_size, take: page_size });
} else { } else {
permissions = await this.permissionRepository.find({ relations: ['principal'] }); permissions = await this.permissionRepository.find({ relations: ['principal'] });

View File

@@ -30,7 +30,7 @@ export class RunnerCardController {
let responseCards: ResponseRunnerCard[] = new Array<ResponseRunnerCard>(); let responseCards: ResponseRunnerCard[] = new Array<ResponseRunnerCard>();
let cards: Array<RunnerCard>; let cards: Array<RunnerCard>;
if (page) { if (page != undefined) {
cards = await this.cardRepository.find({ relations: ['runner', 'runner.group', 'runner.group.parentGroup'], skip: page * page_size, take: page_size }); cards = await this.cardRepository.find({ relations: ['runner', 'runner.group', 'runner.group.parentGroup'], skip: page * page_size, take: page_size });
} else { } else {
cards = await this.cardRepository.find({ relations: ['runner', 'runner.group', 'runner.group.parentGroup'] }); cards = await this.cardRepository.find({ relations: ['runner', 'runner.group', 'runner.group.parentGroup'] });

View File

@@ -34,7 +34,7 @@ export class RunnerController {
let responseRunners: ResponseRunner[] = new Array<ResponseRunner>(); let responseRunners: ResponseRunner[] = new Array<ResponseRunner>();
let runners: Array<Runner>; let runners: Array<Runner>;
if (page) { if (page != undefined) {
runners = await this.runnerRepository.find({ relations: ['scans', 'group', 'group.parentGroup', 'scans.track'], skip: page * page_size, take: page_size }); runners = await this.runnerRepository.find({ relations: ['scans', 'group', 'group.parentGroup', 'scans.track'], skip: page * page_size, take: page_size });
} else { } else {
runners = await this.runnerRepository.find({ relations: ['scans', 'group', 'group.parentGroup', 'scans.track'] }); runners = await this.runnerRepository.find({ relations: ['scans', 'group', 'group.parentGroup', 'scans.track'] });

View File

@@ -33,7 +33,7 @@ export class RunnerOrganizationController {
let responseOrgs: ResponseRunnerOrganization[] = new Array<ResponseRunnerOrganization>(); let responseOrgs: ResponseRunnerOrganization[] = new Array<ResponseRunnerOrganization>();
let orgs: Array<RunnerOrganization>; let orgs: Array<RunnerOrganization>;
if (page) { if (page != undefined) {
orgs = await this.runnerOrganizationRepository.find({ relations: ['contact', 'teams'], skip: page * page_size, take: page_size }); orgs = await this.runnerOrganizationRepository.find({ relations: ['contact', 'teams'], skip: page * page_size, take: page_size });
} else { } else {
orgs = await this.runnerOrganizationRepository.find({ relations: ['contact', 'teams'] }); orgs = await this.runnerOrganizationRepository.find({ relations: ['contact', 'teams'] });
@@ -52,7 +52,7 @@ export class RunnerOrganizationController {
@OnUndefined(RunnerOrganizationNotFoundError) @OnUndefined(RunnerOrganizationNotFoundError)
@OpenAPI({ description: 'Lists all information about the organization whose id got provided.' }) @OpenAPI({ description: 'Lists all information about the organization whose id got provided.' })
async getOne(@Param('id') id: number) { async getOne(@Param('id') id: number) {
let runnerOrg = await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['contact', 'teams'] }); let runnerOrg = await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['contact', 'teams', 'teams.runners', 'teams.runners.scans', 'teams.runners.scans.track', 'runners', 'runners.scans', 'runners.scans.track'] });
if (!runnerOrg) { throw new RunnerOrganizationNotFoundError(); } if (!runnerOrg) { throw new RunnerOrganizationNotFoundError(); }
return new ResponseRunnerOrganization(runnerOrg); return new ResponseRunnerOrganization(runnerOrg);
} }

View File

@@ -31,7 +31,7 @@ export class RunnerTeamController {
let responseTeams: ResponseRunnerTeam[] = new Array<ResponseRunnerTeam>(); let responseTeams: ResponseRunnerTeam[] = new Array<ResponseRunnerTeam>();
let teams: Array<RunnerTeam>; let teams: Array<RunnerTeam>;
if (page) { if (page != undefined) {
teams = await this.runnerTeamRepository.find({ relations: ['parentGroup', 'contact'], skip: page * page_size, take: page_size }); teams = await this.runnerTeamRepository.find({ relations: ['parentGroup', 'contact'], skip: page * page_size, take: page_size });
} else { } else {
teams = await this.runnerTeamRepository.find({ relations: ['parentGroup', 'contact'] }); teams = await this.runnerTeamRepository.find({ relations: ['parentGroup', 'contact'] });
@@ -50,7 +50,7 @@ export class RunnerTeamController {
@OnUndefined(RunnerTeamNotFoundError) @OnUndefined(RunnerTeamNotFoundError)
@OpenAPI({ description: 'Lists all information about the team whose id got provided.' }) @OpenAPI({ description: 'Lists all information about the team whose id got provided.' })
async getOne(@Param('id') id: number) { async getOne(@Param('id') id: number) {
let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact'] }); let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact', 'runners', 'runners.scans', 'runners.scans.track'] });
if (!runnerTeam) { throw new RunnerTeamNotFoundError(); } if (!runnerTeam) { throw new RunnerTeamNotFoundError(); }
return new ResponseRunnerTeam(runnerTeam); return new ResponseRunnerTeam(runnerTeam);
} }

View File

@@ -38,7 +38,7 @@ export class ScanController {
let responseScans: ResponseScan[] = new Array<ResponseScan>(); let responseScans: ResponseScan[] = new Array<ResponseScan>();
let scans: Array<Scan>; let scans: Array<Scan>;
if (page) { if (page != undefined) {
scans = await this.scanRepository.find({ relations: ['runner', 'track'], skip: page * page_size, take: page_size }); scans = await this.scanRepository.find({ relations: ['runner', 'track'], skip: page * page_size, take: page_size });
} else { } else {
scans = await this.scanRepository.find({ relations: ['runner', 'track'] }); scans = await this.scanRepository.find({ relations: ['runner', 'track'] });

View File

@@ -30,7 +30,7 @@ export class ScanStationController {
let responseStations: ResponseScanStation[] = new Array<ResponseScanStation>(); let responseStations: ResponseScanStation[] = new Array<ResponseScanStation>();
let stations: Array<ScanStation>; let stations: Array<ScanStation>;
if (page) { if (page != undefined) {
stations = await this.stationRepository.find({ relations: ['track'], skip: page * page_size, take: page_size }); stations = await this.stationRepository.find({ relations: ['track'], skip: page * page_size, take: page_size });
} else { } else {
stations = await this.stationRepository.find({ relations: ['track'] }); stations = await this.stationRepository.find({ relations: ['track'] });

View File

@@ -28,7 +28,7 @@ export class StatsClientController {
let responseClients: ResponseStatsClient[] = new Array<ResponseStatsClient>(); let responseClients: ResponseStatsClient[] = new Array<ResponseStatsClient>();
let clients: Array<StatsClient>; let clients: Array<StatsClient>;
if (page) { if (page != undefined) {
clients = await this.clientRepository.find({ skip: page * page_size, take: page_size }); clients = await this.clientRepository.find({ skip: page * page_size, take: page_size });
} else { } else {
clients = await this.clientRepository.find(); clients = await this.clientRepository.find();

View File

@@ -3,6 +3,7 @@ import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnection } from 'typeorm'; import { getConnection } from 'typeorm';
import StatsAuth from '../middlewares/StatsAuth'; import StatsAuth from '../middlewares/StatsAuth';
import { Donation } from '../models/entities/Donation'; import { Donation } from '../models/entities/Donation';
import { Donor } from '../models/entities/Donor';
import { Runner } from '../models/entities/Runner'; import { Runner } from '../models/entities/Runner';
import { RunnerOrganization } from '../models/entities/RunnerOrganization'; import { RunnerOrganization } from '../models/entities/RunnerOrganization';
import { RunnerTeam } from '../models/entities/RunnerTeam'; import { RunnerTeam } from '../models/entities/RunnerTeam';
@@ -27,6 +28,7 @@ export class StatsController {
const orgs = await connection.getRepository(RunnerOrganization).count(); const orgs = await connection.getRepository(RunnerOrganization).count();
const users = await connection.getRepository(User).count(); const users = await connection.getRepository(User).count();
const scans = await connection.getRepository(Scan).count({ where: { valid: true } }); const scans = await connection.getRepository(Scan).count({ where: { valid: true } });
const distance_query = await connection.getRepository(Scan).createQueryBuilder('scan') const distance_query = await connection.getRepository(Scan).createQueryBuilder('scan')
.leftJoinAndSelect("scan.track", "track").where("scan.valid = TRUE") .leftJoinAndSelect("scan.track", "track").where("scan.valid = TRUE")
.select("SUM(track.distance)", "sum_track").addSelect("SUM(_distance)", "sum_distance") .select("SUM(track.distance)", "sum_track").addSelect("SUM(_distance)", "sum_distance")
@@ -35,8 +37,11 @@ export class StatsController {
if (distance_query.sum_distance) { if (distance_query.sum_distance) {
distace += parseInt(distance_query.sum_distance) distace += parseInt(distance_query.sum_distance)
} }
let donations = await connection.getRepository(Donation).find({ relations: ['runner', 'runner.scans', 'runner.scans.track'] }); let donations = await connection.getRepository(Donation).find({ relations: ['runner', 'runner.scans', 'runner.scans.track'] });
return new ResponseStats(runners, teams, orgs, users, scans, donations, distace) const donors = await connection.getRepository(Donor).count();
return new ResponseStats(runners, teams, orgs, users, scans, donations, distace, donors)
} }
@Get("/runners/distance") @Get("/runners/distance")

View File

@@ -29,7 +29,7 @@ export class TrackController {
let responseTracks: ResponseTrack[] = new Array<ResponseTrack>(); let responseTracks: ResponseTrack[] = new Array<ResponseTrack>();
let tracks: Array<Track>; let tracks: Array<Track>;
if (page) { if (page != undefined) {
tracks = await this.trackRepository.find({ skip: page * page_size, take: page_size }); tracks = await this.trackRepository.find({ skip: page * page_size, take: page_size });
} }
else { else {

View File

@@ -32,7 +32,7 @@ export class UserController {
let responseUsers: ResponseUser[] = new Array<ResponseUser>(); let responseUsers: ResponseUser[] = new Array<ResponseUser>();
let users: Array<User>; let users: Array<User>;
if (page) { if (page != undefined) {
users = await this.userRepository.find({ relations: ['permissions', 'groups', 'groups.permissions'], skip: page * page_size, take: page_size }); users = await this.userRepository.find({ relations: ['permissions', 'groups', 'groups.permissions'], skip: page * page_size, take: page_size });
} }
else { else {

View File

@@ -31,7 +31,7 @@ export class UserGroupController {
let responseGroups: ResponseUserGroup[] = new Array<ResponseUserGroup>(); let responseGroups: ResponseUserGroup[] = new Array<ResponseUserGroup>();
let groups: Array<UserGroup>; let groups: Array<UserGroup>;
if (page) { if (page != undefined) {
groups = await this.userGroupsRepository.find({ relations: ['permissions'], skip: page * page_size, take: page_size }); groups = await this.userGroupsRepository.find({ relations: ['permissions'], skip: page * page_size, take: page_size });
} else { } else {
groups = await this.userGroupsRepository.find({ relations: ['permissions'] }); groups = await this.userGroupsRepository.find({ relations: ['permissions'] });

View File

@@ -53,7 +53,9 @@ export class ResponseDonation implements IResponse {
*/ */
public constructor(donation: Donation) { public constructor(donation: Donation) {
this.id = donation.id; this.id = donation.id;
this.donor = donation.donor.toResponse(); if (donation.donor) {
this.donor = donation.donor.toResponse();
}
this.amount = donation.amount; this.amount = donation.amount;
this.paidAmount = donation.paidAmount || 0; this.paidAmount = donation.paidAmount || 0;
if (this.paidAmount < this.amount) { if (this.paidAmount < this.amount) {

View File

@@ -4,6 +4,7 @@ import {
import { Donor } from '../entities/Donor'; import { Donor } from '../entities/Donor';
import { ResponseObjectType } from '../enums/ResponseObjectType'; import { ResponseObjectType } from '../enums/ResponseObjectType';
import { IResponse } from './IResponse'; import { IResponse } from './IResponse';
import { ResponseDonation } from './ResponseDonation';
import { ResponseParticipant } from './ResponseParticipant'; import { ResponseParticipant } from './ResponseParticipant';
/** /**
@@ -34,6 +35,8 @@ export class ResponseDonor extends ResponseParticipant implements IResponse {
@IsInt() @IsInt()
paidDonationAmount: number; paidDonationAmount: number;
donations: Array<ResponseDonation>;
/** /**
* Creates a ResponseRunner object from a runner. * Creates a ResponseRunner object from a runner.
* @param runner The user the response shall be build for. * @param runner The user the response shall be build for.
@@ -43,5 +46,11 @@ export class ResponseDonor extends ResponseParticipant implements IResponse {
this.receiptNeeded = donor.receiptNeeded; this.receiptNeeded = donor.receiptNeeded;
this.donationAmount = donor.donationAmount; this.donationAmount = donor.donationAmount;
this.paidDonationAmount = donor.paidDonationAmount; this.paidDonationAmount = donor.paidDonationAmount;
this.donations = new Array<ResponseDonation>();
if (donor.donations?.length > 0) {
for (const donation of donor.donations) {
this.donations.push(donation.toResponse())
}
}
} }
} }

View File

@@ -1,4 +1,4 @@
import { IsInt, IsNotEmpty, IsObject, IsOptional, IsString } from "class-validator"; import { IsInt, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString } from "class-validator";
import { RunnerGroup } from '../entities/RunnerGroup'; import { RunnerGroup } from '../entities/RunnerGroup';
import { ResponseObjectType } from '../enums/ResponseObjectType'; import { ResponseObjectType } from '../enums/ResponseObjectType';
import { IResponse } from './IResponse'; import { IResponse } from './IResponse';
@@ -36,6 +36,10 @@ export abstract class ResponseRunnerGroup implements IResponse {
@IsOptional() @IsOptional()
contact?: ResponseGroupContact; contact?: ResponseGroupContact;
@IsOptional()
@IsNumber()
total_distance: number
/** /**
* Creates a ResponseRunnerGroup object from a runnerGroup. * Creates a ResponseRunnerGroup object from a runnerGroup.
* @param group The runnerGroup the response shall be build for. * @param group The runnerGroup the response shall be build for.
@@ -44,5 +48,6 @@ export abstract class ResponseRunnerGroup implements IResponse {
this.id = group.id; this.id = group.id;
this.name = group.name; this.name = group.name;
if (group.contact) { this.contact = group.contact.toResponse(); }; if (group.contact) { this.contact = group.contact.toResponse(); };
if (group.runners) { this.total_distance = group.runners.reduce((p, c) => p + c.distance, 0) }
} }
} }

View File

@@ -67,6 +67,9 @@ export class ResponseRunnerOrganization extends ResponseRunnerGroup implements I
for (let team of org.teams) { for (let team of org.teams) {
this.teams.push(team.toResponse()); this.teams.push(team.toResponse());
} }
for (const team of this.teams) {
this.total_distance += team.total_distance;
}
} }
if (!org.key) { this.registrationEnabled = false; } if (!org.key) { this.registrationEnabled = false; }

View File

@@ -58,12 +58,30 @@ export class ResponseStats implements IResponse {
@IsInt() @IsInt()
total_donation: number; total_donation: number;
/**
* The total donation count (cent).
*/
@IsInt()
total_donations: number;
/**
* The total donor count.
*/
@IsInt()
total_donors: number;
/** /**
* The average distance ran per runner. * The average distance ran per runner.
*/ */
@IsInt() @IsInt()
average_distance: number; average_distance: number;
/**
* The average donation per distance (cent).
*/
@IsInt()
average_donation: number;
/** /**
* Creates a new stats response containing some basic statistics for a dashboard or public display. * Creates a new stats response containing some basic statistics for a dashboard or public display.
* @param runners Array containing all runners - the following relations have to be resolved: scans, scans.track * @param runners Array containing all runners - the following relations have to be resolved: scans, scans.track
@@ -73,7 +91,7 @@ export class ResponseStats implements IResponse {
* @param scans Array containing all scans - no relations have to be resolved. * @param scans Array containing all scans - no relations have to be resolved.
* @param donations Array containing all donations - the following relations have to be resolved: runner, runner.scans, runner.scans.track * @param donations Array containing all donations - the following relations have to be resolved: runner, runner.scans, runner.scans.track
*/ */
public constructor(runners: number, teams: number, orgs: number, users: number, scans: number, donations: Donation[], distance: number) { public constructor(runners: number, teams: number, orgs: number, users: number, scans: number, donations: Donation[], distance: number, donors: number) {
this.total_runners = runners; this.total_runners = runners;
this.total_teams = teams; this.total_teams = teams;
this.total_orgs = orgs; this.total_orgs = orgs;
@@ -81,6 +99,9 @@ export class ResponseStats implements IResponse {
this.total_scans = scans; this.total_scans = scans;
this.total_distance = distance; this.total_distance = distance;
this.total_donation = donations.reduce((sum, current) => sum + current.amount, 0); this.total_donation = donations.reduce((sum, current) => sum + current.amount, 0);
this.total_donations = donations.length;
this.average_donation = this.total_donation / this.total_donations
this.total_donors = donors;
this.average_distance = this.total_distance / this.total_runners; this.average_distance = this.total_distance / this.total_runners;
} }
} }