59 lines
2.6 KiB
Kotlin
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)
|
|
}
|
|
}
|
|
}
|