Cancel draw problem
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
parent
f41b2e16ab
commit
751e35ac62
|
@ -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})
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue