Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/fog_cup_calculation'
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryJobst committed Nov 10, 2024
2 parents 4d0ea53 + 124d741 commit 07452a6
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 70 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ src/main/.DS_Store
/node_modules/**
/build-with-act.sh
/build-images-with-act.sh
/testdb.mv.db
/testdb.trace.db
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "resulter",
"type": "module",
"version": "0.0.15",
"version": "0.0.17",
"private": true,
"packageManager": "pnpm@8.15.5",
"scripts": {
Expand Down
35 changes: 16 additions & 19 deletions frontend/src/features/event/services/event.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ export class EventService extends GenericService<SportEvent> {
if (response) {
const result = response
result.content = result.content.map((element) => {
if (element.startTime)
element.startTime = new Date(element.startTime)
if (element.startTime) element.startTime = new Date(element.startTime)

return element
})
Expand All @@ -43,7 +42,7 @@ export class EventService extends GenericService<SportEvent> {
static async calculate(result_list_id: number, t: (key: string) => string) {
return axiosInstance
.put(`${resultListUrl}/${result_list_id}/calculate`)
.then(response => response.data)
.then((response) => response.data)
.catch((error) => {
handleApiError(error, t)
return null
Expand All @@ -53,7 +52,7 @@ export class EventService extends GenericService<SportEvent> {
static async getEventStatus(t: (key: string) => string): Promise<EventStatus[] | null> {
return await axiosInstance
.get<EventStatus[]>(eventStatusUrl)
.then(response => response.data)
.then((response) => response.data)
.catch((error) => {
handleApiError(error, t)
return null
Expand All @@ -71,12 +70,12 @@ export class EventService extends GenericService<SportEvent> {
response.data.resultLists = response.data.resultLists.map(
(resultList: ResultList) => {
if (
resultList.createTime
&& typeof resultList.createTime === 'string'
resultList.createTime &&
typeof resultList.createTime === 'string'
) {
// Entfernen des Zeitzone-Identifikators, da dieser nicht von Date.parse() unterstützt wird
const dateStringWithoutTimezone
= resultList.createTime.split('[')[0]
const dateStringWithoutTimezone =
resultList.createTime.split('[')[0]
resultList.createTime = new Date(dateStringWithoutTimezone)
}
return resultList
Expand All @@ -99,7 +98,7 @@ export class EventService extends GenericService<SportEvent> {
'Content-Type': 'multipart/form-data',
},
})
.then(response => response.data)
.then((response) => response.data)
.catch((error) => {
handleApiError(error, t)
return null
Expand Down Expand Up @@ -148,11 +147,10 @@ export class EventService extends GenericService<SportEvent> {
}

static async getCertificate(certificate: Certificate | undefined, t: (key: string) => string) {
if (!certificate || !certificate.event)
return null
if (!certificate || !certificate.event) return null

return axiosInstance
.put(`/event/${certificate.event?.id}/certificate`, certificate, {
.put(`${eventUrl}/${certificate.event?.id}/certificate`, certificate, {
responseType: 'blob',
})
.then((response) => {
Expand All @@ -174,20 +172,19 @@ export class EventService extends GenericService<SportEvent> {
return null
}
return axiosInstance
.get(`/${eventUrl}/${id}/certificate_stats`)
.then(response => response.data)
.get(`${eventUrl}/${id}/certificate_stats`)
.then((response) => response.data)
.catch((error) => {
handleApiError(error, t)
return null
})
}

static async removeEventCertificateStat(id: number, t: (key: string) => string) {
if (!id)
return null
if (!id) return null
return axiosInstance
.delete(`/event_certificate_stat/${id}`)
.then(response => response.data)
.then((response) => response.data)
.catch((error) => {
handleApiError(error, t)
return null
Expand All @@ -197,7 +194,7 @@ export class EventService extends GenericService<SportEvent> {
static async getCertificateSchema(t: (key: string) => string) {
return axiosInstance
.get('/certificate_schema')
.then(response => response.data)
.then((response) => response.data)
.catch((error) => {
handleApiError(error, t)
return null
Expand All @@ -213,7 +210,7 @@ export class EventService extends GenericService<SportEvent> {
}
return axiosInstance
.get(`${resultListUrl}/${id}/cup_score_lists`)
.then(response => response.data)
.then((response) => response.data)
.catch((error) => {
handleApiError(error, t)
return null
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</parent>
<groupId>de.jobst</groupId>
<artifactId>resulter</artifactId>
<version>0.0.16</version>
<version>0.0.17</version>
<name>resulter-api</name>
<description>Backend for resulter web app</description>
<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,51 +19,47 @@ public interface ResultListJdbcRepository extends CrudRepository<ResultListDbo,
Collection<ResultListDbo> findAll();

@Query("""
SELECT DISTINCT
rl.event_id, rl.id as result_list_id, rl.race_id, rl.create_time, rl.create_time_zone, rl.status as result_list_status,
cl.short_name as class_list_short_name, cl.name as class_list_name, cl.gender as class_gender, cl.course_id,
pr.person_id, pr.organisation_id,
prr.start_time, prr.start_time_zone, prr.punch_time, prr.position, prr.race_number, prr.state
FROM result_list rl
LEFT JOIN class_result cl ON rl.id = cl.result_list_id
LEFT JOIN person_result pr ON rl.id = cl.result_list_id and pr.class_result_short_name = cl.short_name
LEFT JOIN person_race_result prr ON rl.id = prr.result_list_id and prr.class_result_short_name = pr.class_result_short_name and prr.person_id = pr.person_id
WHERE rl.id = :resultListId
AND prr.state != 'DID_NOT_START'
ORDER BY rl.id, cl.short_name, prr.race_number, prr.position, pr.person_id
SELECT DISTINCT
rl.event_id, rl.id AS result_list_id, rl.race_id, rl.create_time, rl.create_time_zone, rl.status AS result_list_status,
cl.short_name AS class_list_short_name, cl.name AS class_list_name, cl.gender AS class_gender, cl.course_id,
pr.person_id, pr.organisation_id,
prr.start_time, prr.start_time_zone, prr.punch_time, prr.position, prr.race_number, prr.state
FROM person_race_result prr
INNER JOIN result_list rl ON rl.id = prr.result_list_id and rl.id = :resultListId
INNER JOIN class_result cl ON prr.result_list_id = cl.result_list_id and prr.class_result_short_name = cl.short_name
INNER JOIN person_result pr ON prr.result_list_id = pr.result_list_id and prr.class_result_short_name = pr.class_result_short_name and prr.person_id = pr.person_id
WHERE prr.state != 'DID_NOT_START'
ORDER BY rl.id, cl.short_name, prr.race_number, prr.position, pr.person_id;
""")
Collection<PersonRaceResultJdbcDto> findPersonRaceResultsByResultListId(@Param("resultListId") Long resultListId);

@Query("""
SELECT
rl.event_id, rl.id as result_list_id, rl.race_id, rl.create_time, rl.create_time_zone, rl.status as result_list_status,
cl.short_name as class_list_short_name, cl.name as class_list_name, cl.gender as class_gender, cl.course_id,
pr.person_id, pr.organisation_id,
prr.start_time, prr.start_time_zone, prr.punch_time, prr.position, prr.race_number, prr.state
FROM result_list rl
LEFT JOIN class_result cl ON rl.id = cl.result_list_id
LEFT JOIN person_result pr ON rl.id = cl.result_list_id and pr.class_result_short_name = cl.short_name
LEFT JOIN person_race_result prr ON rl.id = prr.result_list_id and prr.class_result_short_name = pr.class_result_short_name and prr.person_id = pr.person_id
WHERE rl.event_id = :eventId
AND prr.state != 'DID_NOT_START'
ORDER BY rl.id, cl.short_name, prr.race_number, prr.position, pr.person_id
rl.event_id, rl.id AS result_list_id, rl.race_id, rl.create_time, rl.create_time_zone, rl.status AS result_list_status,
cl.short_name AS class_list_short_name, cl.name AS class_list_name, cl.gender AS class_gender, cl.course_id,
pr.person_id, pr.organisation_id,
prr.start_time, prr.start_time_zone, prr.punch_time, prr.position, prr.race_number, prr.state
FROM person_race_result prr
INNER JOIN result_list rl ON rl.id = prr.result_list_id and rl.event_id = :eventId
INNER JOIN class_result cl ON prr.result_list_id = cl.result_list_id and prr.class_result_short_name = cl.short_name
INNER JOIN person_result pr ON prr.result_list_id = pr.result_list_id and prr.class_result_short_name = pr.class_result_short_name and prr.person_id = pr.person_id
WHERE prr.state != 'DID_NOT_START'
ORDER BY rl.id, cl.short_name, prr.race_number, prr.position, pr.person_id;
""")
Collection<PersonRaceResultJdbcDto> findPersonRaceResultsByEventId(@Param("eventId") Long eventId);

@Query("""
SELECT DISTINCT
rl.event_id, rl.id as result_list_id, rl.race_id, rl.create_time, rl.create_time_zone, rl.status as result_list_status,
cl.short_name as class_list_short_name, cl.name as class_list_name, cl.gender as class_gender, cl.course_id,
pr.person_id, pr.organisation_id,
prr.start_time, prr.start_time_zone, prr.punch_time, prr.position, prr.race_number, prr.state
FROM result_list rl
LEFT JOIN class_result cl ON rl.id = cl.result_list_id and cl.short_name = :classResultShortName
LEFT JOIN person_result pr ON rl.id = cl.result_list_id and pr.class_result_short_name = cl.short_name and pr.person_id = :personId
LEFT JOIN person_race_result prr ON rl.id = prr.result_list_id and prr.class_result_short_name = pr.class_result_short_name and prr.person_id = pr.person_id
WHERE rl.id = :resultListId
AND cl.short_name = :classResultShortName
AND pr.person_id = :personId
ORDER BY prr.race_number
SELECT
rl.event_id, rl.id AS result_list_id, rl.race_id, rl.create_time, rl.create_time_zone, rl.status AS result_list_status,
cl.short_name AS class_list_short_name, cl.name AS class_list_name, cl.gender AS class_gender, cl.course_id,
pr.person_id, pr.organisation_id,
prr.start_time, prr.start_time_zone, prr.punch_time, prr.position, prr.race_number, prr.state
FROM person_race_result prr
INNER JOIN result_list rl ON rl.id = prr.result_list_id and rl.id = :resultListId
INNER JOIN class_result cl ON prr.result_list_id = cl.result_list_id and prr.class_result_short_name = cl.short_name and cl.short_name = :classResultShortName
INNER JOIN person_result pr ON prr.result_list_id = pr.result_list_id and prr.class_result_short_name = pr.class_result_short_name and prr.person_id = pr.person_id and pr.person_id = :personId
WHERE prr.state != 'DID_NOT_START'
ORDER BY rl.id, prr.race_number, cl.short_name, prr.race_number, prr.position, pr.person_id;
""")
List<PersonRaceResultJdbcDto> findPersonRaceResultByResultListIdAndClassResultShortNameAndPersonId(
@Param("resultListId") Long resultListId,
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/de/jobst/resulter/domain/ClassResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

public record ClassResult(@NonNull ClassResultName classResultName, @NonNull ClassResultShortName classResultShortName,
@NonNull Gender gender, @NonNull PersonResults personResults, @Nullable CourseId courseId)
Expand All @@ -31,11 +32,13 @@ public int compareTo(@NonNull ClassResult o) {
public List<CupScore> calculate(Cup cup, CupTypeCalculationStrategy cupTypeCalculationStrategy) {
List<PersonResult> personResults =
this.personResults().value().stream().filter(cupTypeCalculationStrategy::valid).sorted().toList();
var organisationByPerson = personResults.stream().collect(Collectors.toMap(PersonResult::personId,
v -> v.organisationId() != null ? v.organisationId() : null ));
List<PersonRaceResult> personRaceResults = personResults.stream()
.flatMap(it -> it.personRaceResults().value().stream())
.filter(y -> y.getState().equals(ResultStatus.OK))
.sorted()
.toList();
return cupTypeCalculationStrategy.calculate(cup, personRaceResults);
return cupTypeCalculationStrategy.calculate(cup, personRaceResults, organisationByPerson);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import de.jobst.resulter.domain.*;

import java.util.List;
import java.util.Map;

public class AddCalculationStrategy implements CupTypeCalculationStrategy {

Expand All @@ -17,7 +18,8 @@ public boolean valid(PersonResult personResult) {
}

@Override
public List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults) {
public List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults,
Map<PersonId, OrganisationId> organisationByPerson) {

return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import de.jobst.resulter.domain.*;

import java.util.List;
import java.util.Map;

public interface CupTypeCalculationStrategy {

boolean valid(ClassResult classResult);

boolean valid(PersonResult personResult);

List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults);
List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults,
Map<PersonId, OrganisationId> organisationByPerson);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import de.jobst.resulter.domain.*;

import java.util.List;
import java.util.Map;

public class KristallCalculationStrategy implements CupTypeCalculationStrategy {

Expand All @@ -17,7 +18,8 @@ public boolean valid(PersonResult personResult) {
}

@Override
public List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults) {
public List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults,
Map<PersonId, OrganisationId> organisationByPerson) {

return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ public class NORCalculationStrategy implements CupTypeCalculationStrategy {
private final Map<OrganisationId, Organisation> organisationById;
private final Organisation norOrganisation;

Set<String> classesToSkip = Set.of("BK", "BL", "Beg", "Trim", "Beginner");
Set<String> classesToSkip = Set.of("BK", "BL", "Beg", "Trim", "Beginner","OffK","OffL","D/H-12 Be");

public NORCalculationStrategy(Map<OrganisationId, Organisation> organisationById) {
this.organisationById = organisationById;
norOrganisation = organisationById.values()
.stream()
.filter(x -> x.containsOrganisationWithShortName(CupType.NOR.value()))
.filter(x -> x.containsOrganisationWithShortName(CUP_TYPE.value()))
.findFirst()
.orElse(null);
}
Expand Down Expand Up @@ -72,7 +72,8 @@ public boolean valid(PersonResult personResult) {
}

@Override
public List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults) {
public List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults,
Map<PersonId, OrganisationId> organisationByPerson) {
if (personRaceResults.isEmpty()) {
return List.of();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,63 @@
package de.jobst.resulter.domain.scoring;

import de.jobst.resulter.domain.*;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.*;

@Slf4j
public class NebelCalculationStrategy implements CupTypeCalculationStrategy {

private final Map<OrganisationId, Organisation> organisationById;

Set<String> classesToSkip = Set.of("BK", "BL", "Beg", "Trim", "Beginner", "OffK", "OffL", "D/H-12 Be");
Set<String> organisationsToSkip = Set.of("ohne", "Volkssport");

public NebelCalculationStrategy(Map<OrganisationId, Organisation> organisationById) {
this.organisationById = organisationById;
}

@Override
public boolean valid(ClassResult classResult) {
return false;
return classesToSkip.stream().noneMatch(it -> classResult.classResultShortName().value().equals(it));
}

@Override
public boolean valid(PersonResult personResult) {
return false;
if (personResult.organisationId() != null && (personResult.organisationId().value () == 131)) {
var org = organisationById.get(personResult.organisationId());
log.debug(org.toString());
}
Boolean result = Optional.ofNullable(organisationById.get(personResult.organisationId()))
.map(v -> {
boolean contains = organisationsToSkip.contains(v.getShortName().value());
return !contains;
})
.orElse(false);
return result;
}

@Override
public List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults) {
public List<CupScore> calculate(Cup cup, List<PersonRaceResult> personRaceResults,
Map<PersonId, OrganisationId> organisationByPerson) {
if (personRaceResults.isEmpty()) {
return List.of();
}

PunchTime fastestTime = personRaceResults.getFirst().getRuntime();
Set<OrganisationId> organisationWithScore = new HashSet<>();
var personRaceResultsWithScore = personRaceResults.stream()
.filter(x -> Optional.ofNullable(organisationByPerson.get(x.getPersonId()))
.filter(organisationWithScore::add) // predicate will be applied only if Optional is not empty
.isPresent())
.toList();

return personRaceResultsWithScore.stream().map(x -> calculateScore(x, fastestTime)).toList();
}

return null;
private CupScore calculateScore(PersonRaceResult personRaceResult, PunchTime fastestTime) {
return CupScore.of(personRaceResult.getPersonId(),
personRaceResult.getClassResultShortName(),
NORCalculationStrategy.calculateNorPoints(fastestTime.value(), personRaceResult.getRuntime().value()));
}
}

0 comments on commit 07452a6

Please sign in to comment.