Cancel draw problem

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2023-04-05 23:28:12 +02:00
parent f41b2e16ab
commit 751e35ac62
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
2 changed files with 108 additions and 2 deletions

View File

@ -1,14 +1,16 @@
# Copyright (C) 2023 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later
import json
from collections import OrderedDict
from random import randint, shuffle
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.utils import translation
from django.utils.translation import gettext_lazy as _
from draw.models import Draw, Pool, Round, TeamDraw
from logs.models import Changelog
from participation.models import Participation, Tournament
from registration.models import Registration
@ -975,6 +977,105 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
{'type': 'draw.box_visibility', 'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.box_visibility', 'visible': True})
elif state == 'WAITING_DRAW_PROBLEM':
p = r.current_pool
accepted_tds = {td.id: td async for td in p.team_draws.filter(accepted__isnull=False)
.prefetch_related('participation__team')}
has_rejected_one_tds = {td.id: td async for td in p.team_draws.exclude(rejected=[])
.prefetch_related('participation__team')}
last_td = None
if accepted_tds or has_rejected_one_tds:
# One team of the already accepted or its problem, we fetch the last one
changelogs = Changelog.objects.filter(
model=await ContentType.objects.aget(app_label=TeamDraw._meta.app_label,
model=TeamDraw._meta.model_name),
action='edit',
instance_pk__in=set(accepted_tds.keys()).union(set(has_rejected_one_tds.keys()))
).order_by('-timestamp')
async for changelog in changelogs:
previous = json.loads(changelog.previous)
data = json.loads(changelog.data)
pk = int(changelog.instance_pk)
print(previous, data, pk)
if 'accepted' in data and data['accepted'] and pk in accepted_tds:
# Undo the last acceptance
last_td = accepted_tds[pk]
last_td.purposed = last_td.accepted
last_td.accepted = None
await last_td.asave()
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_problem',
'round': r.number,
'team': last_td.participation.team.trigram,
'problem': last_td.accepted})
break
if 'rejected' in data and len(data['rejected']) > len(previous['rejected']) \
and pk in has_rejected_one_tds:
# Undo the last reject
last_td = has_rejected_one_tds[pk]
rejected_problem = set(data['rejected']).difference(previous['rejected']).pop()
if rejected_problem not in last_td.rejected:
# This is an old diff
continue
last_td.rejected.remove(rejected_problem)
last_td.purposed = rejected_problem
await last_td.asave()
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.reject_problem',
'round': r.number,
'team': last_td.participation.team.trigram,
'rejected': last_td.rejected})
break
r.current_pool.current_team = last_td
await r.current_pool.asave()
await self.channel_layer.group_send(f"team-{last_td.participation.team.trigram}",
{'type': 'draw.buttons_visibility', 'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.buttons_visibility', 'visible': True})
else:
# Return to the dice choice
pool_tds = {td.id: td async for td in p.team_draws.prefetch_related('participation__team')}
changelogs = Changelog.objects.filter(
model=ContentType.objects.get_for_model(TeamDraw),
action='edit',
instance_pk__in=set(pool_tds.keys())
).order_by('-timestamp')
# Find the last dice that was launched
async for changelog in changelogs:
data = json.loads(changelog.data)
if 'choice_dice' in data and data['choice_dice']:
last_td = pool_tds[int(changelog.instance_pk)]
# Reset the dice
last_td.choice_dice = None
await last_td.asave()
# Reset the dice on the interface
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}", {'type': 'draw.dice',
'team': last_td.participation.team.trigram,
'result': None})
break
p.current_team = None
await p.asave()
# Make dice box visible
for td in pool_tds.values():
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.dice_visibility', 'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': True})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.box_visibility', 'visible': False})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info', 'draw': self.tournament.draw})

View File

@ -618,9 +618,9 @@ document.addEventListener('DOMContentLoaded', () => {
let recapDiv = document.getElementById(`recap-${tournament.id}-round-${round}-team-${team}-rejected`)
recapDiv.textContent = `🗑️ ${rejected.join(', ')}`
let penaltyDiv = document.getElementById(`recap-${tournament.id}-round-${round}-team-${team}-penalty`)
if (rejected.length > problems_count - 5) {
// If more than P - 5 problems were rejected, add a penalty of 0.5 of the coefficient of the oral defender
let penaltyDiv = document.getElementById(`recap-${tournament.id}-round-${round}-team-${team}-penalty`)
if (penaltyDiv === null) {
penaltyDiv = document.createElement('div')
penaltyDiv.id = `recap-${tournament.id}-round-${round}-team-${team}-penalty`
@ -629,6 +629,11 @@ document.addEventListener('DOMContentLoaded', () => {
}
penaltyDiv.textContent = `${0.5 * (rejected.length - (problems_count - 5))}`
}
else {
// Eventually remove this div
if (penaltyDiv !== null)
penaltyDiv.remove()
}
}
/**