Beispiel #1
0
    def _get_sporter_or_404(request, sporter_pk):
        """ Geeft het Sporter record terug van de sporter zelf,
            of in geval van de HWL de gekozen sporter """

        rol_nu, functie_nu = rol_get_huidige_functie(request)
        if rol_nu == Rollen.ROL_HWL:
            try:
                # conversie naar integer geef input-controle
                sporter_pk = int(sporter_pk)
            except (ValueError, TypeError):
                # sporter_pk was geen getal
                raise Http404('Sporter niet gevonden')

            try:
                sporter = Sporter.objects.get(pk=sporter_pk)
            except Sporter.DoesNotExist:
                raise Http404('Sporter niet gevonden')

            # laatste control: de sporter moet lid zijn bij de vereniging van de HWL
            if sporter.bij_vereniging != functie_nu.nhb_ver:
                raise PermissionDenied('Geen sporter van jouw vereniging')

            return sporter

        account = request.user
        sporter = account.sporter_set.all()[
            0]  # ROL_SPORTER geeft bescherming tegen geen sporter

        return sporter
Beispiel #2
0
    def post(self, request, *args, **kwargs):
        """ Deze functie wordt aangeroepen als de knop 'ik geef akkoord voor deze uitslag'
            gebruikt wordt door de RCL.
        """

        rol_nu, functie_nu = rol_get_huidige_functie(self.request)

        wedstrijd_pk = kwargs['wedstrijd_pk'][:
                                              6]  # afkappen voor de veiligheid
        wedstrijd, deelcomp, _ = bepaal_wedstrijd_en_deelcomp_of_404(
            wedstrijd_pk)

        if not mag_deelcomp_wedstrijd_wijzigen(wedstrijd, functie_nu,
                                               deelcomp):
            raise PermissionDenied()

        uitslag = wedstrijd.uitslag
        if not uitslag.is_bevroren:
            uitslag.is_bevroren = True
            uitslag.save()

        url = reverse('CompScores:uitslag-controleren',
                      kwargs={'wedstrijd_pk': wedstrijd.pk})

        return HttpResponseRedirect(url)
Beispiel #3
0
def get_sporter_rayon_nr(request):
    """ Geeft het rayon nummer van de ingelogde sporter terug,
        of 1 als er geen rayon vastgesteld kan worden
    """
    rayon_nr = 1

    rol_nu, functie_nu = rol_get_huidige_functie(request)

    if functie_nu:
        if functie_nu.nhb_ver:
            # HWL, WL
            rayon_nr = functie_nu.nhb_ver.regio.rayon.rayon_nr
        elif functie_nu.nhb_regio:
            # RCL
            rayon_nr = functie_nu.nhb_regio.rayon.rayon_nr
        elif functie_nu.nhb_rayon:
            # RKO
            rayon_nr = functie_nu.nhb_rayon.rayon_nr
    elif rol_nu == Rollen.ROL_SPORTER:
        # sporter
        account = request.user
        if account.sporter_set.count() > 0:
            sporter = account.sporter_set.all()[0]
            if sporter.is_actief_lid and sporter.bij_vereniging:
                nhb_ver = sporter.bij_vereniging
                rayon_nr = nhb_ver.regio.rayon.rayon_nr

    return rayon_nr
Beispiel #4
0
def get_sporter_ver_nr(request):
    """ Geeft het vereniging nhb nummer van de ingelogde schutter terug,
        of 101 als er geen regio vastgesteld kan worden
    """
    ver_nr = -1

    if request.user.is_authenticated:
        rol_nu, functie_nu = rol_get_huidige_functie(request)

        if functie_nu and functie_nu.nhb_ver:
            # HWL, WL, SEC
            ver_nr = functie_nu.nhb_ver.ver_nr

        if ver_nr < 0:
            # pak de vereniging van de ingelogde gebruiker
            account = request.user
            if account.sporter_set.count() > 0:
                sporter = account.sporter_set.all()[0]
                if sporter.is_actief_lid and sporter.bij_vereniging:
                    ver_nr = sporter.bij_vereniging.ver_nr

    ver_nrs = list(
        NhbVereniging.objects.order_by('ver_nr').values_list('ver_nr',
                                                             flat=True))
    if ver_nr not in ver_nrs:
        ver_nr = ver_nrs[0]

    return ver_nr
Beispiel #5
0
    def get_context_data(self, **kwargs):
        """ called by the template system to get the context data for the template """
        context = super().get_context_data(**kwargs)

        try:
            deelcomp_pk = int(
                kwargs['deelcomp_pk'][:6])  # afkappen voor de veiligheid
            deelcomp = DeelCompetitie.objects.get(pk=deelcomp_pk,
                                                  laag=LAAG_REGIO)
        except (ValueError, DeelCompetitie.DoesNotExist):
            raise Http404('Competitie niet gevonden')

        rol_nu, functie_nu = rol_get_huidige_functie(self.request)
        if deelcomp.functie != functie_nu:
            # niet de beheerder
            raise PermissionDenied()

        if not deelcomp.regio_organiseert_teamcompetitie:
            raise Http404('Geen teamcompetitie in deze regio')

        context['deelcomp'] = deelcomp

        if 1 <= deelcomp.huidige_team_ronde <= 7:
            context['alle_regels'], context['aantal_keuzes_nodig'], context[
                'anchor'] = self._bepaal_teams_en_scores(deelcomp)
            context['url_opslaan'] = reverse(
                'CompScores:selecteer-team-scores',
                kwargs={'deelcomp_pk': deelcomp.pk})

        menu_dynamics_competitie(self.request,
                                 context,
                                 comp_pk=deelcomp.competitie.pk)
        return context
Beispiel #6
0
def get_sporter_regio_nr(request):
    """ Geeft het regio nummer van de ingelogde sporter terug,
        of 101 als er geen regio vastgesteld kan worden
    """
    regio_nr = 101

    rol_nu, functie_nu = rol_get_huidige_functie(request)

    if functie_nu:
        if functie_nu.nhb_ver:
            # HWL, WL
            regio_nr = functie_nu.nhb_ver.regio.regio_nr
        elif functie_nu.nhb_regio:
            # RCL
            regio_nr = functie_nu.nhb_regio.regio_nr
        elif functie_nu.nhb_rayon:
            # RKO
            regio = (NhbRegio.objects.filter(
                rayon=functie_nu.nhb_rayon,
                is_administratief=False).order_by('regio_nr'))[0]
            regio_nr = regio.regio_nr
    elif rol_nu == Rollen.ROL_SPORTER:
        # sporter
        account = request.user
        if account.sporter_set.count() > 0:
            sporter = account.sporter_set.select_related(
                'bij_vereniging__regio').all()[0]
            if sporter.is_actief_lid and sporter.bij_vereniging:
                nhb_ver = sporter.bij_vereniging
                regio_nr = nhb_ver.regio.regio_nr

    return regio_nr
Beispiel #7
0
    def test_func(self):
        """ called by the UserPassesTestMixin to verify the user has permissions to use this view """
        self.rol_nu, self.functie_nu = rol_get_huidige_functie(self.request)

        if self.rol_nu == Rollen.ROL_BB:
            self.is_staff = self.request.user.is_staff

        return self.rol_nu in (Rollen.ROL_BB, Rollen.ROL_BKO, Rollen.ROL_RKO,
                               Rollen.ROL_RCL, Rollen.ROL_HWL, Rollen.ROL_SEC)
Beispiel #8
0
    def test_func(self):
        """ called by the UserPassesTestMixin to verify the user has permissions to use this view """

        # evalueer opnieuw welke rechten de gebruiker heeft
        rol_evalueer_opnieuw(self.request)

        self.rol_nu, self.functie_nu = rol_get_huidige_functie(self.request)

        return self.request.user.is_authenticated and rol_mag_wisselen(
            self.request)
Beispiel #9
0
    def get(self, request, *args, **kwargs):
        """ called by the template system to get the context data for the template """

        self.rol_nu, self.functie_nu = rol_get_huidige_functie(request)

        context = dict()

        try:
            comp_pk = int(kwargs['comp_pk'][:6])      # afkappen voor de veiligheid
            comp = (Competitie
                    .objects
                    .get(pk=comp_pk))
        except (ValueError, Competitie.DoesNotExist):
            raise Http404('Competitie niet gevonden')

        comp.bepaal_fase()                     # zet comp.fase
        comp.bepaal_openbaar(self.rol_nu)      # zet comp.is_openbaar

        comp.einde_fase_F = comp.laatst_mogelijke_wedstrijd + datetime.timedelta(days=7)
        comp.einde_fase_G = comp.einde_fase_F + datetime.timedelta(days=1)
        comp.einde_fase_K = comp.rk_eerste_wedstrijd - datetime.timedelta(days=14)
        comp.einde_fase_M = comp.rk_laatste_wedstrijd + datetime.timedelta(days=7)

        if 'B' <= comp.fase <= 'E':
            comp.url_inschrijvingen = reverse('CompInschrijven:lijst-regiocomp-alles',
                                              kwargs={'comp_pk': comp.pk})

        context['comp'] = comp

        self._get_uitslagen(context, comp, request)

        # afhankelijk van de huidige functie vs de competitie leveren we 2 pagina's:
        #   - beheerder
        #   - bezoeker
        template = None

        if self.rol_nu in (Rollen.ROL_BKO, Rollen.ROL_RKO, Rollen.ROL_RCL):
            if self.functie_nu and self.functie_nu.comp_type == comp.afstand:
                # BKO/RKO/RCL van deze specifieke competitie
                template = self._get_competitie_overzicht_beheerder(request, context, comp)
                eval_open_taken(request)

        elif self.rol_nu == Rollen.ROL_BB:
            template = self._get_competitie_overzicht_beheerder(request, context, comp)
            eval_open_taken(request)

        elif self.rol_nu == Rollen.ROL_HWL:
            template = self._get_competitie_overzicht_hwl(request, context, comp)
            eval_open_taken(request)

        if not template:
            template = self._get_competitie_overzicht_schutter_bezoeker(context, comp)

        menu_dynamics_competitie(self.request, context, comp_pk=comp.pk)
        return render(request, template, context)
    def _check_access(self, locatie, ver):
        if ver not in locatie.verenigingen.all():
            raise Http404('Locatie hoort niet bij de vereniging')

        _, functie_nu = rol_get_huidige_functie(self.request)

        # controleer dat de gebruiker HWL is van deze vereniging
        readonly = True
        if functie_nu and functie_nu.rol == 'HWL' and functie_nu.nhb_ver == ver:
            readonly = False

        return readonly
Beispiel #11
0
    def post(self, request, *args, **kwargs):
        """ Deze functie wordt aangeroepen als de RCL op de 'opslaan' knop drukt
            in het wijzig-clusters formulier.
        """

        rol_nu, functie_nu = rol_get_huidige_functie(self.request)

        # filter clusters die aangepast mogen worden op competitie type
        # waarvan de definitie heel handig overeen komt met cluster.gebruik
        gebruik_filter = functie_nu.comp_type

        clusters = (NhbCluster.objects.filter(regio=functie_nu.nhb_regio,
                                              gebruik=gebruik_filter))

        # neem de cluster namen over
        for obj in clusters:
            self._pk2cluster[obj.pk] = obj

            # haal de ingevoerde naam van het cluster op
            cluster_veld = "naam_%s" % obj.pk
            naam = request.POST.get(cluster_veld, obj.naam)
            if naam != obj.naam:
                # wijziging opslaan
                obj.naam = naam[:
                                50]  # te lang kan anders niet opgeslagen worden
                obj.save(update_fields=['naam'])
        # for

        # neem de cluster keuzes voor de verenigingen over
        for obj in (NhbVereniging.objects.filter(
                regio=functie_nu.nhb_regio).prefetch_related('clusters')):

            self._swap_cluster(obj, gebruik_filter)
        # for

        # probeer een competitie te vinden om te tonen in het menu
        try:
            deelcomp = DeelCompetitie.objects.get(
                competitie__afstand=gebruik_filter,
                nhb_regio=functie_nu.nhb_regio)
        except DeelCompetitie.DoesNotExist:
            url = reverse('Competitie:kies')
        else:
            comp_pk = deelcomp.competitie.pk
            url = reverse('Competitie:overzicht', kwargs={'comp_pk': comp_pk})

        return HttpResponseRedirect(url)
Beispiel #12
0
def site_handler500_internal_server_error(request, exception=None):
    """ Django view om code-500 fouten af te handelen.
        500 is "server internal error"

        Deze function wordt aangeroepen bij runtime errors met de view code.
    """
    # print('site_handler500: exception=%s; info=%s' % (repr(exception), str(exception)))
    global in_500_handler

    # voorkom fout op fout
    if not in_500_handler:  # pragma: no branch
        in_500_handler = True

        _, functie_nu = rol_get_huidige_functie(request)

        tb_msg_start = 'Internal server error:\n\n%s %s\n' % (request.method,
                                                              request.path)
        if functie_nu:
            tb_msg_start += 'Huidige functie: [%s] %s\n' % (functie_nu.pk,
                                                            str(functie_nu))
        tb_msg_start += '\n'

        # vang de fout en schrijf deze in de syslog
        tups = sys.exc_info()
        tb = traceback.format_exception(*tups)

        # full traceback in the local log
        tb_msg = tb_msg_start + '\n'.join(tb)
        my_logger.error(tb_msg)

        # stuur een mail naar de ontwikkelaars
        # reduceer tot de nuttige regels
        tb = [line for line in tb if '/site-packages/' not in line]
        tb_msg = tb_msg_start + '\n'.join(tb)

        # deze functie stuurt maximaal 1 mail per dag over hetzelfde probleem
        mailer_notify_internal_error(tb_msg)

        in_500_handler = False

    context = dict()
    context['email_support'] = settings.EMAIL_SUPPORT

    return render(request, TEMPLATE_HANDLER_500, context)
Beispiel #13
0
    def post(self, request, *args, **kwargs):
        """ Deze functie wordt aangeroepen als de knop 'Opslaan' gebruikt wordt
        """

        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            # garbage in
            raise Http404('Geen valide verzoek')

        # print('data:', repr(data))

        wedstrijd = self.laad_wedstrijd_of_404(data)
        uitslag = wedstrijd.uitslag
        if not uitslag:
            raise Http404('Geen wedstrijduitslag')

        # controleer toestemming om scores op te slaan voor deze wedstrijd

        plannen = wedstrijd.competitiewedstrijdenplan_set.all()
        if plannen.count() < 1:
            # wedstrijd met andere bedoeling
            raise Http404('Geen wedstrijdenplan')

        ronde = DeelcompetitieRonde.objects.get(plan=plannen[0])

        rol_nu, functie_nu = rol_get_huidige_functie(request)
        if not mag_deelcomp_wedstrijd_wijzigen(wedstrijd, functie_nu,
                                               ronde.deelcompetitie):
            raise PermissionDenied('Geen toegang')

        # voorkom wijzigingen bevroren wedstrijduitslag
        if rol_nu in (Rollen.ROL_HWL, Rollen.ROL_WL) and uitslag.is_bevroren:
            raise Http404('Uitslag mag niet meer gewijzigd worden')

        door_account = request.user
        when = timezone.now()

        self.scores_opslaan(uitslag, data, when, door_account)

        out = {'done': 1}
        return JsonResponse(out)
Beispiel #14
0
    def get_context_data(self, **kwargs):
        """ called by the template system to get the context data for the template """
        context = super().get_context_data(**kwargs)

        try:
            deelnemer_pk = int(
                self.kwargs['deelnemer_pk'][:6])  # afkappen voor de veiligheid
            deelnemer = (RegioCompetitieSchutterBoog.objects.select_related(
                'deelcompetitie', 'deelcompetitie__competitie').get(
                    pk=deelnemer_pk,
                    deelcompetitie__inschrijf_methode=INSCHRIJF_METHODE_1))
        except (ValueError, TypeError,
                RegioCompetitieSchutterBoog.DoesNotExist):
            raise Http404('Inschrijving niet gevonden')

        context['deelnemer'] = deelnemer

        rol_nu, functie_nu = rol_get_huidige_functie(self.request)

        if rol_nu == Rollen.ROL_SPORTER:
            if self.request.user != deelnemer.sporterboog.sporter.account:
                raise PermissionDenied()
        else:
            # HWL: sporter moet lid zijn van zijn vereniging
            if deelnemer.bij_vereniging != functie_nu.nhb_ver:
                raise PermissionDenied('Sporter is niet van jouw vereniging')

            context['is_hwl'] = True

        # zoek alle dagdelen erbij
        pks = list()
        for ronde in (DeelcompetitieRonde.objects.select_related(
                'deelcompetitie',
                'plan').prefetch_related('plan__wedstrijden').filter(
                    deelcompetitie=deelnemer.deelcompetitie)):
            pks.extend(ronde.plan.wedstrijden.values_list('pk', flat=True))
        # for

        wedstrijden = (
            CompetitieWedstrijd.objects.filter(pk__in=pks).exclude(
                vereniging__isnull=True
            )  # voorkom wedstrijd niet toegekend aan vereniging
            .select_related('vereniging').order_by('datum_wanneer',
                                                   'tijd_begin_wedstrijd'))

        keuze = list(
            deelnemer.inschrijf_gekozen_wedstrijden.values_list('pk',
                                                                flat=True))

        # splits de wedstrijden op naar in-cluster en out-of-cluster
        ver = deelnemer.sporterboog.sporter.bij_vereniging
        ver_in_hwl_cluster = dict()  # [ver_nr] = True/False
        for cluster in (
                ver.clusters.prefetch_related('nhbvereniging_set').filter(
                    gebruik=deelnemer.deelcompetitie.competitie.afstand).all()
        ):
            ver_nrs = list(
                cluster.nhbvereniging_set.values_list('ver_nr', flat=True))
            for ver_nr in ver_nrs:
                ver_in_hwl_cluster[ver_nr] = True
            # for
        # for

        wedstrijden1 = list()
        wedstrijden2 = list()
        for wedstrijd in wedstrijden:
            wedstrijd.is_gekozen = (wedstrijd.pk in keuze)

            if wedstrijd.is_gekozen:
                wedstrijden1.append(wedstrijd)
            else:
                try:
                    in_cluster = ver_in_hwl_cluster[
                        wedstrijd.vereniging.ver_nr]
                except KeyError:
                    in_cluster = False

                if in_cluster:
                    wedstrijden1.append(wedstrijd)
                else:
                    wedstrijden2.append(wedstrijd)
        # for

        if len(wedstrijden1):
            context['wedstrijden_1'] = wedstrijden1
            context['wedstrijden_2'] = wedstrijden2
        else:
            context['wedstrijden_1'] = wedstrijden2

        context['url_opslaan'] = reverse('CompRegio:keuze-zeven-wedstrijden',
                                         kwargs={'deelnemer_pk': deelnemer.pk})

        if rol_nu == Rollen.ROL_SPORTER:
            context['url_terug'] = reverse('Sporter:profiel')
        else:
            context['url_terug'] = reverse(
                'CompRegio:wie-schiet-waar',
                kwargs={'deelcomp_pk': deelnemer.deelcompetitie.pk})

        menu_dynamics(self.request, context, actief='sporter-profiel')
        return context
Beispiel #15
0
 def test_func(self):
     """ called by the UserPassesTestMixin to verify the user has permissions to use this view """
     self.rol_nu, self.functie_nu = rol_get_huidige_functie(self.request)
     return self.rol_nu in (Rollen.ROL_BB, Rollen.ROL_BKO)
Beispiel #16
0
    def get_queryset(self):
        """ called by the template system to get the queryset or list of objects for the template """

        try:
            comp_pk = int(self.kwargs['comp_pk'][:10])      # afkappen voor de veiligheid
            comp = Competitie.objects.get(pk=comp_pk)
        except (ValueError, TypeError, Competitie.DoesNotExist):
            raise Http404('Competitie niet gevonden')

        self.comp = comp
        comp.bepaal_fase()

        # check dat competitie open is voor inschrijvingen
        if not ('B' <= comp.fase <= 'E'):
            raise Http404('Verkeerde competitie fase')

        _, functie_nu = rol_get_huidige_functie(self.request)
        objs = list()

        # bepaal de inschrijfmethode voor deze regio
        if functie_nu.nhb_ver.regio.is_administratief:
            # niemand van deze vereniging mag zich inschrijven
            return objs

        prev_lkl = None
        prev_wedstrijdleeftijd = 0
        jeugdgrens = comp.begin_jaar - MAXIMALE_LEEFTIJD_JEUGD

        # sorteer jeugd op geboorte jaar en daarna naam
        for obj in (Sporter
                    .objects
                    .filter(bij_vereniging=functie_nu.nhb_ver)
                    .filter(geboorte_datum__year__gte=jeugdgrens)
                    .order_by('-geboorte_datum__year', 'achternaam', 'voornaam')):

            # de wedstrijdleeftijd voor dit hele seizoen
            wedstrijdleeftijd = obj.bereken_wedstrijdleeftijd(comp.begin_jaar + 1)
            obj.leeftijd = wedstrijdleeftijd

            # de wedstrijdklasse voor dit hele seizoen
            if wedstrijdleeftijd == prev_wedstrijdleeftijd:
                obj.leeftijdsklasse = prev_lkl
            else:
                for lkl in (LeeftijdsKlasse                         # pragma: no branch
                            .objects
                            .filter(geslacht='M',
                                    min_wedstrijdleeftijd=0)        # exclude veteraan, master
                            .order_by('volgorde')):                 # aspiranten eerst

                    if lkl.leeftijd_is_compatible(wedstrijdleeftijd):
                        obj.leeftijdsklasse = lkl
                        # stop bij eerste passende klasse
                        break
                # for

                prev_lkl = obj.leeftijdsklasse
                prev_wedstrijdleeftijd = wedstrijdleeftijd

            objs.append(obj)
        # for

        # sorteer volwassenen op naam
        for obj in (Sporter
                    .objects
                    .filter(bij_vereniging=functie_nu.nhb_ver)
                    .filter(geboorte_datum__year__lt=jeugdgrens)
                    .order_by('achternaam', 'voornaam')):
            obj.leeftijdsklasse = None
            objs.append(obj)
        # for

        # maak een paar tabellen om database toegangen te verminderen
        sporter_dict = dict()    # [lid_nr] = Sporter
        for sporter in objs:
            sporter.wedstrijdbogen = list()
            sporter_dict[sporter.lid_nr] = sporter
        # for

        ag_dict = dict()        # [sporterboog_pk] = Score
        for score in (Score
                      .objects
                      .select_related('sporterboog')
                      .filter(type=SCORE_TYPE_INDIV_AG,
                              afstand_meter=comp.afstand)):
            ag = Decimal(score.waarde) / 1000
            ag_dict[score.sporterboog.pk] = ag
        # for

        wil_competitie = dict()     # [lid_nr] = True/False
        for voorkeuren in (SporterVoorkeuren
                           .objects
                           .select_related('sporter')
                           .filter(sporter__bij_vereniging=functie_nu.nhb_ver)):
            wil_competitie[voorkeuren.sporter.lid_nr] = voorkeuren.voorkeur_meedoen_competitie
        # for

        is_aangemeld_dict = dict()   # [sporterboog.pk] = True/False
        for deelnemer in (RegioCompetitieSchutterBoog
                          .objects
                          .select_related('sporterboog',
                                          'deelcompetitie')
                          .filter(bij_vereniging=functie_nu.nhb_ver,
                                  deelcompetitie__competitie=comp)):
            is_aangemeld_dict[deelnemer.sporterboog.pk] = True
        # for

        for nr, obj in enumerate(objs):
            obj.volgorde = nr
        # for

        # zoek de bogen informatie bij elk lid
        # split per schutter-boog
        objs2 = list()
        for sporterboog in (SporterBoog
                            .objects
                            .filter(voor_wedstrijd=True)
                            .select_related('sporter',
                                            'boogtype')
                            .order_by('boogtype__volgorde',                # groepeer op boogtype
                                      '-sporter__geboorte_datum__year',    # jongste eerst
                                      'sporter__achternaam',               # binnen de leeftijd op achternaam
                                      'sporter__voornaam')
                            .only('sporter__lid_nr',
                                  'boogtype__afkorting',
                                  'boogtype__beschrijving')):
            try:
                sporter = sporter_dict[sporterboog.sporter.lid_nr]
            except KeyError:
                # sporterboog niet van deze vereniging
                pass
            else:
                # maak een kopie van het nhblid en maak het uniek voor dit boogtype
                obj = copy.copy(sporter)
                obj.afkorting = sporterboog.boogtype.afkorting
                obj.boogtype = sporterboog.boogtype.beschrijving
                obj.check = "lid_%s_boogtype_%s" % (sporter.lid_nr, sporterboog.boogtype.pk)
                obj.mag_teamschieten = True
                if obj.leeftijdsklasse and obj.leeftijdsklasse.is_aspirant_klasse():
                    obj.mag_teamschieten = False

                try:
                    obj.ag = ag_dict[sporterboog.pk]
                except KeyError:
                    obj.ag = AG_NUL

                # kijk of de schutter al aangemeld is
                try:
                    obj.is_aangemeld = is_aangemeld_dict[sporterboog.pk]
                except KeyError:
                    obj.is_aangemeld = False

                # kijk of de schutter wel mee wil doen met de competitie
                try:
                    obj.wil_competitie = wil_competitie[sporterboog.sporter.lid_nr]
                except KeyError:
                    # schutter had geen voorkeuren
                    # dit is een opt-out, dus standaard True
                    obj.wil_competitie = True

                tup = (sporter.volgorde, sporterboog.boogtype.volgorde, obj)
                objs2.append(tup)
        # for

        # sorteer objs2 zodat deze in dezelfde volgorde staat als objs:
        # - jeugd gesorteerd op leeftijd en daarna gesorteerd op naam
        # - senioren gesorteerd op naam
        objs2.sort()

        objs3 = [obj for v1, v2, obj in objs2]

        return objs3
Beispiel #17
0
 def test_func(self):
     """ called by the UserPassesTestMixin to verify the user has permissions to use this view """
     self.rol_nu, self.functie_nu = rol_get_huidige_functie(self.request)
     return self.functie_nu and self.functie_nu.rol in ('HWL', 'WL')
Beispiel #18
0
    def get_context_data(self, **kwargs):
        """ called by the template system to get the context data for the template """
        context = super().get_context_data(**kwargs)

        binnen_locatie, buiten_locatie, externe_locaties, nhbver = self._get_locaties_nhbver_or_404(**kwargs)
        if buiten_locatie and not buiten_locatie.zichtbaar:
            buiten_locatie = None
        context['locatie'] = binnen_locatie
        context['buiten_locatie'] = buiten_locatie
        context['externe_locaties'] = externe_locaties
        context['nhbver'] = nhbver

        for locatie in externe_locaties:
            locatie.geen_naam = locatie.naam.strip() == ""
            locatie.geen_plaats = locatie.plaats.strip() == ""
            locatie.geen_disciplines = locatie.disciplines_str() == ""
        # for

        # zoek de beheerders erbij
        qset = Functie.objects.filter(nhb_ver=nhbver).prefetch_related('accounts')
        try:
            functie_sec = qset.filter(rol='SEC')[0]
            functie_hwl = qset.filter(rol='HWL')[0]
            functie_wl = qset.filter(rol='WL')[0]
        except IndexError:                  # pragma: no cover
            # only in autotest environment
            raise Http404('Rol ontbreekt')

        context['sec_names'] = self.get_all_names(functie_sec)
        context['sec_email'] = functie_sec.bevestigde_email

        if len(context['sec_names']) == 0:
            context['geen_sec'] = True
            try:
                sec = Secretaris.objects.select_related('sporter').get(vereniging=functie_sec.nhb_ver)
            except Secretaris.DoesNotExist:
                pass
            else:
                if sec.sporter:
                    context['sec_names'] = [sec.sporter.volledige_naam()]
                    context['geen_sec'] = False

        context['hwl_names'] = self.get_all_names(functie_hwl)
        context['hwl_email'] = functie_hwl.bevestigde_email

        context['wl_names'] = self.get_all_names(functie_wl)
        context['wl_email'] = functie_wl.bevestigde_email

        if binnen_locatie:
            # beschrijving voor de template
            binnen_locatie.baan_type_str = BAANTYPE2STR[binnen_locatie.baan_type]

            # aantal banen waar uit gekozen kan worden, voor gebruik in de template
            context['banen'] = [nr for nr in range(2, 24+1)]          # 1 baan = handmatig in .dtl

            # lijst van verenigingen voor de template
            binnen_locatie.other_ver = binnen_locatie.verenigingen.exclude(ver_nr=nhbver.ver_nr).order_by('ver_nr')

        if buiten_locatie:
            # aantal banen waar uit gekozen kan worden, voor gebruik in de template
            context['buiten_banen'] = [nr for nr in range(2, 80+1)]   # 1 baan = handmatig in .dtl
            context['buiten_max_afstand'] = [nr for nr in range(30, 100+1, 10)]

            context['disc'] = disc = list()
            disc.append(('disc_outdoor', 'Outdoor', buiten_locatie.discipline_outdoor))
            # disc.append(('disc_indoor', 'Indoor', buiten_locatie.discipline_indoor))
            disc.append(('disc_25m1p', '25m 1pijl', buiten_locatie.discipline_25m1pijl))
            disc.append(('disc_veld', 'Veld', buiten_locatie.discipline_veld))
            disc.append(('disc_3d', '3D', buiten_locatie.discipline_3d))
            disc.append(('disc_run', 'Run archery', buiten_locatie.discipline_run))
            disc.append(('disc_clout', 'Clout', buiten_locatie.discipline_clout))

        # terug en opslaan knoppen voor in de template
        if 'is_ver' in kwargs:      # wordt gezet door VerenigingAccommodatieDetailsView
            context['terug_url'] = reverse('Vereniging:overzicht')
            opslaan_urlconf = 'Vereniging:vereniging-accommodatie-details'
            menu_actief = 'vereniging'
        else:
            context['terug_url'] = reverse('Vereniging:lijst-verenigingen')
            opslaan_urlconf = 'Vereniging:accommodatie-details'
            menu_actief = 'hetplein'

        if binnen_locatie or buiten_locatie:
            context['opslaan_url'] = reverse(opslaan_urlconf,
                                             kwargs={'vereniging_pk': nhbver.pk})

        rol_nu, functie_nu = rol_get_huidige_functie(self.request)

        if self._mag_wijzigen(nhbver, rol_nu, functie_nu):
            context['readonly'] = False

            # geef ook meteen de mogelijkheid om leden te koppelen aan rollen
            if rol_nu == Rollen.ROL_SEC:
                context['url_koppel_sec'] = reverse('Functie:wijzig-beheerders',
                                                    kwargs={'functie_pk': functie_sec.pk})
            context['url_koppel_hwl'] = reverse('Functie:wijzig-beheerders',
                                                kwargs={'functie_pk': functie_hwl.pk})
            context['url_koppel_wl'] = reverse('Functie:wijzig-beheerders',
                                               kwargs={'functie_pk': functie_wl.pk})

            # geef ook meteen de mogelijkheid om de e-mailadressen van een functie aan te passen
            context['url_email_hwl'] = reverse('Functie:wijzig-email',
                                               kwargs={'functie_pk': functie_hwl.pk})
            context['url_email_wl'] = reverse('Functie:wijzig-email',
                                              kwargs={'functie_pk': functie_wl.pk})

            if buiten_locatie:
                context['url_verwijder_buitenbaan'] = context['opslaan_url']
        else:
            context['readonly'] = True

            if binnen_locatie:      # pragma: no branch
                if binnen_locatie.banen_18m + binnen_locatie.banen_25m > 0:
                    context['readonly_show_max_dt'] = True

        menu_dynamics(self.request, context, actief=menu_actief)
        return context
Beispiel #19
0
    def post(self, request, *args, **kwargs):
        """ Deze functie wordt aangeroepen als de gebruik op de 'opslaan' knop drukt
            op het accommodatie-details formulier.
        """
        binnen_locatie, buiten_locatie, _, nhbver = self._get_locaties_nhbver_or_404(**kwargs)

        rol_nu, functie_nu = rol_get_huidige_functie(self.request)

        if not self._mag_wijzigen(nhbver, rol_nu, functie_nu):
            raise PermissionDenied('Wijzigen niet toegestaan')

        if request.POST.get('verwijder_buitenbaan', None):
            if buiten_locatie:
                buiten_locatie.zichtbaar = False
                buiten_locatie.save()
            if 'is_ver' in kwargs:  # wordt gezet door VerenigingAccommodatieDetailsView
                urlconf = 'Vereniging:vereniging-accommodatie-details'
            else:
                urlconf = 'Vereniging:accommodatie-details'
            url = reverse(urlconf, kwargs={'vereniging_pk': nhbver.pk})
            return HttpResponseRedirect(url)

        if request.POST.get('maak_buiten_locatie', None):
            if buiten_locatie:
                if not buiten_locatie.zichtbaar:
                    buiten_locatie.zichtbaar = True
                    buiten_locatie.save()
            elif binnen_locatie:
                buiten = WedstrijdLocatie(
                                baan_type='B',
                                adres_uit_crm=False,
                                adres=binnen_locatie.adres,
                                plaats=binnen_locatie.plaats,
                                notities='')
                buiten.save()
                buiten.verenigingen.add(nhbver)

            if 'is_ver' in kwargs:  # wordt gezet door VerenigingAccommodatieDetailsView
                urlconf = 'Vereniging:vereniging-accommodatie-details'
            else:
                urlconf = 'Vereniging:accommodatie-details'
            url = reverse(urlconf, kwargs={'vereniging_pk': nhbver.pk})
            return HttpResponseRedirect(url)

        form = AccommodatieDetailsForm(request.POST)
        if not form.is_valid():
            raise Http404('Geen valide invoer')

        if binnen_locatie:
            msgs = list()
            data = form.cleaned_data.get('baan_type')
            if binnen_locatie.baan_type != data:
                old_str = BAANTYPE2STR[binnen_locatie.baan_type]
                new_str = BAANTYPE2STR[data]
                msgs.append("baan type aangepast van '%s' naar '%s'" % (old_str, new_str))
                binnen_locatie.baan_type = data

            data = form.cleaned_data.get('banen_18m')
            if binnen_locatie.banen_18m != data:
                msgs.append("Aantal 18m banen aangepast van %s naar %s" % (binnen_locatie.banen_18m, data))
                binnen_locatie.banen_18m = data

            data = form.cleaned_data.get('banen_25m')
            if binnen_locatie.banen_25m != data:
                msgs.append("Aantal 25m banen aangepast van %s naar %s" % (binnen_locatie.banen_25m, data))
                binnen_locatie.banen_25m = data

            # data = form.cleaned_data.get('max_dt')
            # if binnen_locatie.max_dt_per_baan != data:
            #     msgs.append("Max DT per baan aangepast van %s naar %s" % (binnen_locatie.max_dt_per_baan, data))
            #     binnen_locatie.max_dt_per_baan = data

            data_18 = form.cleaned_data.get('max_sporters_18m')
            data_25 = form.cleaned_data.get('max_sporters_25m')
            if data_18 is not None and data_25 is not None:
                if binnen_locatie.max_sporters_18m != data_18 or binnen_locatie.max_sporters_25m != data_25:
                    msgs.append("Max sporters 18m/25m aangepast van %s/%s naar %s/%s" % (binnen_locatie.max_sporters_18m, binnen_locatie.max_sporters_25m, data_18, data_25))
                    binnen_locatie.max_sporters_18m = data_18
                    binnen_locatie.max_sporters_25m = data_25

            if len(msgs) > 0:
                activiteit = "Aanpassingen aan binnen locatie van vereniging %s: %s" % (nhbver, "; ".join(msgs))
                schrijf_in_logboek(request.user, 'Accommodaties', activiteit)
                binnen_locatie.save()

            disc_old = binnen_locatie.disciplines_str()
            binnen_locatie.discipline_indoor = (str(binnen_locatie.banen_18m) != "0" or
                                                str(binnen_locatie.banen_25m) != "0")
            binnen_locatie.discipline_25m1pijl = False
            binnen_locatie.discipline_outdoor = False
            binnen_locatie.discipline_clout = False
            binnen_locatie.discipline_veld = False
            binnen_locatie.discipline_run = False
            binnen_locatie.discipline_3d = False
            disc_new = binnen_locatie.disciplines_str()
            if disc_old != disc_new:
                activiteit = "Aanpassing disciplines van binnen locatie van vereniging %s: [%s] (was [%s])" % (
                                nhbver, disc_new, disc_old)
                schrijf_in_logboek(request.user, 'Accommodaties', activiteit)
                binnen_locatie.save()

            data = form.cleaned_data.get('notities')
            data = data.replace('\r\n', '\n')
            if binnen_locatie.notities != data:
                activiteit = "Aanpassing bijzonderheden van binnen locatie van vereniging %s: %s (was %s)" % (
                                nhbver,
                                repr(data.replace('\n', ' / ')),
                                repr(binnen_locatie.notities.replace('\n', ' / ')))
                schrijf_in_logboek(request.user, 'Accommodaties', activiteit)
                binnen_locatie.notities = data
                binnen_locatie.save()

        if buiten_locatie:
            msgs = list()
            updated = list()

            data = form.cleaned_data.get('buiten_banen')
            if buiten_locatie.buiten_banen != data:
                msgs.append("Aantal buiten banen aangepast van %s naar %s" % (buiten_locatie.buiten_banen, data))
                buiten_locatie.buiten_banen = data
                updated.append('buiten_banen')

            data = form.cleaned_data.get('buiten_max_afstand')
            if buiten_locatie.buiten_max_afstand != data:
                msgs.append("Maximale afstand aangepast van %s naar %s" % (buiten_locatie.buiten_max_afstand, data))
                buiten_locatie.buiten_max_afstand = data
                updated.append('buiten_max_afstand')

            if len(msgs) > 0:
                activiteit = "Aanpassingen aan buiten locatie van vereniging %s: %s" % (nhbver, "; ".join(msgs))
                schrijf_in_logboek(request.user, 'Accommodaties', activiteit)

            buiten_locatie.save(update_fields=updated)

            data = form.cleaned_data.get('buiten_notities')
            data = data.replace('\r\n', '\n')
            if buiten_locatie.notities != data:
                activiteit = "Aanpassing notitie van buiten locatie van vereniging %s: %s (was %s)" % (
                                    nhbver,
                                    repr(data.replace('\n', ' / ')),
                                    repr(buiten_locatie.notities.replace('\n', ' / ')))
                schrijf_in_logboek(request.user, 'Accommodaties', activiteit)
                buiten_locatie.notities = data
                buiten_locatie.save(update_fields=['notities'])

            disc_old = buiten_locatie.disciplines_str()
            buiten_locatie.discipline_25m1pijl = form.cleaned_data.get('disc_25m1p')
            buiten_locatie.discipline_outdoor = form.cleaned_data.get('disc_outdoor')
            buiten_locatie.discipline_indoor = False
            buiten_locatie.discipline_clout = form.cleaned_data.get('disc_clout')
            buiten_locatie.discipline_veld = form.cleaned_data.get('disc_veld')
            buiten_locatie.discipline_run = form.cleaned_data.get('disc_run')
            buiten_locatie.discipline_3d = form.cleaned_data.get('disc_3d')
            disc_new = buiten_locatie.disciplines_str()
            if disc_old != disc_new:
                activiteit = "Aanpassing disciplines van buiten locatie van vereniging %s: [%s] (was [%s])" % (
                                nhbver, disc_new, disc_old)
                schrijf_in_logboek(request.user, 'Accommodaties', activiteit)
                buiten_locatie.save()

        if 'is_ver' in kwargs:
            url = reverse('Vereniging:overzicht')
        else:
            url = reverse('Vereniging:lijst-verenigingen')

        return HttpResponseRedirect(url)
Beispiel #20
0
    def get_context_data(self, **kwargs):
        """ called by the template system to get the context data for the template """
        context = super().get_context_data(**kwargs)

        rol_nu, functie_nu = rol_get_huidige_functie(self.request)
        context['huidige_rol'] = rol_get_beschrijving(self.request)

        context['terug_url'] = reverse('Competitie:kies')

        # filter clusters die aangepast mogen worden op competitie type
        # waarvan de definitie heel handig overeen komt met cluster.gebruik
        context['gebruik'] = gebruik_filter = functie_nu.comp_type

        # probeer een competitie te vinden om te tonen in het menu
        try:
            deelcomp = DeelCompetitie.objects.get(
                competitie__afstand=gebruik_filter,
                nhb_regio=functie_nu.nhb_regio)
        except DeelCompetitie.DoesNotExist:
            comp_pk = None
        else:
            comp_pk = deelcomp.competitie.pk
            context['terug_url'] = reverse('Competitie:overzicht',
                                           kwargs={'comp_pk': comp_pk})

        # cluster namen
        objs = (NhbCluster.objects.filter(
            regio=functie_nu.nhb_regio,
            gebruik=gebruik_filter).select_related('regio').order_by('letter'))
        context['cluster_list'] = objs
        context['regio_heeft_clusters'] = objs.count() > 0
        context['opslaan_url'] = reverse('CompRegio:clusters')

        for obj in objs:
            obj.veld_naam = "naam_%s" % obj.pk
        # for

        # maak lijstje voor het formulier met de keuze opties van de pull-down lijstjes
        opts = objs[:]
        for opt in opts:
            opt.tekst = opt.cluster_code_str()
            opt.choice_name = str(opt.pk)  # gebruik de cluster pk als selector
        # for

        # voeg de "geen cluster" opties toe
        opt_geen = NhbCluster()
        opt_geen.tekst = "Geen"
        opt_geen.choice_name = "0"
        opts.insert(0, opt_geen)

        # vereniging in de regio
        objs = (NhbVereniging.objects.filter(regio=functie_nu.nhb_regio).
                prefetch_related('clusters').order_by('ver_nr'))
        context['object_list'] = objs

        for obj in objs:
            # voeg form-fields toe die voor de post gebruikt kunnen worden
            obj.veld_naam = 'ver_' + str(obj.ver_nr)

            # maak een kopie om een vlag te kunnen zetten op de huidige optie
            obj.cluster_opties = copy.deepcopy(opts)

            # zet de 'selected' vlag op de huidige cluster keuzes voor de vereniging
            for cluster in obj.clusters.all():
                # zoek dit cluster op
                for opt in obj.cluster_opties:
                    if opt.pk == cluster.pk:
                        opt.actief = True
                # for
            # for
        # for

        context['handleiding_clusters_url'] = reverse('Handleiding:Clusters')
        context['email_bondsbureau'] = settings.EMAIL_BONDSBUREAU

        if comp_pk:
            menu_dynamics_competitie(self.request, context, comp_pk=comp_pk)
        else:
            menu_dynamics(self.request, context, actief='competitie')

        return context
Beispiel #21
0
    def post(self, request, *args, **kwargs):

        try:
            deelcomp_pk = int(
                kwargs['deelcomp_pk'][:6])  # afkappen voor de veiligheid
            deelcomp = DeelCompetitie.objects.get(pk=deelcomp_pk,
                                                  laag=LAAG_REGIO)
        except (ValueError, DeelCompetitie.DoesNotExist):
            raise Http404('Competitie niet gevonden')

        rol_nu, functie_nu = rol_get_huidige_functie(self.request)
        if deelcomp.functie != functie_nu:
            # niet de beheerder
            raise PermissionDenied()

        if not deelcomp.regio_organiseert_teamcompetitie:
            raise Http404('Geen teamcompetitie in deze regio')

        alle_regels, _, _ = self._bepaal_teams_en_scores(deelcomp)

        # for k, v in request.POST.items():
        #     print('%s=%s' % (k, repr(v)))

        # verzamel de gewenste keuzes
        ronde_teams = dict(
        )  # [ronde_team.pk] = (ronde_team, sporterboog_pk2score_pk)

        for regel in alle_regels:
            # regel = team
            try:
                team_scores = ronde_teams[regel.ronde_team.pk]
            except KeyError:
                team_scores = list()
                ronde_teams[regel.ronde_team.pk] = (regel.ronde_team,
                                                    team_scores)

            for deelnemer in regel.deelnemers:
                if deelnemer.kan_kiezen:
                    score_pk_str = request.POST.get(
                        deelnemer.id_radio,
                        '')[:10]  # afkappen voor de veiligheid
                    if score_pk_str:
                        # er is een keuze gemaakt
                        try:
                            score_pk = int(score_pk_str)
                        except (ValueError, TypeError):
                            raise Http404('Verkeerde parameter')

                        for wedstrijd, score in deelnemer.gevonden_scores:
                            if score.pk == score_pk:
                                # het is echt een score van deze deelnemer
                                team_scores.append(score.pk)
                                break
                        # for
                else:
                    for wedstrijd, score in deelnemer.gevonden_scores:
                        if wedstrijd and not score.block_selection:
                            team_scores.append(score.pk)
            # for
        # for

        for ronde_team, score_pks in ronde_teams.values():
            ronde_team.scores_feitelijk.set(score_pks)
        # for

        # trigger de achtergrondtaak om de team scores opnieuw te berekenen
        update_uitslag_teamcompetitie()

        url = reverse('CompScores:scores-rcl',
                      kwargs={'deelcomp_pk': deelcomp.pk})
        return HttpResponseRedirect(url)
Beispiel #22
0
    def get_context_data(self, **kwargs):
        """ called by the template system to get the context data for the template """
        context = super().get_context_data(**kwargs)

        try:
            deelcomp_pk = int(
                kwargs['deelcomp_pk'][:6])  # afkappen voor de veiligheid
            deelcomp = DeelCompetitie.objects.get(pk=deelcomp_pk,
                                                  laag=LAAG_REGIO)
        except (ValueError, DeelCompetitie.DoesNotExist):
            raise Http404('Competitie niet gevonden')

        rol_nu, functie_nu = rol_get_huidige_functie(self.request)
        if deelcomp.functie != functie_nu:
            # niet de beheerder
            raise PermissionDenied()

        context['deelcomp'] = deelcomp

        # TODO: check competitie fase

        if deelcomp.regio_organiseert_teamcompetitie:
            context['url_team_scores'] = reverse(
                'CompScores:selecteer-team-scores',
                kwargs={'deelcomp_pk': deelcomp.pk})

        # deelcompetitie bestaat uit rondes
        # elke ronde heeft een plan met wedstrijden

        wedstrijd_pks = list()
        wedstrijd2beschrijving = dict()
        comp_str = deelcomp.competitie.beschrijving

        for ronde in (DeelcompetitieRonde.objects.select_related(
                'plan').prefetch_related('plan__wedstrijden').filter(
                    deelcompetitie=deelcomp)):

            for wedstrijd in ronde.plan.wedstrijden.all():
                wedstrijd_pks.append(wedstrijd.pk)
                beschrijving = ronde.beschrijving
                if not beschrijving and ronde.cluster:
                    beschrijving = ronde.cluster.naam
                if not beschrijving:
                    beschrijving = "?? (ronde)"
                wedstrijd2beschrijving[
                    wedstrijd.pk] = "%s - %s" % (comp_str, beschrijving)
            # for
        # for

        wedstrijden = (CompetitieWedstrijd.objects.select_related(
            'uitslag', 'vereniging').filter(pk__in=wedstrijd_pks).annotate(
                scores_count=Count('uitslag__scores')).order_by(
                    'datum_wanneer', 'tijd_begin_wedstrijd',
                    'pk'))  # vaste sortering bij gelijke datum/tijd

        for wedstrijd in wedstrijden:
            heeft_uitslag = (wedstrijd.uitslag and wedstrijd.scores_count > 0)

            beschrijving = wedstrijd2beschrijving[wedstrijd.pk]
            if wedstrijd.beschrijving != beschrijving:
                wedstrijd.beschrijving = beschrijving
                wedstrijd.save()

            # geef RCL de mogelijkheid om te scores aan te passen
            # de HWL/WL krijgen deze link vanuit Vereniging::Wedstrijden
            if heeft_uitslag:
                wedstrijd.url_uitslag_controleren = reverse(
                    'CompScores:uitslag-controleren',
                    kwargs={'wedstrijd_pk': wedstrijd.pk})
            else:
                # TODO: knop pas beschikbaar maken op wedstrijddatum tot datum+N
                wedstrijd.url_uitslag_invoeren = reverse(
                    'CompScores:uitslag-invoeren',
                    kwargs={'wedstrijd_pk': wedstrijd.pk})
        # for

        context['wedstrijden'] = wedstrijden

        menu_dynamics_competitie(self.request,
                                 context,
                                 comp_pk=deelcomp.competitie.pk)
        return context
Beispiel #23
0
    def post(request, *args, **kwargs):
        """ Deze functie wordt aangeroepen als de sporter de knop 'Opslaan' gebruikt
            op de pagina waar zijn 7 wedstrijden te kiezen zijn,
        """

        try:
            deelnemer_pk = int(
                kwargs['deelnemer_pk'][:6])  # afkappen voor de veiligheid
            deelnemer = (RegioCompetitieSchutterBoog.objects.select_related(
                'deelcompetitie', 'deelcompetitie__competitie').get(
                    pk=deelnemer_pk,
                    deelcompetitie__inschrijf_methode=INSCHRIJF_METHODE_1))
        except (ValueError, TypeError,
                RegioCompetitieSchutterBoog.DoesNotExist):
            raise Http404('Inschrijving niet gevonden')

        rol_nu, functie_nu = rol_get_huidige_functie(request)

        # controleer dat ingelogde gebruiker deze wijziging mag maken
        if rol_nu == Rollen.ROL_SPORTER:
            if request.user != deelnemer.sporterboog.sporter.account:
                raise PermissionDenied()
        else:
            # HWL: sporter moet lid zijn van zijn vereniging
            if deelnemer.bij_vereniging != functie_nu.nhb_ver:
                raise PermissionDenied('Sporter is niet van jouw vereniging')

        # zoek alle wedstrijden erbij
        pks = list()
        for ronde in (DeelcompetitieRonde.objects.select_related(
                'deelcompetitie',
                'plan').prefetch_related('plan__wedstrijden').filter(
                    deelcompetitie=deelnemer.deelcompetitie)):
            pks.extend(ronde.plan.wedstrijden.values_list('pk', flat=True))
        # for

        # zoek alle wedstrijden erbij
        wedstrijden = (CompetitieWedstrijd.objects.filter(
            pk__in=pks).select_related('vereniging').order_by(
                'datum_wanneer', 'tijd_begin_wedstrijd'))

        keuze = list(
            deelnemer.inschrijf_gekozen_wedstrijden.values_list('pk',
                                                                flat=True))
        keuze_add = list()
        aanwezig = len(keuze)

        for wedstrijd in wedstrijden:
            param = 'wedstrijd_%s' % wedstrijd.pk
            if request.POST.get(param, '') != '':
                # deze wedstrijd is gekozen
                if wedstrijd.pk in keuze:
                    # al gekozen, dus behouden
                    keuze.remove(wedstrijd.pk)
                else:
                    # toevoegen
                    keuze_add.append(wedstrijd.pk)
        # for

        # alle overgebleven wedstrijden zijn ongewenst
        aanwezig -= len(keuze)
        deelnemer.inschrijf_gekozen_wedstrijden.remove(*keuze)

        # controleer dat er maximaal 7 momenten gekozen worden
        if aanwezig + len(keuze_add) > 7:
            # begrens het aantal toe te voegen wedstrijden
            keuze_add = keuze_add[:7 - aanwezig]

        deelnemer.inschrijf_gekozen_wedstrijden.add(*keuze_add)

        if rol_nu == Rollen.ROL_SPORTER:
            url = reverse('Sporter:profiel')
        else:
            url = reverse('CompRegio:wie-schiet-waar',
                          kwargs={'deelcomp_pk': deelnemer.deelcompetitie.pk})

        return HttpResponseRedirect(url)