Files
scavengerhunt-api/src/main/kotlin/net/halfbinary/scavengerhuntapi/service/StatsService.kt

59 lines
2.6 KiB
Kotlin

package net.halfbinary.scavengerhuntapi.service
import net.halfbinary.scavengerhuntapi.model.HuntId
import net.halfbinary.scavengerhuntapi.model.PhotoStatus
import net.halfbinary.scavengerhuntapi.model.domain.HunterLeaderboardEntry
import net.halfbinary.scavengerhuntapi.model.domain.TeamLeaderboardEntry
import net.halfbinary.scavengerhuntapi.repository.ItemRepository
import net.halfbinary.scavengerhuntapi.repository.PhotoRepository
import org.springframework.stereotype.Service
@Service
class StatsService(
private val photoRepository: PhotoRepository,
private val itemRepository: ItemRepository,
private val teamService: TeamService,
private val hunterService: HunterService
) {
fun getTeamLeaderboard(huntId: HuntId): List<TeamLeaderboardEntry> {
val approvedPhotos = photoRepository.findByHuntIdAndStatus(huntId, PhotoStatus.APPROVED)
val itemPoints = itemRepository.findAllByHuntId(huntId).associate { it.id to it.points }
val teams = teamService.getListOfTeamsForHunt(huntId)
val sortedScores = teams.map { team ->
val teamHunterIds = teamService.getHunterIdsForTeam(team.id)
val score = approvedPhotos
.filter { it.hunterId in teamHunterIds }
.distinctBy { it.itemId }
.sumOf { itemPoints[it.itemId] ?: 0 }
team to score
}.sortedByDescending { (_, score) -> score }
var rank = 1
return sortedScores.mapIndexed { index, (team, score) ->
if (index > 0 && sortedScores[index - 1].second != score) rank = index + 1
TeamLeaderboardEntry(rank = rank, teamName = team.name, score = score)
}
}
fun getHunterLeaderboard(huntId: HuntId): List<HunterLeaderboardEntry> {
val approvedPhotos = photoRepository.findByHuntIdAndStatus(huntId, PhotoStatus.APPROVED)
val itemPoints = itemRepository.findAllByHuntId(huntId).associate { it.id to it.points }
val sortedScores = approvedPhotos
.groupBy { it.hunterId }
.map { (hunterId, photos) ->
val score = photos.distinctBy { it.itemId }.sumOf { itemPoints[it.itemId] ?: 0 }
hunterId to score
}
.sortedByDescending { (_, score) -> score }
var rank = 1
return sortedScores.mapIndexed { index, (hunterId, score) ->
if (index > 0 && sortedScores[index - 1].second != score) rank = index + 1
val hunter = hunterService.getHunterById(hunterId)
HunterLeaderboardEntry(rank = rank, hunterName = hunter.name, score = score)
}
}
}