mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 06:22:13 +01:00 
			
		
		
		
	Cancel draw problem
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
		@@ -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()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user