mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 08:22:10 +01:00 
			
		
		
		
	Reorganize the cancel step code in order to make it more readable
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
		@@ -942,182 +942,268 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
			
		||||
        if not await Draw.objects.filter(tournament=self.tournament).aexists():
 | 
			
		||||
            return await self.alert(_("The draw has not started yet."), 'danger')
 | 
			
		||||
 | 
			
		||||
        content_type = await ContentType.objects.aget(app_label=TeamDraw._meta.app_label,
 | 
			
		||||
                                                      model=TeamDraw._meta.model_name)
 | 
			
		||||
 | 
			
		||||
        state = self.tournament.draw.get_state()
 | 
			
		||||
 | 
			
		||||
        self.tournament.draw.last_message = ""
 | 
			
		||||
        await self.tournament.draw.asave()
 | 
			
		||||
 | 
			
		||||
        r = self.tournament.draw.current_round
 | 
			
		||||
 | 
			
		||||
        if state == 'DRAW_ENDED' or state == 'WAITING_FINAL':
 | 
			
		||||
            td = self.tournament.draw.current_round.current_pool.current_team
 | 
			
		||||
            td.purposed = td.accepted
 | 
			
		||||
            td.accepted = None
 | 
			
		||||
            await td.asave()
 | 
			
		||||
 | 
			
		||||
            await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
			
		||||
                                                {'type': 'draw.continue_visibility', 'visible': False})
 | 
			
		||||
 | 
			
		||||
            await self.channel_layer.group_send(f"team-{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})
 | 
			
		||||
 | 
			
		||||
            await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                {'type': 'draw.set_problem',
 | 
			
		||||
                                                 'round': r.number,
 | 
			
		||||
                                                 'team': td.participation.team.trigram,
 | 
			
		||||
                                                 'problem': td.accepted})
 | 
			
		||||
            await self.undo_end_draw()
 | 
			
		||||
        elif state == 'WAITING_CHOOSE_PROBLEM':
 | 
			
		||||
            td = self.tournament.draw.current_round.current_pool.current_team
 | 
			
		||||
            td.purposed = None
 | 
			
		||||
            await td.asave()
 | 
			
		||||
 | 
			
		||||
            await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
 | 
			
		||||
                                                {'type': 'draw.buttons_visibility', 'visible': False})
 | 
			
		||||
            await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
			
		||||
                                                {'type': 'draw.buttons_visibility', 'visible': False})
 | 
			
		||||
            await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
 | 
			
		||||
                                                {'type': 'draw.box_visibility', 'visible': True})
 | 
			
		||||
            await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
			
		||||
                                                {'type': 'draw.box_visibility', 'visible': True})
 | 
			
		||||
            await self.undo_draw_problem()
 | 
			
		||||
        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=content_type,
 | 
			
		||||
                    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)
 | 
			
		||||
 | 
			
		||||
                    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=content_type,
 | 
			
		||||
                    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.undo_process_problem()
 | 
			
		||||
        elif state == 'DICE_ORDER_POULE':
 | 
			
		||||
            p = r.current_pool
 | 
			
		||||
            already_launched_tds = {td.id: td async for td in p.team_draws.filter(choice_dice__isnull=False)
 | 
			
		||||
                                    .prefetch_related('participation__team')}
 | 
			
		||||
            await self.undo_pool_dice()
 | 
			
		||||
        elif state == 'DICE_SELECT_POULES':
 | 
			
		||||
            await self.undo_order_dice()
 | 
			
		||||
 | 
			
		||||
            if already_launched_tds:
 | 
			
		||||
                # Reset the last dice
 | 
			
		||||
                changelogs = Changelog.objects.filter(
 | 
			
		||||
                    model=content_type,
 | 
			
		||||
                    action='edit',
 | 
			
		||||
                    instance_pk__in=set(already_launched_tds.keys())
 | 
			
		||||
                ).order_by('-timestamp')
 | 
			
		||||
        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                            {'type': 'draw.set_info', 'draw': self.tournament.draw})
 | 
			
		||||
        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                            {'type': 'draw.set_active', 'draw': self.tournament.draw})
 | 
			
		||||
 | 
			
		||||
                # 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 = already_launched_tds[int(changelog.instance_pk)]
 | 
			
		||||
                        # Reset the dice
 | 
			
		||||
                        last_td.choice_dice = None
 | 
			
		||||
                        await last_td.asave()
 | 
			
		||||
    async def undo_end_draw(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        If the draw is ended, or if we are between the two rounds of the final,
 | 
			
		||||
        then we cancel the last problem that was accepted.
 | 
			
		||||
        """
 | 
			
		||||
        r = self.tournament.draw.current_round
 | 
			
		||||
        td = r.current_pool.current_team
 | 
			
		||||
        td.purposed = td.accepted
 | 
			
		||||
        td.accepted = None
 | 
			
		||||
        await td.asave()
 | 
			
		||||
 | 
			
		||||
                        # Reset the dice on the interface
 | 
			
		||||
        await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
			
		||||
                                            {'type': 'draw.continue_visibility', 'visible': False})
 | 
			
		||||
 | 
			
		||||
        await self.channel_layer.group_send(f"team-{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})
 | 
			
		||||
 | 
			
		||||
        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                            {'type': 'draw.set_problem',
 | 
			
		||||
                                             'round': r.number,
 | 
			
		||||
                                             'team': td.participation.team.trigram,
 | 
			
		||||
                                             'problem': td.accepted})
 | 
			
		||||
 | 
			
		||||
    async def undo_draw_problem(self):
 | 
			
		||||
        """
 | 
			
		||||
        A problem was drawn and we wait for the current team to accept or reject the problem.
 | 
			
		||||
        Then, we just reset the problem draw.
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        td = self.tournament.draw.current_round.current_pool.current_team
 | 
			
		||||
        td.purposed = None
 | 
			
		||||
        await td.asave()
 | 
			
		||||
 | 
			
		||||
        await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
 | 
			
		||||
                                            {'type': 'draw.buttons_visibility', 'visible': False})
 | 
			
		||||
        await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
			
		||||
                                            {'type': 'draw.buttons_visibility', 'visible': False})
 | 
			
		||||
        await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
 | 
			
		||||
                                            {'type': 'draw.box_visibility', 'visible': True})
 | 
			
		||||
        await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
			
		||||
                                            {'type': 'draw.box_visibility', 'visible': True})
 | 
			
		||||
 | 
			
		||||
    async def undo_process_problem(self):
 | 
			
		||||
        """
 | 
			
		||||
        Now, a team must draw a new problem. Multiple cases are possible:
 | 
			
		||||
        * In the same pool, a previous team accepted a problem ;
 | 
			
		||||
        * In the same pool, a previous team rejected a problem ;
 | 
			
		||||
        * The current team rejected a problem that was previously rejected ;
 | 
			
		||||
        * The last team drawn its dice to choose the draw order.
 | 
			
		||||
 | 
			
		||||
        In the two first cases, we explore the database history to fetch what team accepted or rejected
 | 
			
		||||
        its problem at last.
 | 
			
		||||
        The third case is ignored, because too hard and too useless to manage.
 | 
			
		||||
        For the last case, we cancel the last dice.
 | 
			
		||||
        """
 | 
			
		||||
        content_type = await ContentType.objects.aget(app_label=TeamDraw._meta.app_label,
 | 
			
		||||
                                                      model=TeamDraw._meta.model_name)
 | 
			
		||||
 | 
			
		||||
        r = self.tournament.draw.current_round
 | 
			
		||||
        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=content_type,
 | 
			
		||||
                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)
 | 
			
		||||
 | 
			
		||||
                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=content_type,
 | 
			
		||||
                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})
 | 
			
		||||
 | 
			
		||||
    async def undo_pool_dice(self):
 | 
			
		||||
        """
 | 
			
		||||
        Teams of a pool are launching their dices to define the draw order.
 | 
			
		||||
        We reset the last dice if possible, or we go to the last pool, or the last round,
 | 
			
		||||
        or the passage dices.
 | 
			
		||||
        """
 | 
			
		||||
        content_type = await ContentType.objects.aget(app_label=TeamDraw._meta.app_label,
 | 
			
		||||
                                                      model=TeamDraw._meta.model_name)
 | 
			
		||||
 | 
			
		||||
        r = self.tournament.draw.current_round
 | 
			
		||||
        p = r.current_pool
 | 
			
		||||
        already_launched_tds = {td.id: td async for td in p.team_draws.filter(choice_dice__isnull=False)
 | 
			
		||||
                                .prefetch_related('participation__team')}
 | 
			
		||||
 | 
			
		||||
        if already_launched_tds:
 | 
			
		||||
            # Reset the last dice
 | 
			
		||||
            changelogs = Changelog.objects.filter(
 | 
			
		||||
                model=content_type,
 | 
			
		||||
                action='edit',
 | 
			
		||||
                instance_pk__in=set(already_launched_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 = already_launched_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
 | 
			
		||||
        else:
 | 
			
		||||
            # Go to the previous pool if possible
 | 
			
		||||
            if p.letter > 1:
 | 
			
		||||
                # Go to the previous pool
 | 
			
		||||
                previous_pool = await r.pool_set.prefetch_related('current_team__participation__team') \
 | 
			
		||||
                    .aget(letter=p.letter - 1)
 | 
			
		||||
                r.current_pool = previous_pool
 | 
			
		||||
                await r.asave()
 | 
			
		||||
 | 
			
		||||
                td = previous_pool.current_team
 | 
			
		||||
                td.purposed = td.accepted
 | 
			
		||||
                td.accepted = None
 | 
			
		||||
                await td.asave()
 | 
			
		||||
 | 
			
		||||
                await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                    {'type': 'draw.dice_visibility', 'visible': False})
 | 
			
		||||
 | 
			
		||||
                await self.channel_layer.group_send(f"team-{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})
 | 
			
		||||
 | 
			
		||||
                await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                    {'type': 'draw.set_problem',
 | 
			
		||||
                                                     'round': r.number,
 | 
			
		||||
                                                     'team': td.participation.team.trigram,
 | 
			
		||||
                                                     'problem': td.accepted})
 | 
			
		||||
            elif r.number == 2:
 | 
			
		||||
                if not self.tournament.final:
 | 
			
		||||
                    # Go to the previous round
 | 
			
		||||
                    r1 = await self.tournament.draw.round_set \
 | 
			
		||||
                        .prefetch_related('current_pool__current_team__participation__team').aget(number=1)
 | 
			
		||||
                    self.tournament.draw.current_round = r1
 | 
			
		||||
                    await self.tournament.draw.asave()
 | 
			
		||||
 | 
			
		||||
                    async for td in r1.team_draws.prefetch_related('participation__team').all():
 | 
			
		||||
                        await self.channel_layer.group_send(
 | 
			
		||||
                            f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
			
		||||
                                                                 'team': last_td.participation.team.trigram,
 | 
			
		||||
                                                                 'result': None})
 | 
			
		||||
                        break
 | 
			
		||||
            else:
 | 
			
		||||
                # Go to the previous pool if possible
 | 
			
		||||
                if p.letter > 1:
 | 
			
		||||
                    # Go to the previous pool
 | 
			
		||||
                    previous_pool = await r.pool_set.prefetch_related('current_team__participation__team')\
 | 
			
		||||
                        .aget(letter=p.letter - 1)
 | 
			
		||||
                    r.current_pool = previous_pool
 | 
			
		||||
                    await r.asave()
 | 
			
		||||
                                                                 'team': td.participation.team.trigram,
 | 
			
		||||
                                                                 'result': td.choice_dice})
 | 
			
		||||
 | 
			
		||||
                    await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                        {'type': 'draw.send_poules', 'round': r1})
 | 
			
		||||
 | 
			
		||||
                    previous_pool = r1.current_pool
 | 
			
		||||
 | 
			
		||||
                    td = previous_pool.current_team
 | 
			
		||||
                    td.purposed = td.accepted
 | 
			
		||||
@@ -1134,132 +1220,59 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
			
		||||
 | 
			
		||||
                    await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                        {'type': 'draw.set_problem',
 | 
			
		||||
                                                         'round': r.number,
 | 
			
		||||
                                                         'round': r1.number,
 | 
			
		||||
                                                         'team': td.participation.team.trigram,
 | 
			
		||||
                                                         'problem': td.accepted})
 | 
			
		||||
                elif r.number == 2:
 | 
			
		||||
                    if not self.tournament.final:
 | 
			
		||||
                        # Go to the previous round
 | 
			
		||||
                        r1 = await self.tournament.draw.round_set\
 | 
			
		||||
                            .prefetch_related('current_pool__current_team__participation__team').aget(number=1)
 | 
			
		||||
                        self.tournament.draw.current_round = r1
 | 
			
		||||
                        await self.tournament.draw.asave()
 | 
			
		||||
                else:
 | 
			
		||||
                    # Don't continue the final tournament
 | 
			
		||||
                    r1 = await self.tournament.draw.round_set \
 | 
			
		||||
                        .prefetch_related('current_pool__current__team__participation__team').aget(number=1)
 | 
			
		||||
                    self.tournament.draw.current_round = r1
 | 
			
		||||
                    await self.tournament.draw.asave()
 | 
			
		||||
 | 
			
		||||
                        async for td in r1.team_draws.prefetch_related('participation__team').all():
 | 
			
		||||
                            await self.channel_layer.group_send(
 | 
			
		||||
                                f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
			
		||||
                                                                     'team': td.participation.team.trigram,
 | 
			
		||||
                                                                     'result': td.choice_dice})
 | 
			
		||||
 | 
			
		||||
                        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                            {'type': 'draw.send_poules', 'round': r1})
 | 
			
		||||
 | 
			
		||||
                        previous_pool = r1.current_pool
 | 
			
		||||
 | 
			
		||||
                        td = previous_pool.current_team
 | 
			
		||||
                        td.purposed = td.accepted
 | 
			
		||||
                        td.accepted = None
 | 
			
		||||
                    async for td in r.teamdraw_set.all():
 | 
			
		||||
                        td.pool = None
 | 
			
		||||
                        td.choose_index = None
 | 
			
		||||
                        td.choice_dice = None
 | 
			
		||||
                        await td.asave()
 | 
			
		||||
 | 
			
		||||
                        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                            {'type': 'draw.dice_visibility', 'visible': False})
 | 
			
		||||
 | 
			
		||||
                        await self.channel_layer.group_send(f"team-{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})
 | 
			
		||||
 | 
			
		||||
                        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                            {'type': 'draw.set_problem',
 | 
			
		||||
                                                             'round': r1.number,
 | 
			
		||||
                                                             'team': td.participation.team.trigram,
 | 
			
		||||
                                                             'problem': td.accepted})
 | 
			
		||||
                    else:
 | 
			
		||||
                        # Don't continue the final tournament
 | 
			
		||||
                        r1 = await self.tournament.draw.round_set \
 | 
			
		||||
                            .prefetch_related('current_pool__current__team__participation__team').aget(number=1)
 | 
			
		||||
                        self.tournament.draw.current_round = r1
 | 
			
		||||
                        await self.tournament.draw.asave()
 | 
			
		||||
 | 
			
		||||
                        async for td in r.teamdraw_set.all():
 | 
			
		||||
                            td.pool = None
 | 
			
		||||
                            td.choose_index = None
 | 
			
		||||
                            td.choice_dice = None
 | 
			
		||||
                            await td.asave()
 | 
			
		||||
 | 
			
		||||
                        async for td in r1.team_draws.prefetch_related('participation__team').all():
 | 
			
		||||
                            await self.channel_layer.group_send(
 | 
			
		||||
                                f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
			
		||||
                                                                     'team': td.participation.team.trigram,
 | 
			
		||||
                                                                     'result': td.choice_dice})
 | 
			
		||||
 | 
			
		||||
                        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                            {'type': 'draw.dice_visibility', 'visible': False})
 | 
			
		||||
                        await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
			
		||||
                                                            {'type': 'draw.continue_visibility', 'visible': True})
 | 
			
		||||
                else:
 | 
			
		||||
                    # Go to the dice order
 | 
			
		||||
                    async for r0 in self.tournament.draw.round_set.all():
 | 
			
		||||
                        async for td in r0.teamdraw_set.all():
 | 
			
		||||
                            td.pool = None
 | 
			
		||||
                            td.passage_index = None
 | 
			
		||||
                            td.choose_index = None
 | 
			
		||||
                            td.choice_dice = None
 | 
			
		||||
                            await td.asave()
 | 
			
		||||
 | 
			
		||||
                    r.current_pool = None
 | 
			
		||||
                    await r.asave()
 | 
			
		||||
 | 
			
		||||
                    round_tds = {td.id: td async for td in r.team_draws.prefetch_related('participation__team')}
 | 
			
		||||
 | 
			
		||||
                    # Reset the last dice
 | 
			
		||||
                    changelogs = Changelog.objects.filter(
 | 
			
		||||
                        model=content_type,
 | 
			
		||||
                        action='edit',
 | 
			
		||||
                        instance_pk__in=set(round_tds.keys())
 | 
			
		||||
                    ).order_by('-timestamp')
 | 
			
		||||
 | 
			
		||||
                    # Find the last dice that was launched
 | 
			
		||||
                    async for changelog in changelogs:
 | 
			
		||||
                        data = json.loads(changelog.data)
 | 
			
		||||
                        if 'passage_dice' in data and data['passage_dice']:
 | 
			
		||||
                            last_td = round_tds[int(changelog.instance_pk)]
 | 
			
		||||
                            # Reset the dice
 | 
			
		||||
                            last_td.passage_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
 | 
			
		||||
 | 
			
		||||
                    async for td in r.team_draws.prefetch_related('participation__team').all():
 | 
			
		||||
                    async for td in r1.team_draws.prefetch_related('participation__team').all():
 | 
			
		||||
                        await self.channel_layer.group_send(
 | 
			
		||||
                            f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
			
		||||
                                                                 'team': td.participation.team.trigram,
 | 
			
		||||
                                                                 'result': td.passage_dice})
 | 
			
		||||
                                                                 'result': td.choice_dice})
 | 
			
		||||
 | 
			
		||||
                    await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                        {'type': 'draw.dice_visibility', 'visible': True})
 | 
			
		||||
        elif state == 'DICE_SELECT_POULES':
 | 
			
		||||
            already_launched_tds = {td.id: td async for td in r.team_draws.filter(passage_dice__isnull=False)
 | 
			
		||||
                                    .prefetch_related('participation__team')}
 | 
			
		||||
                                                        {'type': 'draw.dice_visibility', 'visible': False})
 | 
			
		||||
                    await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
 | 
			
		||||
                                                        {'type': 'draw.continue_visibility', 'visible': True})
 | 
			
		||||
            else:
 | 
			
		||||
                # Go to the dice order
 | 
			
		||||
                async for r0 in self.tournament.draw.round_set.all():
 | 
			
		||||
                    async for td in r0.teamdraw_set.all():
 | 
			
		||||
                        td.pool = None
 | 
			
		||||
                        td.passage_index = None
 | 
			
		||||
                        td.choose_index = None
 | 
			
		||||
                        td.choice_dice = None
 | 
			
		||||
                        await td.asave()
 | 
			
		||||
 | 
			
		||||
                r.current_pool = None
 | 
			
		||||
                await r.asave()
 | 
			
		||||
 | 
			
		||||
                round_tds = {td.id: td async for td in r.team_draws.prefetch_related('participation__team')}
 | 
			
		||||
 | 
			
		||||
            if already_launched_tds:
 | 
			
		||||
                # Reset the last dice
 | 
			
		||||
                changelogs = Changelog.objects.filter(
 | 
			
		||||
                    model=content_type,
 | 
			
		||||
                    action='edit',
 | 
			
		||||
                    instance_pk__in=set(already_launched_tds.keys())
 | 
			
		||||
                    instance_pk__in=set(round_tds.keys())
 | 
			
		||||
                ).order_by('-timestamp')
 | 
			
		||||
 | 
			
		||||
                # Find the last dice that was launched
 | 
			
		||||
                async for changelog in changelogs:
 | 
			
		||||
                    data = json.loads(changelog.data)
 | 
			
		||||
                    if 'passage_dice' in data and data['passage_dice']:
 | 
			
		||||
                        last_td = already_launched_tds[int(changelog.instance_pk)]
 | 
			
		||||
                        last_td = round_tds[int(changelog.instance_pk)]
 | 
			
		||||
                        # Reset the dice
 | 
			
		||||
                        last_td.passage_dice = None
 | 
			
		||||
                        await last_td.asave()
 | 
			
		||||
@@ -1270,13 +1283,52 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
 | 
			
		||||
                                                                 'team': last_td.participation.team.trigram,
 | 
			
		||||
                                                                 'result': None})
 | 
			
		||||
                        break
 | 
			
		||||
            else:
 | 
			
		||||
                await self.abort()
 | 
			
		||||
 | 
			
		||||
        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                            {'type': 'draw.set_info', 'draw': self.tournament.draw})
 | 
			
		||||
        await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                            {'type': 'draw.set_active', 'draw': self.tournament.draw})
 | 
			
		||||
                async for td in r.team_draws.prefetch_related('participation__team').all():
 | 
			
		||||
                    await self.channel_layer.group_send(
 | 
			
		||||
                        f"tournament-{self.tournament.id}", {'type': 'draw.dice',
 | 
			
		||||
                                                             'team': td.participation.team.trigram,
 | 
			
		||||
                                                             'result': td.passage_dice})
 | 
			
		||||
 | 
			
		||||
                await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
 | 
			
		||||
                                                    {'type': 'draw.dice_visibility', 'visible': True})
 | 
			
		||||
 | 
			
		||||
    async def undo_order_dice(self):
 | 
			
		||||
        """
 | 
			
		||||
        Undo the last dice for the passage order, or abort the draw if we are at the beginning.
 | 
			
		||||
        """
 | 
			
		||||
        content_type = await ContentType.objects.aget(app_label=TeamDraw._meta.app_label,
 | 
			
		||||
                                                      model=TeamDraw._meta.model_name)
 | 
			
		||||
 | 
			
		||||
        r = self.tournament.draw.current_round
 | 
			
		||||
        already_launched_tds = {td.id: td async for td in r.team_draws.filter(passage_dice__isnull=False)
 | 
			
		||||
                                .prefetch_related('participation__team')}
 | 
			
		||||
 | 
			
		||||
        if already_launched_tds:
 | 
			
		||||
            # Reset the last dice
 | 
			
		||||
            changelogs = Changelog.objects.filter(
 | 
			
		||||
                model=content_type,
 | 
			
		||||
                action='edit',
 | 
			
		||||
                instance_pk__in=set(already_launched_tds.keys())
 | 
			
		||||
            ).order_by('-timestamp')
 | 
			
		||||
 | 
			
		||||
            # Find the last dice that was launched
 | 
			
		||||
            async for changelog in changelogs:
 | 
			
		||||
                data = json.loads(changelog.data)
 | 
			
		||||
                if 'passage_dice' in data and data['passage_dice']:
 | 
			
		||||
                    last_td = already_launched_tds[int(changelog.instance_pk)]
 | 
			
		||||
                    # Reset the dice
 | 
			
		||||
                    last_td.passage_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
 | 
			
		||||
        else:
 | 
			
		||||
            await self.abort()
 | 
			
		||||
 | 
			
		||||
    async def draw_alert(self, content):
 | 
			
		||||
        """
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user