fix/winnings #15

Merged
arthur.valin merged 3 commits from fix/winnings into master 11 months ago

@ -6,6 +6,7 @@ import allin.model.FriendStatus
interface FriendDataSource { interface FriendDataSource {
fun addFriend(sender: String, receiver: String) fun addFriend(sender: String, receiver: String)
fun getFriendFromUserId(id: String): List<UserDTO> fun getFriendFromUserId(id: String): List<UserDTO>
fun getFriendRequestsFromUserId(id: String): List<UserDTO>
fun deleteFriend(senderId: String, receiverId: String): Boolean fun deleteFriend(senderId: String, receiverId: String): Boolean
fun isFriend(firstUser: String, secondUser: String): Boolean fun isFriend(firstUser: String, secondUser: String): Boolean
fun filterUsersByUsername(fromUserId: String, search: String): List<UserDTO> fun filterUsersByUsername(fromUserId: String, search: String): List<UserDTO>

@ -90,7 +90,21 @@ class MockBetDataSource(private val mockData: MockDataSource.MockData) : BetData
if (bet.status != CANCELLED && bet.status != FINISHED) { if (bet.status != CANCELLED && bet.status != FINISHED) {
if (date >= bet.endRegistration) { if (date >= bet.endRegistration) {
if (date >= bet.endBet) { if (date >= bet.endBet) {
if (date.plusWeeks(1) >= bet.endBet) {
bets[idx] = bet.copy(status = CANCELLED)
participations
.filter { it.betId == bets[idx].id }
.forEach { p ->
users.replaceAll {
if (it.username == p.username) {
it.copy(nbCoins = it.nbCoins + p.stake)
} else it
}
}
} else {
bets[idx] = bet.copy(status = CLOSING) bets[idx] = bet.copy(status = CLOSING)
}
} else { } else {
bets[idx] = bet.copy(status = WAITING) bets[idx] = bet.copy(status = WAITING)
} }
@ -115,12 +129,14 @@ class MockBetDataSource(private val mockData: MockDataSource.MockData) : BetData
it.copy(status = FINISHED) it.copy(status = FINISHED)
} else it } else it
} }
val resultAnswerInfo = answerInfos.find { it.betId == betId && it.response == result }
participations.filter { it.betId == betId && it.answer == result } participations.filter { it.betId == betId && it.answer == result }
.forEach { participation -> .forEach { participation ->
val amount = (participation.stake * (resultAnswerInfo?.odds ?: 1f)).roundToInt()
users.replaceAll { users.replaceAll {
if (it.username == participation.username) { if (it.username == participation.username) {
it.copy(nbCoins = it.nbCoins + participation.stake) it.copy(nbCoins = it.nbCoins + amount)
} else it } else it
} }
resultNotifications.add(Pair(betId, participation.username)) resultNotifications.add(Pair(betId, participation.username))

@ -26,6 +26,15 @@ class MockFriendDataSource(private val mockData: MockDataSource.MockData) : Frie
) )
} }
override fun getFriendRequestsFromUserId(id: String): List<UserDTO> {
return friends
.filter { (it.receiver == id) && !isFriend(id, it.sender) }
.mapNotNull {
users.find { usr -> usr.id == it.sender }
?.toDto(friendStatus = FriendStatus.NOT_FRIEND)
}
}
override fun deleteFriend(senderId: String, receiverId: String) = override fun deleteFriend(senderId: String, receiverId: String) =
friends.removeIf { (it.sender == senderId) && (it.receiver == receiverId) } friends.removeIf { (it.sender == senderId) && (it.receiver == receiverId) }

@ -8,6 +8,8 @@ import org.ktorm.dsl.*
import org.ktorm.entity.* import org.ktorm.entity.*
import java.time.ZoneId import java.time.ZoneId
import java.time.ZonedDateTime import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit
import kotlin.math.roundToInt
class PostgresBetDataSource(private val database: Database) : BetDataSource { class PostgresBetDataSource(private val database: Database) : BetDataSource {
@ -60,12 +62,12 @@ class PostgresBetDataSource(private val database: Database) : BetDataSource {
.map { it.toBet(database) } .map { it.toBet(database) }
} }
override fun getToConfirm(id: String): List<BetDetail> { override fun getToConfirm(username: String): List<BetDetail> {
return database.bets return database.bets
.filter { .filter {
(it.createdBy eq id) and (BetsEntity.status eq BetStatus.CLOSING) (it.createdBy eq username) and (BetsEntity.status eq BetStatus.CLOSING)
} }
.map { it.toBetDetail(database, id) } .map { it.toBetDetail(database, username) }
} }
override fun confirmBet(betId: String, result: String) { override fun confirmBet(betId: String, result: String) {
@ -81,16 +83,26 @@ class PostgresBetDataSource(private val database: Database) : BetDataSource {
) )
} }
val resultAnswerInfo = database.betAnswerInfos
.find { (it.betId eq betId) and (it.response eq result) }
?.toBetAnswerInfo()
database.participations.filter { database.participations.filter {
(ParticipationsEntity.betId eq betId) and (ParticipationsEntity.betId eq betId) and
(ParticipationsEntity.answer eq result) (ParticipationsEntity.answer eq result)
}.forEach { }.forEach { participation ->
database.betResultNotifications.add( database.betResultNotifications.add(
BetResultNotificationEntity { BetResultNotificationEntity {
this.betId = betId this.betId = betId
this.username = it.username this.username = participation.username
} }
) )
val amount = (participation.stake * (resultAnswerInfo?.odds ?: 1f)).roundToInt()
database.update(UsersEntity) { usr ->
set(usr.nbCoins, usr.nbCoins + amount)
where { usr.username eq participation.username }
}
} }
} }
@ -203,23 +215,33 @@ class PostgresBetDataSource(private val database: Database) : BetDataSource {
} }
override fun updateBetStatuses(date: ZonedDateTime) { override fun updateBetStatuses(date: ZonedDateTime) {
database.update(BetsEntity) { database.bets
set(BetsEntity.status, BetStatus.WAITING) .filter {
where {
(date.toInstant() greaterEq BetsEntity.endRegistration) and (date.toInstant() greaterEq BetsEntity.endRegistration) and
(date.toInstant() less BetsEntity.endBet) and
(BetsEntity.status notEq BetStatus.FINISHED) and (BetsEntity.status notEq BetStatus.FINISHED) and
(BetsEntity.status notEq BetStatus.CANCELLED) (BetsEntity.status notEq BetStatus.CANCELLED)
} }.let {
it.filter { date.toInstant() less BetsEntity.endBet }.forEach { bet ->
bet.status = BetStatus.WAITING
bet.flushChanges()
} }
database.update(BetsEntity) { it.filter { date.toInstant() greaterEq BetsEntity.endBet }.forEach { bet ->
set(BetsEntity.status, BetStatus.CLOSING) if (date.toInstant() >= bet.endBet.plus(7, ChronoUnit.DAYS)) {
where { database.participations
(date.toInstant() greaterEq BetsEntity.endRegistration) and .filter { it.betId eq bet.id }
(date.toInstant() greaterEq BetsEntity.endBet) and .forEach { participation ->
(BetsEntity.status notEq BetStatus.FINISHED) and database.users.find { it.username eq participation.username }?.let { user ->
(BetsEntity.status notEq BetStatus.CANCELLED) user.nbCoins += participation.stake
user.flushChanges()
}
}
bet.status = BetStatus.CANCELLED
bet.flushChanges()
} else {
bet.status = BetStatus.CLOSING
bet.flushChanges()
}
} }
} }
} }

@ -37,10 +37,26 @@ class PostgresFriendDataSource(private val database: Database) : FriendDataSourc
) )
} }
override fun getFriendRequestsFromUserId(id: String): List<UserDTO> {
return database.friends
.filter { it.receiver eq id }
.mapNotNull {
if (isFriend(firstUser = id, secondUser = it.sender)) {
null
} else {
database.users.find { usr ->
usr.id eq it.sender
}?.toUserDTO(friendStatus = FriendStatus.NOT_FRIEND)
}
}
}
override fun deleteFriend(senderId: String, receiverId: String): Boolean { override fun deleteFriend(senderId: String, receiverId: String): Boolean {
database.friends.removeIf { (it.sender eq receiverId) and (it.receiver eq senderId) } val result = database.friends.removeIf { (it.sender eq receiverId) and (it.receiver eq senderId) } +
return database.friends.removeIf { (it.sender eq senderId) and (it.receiver eq receiverId) } > 0 database.friends.removeIf { (it.sender eq senderId) and (it.receiver eq receiverId) }
return result > 0
} }
override fun isFriend(firstUser: String, secondUser: String) = override fun isFriend(firstUser: String, secondUser: String) =

@ -3,10 +3,14 @@ package allin.data.postgres.entities
import allin.model.BetResult import allin.model.BetResult
import allin.model.BetResultDetail import allin.model.BetResultDetail
import org.ktorm.database.Database import org.ktorm.database.Database
import org.ktorm.dsl.and
import org.ktorm.dsl.eq
import org.ktorm.entity.Entity import org.ktorm.entity.Entity
import org.ktorm.entity.find
import org.ktorm.entity.sequenceOf import org.ktorm.entity.sequenceOf
import org.ktorm.schema.Table import org.ktorm.schema.Table
import org.ktorm.schema.varchar import org.ktorm.schema.varchar
import kotlin.math.roundToInt
interface BetResultEntity : Entity<BetResultEntity> { interface BetResultEntity : Entity<BetResultEntity> {
@ -24,15 +28,20 @@ interface BetResultEntity : Entity<BetResultEntity> {
fun toBetResultDetail( fun toBetResultDetail(
database: Database, database: Database,
participationEntity: ParticipationEntity participationEntity: ParticipationEntity
) = ): BetResultDetail {
BetResultDetail( val answerInfo = database.betAnswerInfos.find {
(it.betId eq bet.id) and (it.response eq participationEntity.answer)
}?.toBetAnswerInfo()
return BetResultDetail(
betResult = this.toBetResult(), betResult = this.toBetResult(),
bet = bet.toBet(database), bet = bet.toBet(database),
participation = participationEntity.toParticipation(), participation = participationEntity.toParticipation(),
amount = participationEntity.stake, amount = (participationEntity.stake * (answerInfo?.odds ?: 1f)).roundToInt(),
won = participationEntity.answer == result won = participationEntity.answer == result
) )
} }
}
object BetResultsEntity : Table<BetResultEntity>("betresult") { object BetResultsEntity : Table<BetResultEntity>("betresult") {
val betId = varchar("betid").primaryKey().references(BetsEntity) { it.bet } val betId = varchar("betid").primaryKey().references(BetsEntity) { it.bet }

@ -45,6 +45,32 @@ fun Application.friendRouter() {
} }
} }
}
get("/friends/requests", {
description = "Allows you to recover all friend requests of a JWT Token"
request {
headerParameter<JWTPrincipal>("JWT token of the logged user")
}
response {
HttpStatusCode.Accepted to {
description = "The list of friend requests is available"
body<List<UserDTO>> {
description = "List of friend requests"
}
}
}
}) {
hasToken { principal ->
verifyUserFromToken(userDataSource, principal) { _, _ ->
val username = tokenManagerBet.getUsernameFromToken(principal)
val user = userDataSource.getUserByUsername(username).first
call.respond(
HttpStatusCode.Accepted,
friendDataSource.getFriendRequestsFromUserId(user?.id.toString())
)
}
}
} }
post("/friends/add", { post("/friends/add", {
description = "Allows a user to add a friend" description = "Allows a user to add a friend"
@ -128,12 +154,10 @@ fun Application.friendRouter() {
if (user == null || userFriend == null) { if (user == null || userFriend == null) {
call.respond(HttpStatusCode.Conflict, ApiMessage.USER_NOT_FOUND) call.respond(HttpStatusCode.Conflict, ApiMessage.USER_NOT_FOUND)
} else { } else {
val friendlist = friendDataSource.getFriendFromUserId(user.id) if (friendDataSource.deleteFriend(user.id, userFriend.id)) {
if (!friendlist.map { it.id }.contains(userFriend.id)) {
call.respond(HttpStatusCode.Conflict, ApiMessage.FRIENDS_DOESNT_EXISTS)
} else {
friendDataSource.deleteFriend(user.id, userFriend.id)
call.respond(HttpStatusCode.Created, usernameFriend) call.respond(HttpStatusCode.Created, usernameFriend)
} else {
call.respond(HttpStatusCode.Conflict, ApiMessage.FRIENDS_DOESNT_EXISTS)
} }
} }
} }

Loading…
Cancel
Save