Example #1
0
def url_picker_context(site):
    """Return template context needed for the URL picker utility"""
    articles = Article.objects.filter(
        # Article has not reached its unpublish date
        Q(unpub_date__gt=date.today()) |
        Q(unpub_date__isnull=True),

        published=True,
        pub_date__lt=datetime.now(),
        site=site,
    ).prefetch_related(
        'versions',
        # Note that content prefetching is necessary because we will later
        # extract the title content
        'versions__rows',
        'versions__rows__columns',
        'versions__rows__columns__contents',
    ).order_by(
        '-pub_date',
    )

    return {'url_picker': {
        'pages': Page.objects.filter(site=site).order_by('title'),
        'articles': articles,
        'foreninger': Forening.get_all_sorted(),
        'site': site,
    }}
Example #2
0
def index(request):
    context = {
        'admin_user_search_char_length': settings.ADMIN_USER_SEARCH_CHAR_LENGTH,
        'turleder_roles': Turleder.TURLEDER_CHOICES,
        'instruktor_roles': Instruktor.ROLE_CHOICES,
        'all_foreninger': Forening.get_all_sorted(),
    }
    return render(request, 'central/admin/turledere/index.html', context)
Example #3
0
def show(request, user_id):
    try:
        other_user = User.objects.filter(
            id=user_id,
        ).prefetch_related(
            'turleder_active_foreninger',
        ).get()
    except User.DoesNotExist:
        messages.warning(request, 'no_such_user')
        return redirect('admin:users.index')

    # Admins can assign user/admin, users can assign users
    assignable_admin = [a for a in request.user.all_foreninger() if a.role == 'admin']
    assignable_user = [a for a in request.user.all_foreninger() if a.role == 'user']
    # Don't let users assign new permissions for those that already have user status
    # Use ForeningRole for other_user, because we can't set permissions for foreninger that are
    # based on parent foreninger (to remove access to a child, you have to remove admin-permission
    # to the parent)
    other_user_foreninger = Forening.objects.filter(users=other_user)
    assignable_user = [a for a in assignable_user if a not in other_user_foreninger]
    assignable_foreninger = assignable_admin + assignable_user

    # Only admins can revoke forening relation
    revokable_foreninger = [a for a in assignable_admin if a in other_user_foreninger]

    today = date.today()

    # We can't just add 365*5 timedelta days because that doesn't account for leap years,
    # this does.
    try:
        five_years_from_now = date(year=(today.year + 5), month=today.month, day=today.day)
    except ValueError:
        # This will only occur when today is February 29th during a leap year (right?)
        five_years_from_now = date(year=(today.year + 5), month=today.month, day=(today.day - 1))

    context = {
        'other_user': other_user,
        'revokable_foreninger': Forening.sort(revokable_foreninger),
        'assignable_foreninger': Forening.sort(assignable_foreninger),
        'all_foreninger': Forening.get_all_sorted(),
        'turleder_roles': Turleder.TURLEDER_CHOICES,
        'five_years_from_now': five_years_from_now,
    }
    return render(request, 'central/admin/users/show/index.html', context)
Example #4
0
 def process_request(self, request):
     if 'active_forening' in request.session:
         try:
             request.active_forening = Forening.get_cached_forening(
                 id=request.session['active_forening'],
             )
         except Forening.DoesNotExist:
             # It might have been removed, remove it and let the user choose
             # a new one
             del request.session['active_forening']
Example #5
0
def index(request):
    query = request.GET.copy()

    # Default organizers: If visiting a local site, default to the owner of the current site (except for DNT central)
    if not request.GET.get("organizers", "") and request.site.forening.id != Forening.DNT_CENTRAL_ID:
        query["organizers"] = "%s:%s" % ("forening", request.site.forening.id)

    # Default minimum duration is always 1
    query["min_duration"] = query.get("min_duration", "1")

    filter, aktivitet_dates = filter_aktivitet_dates(query)
    aktivitet_dates_pagenav = paginate_aktivitet_dates(filter, aktivitet_dates)

    # Usually, the 'sentral' type is sorted first, but in this case we want it last
    all_foreninger = Forening.get_all_sorted()
    sentral = all_foreninger[0]
    if not sentral["code"] == "sentral":
        # We made an incorrect assumption, log it but try to continue rendering instead of raising an error
        logger.error(
            "Assumed first group of forening to be type 'sentral', was really '%s'" % sentral["code"],
            extra={"request": request, "all_foreninger": all_foreninger},
        )
    # Remove and append the sentral group to the end
    all_foreninger.remove(sentral)
    all_foreninger.append(sentral)

    # Look up DNT cabins with serving
    cabins = sorted(
        Sted.list(
            params={
                "tags": "Hytte",
                "betjeningsgrad": "Betjent",
                "privat": {"hytteeier": "DNT"},
                "status": "Offentlig",
                "tilbyder": "DNT",
            }
        ),
        key=lambda s: s["navn"],
    )

    context = {
        "aktivitet_dates": aktivitet_dates_pagenav,
        "difficulties": Aktivitet.DIFFICULTY_CHOICES,
        "categories": Aktivitet.CATEGORY_CHOICES,
        "category_types": Aktivitet.CATEGORY_TYPES_LIST,
        "audiences": Aktivitet.AUDIENCE_CHOICES,
        "omrader": sorted(Område.list(params={"status": "Offentlig", "tilbyder": "DNT"}), key=lambda o: o["navn"]),
        "cabins": cabins,
        "all_foreninger": all_foreninger,
        "filter": filter,
    }
    return render(request, "common/aktiviteter/index.html", context)
Example #6
0
def url_picker_context(active_site):
    article_versions = Version.objects.select_related('variant', 'variant__article').filter(
        variant__article__isnull=False,
        variant__segment__isnull=True,
        variant__article__published=True,
        active=True,
        variant__article__pub_date__lt=datetime.now(),
        variant__article__site=active_site,
    ).order_by('-variant__article__pub_date')

    return {'url_picker': {
        'pages': Page.on(active_site).order_by('title'),
        'article_versions': article_versions,
        'foreninger': Forening.get_all_sorted(),
    }}
    def admin_context(self, site):
        # Look up DNT cabins with serving
        cabins = sorted(Sted.list(params={
            'tags': 'Hytte',
            'betjeningsgrad': 'Betjent',
            'grupper': '',
            'privat': {'hytteeier': 'DNT'},
            'status': 'Offentlig',
            'tilbyder': 'DNT',
        }), key=lambda s: s['navn'])

        return {
            'all_foreninger_sorted': Forening.get_all_sorted(),
            'audiences': Aktivitet.AUDIENCE_CHOICES,
            'categories': Aktivitet.CATEGORY_CHOICES,
            'category_types': [{
                'category': [c[1] for c in Aktivitet.CATEGORY_CHOICES if c[0] == category['category']][0],
                'types': category['types']
            } for category in Aktivitet.CATEGORY_TYPES_LIST],
            'cabins': cabins,
        }
Example #8
0
def create(request, forening_id):
    current_forening = Forening.objects.get(id=forening_id)

    if current_forening not in request.user.all_foreninger():
        raise PermissionDenied

    # The parent choices are tricky to define in the forms API, so do it here.
    # Note that we're intentionally letting users choose parents among only those they have permission to.
    all_sorted = request.user.all_foreninger_sorted()
    parents_choices = {
        'forening': all_sorted['forening'],
        'turlag': all_sorted['turlag'],
    }

    # If the parent of the current forening isn't in the user's permissions, we still need to include that one as an
    # available parent so that they're able to make changes.
    if current_forening.type != 'sentral':
        for current_parent in current_forening.get_main_foreninger():
            if current_parent not in parents_choices['forening'] and current_parent not in parents_choices['turlag']:
                parents_choices[current_parent.type].append(current_parent)

    form = CreateForeningForm(request.user, initial={
        'zipcode': '',
    })

    context = {
        'current_forening': current_forening,
        'parents_choices': parents_choices,
        'admin_user_search_char_length': settings.ADMIN_USER_SEARCH_CHAR_LENGTH,
        'form': form,
    }

    # Give URLPicker the homepage site for the current forening. If they don't have one, just use the central site
    relevant_site = current_forening.get_homepage_site() or Site.get_central()
    context.update(url_picker_context(relevant_site))

    if request.method == 'GET':
        return render(request, 'central/admin/foreninger/create.html', context)

    elif request.method == 'POST':

        form = CreateForeningForm(request.user, request.POST)
        if form.is_valid():
            forening = Forening()
            forening.name = form.cleaned_data['name']
            forening.type = form.cleaned_data['type']
            if forening.type == 'turgruppe':
                forening.group_type = form.cleaned_data['group_type']
            else:
                forening.group_type = ''

            forening.save()

            # Set M2M-fields after the initial db-save
            forening.parents = form.cleaned_data['parents']

            # Ensure the Turbasen object is re-saved with applicable M2M-relations
            forening.save_turbasen_object()

            # Add the current user as admin on the new forening
            role = ForeningRole(
                user=request.user,
                forening=forening,
                role='admin',
            )
            role.save()
            # FIXME: We can't delete the permission cache for all users, so some may find that they can't edit
            # the new forening even though they should be able, until the cache (which is currently 24h) expires.
            cache.delete('user.%s.all_foreninger' % request.user.id)

            messages.info(request, 'forening_create_success')
            request.session['active_forening'] = forening.id
            cache.delete('foreninger.all.sorted_by_name')
            cache.delete('foreninger.all.sorted_by_type')
            cache.delete('foreninger.rendered_select')
            cache.delete('forening.%s' % forening.id)
            cache.delete('forening.main_foreninger.%s' % forening.id)
            return redirect('admin:foreninger.edit', forening.id)
        else:
            context.update({'form': form})
            return render(request, 'central/admin/foreninger/create.html', context)

    else:
        return redirect('admin:foreninger.create', current_forening.id)
Example #9
0
def renew_membership(request):
    if request.method != 'POST':
        return redirect('user:account')

    if 'stripeToken' not in request.POST:
        return redirect('user:account')

    description = "Fornying av medlemskap"

    if date.today() < membership_year_start()['public_date']:
        applicable_year = membership_year_start()['public_date'].year
    else:
        applicable_year = membership_year_start()['public_date'].year + 1

    metadata = {
        'Periode': 'Medlemsåret %s' % applicable_year,
    }

    if not request.user.has_family():
        # Single member, pay their own invoice
        amount = request.user.payment.status['amount_due']
        metadata['Medlemskap'] = request.user.membership_type()['name']
        metadata['Medlem'] = '%s (medlemsnr: %s)' % (request.user.get_full_name(), request.user.memberid)
        request.user.clear_cache()
    elif request.user.family.relation == 'family':
        # Family membership, pay the invoice of the parent
        amount = request.user.payment.status['amount_due']
        metadata['Medlemskap'] = 'Familiemedlemskap'
        metadata['Familie hovedmedlem'] = '%s (medlemsnr: %s)' % (
            request.user.family.parent.get_full_name(),
            request.user.family.parent.memberid,
        )
        metadata['Alle familiemedlemmer'] = ', '.join([
            '%s (medlemsnr: %s)' % (u.get_full_name(), u.memberid)
            for u in request.user.family.all_members()
        ])
        request.user.family.clear_cache()
    elif request.user.family.relation == 'household':
        # Household membership, each member has their own invoice.
        amount = request.user.family.payment_amount_due()
        metadata['Medlemskap'] = 'Husstandsmedlemskap'
        metadata['Medlemmer'] = ', '.join([
            '%s (medlemsnr: %s, %s, %s)' % (
                u.get_full_name(),
                u.memberid,
                u.membership_type()['name'],
                currency(u.payment.status['amount_due']),
            )
            for u in request.user.family.payment_members()
        ])
        request.user.family.clear_cache()

    charge = Charge.new_charge(
        Forening.get_cached_forening(id=Forening.DNT_CENTRAL_ID).payment_auth()['stripe_user_id'],
        request.user,
        request.POST['stripeToken'],
        amount,
        description,
        metadata,
    )

    try:
        if not charge.was_success():
            # Unsuccessful payment. Store the error message and display it on the account page
            request.session['membership.%s.payment_failure' % request.user.memberid] = {
                'error_display': charge.get_error_code_display(),
                'error_message': charge.error_message,
            }
        else:
            # Payment was succesful; save it to Focus
            if not request.user.has_family() or request.user.family.relation == 'family':
                request.user.payment.save_pending_payment(charge.charge_id, amount)
            else:
                for household_member in request.user.family.payment_members():
                    household_member.payment.save_pending_payment(
                        charge.charge_id,
                        household_member.payment.status['amount_due'],
                    )
    except:
        # Problem during pending payment registration - likely connection issue with Focus.
        # - Since the payment isn't stored in Focus, the user will not get the confirmation, so add an error message
        #   explaining the situation.
        # - Manual followup is required by memberservice, so send email to memberservice with required information
        # - Log an error to be able to trace events, in case it's ever needed
        messages.error(request, 'payment_registration_failure')
        logger.error(
            "Feil ved lagring av medlemskapsfornyelse i Focus",
            exc_info=sys.exc_info(),
            extra={
                'request': request,
                'amount': amount,
                'metadata': metadata,
                'charge': charge,
            },
        )
        try:
            context = {
                'amount': amount,
                'metadata': metadata,
                'charge': charge,
            }
            message = render_to_string('common/focus/payment_registration_failure.txt', context, request=request)
            send_mail(
                "Fornying av medlemskap kunne ikke lagres i Focus",
                message,
                settings.DEFAULT_FROM_EMAIL,
                [settings.MEMBERSERVICE_EMAIL],
            )
        except (SMTPException, SSLError, UnicodeEncodeError):
            # Jesus. Error upon error. Log it, hopefully devs will be able to follow up.
            logger.error(
                "Kunne ikke sende varselsepost til medlemsservice, beskjed må gis manuelt",
                extra={
                    'request': request,
                    'message': message,
                    'amount': amount,
                    'metadata': metadata,
                    'charge': charge,
                },
            )
    finally:
        return redirect('%s#forny-medlemskap' % reverse('user:account'))
Example #10
0
def edit(request, aktivitet):
    if request.method == 'GET':
        aktivitet = Aktivitet.objects.prefetch_related('municipalities', 'counties').get(id=aktivitet)
        context = {
            'aktivitet': aktivitet,
            'difficulties': Aktivitet.DIFFICULTY_CHOICES,
            'audiences': AktivitetAudience.AUDIENCE_CHOICES,
            'categories': Aktivitet.CATEGORY_CHOICES,
            'all_foreninger': Forening.get_all_sorted(),
            'cabins': Cabin.objects.order_by('name'),
            'admin_user_search_char_length': settings.ADMIN_USER_SEARCH_CHAR_LENGTH,
            'counties': County.typical_objects().order_by('name'),
            'municipalities': Municipality.objects.order_by('name'),
            'omrader': sorted(Omrade.lookup(), key=lambda o: o.navn),
            'now': datetime.now()
        }
        return render(request, 'common/admin/aktiviteter/edit/edit.html', context)
    elif request.method == 'POST':
        errors = False

        aktivitet = Aktivitet.objects.get(id=aktivitet)

        if aktivitet.is_imported():
            # Should only be possible by circumventing client-side restrictions
            return redirect('admin.aktiviteter.views.edit', aktivitet.id)

        if 'code' in request.POST:
            aktivitet.code = request.POST['code']

        if 'title' in request.POST:
            aktivitet.title = request.POST['title']

        if 'description' in request.POST:
            aktivitet.description = request.POST['description']

        if 'difficulty' in request.POST:
            aktivitet.difficulty = request.POST['difficulty']

        if 'audiences' in request.POST:
            aktivitet.audiences = [
                AktivitetAudience.objects.get(name=audience)
                for audience in request.POST.getlist('audiences')
            ]

        if 'category' in request.POST:
            aktivitet.category = request.POST['category']

        if 'category_type' in request.POST:
            aktivitet.category_type = request.POST['category_type']

        if 'publish' in request.POST:
            aktivitet.published = request.POST.get('publish') == 'publish'

        if 'getting_there' in request.POST:
            aktivitet.getting_there = request.POST['getting_there']

        if 'omrader' in request.POST:
            aktivitet.omrader = request.POST.getlist('omrader')

        if 'ntb_id' not in request.POST or request.POST['ntb_id'] == '':
            aktivitet.turforslag = None
        else:
            aktivitet.turforslag = request.POST['ntb_id']

        if aktivitet.published:
            # If published, set the extra relevant fields (otherwise ignore them)
            aktivitet.private = request.POST['private'] == 'private'
            try:
                aktivitet.pub_date = datetime.strptime(request.POST['pub_date'], "%d.%m.%Y").date()
            except ValueError:
                errors = True
                messages.error(request, 'invalid_date_format')

        forening_type, forening_id = request.POST['forening'].split(':')
        if forening_type == 'forening':
            forening = Forening.objects.get(id=forening_id)
            if not forening in request.user.children_foreninger():
                raise PermissionDenied
            aktivitet.forening = forening
        elif forening_type == 'cabin':
            aktivitet.forening_cabin = Cabin.objects.get(id=forening_id)
        else:
            raise PermissionDenied

        if 'co_foreninger[]' in request.POST and request.POST['co_foreninger[]'] != '':
            co_foreninger = []
            co_foreninger_cabin = []
            for co_forening in request.POST.getlist('co_foreninger[]'):
                type, id = co_forening.split(':')
                if type == 'forening':
                    co_foreninger.append(id)
                elif type == 'cabin':
                    co_foreninger_cabin.append(id)
                else:
                    raise PermissionDenied

            aktivitet.co_foreninger = co_foreninger
            aktivitet.co_foreninger_cabin = co_foreninger_cabin
        else:
            aktivitet.co_foreninger = []
            aktivitet.co_foreninger_cabin = []

        if 'latlng' in request.POST:
            latlng = request.POST['latlng'].split(',')
            if len(latlng) == 2:
                aktivitet.start_point = Point(float(latlng[0]), float(latlng[1]))

        aktivitet.save()

        aktivitet.counties = request.POST.getlist('counties')
        aktivitet.municipalities = request.POST.getlist('municipalities')

        aktivitet.category_tags.clear()
        if 'category_tags' in request.POST and request.POST['category_tags'] != '':
            for tag in request.POST.getlist('category_tags'):
                obj, created = Tag.objects.get_or_create(name=tag)
                aktivitet.category_tags.add(obj)

        aktivitet.images.all().delete()
        for i, image in parse_html_array(request.POST, 'images').items():
            AktivitetImage(
                aktivitet=aktivitet,
                url=image['url'],
                text=image['description'],
                photographer=image['photographer'],
                order=i
            ).save()

        dates = parse_html_array(request.POST, 'dates').items()

        # Remove the date objects that were explicitly deleted (checks and verifications are done
        # client-side). Verify that those that would be implicitly deleted (by not being POSTed for
        # editing) match those explicitly POSTed.
        date_ids = [int(d['id']) for k, d in dates if d['id'] != '']
        implicit_del = set([date.id for date in aktivitet.dates.all() if date.id not in date_ids])

        if len(implicit_del) > 0:
            # Better to raise an exception and not delete anything. The user will be confused and
            # lose edits, but we'll get a report and hopefully be able to fix this, if it ever
            # happens.
            raise Exception("Implicit delete of AktivitetDate is strictly forbidden!")

        for i, date in dates:
            if date['id'] != '':
                # @TODO Check if this can be exploited. Can you hijack another trip's date by
                # setting an arbitrary ID in the date['id'] field?
                model = AktivitetDate.objects.get(id=date['id'])
            else:
                model = AktivitetDate(aktivitet=aktivitet)

            # @TODO for existing dates; if model.start_date > now; dissalow editing.

            # Explicit delete of dates
            if date['status'] == 'delete':
                if date['id'] != '':
                    if model.participant_count() > 0:
                        raise Exception("Date with participants can not be deleted!")
                    model.delete()
                continue

            try:
                if not date['start_time']: date['start_time'] = '08:00'
                if not date['end_time']: date['end_time'] = '16:00'

                # @TODO check start_time > now
                model.start_date = datetime.strptime(
                    "%s %s" % (date['start_date'], date['start_time']),
                    "%d.%m.%Y %H:%M"
                )

                # @TODO check end_time > start_time
                model.end_date = datetime.strptime(
                    "%s %s" % (date['end_date'], date['end_time']),
                    "%d.%m.%Y %H:%M"
                )

                # @TODO check start_date > meeting_time
                if date['start_date'] and date['meeting_time']:
                    model.meeting_time = datetime.strptime(
                        "%s %s" % (date['start_date'], date['meeting_time']),
                        "%d.%m.%Y %H:%M"
                    )

                if not date['signup_method'] or date['signup_method'] == 'none':
                    # To the next maintainer. This block indicates that a date does not allow
                    # signup. However, keep in mind that this might be an existing date with
                    # participants. Hence, do not set model.participant to None event though it
                    # might be tempting!

                    model.signup_enabled = False
                    model.signup_start = None
                    model.signup_deadline = None
                    model.cancel_deadline = None

                elif date['signup_method'] == 'normal' or date['signup_method'] == 'simple':
                    model.signup_enabled = True

                    if date.get('max_participants_limited'):
                        model.max_participants = date['max_participants']
                    else:
                        model.max_participants = None

                    if date.get('no_signup_start') == '1':
                        model.signup_start = None
                    else:
                        model.signup_start = datetime.strptime(
                            date['signup_start'],
                            "%d.%m.%Y",
                        ).date()

                    if 'no_signup_deadline' in date and date['no_signup_deadline'] == '1':
                        model.signup_deadline = None
                    elif 'signup_deadline' in date and date['signup_deadline'] != '':
                        model.signup_deadline = datetime.strptime(
                            date['signup_deadline'],
                            "%d.%m.%Y",
                        ).date()

                    if 'no_cancel_deadline' in date and date['no_cancel_deadline'] == '1':
                        model.cancel_deadline = None
                    elif 'cancel_deadline' in date and date['cancel_deadline'] != '':
                        model.cancel_deadline = datetime.strptime(
                            date['cancel_deadline'], "%d.%m.%Y"
                        ).date()

                else:
                    raise Exception("Unrecognized POST value for signup_method field")

            except ValueError:
                errors = True
                messages.error(request, 'invalid_date_format')
                return redirect('admin.aktiviteter.views.edit', aktivitet.id)

            # Note that simple signup is currently disabled and due to be removed
            model.signup_simple_allowed = False
            model.meeting_place = date['meeting_place']
            model.contact_type = date['contact_type']
            model.contact_custom_name = date['contact_custom_name']
            model.contact_custom_phone = date['contact_custom_phone']
            model.contact_custom_email = date['contact_custom_email']
            model.should_have_turleder = date.get('should_have_turleder') == '1'
            model.save()

            if date.get('should_have_turleder') == '1':
                # We need to specify the key for this particular field because the parse_html_array
                # function does not properly parse multidimensional arrays.
                key = 'dates[%s][turleder][]' % i
                if key in request.POST and request.POST[key] != '':
                    model.turledere = request.POST.getlist(key)
            else:
                model.turledere = []

        if not errors:
            messages.info(request, 'save_success')

        if json.loads(request.POST['preview']):
            return redirect('admin.aktiviteter.views.preview', aktivitet.id)
        else:
            return redirect('admin.aktiviteter.views.edit', aktivitet.id)
Example #11
0
def index(request):
    filter_ = DEFAULT_FILTER.copy()
    filter_.update(request.GET.dict())

    # Default organizers: If visiting a local site, default to the owner of the current site (except for DNT central)
    if not filter_['organizers'] and request.site.forening.id != Forening.DNT_CENTRAL_ID:
        filter_['organizers'] = '%s:%s' % ('forening', request.site.forening.id)

    # Interestingly, the paginator will perform a COUNT query to count the
    # total number of objects, regardless of whether it is used in the
    # template. Therefore, even if we get a cache hit for the listing template
    # fragment, it will perform the query unnecessarily. So explicitly check
    # if the current filter is cached or not, and if so, skip the pagination.
    cache_key = make_template_fragment_key(
        'aktivitet_listing',
        [filter_hash(filter_)],
    )
    if cache.get(cache_key) is not None:
        aktivitet_dates_pagenav = None
    else:
        filter_, aktivitet_dates = filter_aktivitet_dates(filter_)
        aktivitet_dates_pagenav = paginate_aktivitet_dates(filter_, aktivitet_dates)

    # Usually, the 'sentral' type is sorted first, but in this case we want it last
    all_foreninger = Forening.get_all_sorted()
    sentral = all_foreninger[0]
    if not sentral['code'] == 'sentral':
        # We made an incorrect assumption, log it but try to continue rendering instead of raising an error
        logger.error(
            "Assumed first group of forening to be type 'sentral', was really '%s'" % sentral['code'],
            extra={
                'request': request,
                'all_foreninger': all_foreninger,
            }
        )
    # Remove and append the sentral group to the end
    all_foreninger.remove(sentral)
    all_foreninger.append(sentral)

    # Look up DNT cabins with serving
    cabins = sorted(Sted.list(params={
        'tags': 'Hytte',
        'betjeningsgrad': 'Betjent',
        'privat': {'hytteeier': 'DNT'},
        'status': 'Offentlig',
        'tilbyder': 'DNT',
    }), key=lambda s: s['navn'])

    # Set url query parameters for pagination links
    query_string = get_filter_query_string(request.GET.dict())

    context = {
        'aktivitet_dates': aktivitet_dates_pagenav,
        'difficulties': Aktivitet.DIFFICULTY_CHOICES,
        'categories': Aktivitet.CATEGORY_CHOICES,
        'category_types': Aktivitet.CATEGORY_TYPES_LIST,
        'audiences': Aktivitet.AUDIENCE_CHOICES,
        'omrader': sorted(Område.list(params={'status': 'Offentlig', 'tilbyder': 'DNT'}), key=lambda o: o['navn']),
        'cabins': cabins,
        'all_foreninger': all_foreninger,
        'query_string': query_string,
        'filter': filter_,
        'filter_hash': filter_hash(filter_),
    }
    return render(request, 'common/aktiviteter/index.html', context)
Example #12
0
 def children_foreninger_sorted(self):
     return Forening.sort(self.children_foreninger())
Example #13
0
 def all_foreninger_sorted_with_type_data(self):
     return Forening.sort_with_type_data(self.all_foreninger())
Example #14
0
def create(request, forening_id):
    current_forening = Forening.objects.get(id=forening_id)

    if current_forening not in request.user.all_foreninger():
        raise PermissionDenied

    # The parent choices are tricky to define in the forms API, so do it here.
    # Note that we're intentionally letting users choose parents among only
    # those they have permission to.
    all_sorted = request.user.all_foreninger_sorted()
    parents_choices = {
        'forening': all_sorted['forening'],
        'turlag': all_sorted['turlag'],
    }

    # If the parent of the current forening isn't in the user's permissions, we
    # still need to include that one as an available parent so that they're
    # able to make changes.
    if current_forening.type != 'sentral':
        for current_parent in current_forening.get_main_foreninger():
            if (current_parent not in parents_choices['forening'] and
                    current_parent not in parents_choices['turlag']):
                parents_choices[current_parent.type].append(current_parent)

    form = CreateForeningForm(request.user, initial={
        'zipcode': '',
    })

    context = {
        'current_forening': current_forening,
        'parents_choices': parents_choices,
        'admin_user_search_char_length': settings.ADMIN_USER_SEARCH_CHAR_LENGTH,
        'form': form,
    }

    # Give URLPicker the homepage site for the current forening. If they don't
    # have one, just use the central site
    relevant_site = current_forening.get_homepage_site() or Site.get_central()
    context.update(url_picker_context(relevant_site))

    if request.method == 'GET':
        return render(request, 'central/admin/foreninger/create.html', context)

    elif request.method == 'POST':

        form = CreateForeningForm(request.user, request.POST)
        if form.is_valid():
            forening = Forening()
            forening.name = form.cleaned_data['name']
            forening.type = form.cleaned_data['type']
            if forening.type == 'turgruppe':
                forening.group_type = form.cleaned_data['group_type']
            else:
                forening.group_type = ''

            forening.save()

            # Set M2M-fields after the initial db-save
            forening.parents = form.cleaned_data['parents']

            # Ensure the Turbasen object is re-saved with applicable
            # M2M-relations
            forening.save_turbasen_object()

            # Add the current user as admin on the new forening
            request.user.add_perm(
                'sherpa/association/user',
                association_id=forening.id,
                created_by=request.user
            )
            request.user.add_perm(
                'sherpa/association/admin',
                association_id=forening.id,
                created_by=request.user
            )
            cache.clear()
            return redirect('admin:foreninger.edit', forening.id)
        else:
            context.update({'form': form})
            return render(
                request,
                'central/admin/foreninger/create.html',
                context)

    else:
        return redirect('admin:foreninger.create', current_forening.id)
Example #15
0
    def clean(self):
        cleaned_data = super().clean()

        type_ = cleaned_data.get('type')
        parents = cleaned_data.get('parents')

        if type_ in ['sentral', 'forening']:
            # In this case, the UI will have hidden the parents input, but it might still have a value, so
            # force it to empty. The hiding of the field should make this behavior intuitive.
            cleaned_data['parent'] = []
            parents = []

        # These types must have a parent, but that can't be enforced on the DB-level for *new* foreninger since parents
        # are a M2M-relationship (so the child needs to be saved before the parent can be related), so check it here.
        if type_ in ['turlag', 'turgruppe'] and len(parents) == 0:
            self.add_error(
                'parents',
                "%s må ha en moderforening!" % (
                    'Et turlag' if type_ == 'turlag' else 'En turgruppe',
                )
            )
            parents = None

        # Non DNT admins cannot set type forening/sentral
        if not self._user.is_admin_in_dnt_central() and type_ in ['sentral', 'forening']:
            self.add_error(
                'type',
                "Du har ikke tillatelse til å opprette sentrale grupper eller medlemsforeninger. Vennligst ta " \
                "kontakt med DNT sentralt.",
            )

        # Validate the new forening type and parents relationship
        try:
            forening = Forening()
            forening.validate_relationships(
                simulate_type=type_,
                simulate_parents=parents,
            )

        except ForeningWithItselfAsParent:
            self.add_error(
                'parents',
                "%s kan ikke være underlagt seg selv." % forening.name
            )

        except SentralForeningWithRelation:
            self.add_error(
                'parents',
                "En sentral forening kan ikke ha noen koblinger til andre foreningstyper."
            )

        except ForeningWithForeningParent:
            self.add_error(
                'parents',
                "En forening kan ikke være underlagt en annen forening."
            )

        except TurlagWithTurlagParent:
            self.add_error(
                'parents',
                "Et turlag kan ikke være underlagt et annet turlag."
            )

        except TurgruppeWithTurgruppeParent:
            self.add_error(
                'parents',
                "En turgruppe kan ikke være underlagt en annen turgruppe."
            )

        except ForeningWithTurlagParent:
            self.add_error(
                'parents',
                "Foreninger kan ikke være underlagt turlag/turgrupper."
            )

        except TurlagWithTurgruppeParent:
            self.add_error(
                'parents',
                "Et turlag kan ikke være underlagt en turgruppe."
            )

        return cleaned_data
Example #16
0
def show(request, user_id):
    try:
        other_user = User.objects.filter(
            id=user_id,
        ).prefetch_related(
            'turledere',
            'turleder_active_foreninger',
        ).get()
    except User.DoesNotExist:
        messages.warning(request, 'no_such_user')
        return redirect('admin:users.index')

    # Admins can assign user/admin, users can assign users
    assignable_admin = [
        a for a in request.user.all_foreninger() if a.role == 'admin'
    ]
    assignable_user = [
        a for a in request.user.all_foreninger() if a.role == 'user'
    ]
    # Don't let users assign new permissions for those that already have user
    # status.
    # Use UserPermissionGrant for other_user, because we can't set permissions
    # for foreninger that are based on parent foreninger (to remove access to
    # a child, you have to remove admin-permission to the parent)
    p_name = 'sherpa/association/user'
    other_user_foreninger = Forening.objects.filter(
        user_permission_grants__user_permission__name=p_name,
        user_permission_grants__user=other_user
    )

    assignable_user = [
        a for a in assignable_user if a not in other_user_foreninger
    ]
    assignable_foreninger = assignable_admin + assignable_user

    # Only admins can revoke forening relation
    revokable_foreninger = [
        a for a in assignable_admin if a in other_user_foreninger
    ]

    today = date.today()

    # We can't just add 365*5 timedelta days because that doesn't account for
    # leap years, this does.
    try:
        five_years_from_now = date(
            year=(today.year + 5),
            month=today.month,
            day=today.day
        )
    except ValueError:
        # This will only occur when today is February 29th during a leap year
        # (right?)
        five_years_from_now = date(
            year=(today.year + 5),
            month=today.month,
            day=(today.day - 1)
        )

    # Select participant groups where user is signee or participant
    aktivitet_data = get_aktivitet_list_participant_groups(other_user)

    # Sort by user / other
    aktiviteter_user = {
        'past': [a for a in aktivitet_data['past'] if a['user_is_signed_up']],
        'future': [
            a for a in aktivitet_data['future'] if a['user_is_signed_up']],
    }
    aktiviteter_other = {
        'past': [
            a for a in aktivitet_data['past'] if not a['user_is_signed_up']],
        'future': [
            a for a in aktivitet_data['future'] if not a['user_is_signed_up']],
    }

    # Get aktiviteter from montis
    montis_error = False
    montis_data = None
    if other_user.is_member():
        montis_data = get_aktivitet_list_from_montis(other_user)
        montis_error = montis_data.get('montis_error', False)

        if (len(montis_data['past']) + len(montis_data['future'])) == 0:
            montis_data = None
        else:
            montis_data['past'].sort(key=lambda d: d['start_date'])
            montis_data['future'].sort(key=lambda d: d['start_date'])

    aktiviteter_count = (
        len(aktivitet_data['past']) + len(aktivitet_data['future']))
    if montis_data:
        aktiviteter_count += (
            len(montis_data['past']) + len(montis_data['future']))

    # Select dates where user is turleder
    turleder_dates = other_user.turleder_aktivitet_dates.all()
    turleder_dates = {
        'future': [d for d in turleder_dates if d.start_date >= date.today()],
        'past': [d for d in turleder_dates if d.start_date < date.today()],
    }

    context = {
        'other_user': other_user,
        'revokable_foreninger': Forening.sort(revokable_foreninger),
        'assignable_foreninger': Forening.sort(assignable_foreninger),
        'all_foreninger': Forening.get_all_sorted(),
        'turleder_roles': Turleder.TURLEDER_CHOICES,
        'five_years_from_now': five_years_from_now,
        'aktiviteter_user': aktiviteter_user,
        'aktiviteter_other': aktiviteter_other,
        'montis_data': montis_data,
        'aktiviteter_count': aktiviteter_count,
        'turleder_dates': turleder_dates,
        'montis_error': montis_error,
        'consent_pretty': json.dumps(other_user.consent, indent=2),
        'consent': other_user.get_consent_preferences(),
        'consent_json': json.dumps(other_user.consent),
    }

    if other_user.is_member() and other_user.can_reserve_against_publications():
        context.update({
            'enable_publications_toggle': True,
            'can_reserve_against_publications': other_user.can_reserve_against_publications(),
            'reserved_against_fjellogvidde': other_user.get_reserved_against_fjellogvidde(),
            'reserved_against_yearbook': other_user.get_reserved_against_yearbook(),
        })

    return render(request, 'central/admin/users/show/index.html', context)
Example #17
0
    def clean(self):
        cleaned_data = super().clean()

        type_ = cleaned_data.get('type')
        parents = cleaned_data.get('parents')

        if type_ in ['sentral', 'forening']:
            # In this case, the UI will have hidden the parents input, but it might still have a value, so
            # force it to empty. The hiding of the field should make this behavior intuitive.
            cleaned_data['parent'] = []
            parents = []

        # These types must have a parent, but that can't be enforced on the DB-level for *new* foreninger since parents
        # are a M2M-relationship (so the child needs to be saved before the parent can be related), so check it here.
        if type_ in ['turlag', 'turgruppe'] and len(parents) == 0:
            self.add_error(
                'parents',
                "%s må ha en moderforening!" % (
                    'Et turlag' if type_ == 'turlag' else 'En turgruppe',
                )
            )
            parents = None

        # The following check should be skipped if this form is actually an
        # instance of the EditForeningForm subclass
        if not isinstance(self, EditForeningForm):
            # Non DNT admins cannot set type forening/sentral. Note that the
            # edit form should allow non-admins to save objects of this type
            # as long as it isn't changed.
            if not self._user.is_admin_in_dnt_central() and type_ in ['sentral', 'forening']:
                self.add_error(
                    'type',
                    "Du har ikke tillatelse til å opprette sentrale grupper eller medlemsforeninger. Vennligst ta " \
                    "kontakt med DNT sentralt.",
                )

        # Validate focus_id
        focus_id = cleaned_data['focus_id']
        if focus_id is not None:
            others = Forening.objects.filter(
                focus_id=focus_id
            ).exclude(
                id=cleaned_data['forening'].id
            )

            if others.count():
                other = others.all()[0]
                self.add_error(
                    'focus_id',
                    (
                        f"Focus ID «{focus_id}» er allerede registrert på "
                        f"foreningen {other.name}."
                    )
                )

        # Validate the new forening type and parents relationship
        try:
            forening = Forening()
            forening.validate_relationships(
                simulate_type=type_,
                simulate_parents=parents,
            )

        except ForeningWithItselfAsParent:
            self.add_error(
                'parents',
                "%s kan ikke være underlagt seg selv." % forening.name
            )

        except SentralForeningWithRelation:
            self.add_error(
                'parents',
                "En sentral forening kan ikke ha noen koblinger til andre foreningstyper."
            )

        except ForeningWithForeningParent:
            self.add_error(
                'parents',
                "En forening kan ikke være underlagt en annen forening."
            )

        except TurlagWithTurlagParent:
            self.add_error(
                'parents',
                "Et turlag kan ikke være underlagt et annet turlag."
            )

        except TurgruppeWithTurgruppeParent:
            self.add_error(
                'parents',
                "En turgruppe kan ikke være underlagt en annen turgruppe."
            )

        except ForeningWithTurlagParent:
            self.add_error(
                'parents',
                "Foreninger kan ikke være underlagt turlag/turgrupper."
            )

        except TurlagWithTurgruppeParent:
            self.add_error(
                'parents',
                "Et turlag kan ikke være underlagt en turgruppe."
            )

        return cleaned_data
Example #18
0
def index(request, forening_id):
    current_forening = Forening.objects.get(id=forening_id)
    if current_forening not in request.user.all_foreninger():
        raise PermissionDenied

    forening_users = list(User.objects.filter(foreninger=current_forening))

    forening_users_by_parent = []

    parent_ids = [p.id for p in current_forening.get_parents_deep()]
    forening_users_by_parent_all = list(User.objects.filter(foreninger__in=parent_ids))

    # Prefetch and cache the actors
    memberids = [u.memberid for u in (forening_users + forening_users_by_parent)]
    for actor in Actor.get_personal_members().filter(memberid__in=memberids):
        cache.set('actor.%s' % actor.memberid, actor, settings.FOCUS_MEMBER_CACHE_PERIOD)

    # Safe to iterate without having n+1 issues

    # Filter on admins
    forening_users_by_parent = []
    for user in forening_users_by_parent_all:
        for forening in user.all_foreninger():
            if forening == current_forening and forening.role == 'admin':
                forening_users_by_parent.append(user)

    forening_users = sorted(forening_users, key=lambda u: u.get_full_name())
    forening_users_by_parent = sorted(forening_users_by_parent, key=lambda u: u.get_full_name())
    sherpa_admins = sorted(User.objects.filter(permissions__name='sherpa_admin'), key=lambda u: u.get_full_name())

    # The parent choices are tricky to define in the forms API, so do it here.
    # Note that we're intentionally letting users choose parents among only those they have permission to.
    all_sorted = request.user.all_foreninger_sorted()
    parents_choices = {
        'forening': all_sorted['forening'],
        'turlag': all_sorted['turlag'],
    }

    # If the parent of the current forening isn't in the user's permissions, we still need to include that one as an
    # available parent so that they're able to make changes.
    if current_forening.type != 'sentral':
        for current_parent in current_forening.get_main_foreninger():
            if current_parent not in parents_choices['forening'] and current_parent not in parents_choices['turlag']:
                parents_choices[current_parent.type].append(current_parent)

    context = {
        'current_forening': current_forening,
        'forening_users': forening_users,
        'forening_users_by_parent': forening_users_by_parent,
        'sherpa_admins': sherpa_admins,
        'parents_choices': parents_choices,
        'admin_user_search_char_length': settings.ADMIN_USER_SEARCH_CHAR_LENGTH
    }

    zipcode = current_forening.zipcode
    edit_form_zipcode_area = zipcode.area if zipcode is not None else ''

    if current_forening.contact_person is not None:
        choose_contact = 'person'
        contact_person = current_forening.contact_person.id
        contact_person_name = current_forening.contact_person.get_full_name()
        phone = current_forening.contact_person.get_phone_mobile()
        email = current_forening.contact_person.get_sherpa_email()
    elif current_forening.contact_person_name != '':
        choose_contact = 'person'
        contact_person = None
        contact_person_name = current_forening.contact_person_name
        phone = current_forening.phone
        email = current_forening.email
    else:
        choose_contact = 'forening'
        contact_person = None
        contact_person_name = ''
        phone = current_forening.phone
        email = current_forening.email

    edit_form = ExistingForeningDataForm(request.user, prefix='edit', initial={
        'forening': current_forening.id,
        'parents': current_forening.parents.all(),
        'name': current_forening.name,
        'type': current_forening.type,
        'group_type': current_forening.group_type,
        'post_address': current_forening.post_address,
        'visit_address': current_forening.visit_address,
        'zipcode': zipcode.zipcode if zipcode is not None else '',
        'counties': current_forening.counties.all(),
        'choose_contact': choose_contact,
        'contact_person': contact_person,
        'contact_person_name': contact_person_name,
        'phone': phone,
        'email': email,
        'organization_no': current_forening.organization_no,
        'gmap_url': current_forening.gmap_url,
        'facebook_url': current_forening.facebook_url,
    })

    create_form = ForeningDataForm(request.user, prefix='create', initial={
        'zipcode': '',
    })

    context.update({
        'edit_form': edit_form,
        'create_form': create_form,
        'edit_form_zipcode_area': edit_form_zipcode_area,
    })

    if request.method == 'GET':
        return render(request, 'common/admin/forening/index.html', context)

    elif request.method == 'POST':

        if request.POST.get('form') == 'edit':
            edit_form = ExistingForeningDataForm(request.user, request.POST, prefix='edit')
            if edit_form.is_valid():
                forening = edit_form.cleaned_data['forening']
                forening.parents = edit_form.cleaned_data['parents']
                forening.name = edit_form.cleaned_data['name']
                forening.type = edit_form.cleaned_data['type']
                if forening.type == 'turgruppe':
                    forening.group_type = edit_form.cleaned_data['group_type']
                else:
                    forening.group_type = ''
                forening.post_address = edit_form.cleaned_data['post_address']
                forening.visit_address = edit_form.cleaned_data['visit_address']
                forening.zipcode = edit_form.cleaned_data['zipcode']
                forening.counties = edit_form.cleaned_data['counties']

                if edit_form.cleaned_data['choose_contact'] == 'person':
                    if edit_form.cleaned_data['contact_person'] is not None:
                        forening.contact_person = edit_form.cleaned_data['contact_person']
                        forening.contact_person_name = ''
                    else:
                        forening.contact_person = None
                        forening.contact_person_name = edit_form.cleaned_data['contact_person_name']
                else:
                    forening.contact_person = None
                    forening.contact_person_name = ''

                forening.phone = edit_form.cleaned_data['phone']
                forening.email = edit_form.cleaned_data['email']

                forening.organization_no = edit_form.cleaned_data['organization_no']
                forening.gmap_url = edit_form.cleaned_data['gmap_url']
                forening.facebook_url = edit_form.cleaned_data['facebook_url']
                forening.save()
                messages.info(request, 'forening_save_success')
                cache.delete('foreninger.all.sorted_by_name')
                cache.delete('foreninger.all.sorted_by_name.with_active_url')
                cache.delete('foreninger.all.sorted_by_type')
                cache.delete('forening.%s' % forening.id)
                cache.delete('forening.main_foreninger.%s' % forening.id)
                return redirect('admin.forening.views.index', current_forening.id)
            else:
                context.update({'edit_form': edit_form})
                return render(request, 'common/admin/forening/index.html', context)

        elif request.POST.get('form') == 'create':
            create_form = ForeningDataForm(request.user, request.POST, prefix='create')
            if create_form.is_valid():
                forening = Forening()
                forening.name = create_form.cleaned_data['name']
                forening.type = create_form.cleaned_data['type']
                if forening.type == 'turgruppe':
                    forening.group_type = create_form.cleaned_data['group_type']
                else:
                    forening.group_type = ''
                forening.post_address = create_form.cleaned_data['post_address']
                forening.visit_address = create_form.cleaned_data['visit_address']
                forening.zipcode = create_form.cleaned_data['zipcode']

                if create_form.cleaned_data['choose_contact'] == 'person':
                    if create_form.cleaned_data['contact_person'] is not None:
                        forening.contact_person = create_form.cleaned_data['contact_person']
                        forening.contact_person_name = ''
                    else:
                        forening.contact_person = None
                        forening.contact_person_name = create_form.cleaned_data['contact_person_name']
                else:
                    forening.contact_person = None
                    forening.contact_person_name = ''

                forening.phone = create_form.cleaned_data['phone']
                forening.email = create_form.cleaned_data['email']

                forening.organization_no = create_form.cleaned_data['organization_no']
                forening.gmap_url = create_form.cleaned_data['gmap_url']
                forening.facebook_url = create_form.cleaned_data['facebook_url']
                forening.save()

                # Set M2M-fields after the initial db-save
                forening.parents = create_form.cleaned_data['parents']
                forening.counties = create_form.cleaned_data['counties']

                # Add the current user as admin on the new forening
                role = ForeningRole(
                    user=request.user,
                    forening=forening,
                    role='admin',
                )
                role.save()
                # FIXME: We can't delete the permission cache for all users, so some may find that they can't edit
                # the new forening even though they should be able, until the cache (which is currently 24h) expires.
                cache.delete('user.%s.all_foreninger' % request.user.id)

                messages.info(request, 'forening_create_success')
                request.session['active_forening'] = forening.id
                cache.delete('foreninger.all.sorted_by_name')
                cache.delete('foreninger.all.sorted_by_name.with_active_url')
                cache.delete('foreninger.all.sorted_by_type')
                cache.delete('forening.%s' % forening.id)
                cache.delete('forening.main_foreninger.%s' % forening.id)
                # Since GET url == POST url, we need to specifically set the tab hashtag we want, or the existing
                # one (create) will be kept
                return redirect('%s#metadata' % reverse('admin.forening.views.index', args=[current_forening.id]))
            else:
                context.update({'create_form': create_form})
                return render(request, 'common/admin/forening/index.html', context)

        else:
            return redirect('admin.forening.views.index', current_forening.id)
Example #19
0
 def forening(self):
     """Return the forening owning the account for this charge"""
     return Forening.get_by_stripe_id(self.account_id)
Example #20
0
    def clean(self):
        cleaned_data = super(ForeningDataForm, self).clean()

        if cleaned_data.get('choose_contact') == 'person':
            if cleaned_data.get('contact_person') is None and \
                (cleaned_data.get('contact_person_name') is None or cleaned_data.get('contact_person_name') == ''):
                self.add_error(
                    'contact_person_name',
                    u"Hvis det er en kontaktperson som kan kontaktes, må du oppgi et navn eller velge en person " \
                    u"fra medlemsregisteret.",
                )

        type_ = cleaned_data.get('type')
        parents = cleaned_data.get('parents')

        if type_ in ['sentral', 'forening']:
            # In this case, the UI will have hidden the parents input, but it might still have a value, so
            # force it to empty. The hiding of the field should make this behavior intuitive.
            cleaned_data['parent'] = []
            parents = []

        # These types must have a parent, but that can't be enforced on the DB-level for *new* foreninger since parents
        # are a M2M-relationship (so the child needs to be saved before the parent can be related), so check it here.
        elif type_ in ['turlag', 'turgruppe'] and len(parents) == 0:
            self.add_error(
                'parents',
                u"%s må ha en moderforening!" % (
                    'Et turlag' if type_ == 'turlag' else 'En turgruppe',
                )
            )
            parents = None

        # Non DNT admins cannot *create* forening with type forening/sentral
        # Note that this might be legal in derived classes, so check this only for the base class
        # Shouldn't be possible without a manual POST
        if type(self) == ForeningDataForm and not self._user.is_admin_in_dnt_central() and type_ in ['sentral', 'forening']:
            self.add_error(
                'type',
                u"Du har ikke tillatelse til å opprette sentrale grupper eller medlemsforeninger. Vennligst ta " \
                u"kontakt med DNT sentralt.",
            )

        # Validate the new forening type and parents relationship
        try:
            forening = Forening()
            forening.validate_relationships(
                simulate_type=type_,
                simulate_parents=parents,
            )

        except ForeningWithItselfAsParent:
            # Shouldn't be possible without a manual POST
            self.add_error(
                'parents',
                u"%s kan ikke være underlagt seg selv." % forening.name
            )

        except SentralForeningWithRelation:
            # Shouldn't be possible without a manual POST
            self.add_error(
                'parents',
                u"En sentral forening kan ikke ha noen koblinger til andre foreningstyper."
            )

        except ForeningWithForeningParent:
            self.add_error(
                'parents',
                u"En forening kan ikke være underlagt en annen forening."
            )

        except TurlagWithTurlagParent:
            self.add_error(
                'parents',
                u"Et turlag kan ikke være underlagt et annet turlag."
            )

        except TurgruppeWithTurgruppeParent:
            self.add_error(
                'parents',
                u"En turgruppe kan ikke være underlagt en annen turgruppe."
            )

        except ForeningWithTurlagParent:
            self.add_error(
                'parents',
                u"Foreninger kan ikke være underlagt turlag/turgrupper."
            )

        except TurlagWithTurgruppeParent:
            self.add_error(
                'parents',
                u"Et turlag kan ikke være underlagt en turgruppe."
            )
Example #21
0
 def admin_context(self, site):
     return {
         'all_foreninger_sorted': Forening.get_all_sorted_with_type_data(),
         'audiences': AktivitetAudience.AUDIENCE_CHOICES,
         'categories': Aktivitet.CATEGORY_CHOICES,
     }
Example #22
0
 def all_foreninger_sorted(self):
     return Forening.sort(self.all_foreninger())