Пример #1
0
 def log_view(self, request, **extra_attrs):
     """
     Logs an instance of this persons' Personally Identifiable Information being viewed by
     another user.
     """
     from event_log.utils import emit
     emit('core.person.viewed', person=self, request=request, **extra_attrs)
Пример #2
0
def sudo_view(request):
    next = request.GET.get('next') or '/'
    claims = {k: v for (k, v) in request.POST.items() if k in CBAC_SUDO_CLAIMS}

    cbac_entry = CBACEntry(
        user=request.user,
        valid_until=now() + timedelta(minutes=CBAC_SUDO_VALID_MINUTES),
        claims=claims,
        created_by=request.user,
    )
    cbac_entry.save()

    messages.warning(
        request, f'Käyttöoikeustarkastus ohitettu pääkäyttäjän oikeuksin. '
        f'Väliaikainen käyttöoikeus on voimassa {CBAC_SUDO_VALID_MINUTES} minuuttia.'
    )

    emit('access.cbac.sudo',
         request=request,
         other_fields=cbac_entry.as_dict())
    emit('access.cbacentry.created',
         request=request,
         other_fields=cbac_entry.as_dict())

    return redirect(next)
Пример #3
0
    def archive_signup(self, signup):
        """
        If the signup is in a positive final state, archives it. Otherwise deletes it.
        An event log entry is emitted in both cases.

        Archiving a signup means making an ArchivedSignup of it and deleting the original
        Signup and its SignupExtra.
        """
        with transaction.atomic():
            person = signup.person
            event = signup.event

            if signup.state in ARCHIVE_STATES:
                event_type = 'labour.signup.archived'

                archived_signup, created = ArchivedSignup.objects.get_or_create(
                    person=signup.person,
                    event=signup.event,
                    job_title=signup.some_job_title,
                )

                archived_signup.job_categories_accepted.set(signup.job_categories_accepted.all())
                archived_signup.personnel_classes.set(signup.personnel_classes.all())
            else:
                event_type = 'labour.signup.deleted'

            signup.signup_extra.delete()
            signup.delete()

            emit(event_type, person=person, event=event)
Пример #4
0
def core_password_view(request):
    form = initialize_form(PasswordForm, request, the_request=request)

    if request.method == 'POST':
        if form.is_valid():
            old_password = form.cleaned_data['old_password']
            new_password = form.cleaned_data['new_password']

            try:
                change_user_password(request.user, old_password=old_password, new_password=new_password)
            except RuntimeError:
                logger.exception('Failed to change password')
                messages.error(request, 'Salasanan vaihto epäonnistui. Ole hyvä ja yritä myöhemmin uudelleen.')
                return redirect('core_password_view')
            else:
                messages.success(request, 'Salasanasi on vaihdettu. Voit nyt kirjautua uudestaan sisään uudella salasanallasi.')
                emit('core.password.changed', request=request)
                return redirect('core_frontpage_view')
        else:
            messages.error(request, 'Ole hyvä ja korjaa virheelliset kentät.')

    vars = dict(
        form=form,
    )

    return render(request, 'core_password_view.pug', vars)
Пример #5
0
def tickets_admin_accommodation_view(request, vars, event, limit_group_id=None):
    if limit_group_id is not None:
        limit_group_id = int(limit_group_id)
        limit_group = get_object_or_404(LimitGroup, id=limit_group_id, event=event)
        query = Q(
            # Belongs to the selected night and school
            limit_groups=limit_group,
        ) & (
            Q(
                # Accommodation information is manually added
                order_product__isnull=True
            ) | Q(
                # Order is confirmed
                order_product__order__confirm_time__isnull=False,

                # Order is paid
                order_product__order__payment_date__isnull=False,

                # Order is not cancelled
                order_product__order__cancellation_time__isnull=True,
            )
        )
        accommodees = AccommodationInformation.objects.filter(query).order_by('last_name', 'first_name')
        active_filter = limit_group
    else:
        accommodees = []
        active_filter = None

    format = request.GET.get('format', 'screen')

    if format in CSV_EXPORT_FORMATS:
        filename = "{event.slug}-{active_filter}-{timestamp}.{format}".format(
            event=event,
            active_filter=slugify(limit_group.description),
            timestamp=now().strftime('%Y%m%d%H%M%S'),
            format=format,
        )

        emit('core.person.exported', request=request, event=event)

        return csv_response(event, AccommodationInformation, accommodees, filename=filename, dialect=CSV_EXPORT_FORMATS[format])
    elif format == 'screen':
        filters = [
            (limit_group_id == lg.id, lg)
            for lg in LimitGroup.objects.filter(
                event=event,
                product__requires_accommodation_information=True,
            ).distinct()
        ]

        vars.update(
            accommodees=accommodees,
            active_filter=active_filter,
            filters=filters,
        )

        return render(request, 'tickets_admin_accommodation_view.pug', vars)
    else:
        raise NotImplementedError(format)
Пример #6
0
 def log_view(self, request, **extra_attrs):
     """
     Logs an instance of this persons' Personally Identifiable Information being viewed by
     another user.
     """
     from event_log.utils import emit
     emit(
         'core.person.viewed',
         person=self,
         request=request,
         **extra_attrs
     )
Пример #7
0
    def wrapped_view(request, *args, **kwargs):
        claims = get_default_claims(request)
        user = request.user

        logger.debug("CBAC: Checking permissions: user=%r, claims=%s",
                     user.username, claims)
        if not CBACEntry.is_allowed(user, claims):
            logger.warning("CBAC: Permission denied: user=%r, claims=%r",
                           user.username, claims)
            emit('access.cbac.denied',
                 request=request,
                 other_fields={'claims': claims})
            raise CBACPermissionDenied(claims)

        return view_func(request, *args, **kwargs)
Пример #8
0
def directory_view(request, vars, organization):
    people = organization.people
    num_total_people = people.count()

    events = organization.events.all()
    event_filters = Filter(request, 'event').add_objects('event', events)
    event_slug = event_filters.selected_slug
    if event_slug:
        event = get_object_or_404(events, slug=event_slug)
        people = event.people
    else:
        event = None

    search_form = SearchForm(request.GET)
    if search_form.is_valid():
        query = search_form.cleaned_data['query']
        if query:
            people = people.annotate(search=SearchVector(
                'first_name', 'surname', 'nick', 'email', 'phone',
                'user__username'), ).filter(search=query)

    hide_warning = None
    if request.method == 'POST':
        if request.POST.get('action') == 'hide-warning':
            hide_warning = request.session[HIDE_WARNING_SESSION_KEY] = True
        else:
            messages.error(request, _('Unknown action.'))

    if hide_warning is None:
        hide_warning = request.session.get(HIDE_WARNING_SESSION_KEY, False)

    vars.update(
        event_filters=event_filters,
        num_total_people=num_total_people,
        people=people,
        search_form=search_form,
        show_warning=not hide_warning,
    )

    if search_form.is_valid() and query:
        emit('directory.search.performed',
             search_term=query,
             request=request,
             organization=organization)
    else:
        emit('directory.viewed', request=request, organization=organization)

    return render(request, 'directory_view.pug', vars)
Пример #9
0
def directory_view(request, vars, organization):
    people = organization.people
    num_total_people = people.count()

    events = organization.events.all()
    event_filters = Filter(request, 'event').add_objects('event', events)
    event_slug = event_filters.selected_slug
    if event_slug:
        event = get_object_or_404(events, slug=event_slug)
        people = event.people
    else:
        event = None

    search_form = SearchForm(request.GET)
    if search_form.is_valid():
        query = search_form.cleaned_data['query']
        if query:
            people = people.annotate(
                search=SearchVector('first_name', 'surname', 'nick', 'email', 'phone', 'user__username'),
            ).filter(search=query)

    hide_warning = None
    if request.method == 'POST':
        if request.POST.get('action') == 'hide-warning':
            hide_warning = request.session[HIDE_WARNING_SESSION_KEY] = True
        else:
            messages.error(request, _('Unknown action.'))

    if hide_warning is None:
        hide_warning = request.session.get(HIDE_WARNING_SESSION_KEY, False)

    vars.update(
        event_filters=event_filters,
        num_total_people=num_total_people,
        people=people,
        search_form=search_form,
        show_warning=not hide_warning,
    )

    if search_form.is_valid() and query:
        emit('directory.search.performed', search_term=query, request=request, organization=organization)
    else:
        emit('directory.viewed', request=request, organization=organization)

    return render(request, 'directory_view.pug', vars)
Пример #10
0
def tracon2017_afterparty_participants_view(request, vars, event):
    assert event.slug == 'tracon2017'

    participants = SignupExtraAfterpartyProxy.objects.filter(afterparty_participation=True)

    filename = "{event.slug}_afterparty_participants_{timestamp}.xlsx".format(
        event=event,
        timestamp=now().strftime('%Y%m%d%H%M%S'),
        format=format,
    )

    emit('core.person.exported', request=request, event=event)

    return csv_response(event, SignupExtraAfterpartyProxy, participants,
        dialect='xlsx',
        filename=filename,
        m2m_mode='separate_columns',
    )
Пример #11
0
def traconpaidat2019_custom_shirts_view(request, vars, event):
    assert event.slug == 'traconpaidat2019'

    shirts = CustomShirtProxy.objects.all()

    filename = "{event.slug}_nimikoidut_{timestamp}.xlsx".format(
        event=event,
        timestamp=now().strftime('%Y%m%d%H%M%S'),
        format=format,
    )

    emit('core.person.exported', request=request, event=event)

    return csv_response(event, CustomShirtProxy, shirts,
        dialect='xlsx',
        filename=filename,
        m2m_mode='separate_columns',
    )
Пример #12
0
def core_admin_impersonate_view(request, username):
    user = get_object_or_404(get_user_model(), username=username)

    try:
        person = user.person
    except Person.DoesNotExist:
        person = None

    emit('core.person.impersonated', request=request, person=person)

    next = get_next(request)
    user = authenticate(username=username, allow_passwordless_login=YES_PLEASE_ALLOW_PASSWORDLESS_LOGIN)

    messages.warning(request,
        'Käytät nyt Kompassia toisen käyttäjän oikeuksilla. Tämän toiminnon käyttö on sallittua '
        'ainoastaan sellaisiin ylläpitotoimenpiteisiin, joiden hoitaminen ylläpitotunnuksilla on '
        'muuten tarpeettoman työlästä tai hankalaa. Muista kirjautua ulos, kun olet saanut '
        'ylläpitotoimenpiteet hoidettua.'
    )

    return do_login(request, user, password=None, next=next)
Пример #13
0
def traconpaidat2019_custom_shirts_view(request, vars, event):
    assert event.slug == 'traconpaidat2019'

    shirts = CustomShirtProxy.objects.all()

    filename = "{event.slug}_nimikoidut_{timestamp}.xlsx".format(
        event=event,
        timestamp=now().strftime('%Y%m%d%H%M%S'),
        format=format,
    )

    emit('core.person.exported', request=request, event=event)

    return csv_response(
        event,
        CustomShirtProxy,
        shirts,
        dialect='xlsx',
        filename=filename,
        m2m_mode='separate_columns',
    )
Пример #14
0
    def ensure_admin_group_privileges_for_event(cls, event, *, t: datetime = None, request = None):
        if t is None:
            t = now()

        for app_name in SUPPORTED_APPS:
            meta = event.get_app_event_meta(app_name)

            if not meta:
                continue

            admin_group = meta.admin_group
            admin_group_members = admin_group.user_set.all()

            # remove access from those who should not have it
            entries_to_remove = cls.objects.filter(granted_by_group=admin_group).exclude(user__in=admin_group_members)
            for cbac_entry in entries_to_remove:
                emit('access.cbacentry.deleted', request=request, other_fields=cbac_entry.as_dict())
            entries_to_remove.delete()

            # add access to those who should have it but do not yet have
            for user in admin_group_members:
                cbac_entry, created = cls.objects.get_or_create(
                    user=user,
                    granted_by_group=admin_group,
                    defaults=dict(
                        valid_from=t,
                        valid_until=event.end_time + timedelta(CBAC_VALID_AFTER_EVENT_DAYS),
                        claims={
                            "organization": event.organization.slug,
                            "event": event.slug,
                            "app": app_name,
                        },
                        created_by=request.user if request else None,
                    ),
                )
                log_get_or_create(logger, cbac_entry, created)
                if created:
                    emit('access.cbacentry.created', request=request, other_fields=cbac_entry.as_dict())
Пример #15
0
def core_admin_impersonate_view(request, username):
    user = get_object_or_404(get_user_model(), username=username)

    try:
        person = user.person
    except Person.DoesNotExist:
        person = None

    emit('core.person.impersonated', request=request, person=person)

    next = get_next(request)
    user = authenticate(
        username=username,
        allow_passwordless_login=YES_PLEASE_ALLOW_PASSWORDLESS_LOGIN)

    messages.warning(
        request,
        'Käytät nyt Kompassia toisen käyttäjän oikeuksilla. Tämän toiminnon käyttö on sallittua '
        'ainoastaan sellaisiin ylläpitotoimenpiteisiin, joiden hoitaminen ylläpitotunnuksilla on '
        'muuten tarpeettoman työlästä tai hankalaa. Muista kirjautua ulos, kun olet saanut '
        'ylläpitotoimenpiteet hoidettua.')

    return do_login(request, user, password=None, next=next)
Пример #16
0
def tickets_admin_accommodation_view(request,
                                     vars,
                                     event,
                                     limit_group_id=None):
    if limit_group_id is not None:
        limit_group_id = int(limit_group_id)
        limit_group = get_object_or_404(LimitGroup,
                                        id=limit_group_id,
                                        event=event)
        query = Q(
            # Belongs to the selected night and school
            limit_groups=limit_group, ) & (
                Q(
                    # Accommodation information is manually added
                    order_product__isnull=True) | Q(
                        # Order is confirmed
                        order_product__order__confirm_time__isnull=False,

                        # Order is paid
                        order_product__order__payment_date__isnull=False,

                        # Order is not cancelled
                        order_product__order__cancellation_time__isnull=True,
                    ))
        accommodees = AccommodationInformation.objects.filter(query).order_by(
            'last_name', 'first_name')
        active_filter = limit_group
    else:
        accommodees = []
        active_filter = None
        limit_group = None

    format = request.GET.get('format', 'screen')

    if format in CSV_EXPORT_FORMATS:
        filename = "{event.slug}-{active_filter}-{timestamp}.{format}".format(
            event=event,
            active_filter=slugify(limit_group.description)
            if limit_group else "tickets",
            timestamp=now().strftime('%Y%m%d%H%M%S'),
            format=format,
        )

        emit('core.person.exported', request=request, event=event)

        return csv_response(event,
                            AccommodationInformation,
                            accommodees,
                            filename=filename,
                            dialect=CSV_EXPORT_FORMATS[format])
    elif format == 'screen':
        filters = [(limit_group_id == lg.id, lg)
                   for lg in LimitGroup.objects.filter(
                       event=event,
                       product__requires_accommodation_information=True,
                   ).distinct()]

        vars.update(
            accommodees=accommodees,
            active_filter=active_filter,
            filters=filters,
        )

        return render(request, 'tickets_admin_accommodation_view.pug', vars)
    else:
        raise NotImplementedError(format)
Пример #17
0
def tickets_admin_order_view(request, vars, event, order_id):
    order = get_object_or_404(Order, id=int(order_id), event=event)

    customer_form = initialize_form(
        CustomerForm,
        request,
        instance=order.customer,
        prefix='customer',
    )

    order_form = initialize_form(
        AdminOrderForm,
        request,
        instance=order,
        prefix='order',
        readonly=True,
    )

    order_product_forms = OrderProductForm.get_for_order(request,
                                                         order,
                                                         admin=True)

    can_mark_paid = order.is_confirmed and not order.is_paid and not order.is_cancelled
    can_resend = order.is_confirmed and order.is_paid and not order.is_cancelled
    can_cancel = order.is_confirmed and not order.is_cancelled
    can_uncancel = order.is_cancelled

    if request.method == 'POST':
        if customer_form.is_valid() and all(
                form.fields['count'].widget.attrs.get('readonly', False)
                or form.is_valid() for form in order_product_forms):

            def save():
                customer_form.save()
                for form in order_product_forms:
                    if form.fields['count'].widget.attrs.get(
                            'readonly', False):
                        continue

                    form.save()

                order.clean_up_order_products()

            if 'cancel' in request.POST and can_cancel:
                save()
                order.cancel()
                messages.success(request, 'Tilaus peruutettiin.')
                return redirect('tickets_admin_order_view', event.slug,
                                order.pk)

            elif 'uncancel' in request.POST and can_uncancel:
                save()
                order.uncancel()
                messages.success(request, 'Tilaus palautettiin.')
                return redirect('tickets_admin_order_view', event.slug,
                                order.pk)

            elif 'mark-paid' in request.POST and can_mark_paid:
                save()
                order.confirm_payment()
                messages.success(request, 'Tilaus merkittiin maksetuksi.')
                return redirect('tickets_admin_order_view', event.slug,
                                order.pk)

            elif 'resend-confirmation' in request.POST and can_resend:
                save()
                order.send_confirmation_message('payment_confirmation')
                messages.success(request,
                                 'Vahvistusviesti lähetettiin uudelleen.')
                return redirect('tickets_admin_order_view', event.slug,
                                order.pk)

            elif 'save' in request.POST:
                save()
                messages.success(request, 'Muutokset tallennettiin.')

            else:
                messages.error(request, 'Tuntematon tai kielletty toiminto.')
        else:
            messages.error(request, 'Ole hyvä ja tarkista lomake.')

    vars.update(
        order=order,
        customer_form=customer_form,
        order_form=order_form,
        can_cancel=can_cancel,
        can_mark_paid=can_mark_paid,
        can_resend=can_resend,
        can_uncancel=can_uncancel,

        # XXX due to template being shared with public view, needs to be named "form"
        form=order_product_forms,
    )

    # Slightly abusing the core.person.view entry type as there is no Person.
    # But the context field provides enough clue.
    emit('core.person.viewed', request=request, event=event)

    return render(request, 'tickets_admin_order_view.pug', vars)
Пример #18
0
def membership_admin_members_view(request, vars, organization, format='screen'):
    memberships = organization.memberships.all().select_related('person')
    num_all_members = memberships.count()

    state_filters = Filter(request, 'state').add_choices('state', STATE_CHOICES)
    memberships = state_filters.filter_queryset(memberships)

    filter_active = any(f.selected_slug != f.default for f in [
        state_filters,
    ])

    memberships = memberships.order_by('person__surname', 'person__official_first_names')

    if request.method == 'POST' and state_filters.selected_slug == 'approval':
        # PLEASE DON'T: locally cached objects do not get updated and apply_state does not do the needful
        # memberships.update(state='in_effect')

        # TODO encap in Membership
        for membership in memberships:
            membership.state = 'in_effect'
            membership.save()
            membership.apply_state()

        messages.success(request, 'Hyväksyntää odottavat jäsenhakemukset hyväksyttiin.')
        return redirect('membership_admin_members_view', organization.slug)

    export_type = state_filters.selected_slug or 'all'
    export_type_verbose = EXPORT_TYPE_VERBOSE[export_type]

    title = '{organization.name} – {export_type_verbose}'.format(
        organization=organization,
        export_type_verbose=export_type_verbose,
    )

    vars.update(
        show_approve_all_button=state_filters.selected_slug == 'approval',
        memberships=memberships,
        num_members=memberships.count(),
        num_all_members=num_all_members,
        state_filters=state_filters,
        filter_active=filter_active,
        css_to_show_filter_panel='in' if filter_active else '',
        export_formats=EXPORT_FORMATS,
        now=now(),
        title=title,
    )

    if format in HTML_TEMPLATES:
        return render(request, HTML_TEMPLATES[format], vars)
    elif format in CSV_EXPORT_FORMATS:
        filename = "{organization.slug}_members_{timestamp}.{format}".format(
            organization=organization,
            timestamp=now().strftime('%Y%m%d%H%M%S'),
            format=format,
        )

        emit('core.person.exported', request=request, organization=organization)

        return csv_response(organization, Membership, memberships,
            dialect=format,
            filename=filename,
            m2m_mode='separate_columns',
        )
    else:
        raise NotImplementedError(format)
Пример #19
0
def membership_admin_members_view(request,
                                  vars,
                                  organization,
                                  format='screen'):
    memberships = organization.memberships.all().select_related('person')
    num_all_members = memberships.count()

    state_filters = Filter(request,
                           'state').add_choices('state', STATE_CHOICES)
    memberships = state_filters.filter_queryset(memberships)

    filter_active = any(f.selected_slug != f.default for f in [
        state_filters,
    ])

    memberships = memberships.order_by('person__surname',
                                       'person__official_first_names')

    if request.method == 'POST' and state_filters.selected_slug == 'approval':
        # PLEASE DON'T: locally cached objects do not get updated and apply_state does not do the needful
        # memberships.update(state='in_effect')

        # TODO encap in Membership
        for membership in memberships:
            membership.state = 'in_effect'
            membership.save()
            membership.apply_state()

        messages.success(
            request, 'Hyväksyntää odottavat jäsenhakemukset hyväksyttiin.')
        return redirect('membership_admin_members_view', organization.slug)

    export_type = state_filters.selected_slug or 'all'
    export_type_verbose = EXPORT_TYPE_VERBOSE[export_type]

    title = '{organization.name} – {export_type_verbose}'.format(
        organization=organization,
        export_type_verbose=export_type_verbose,
    )

    vars.update(
        show_approve_all_button=state_filters.selected_slug == 'approval',
        memberships=memberships,
        num_members=memberships.count(),
        num_all_members=num_all_members,
        state_filters=state_filters,
        filter_active=filter_active,
        css_to_show_filter_panel='in' if filter_active else '',
        export_formats=EXPORT_FORMATS,
        now=now(),
        title=title,
    )

    if format in HTML_TEMPLATES:
        return render(request, HTML_TEMPLATES[format], vars)
    elif format in CSV_EXPORT_FORMATS:
        filename = "{organization.slug}_members_{timestamp}.{format}".format(
            organization=organization,
            timestamp=now().strftime('%Y%m%d%H%M%S'),
            format=format,
        )

        emit('core.person.exported',
             request=request,
             organization=organization)

        return csv_response(
            organization,
            Membership,
            memberships,
            dialect=format,
            filename=filename,
            m2m_mode='separate_columns',
        )
    else:
        raise NotImplementedError(format)
Пример #20
0
def actual_labour_signup_view(request, event, alternative_form_slug):
    vars = page_wizard_vars(request)

    signup = event.labour_event_meta.get_signup_for_person(request.user.person)

    if alternative_form_slug is not None:
        # Alternative signup form specified via URL

        alternative_signup_form = get_object_or_404(AlternativeSignupForm, event=event, slug=alternative_form_slug)

        if (
            signup.alternative_signup_form_used is not None and \
            signup.alternative_signup_form_used.pk != alternative_signup_form.pk
        ):
            messages.error(request, _('Your application has not been submitted using this form.'))
            return redirect('core_event_view', event.slug)
    elif signup.pk is not None and signup.alternative_signup_form_used is not None:
        # Alternative signup form used to sign up
        alternative_signup_form = signup.alternative_signup_form_used
    else:
        # Use default signup form
        alternative_signup_form = None

    if alternative_signup_form is not None:
        # Using an alternative signup form

        if not alternative_signup_form.is_active:
            messages.error(request, _('The signup form you have requested is not currently active.'))
            return redirect('core_event_view', event.slug)

        if alternative_signup_form.signup_message:
            messages.warning(request, alternative_signup_form.signup_message)

        SignupFormClass = alternative_signup_form.signup_form_class
        SignupExtraFormClass = alternative_signup_form.signup_extra_form_class
    else:
        # Using default signup form

        if not event.labour_event_meta.is_registration_open:
            messages.error(request, _('This event is not currently accepting applications.'))
            return redirect('core_event_view', event.slug)

        if event.labour_event_meta.signup_message:
            messages.warning(request, event.labour_event_meta.signup_message)

        SignupFormClass = None
        SignupExtraFormClass = None

    if signup.is_processed:
        messages.error(request, _(
            'Your application has already been processed, so you can no longer edit it. '
            'Please contact the volunteer coordinator for any further changes.'
        ))
        return redirect('core_event_view', event.slug)

    if signup.pk is not None:
        old_state = signup.state
        submit_text = _('Update application')
    else:
        old_state = None
        submit_text = _('Submit application')

    signup_extra = signup.signup_extra
    signup_form, signup_extra_form = initialize_signup_forms(request, event, signup,
        SignupFormClass=SignupFormClass,
        SignupExtraFormClass=SignupExtraFormClass,
    )

    if request.method == 'POST':
        if signup_form.is_valid() and signup_extra_form.is_valid():
            if signup.pk is None:
                message = _('Thank you for your application!')
                event_type = 'labour.signup.created'
            else:
                message = _('Your application has been updated.')
                event_type = 'labour.signup.updated'

            if alternative_signup_form is not None:
                signup.alternative_signup_form_used = alternative_signup_form

                set_attrs(signup, **signup_form.get_excluded_field_defaults())
                set_attrs(signup_extra, **signup_extra_form.get_excluded_field_defaults())

            with transaction.atomic():
                signup = signup_form.save()

                signup_extra.signup = signup
                signup_extra = signup_extra_form.save()

                if alternative_signup_form is not None:
                    # Save m2m field defaults
                    for obj, form in [
                        (signup, signup_form),
                        (signup_extra, signup_extra_form),
                    ]:
                        defaults = form.get_excluded_m2m_field_defaults() or {}
                        for key, values in defaults.items():
                            getattr(obj, key).set(values)

            emit(event_type, request=request, person=request.user.person, event=event)

            signup.apply_state()

            messages.success(request, message)
            return redirect('core_event_view', event.slug)
        else:
            messages.error(request, _('Please check the form.'))

    available_job_categories = signup_form.get_job_categories(event=event)
    all_job_categories = JobCategory.objects.filter(event=event)

    # FIXME use id and data attr instead of category name
    non_qualified_category_names = [
        jc.name for jc in available_job_categories
        if not jc.is_person_qualified(request.user.person)
    ]

    vars.update(
        alternative_signup_form=alternative_signup_form,
        event=event,
        signup_extra_form=signup_extra_form,
        signup_form=signup_form,
        signup=signup,
        submit_text=submit_text,

        # XXX HACK descriptions injected using javascript
        job_descriptions_json=json.dumps(dict((cat.pk, cat.description) for cat in all_job_categories)),
        non_qualified_category_names_json=json.dumps(non_qualified_category_names),
    )

    return render(request, 'labour_signup_view.pug', vars)
Пример #21
0
def labour_admin_signups_view(request, vars, event, format='screen'):
    meta = event.labour_event_meta
    SignupClass = SignupCertificateProxy if format == 'html' else Signup
    SignupExtra = meta.signup_extra_model
    signups = SignupClass.objects.filter(event=event)
    signups = signups.select_related('person').select_related('event')
    signups = signups.prefetch_related('job_categories').prefetch_related('job_categories_accepted')

    if format in HTML_TEMPLATES:
        num_all_signups = signups.count()

    job_categories = event.jobcategory_set.all()
    personnel_classes = event.personnelclass_set.filter(app_label='labour')

    job_category_filters = Filter(request, "job_category").add_objects("job_categories__slug", job_categories)
    signups = job_category_filters.filter_queryset(signups)
    job_category_accepted_filters = Filter(request, "job_category_accepted").add_objects("job_categories_accepted__slug", job_categories)
    signups = job_category_accepted_filters.filter_queryset(signups)
    personnel_class_filters = Filter(request, "personnel_class").add_objects("personnel_classes__slug", personnel_classes)
    signups = personnel_class_filters.filter_queryset(signups)

    state_filter = SignupStateFilter(request, "state")
    signups = state_filter.filter_queryset(signups)

    if SignupExtra.get_field('night_work'):
        night_work_path = '{prefix}{app_label}_signup_extra__night_work'.format(
            prefix='person__' if SignupExtra.schema_version >= 2 else '',
            app_label=SignupExtra._meta.app_label
        )
        night_work_filter = Filter(request, 'night_work').add_booleans(night_work_path)
        signups = night_work_filter.filter_queryset(signups)
    else:
        night_work_filter = None

    sorter = Sorter(request, "sort")
    sorter.add("name", name='Sukunimi, Etunimi', definition=('person__surname', 'person__first_name'))
    sorter.add("newest", name='Uusin ensin', definition=('-created_at',))
    sorter.add("oldest", name='Vanhin ensin', definition=('created_at',))
    signups = sorter.order_queryset(signups)

    if request.method == 'POST':
        action = request.POST.get('action', None)
        if action == 'reject':
            SignupClass.mass_reject(signups)
        elif action == 'request_confirmation':
            SignupClass.mass_request_confirmation(signups)
        elif action == 'send_shifts':
            SignupClass.mass_send_shifts(signups)
        else:
            messages.error(request, 'Ei semmosta toimintoa oo.')

        return redirect('labour_admin_signups_view', event.slug)

    elif format in HTML_TEMPLATES:
        num_would_mass_reject = signups.filter(**SignupClass.get_state_query_params('new')).count()
        num_would_mass_request_confirmation = signups.filter(**SignupClass.get_state_query_params('accepted')).count()
        num_would_send_shifts = SignupClass.filter_signups_for_mass_send_shifts(signups).count()

        mass_operations = OrderedDict([
            ('reject', MassOperation(
                'reject',
                'labour-admin-mass-reject-modal',
                'Hylkää kaikki käsittelemättömät...',
                num_would_mass_reject,
            )),
            ('request_confirmation', MassOperation(
                'request_confirmation',
                'labour-admin-mass-request-confirmation-modal',
                'Vaadi vahvistusta kaikilta hyväksytyiltä...',
                num_would_mass_request_confirmation,
            )),
            ('send_shifts', MassOperation(
                'send_shifts',
                'labour-admin-mass-send-shifts-modal',
                'Lähetä vuorot kaikille vuoroja odottaville, joille ne on määritelty...',
                num_would_send_shifts,
            )),
        ])

        vars.update(
            export_formats=EXPORT_FORMATS,
            job_category_accepted_filters=job_category_accepted_filters,
            job_category_filters=job_category_filters,
            mass_operations=mass_operations,
            night_work_filter=night_work_filter,
            num_all_signups=num_all_signups,
            num_signups=signups.count(),
            personnel_class_filters=personnel_class_filters,
            signups=signups,
            sorter=sorter,
            state_filter=state_filter,
            css_to_show_filter_panel='in' if any(f.selected_slug != f.default for f in [
                job_category_filters,
                job_category_accepted_filters,
                personnel_class_filters,
                state_filter,
                sorter,
            ]) else '',
            now=now(),
        )

        html_template = HTML_TEMPLATES[format]

        return render(request, html_template, vars)
    elif format in CSV_EXPORT_FORMATS:
        filename = "{event.slug}_signups_{timestamp}.{format}".format(
            event=event,
            timestamp=now().strftime('%Y%m%d%H%M%S'),
            format=format,
        )

        emit('core.person.exported', request=request, event=event)

        return csv_response(event, SignupClass, signups,
            dialect=CSV_EXPORT_FORMATS[format],
            filename=filename,
            m2m_mode='separate_columns',
        )
    else:
        raise NotImplementedError(format)
def programme_admin_organizers_view(request, vars, event, format='screen'):
    programme_roles = (
        ProgrammeRole.objects.filter(programme__category__event=event)
        .select_related('person')
        .select_related('programme')
        .select_related('role')
        .order_by('person__surname', 'person__first_name', 'programme__title')
    )

    personnel_classes = PersonnelClass.objects.filter(
        event=event,
        role__personnel_class__event=event,
    )
    personnel_class_filters = Filter(request, 'personnel_class')
    personnel_class_filters.add_objects('role__personnel_class__slug', personnel_classes)
    programme_roles = personnel_class_filters.filter_queryset(programme_roles)

    roles = Role.objects.filter(personnel_class__event=event)
    role_filters = Filter(request, 'role')
    role_filters.add_objects('role__slug', roles)
    programme_roles = role_filters.filter_queryset(programme_roles)

    forms = AlternativeProgrammeForm.objects.filter(event=event)
    form_filters = Filter(request, 'form')
    form_filters.add_objects('programme__form_used__slug', forms)
    programme_roles = form_filters.filter_queryset(programme_roles)

    active_filters = Filter(request, 'active').add_booleans('is_active')
    programme_roles = active_filters.filter_queryset(programme_roles)

    organizers = []
    prs_by_organizer = groupby_strict(programme_roles, lambda pr: pr.person)
    for organizer, prs in prs_by_organizer:
        organizer.current_event_programme_roles = prs
        organizers.append(organizer)

    vars.update(
        active_filters=active_filters,
        export_formats=EXPORT_FORMATS,
        form_filters=form_filters,
        num_organizers=len(organizers),
        num_total_organizers=Person.objects.filter(programme__category__event=event).distinct().count(),
        organizers=organizers,
        personnel_class_filters=personnel_class_filters,
        role_filters=role_filters,
    )

    if format == 'screen':
        return render(request, 'programme_admin_organizers_view.pug', vars)
    elif format == 'txt':
        emails = '\n'.join(programme_roles.order_by('person__email').values_list('person__email', flat=True).distinct())
        emit('core.person.exported', request=request, event=event)
        return HttpResponse(emails, content_type='text/plain')
    elif format in CSV_EXPORT_FORMATS:
        filename = "{event.slug}_programme_organizers_{timestamp}.{format}".format(
            event=event,
            timestamp=now().strftime('%Y%m%d%H%M%S'),
            format=format,
        )

        emit('core.person.exported', request=request, event=event)

        return csv_response(event, ProgrammeRole, programme_roles,
            dialect=CSV_EXPORT_FORMATS[format],
            filename=filename,
            m2m_mode='separate_columns',
        )
    else:
        raise NotImplementedError(format)
Пример #23
0
def tickets_admin_order_view(request, vars, event, order_id):
    order = get_object_or_404(Order, id=int(order_id), event=event)

    customer_form = initialize_form(CustomerForm, request,
        instance=order.customer,
        prefix='customer',
    )

    order_form = initialize_form(AdminOrderForm, request,
        instance=order,
        prefix='order',
        readonly=True,
    )

    order_product_forms = OrderProductForm.get_for_order(request, order, admin=True)

    can_mark_paid = order.is_confirmed and not order.is_paid and not order.is_cancelled
    can_resend = order.is_confirmed and order.is_paid and not order.is_cancelled
    can_cancel = order.is_confirmed and not order.is_cancelled
    can_uncancel = order.is_cancelled

    if request.method == 'POST':
        if customer_form.is_valid() and all(form.fields['count'].widget.attrs.get('readonly', False) or form.is_valid() for form in order_product_forms):
            def save():
                customer_form.save()
                for form in order_product_forms:
                    if form.fields['count'].widget.attrs.get('readonly', False):
                        continue

                    form.save()

                order.clean_up_order_products()

            if 'cancel' in request.POST and can_cancel:
                save()
                order.cancel()
                messages.success(request, 'Tilaus peruutettiin.')
                return redirect('tickets_admin_order_view', event.slug, order.pk)

            elif 'uncancel' in request.POST and can_uncancel:
                save()
                order.uncancel()
                messages.success(request, 'Tilaus palautettiin.')
                return redirect('tickets_admin_order_view', event.slug, order.pk)

            elif 'mark-paid' in request.POST and can_mark_paid:
                save()
                order.confirm_payment()
                messages.success(request, 'Tilaus merkittiin maksetuksi.')
                return redirect('tickets_admin_order_view', event.slug, order.pk)

            elif 'resend-confirmation' in request.POST and can_resend:
                save()
                order.send_confirmation_message('payment_confirmation')
                messages.success(request, 'Vahvistusviesti lähetettiin uudelleen.')
                return redirect('tickets_admin_order_view', event.slug, order.pk)

            elif 'save' in request.POST:
                save()
                messages.success(request, 'Muutokset tallennettiin.')

            else:
                messages.error(request, 'Tuntematon tai kielletty toiminto.')
        else:
            messages.error(request, 'Ole hyvä ja tarkista lomake.')

    vars.update(
        order=order,

        customer_form=customer_form,
        order_form=order_form,

        can_cancel=can_cancel,
        can_mark_paid=can_mark_paid,
        can_resend=can_resend,
        can_uncancel=can_uncancel,

        # XXX due to template being shared with public view, needs to be named "form"
        form=order_product_forms,
    )

    # Slightly abusing the core.person.view entry type as there is no Person.
    # But the context field provides enough clue.
    emit('core.person.viewed', request=request, event=event)

    return render(request, 'tickets_admin_order_view.pug', vars)
Пример #24
0
def admin_organizers_view(request, vars, event, format='screen'):
    programme_roles = (
        ProgrammeRole.objects.filter(
            programme__category__event=event).select_related('person').
        select_related('programme').select_related('role').order_by(
            'person__surname', 'person__first_name', 'programme__title'))

    personnel_classes = PersonnelClass.objects.filter(
        event=event,
        role__personnel_class__event=event,
    )
    personnel_class_filters = Filter(request, 'personnel_class')
    personnel_class_filters.add_objects('role__personnel_class__slug',
                                        personnel_classes)
    programme_roles = personnel_class_filters.filter_queryset(programme_roles)

    roles = Role.objects.filter(personnel_class__event=event)
    role_filters = Filter(request, 'role')
    role_filters.add_objects('role__slug', roles)
    programme_roles = role_filters.filter_queryset(programme_roles)

    forms = AlternativeProgrammeForm.objects.filter(event=event)
    form_filters = Filter(request, 'form')
    form_filters.add_objects('programme__form_used__slug', forms)
    programme_roles = form_filters.filter_queryset(programme_roles)

    active_filters = Filter(request, 'active').add_booleans('is_active')
    programme_roles = active_filters.filter_queryset(programme_roles)

    organizers = []
    prs_by_organizer = groupby_strict(programme_roles, lambda pr: pr.person)
    for organizer, prs in prs_by_organizer:
        organizer.current_event_programme_roles = prs
        organizers.append(organizer)

    vars.update(
        active_filters=active_filters,
        export_formats=EXPORT_FORMATS,
        form_filters=form_filters,
        num_organizers=len(organizers),
        num_total_organizers=Person.objects.filter(
            programme__category__event=event).distinct().count(),
        organizers=organizers,
        personnel_class_filters=personnel_class_filters,
        role_filters=role_filters,
    )

    if format == 'screen':
        return render(request, 'programme_admin_organizers_view.pug', vars)
    elif format == 'txt':
        emails = '\n'.join(
            programme_roles.order_by('person__email').values_list(
                'person__email', flat=True).distinct())
        emit('core.person.exported', request=request, event=event)
        return HttpResponse(emails, content_type='text/plain')
    elif format in CSV_EXPORT_FORMATS:
        filename = "{event.slug}_programme_organizers_{timestamp}.{format}".format(
            event=event,
            timestamp=now().strftime('%Y%m%d%H%M%S'),
            format=format,
        )

        emit('core.person.exported', request=request, event=event)

        return csv_response(
            event,
            ProgrammeRole,
            programme_roles,
            dialect=CSV_EXPORT_FORMATS[format],
            filename=filename,
            m2m_mode='separate_columns',
        )
    else:
        raise NotImplementedError(format)
Пример #25
0
def labour_admin_signups_view(request, vars, event, format='screen'):
    meta = event.labour_event_meta
    SignupClass = SignupCertificateProxy if format == 'html' else Signup
    SignupExtra = meta.signup_extra_model
    signups = SignupClass.objects.filter(event=event)
    signups = signups.select_related('person').select_related('event')
    signups = signups.prefetch_related('job_categories').prefetch_related(
        'job_categories_accepted')

    if format in HTML_TEMPLATES:
        num_all_signups = signups.count()

    job_categories = event.jobcategory_set.all()
    personnel_classes = event.personnelclass_set.filter(app_label='labour')

    job_category_filters = Filter(request, "job_category").add_objects(
        "job_categories__slug", job_categories)
    signups = job_category_filters.filter_queryset(signups)
    job_category_accepted_filters = Filter(
        request,
        "job_category_accepted").add_objects("job_categories_accepted__slug",
                                             job_categories)
    signups = job_category_accepted_filters.filter_queryset(signups)
    personnel_class_filters = Filter(request, "personnel_class").add_objects(
        "personnel_classes__slug", personnel_classes)
    signups = personnel_class_filters.filter_queryset(signups)

    state_filter = SignupStateFilter(request, "state")
    signups = state_filter.filter_queryset(signups)

    if SignupExtra.get_field('night_work'):
        night_work_path = '{prefix}{app_label}_signup_extra__night_work'.format(
            prefix='person__' if SignupExtra.schema_version >= 2 else '',
            app_label=SignupExtra._meta.app_label)
        night_work_filter = Filter(request,
                                   'night_work').add_booleans(night_work_path)
        signups = night_work_filter.filter_queryset(signups)
    else:
        night_work_filter = None

    sorter = Sorter(request, "sort")
    sorter.add("name",
               name='Sukunimi, Etunimi',
               definition=('person__surname', 'person__first_name'))
    sorter.add("newest", name='Uusin ensin', definition=('-created_at', ))
    sorter.add("oldest", name='Vanhin ensin', definition=('created_at', ))
    signups = sorter.order_queryset(signups)

    if request.method == 'POST':
        action = request.POST.get('action', None)
        if action == 'reject':
            SignupClass.mass_reject(signups)
        elif action == 'request_confirmation':
            SignupClass.mass_request_confirmation(signups)
        elif action == 'send_shifts':
            SignupClass.mass_send_shifts(signups)
        else:
            messages.error(request, 'Ei semmosta toimintoa oo.')

        return redirect('labour_admin_signups_view', event.slug)

    elif format in HTML_TEMPLATES:
        num_would_mass_reject = signups.filter(
            **SignupClass.get_state_query_params('new')).count()
        num_would_mass_request_confirmation = signups.filter(
            **SignupClass.get_state_query_params('accepted')).count()
        num_would_send_shifts = SignupClass.filter_signups_for_mass_send_shifts(
            signups).count()

        mass_operations = OrderedDict([
            ('reject',
             MassOperation(
                 'reject',
                 'labour-admin-mass-reject-modal',
                 'Hylkää kaikki käsittelemättömät...',
                 num_would_mass_reject,
             )),
            ('request_confirmation',
             MassOperation(
                 'request_confirmation',
                 'labour-admin-mass-request-confirmation-modal',
                 'Vaadi vahvistusta kaikilta hyväksytyiltä...',
                 num_would_mass_request_confirmation,
             )),
            ('send_shifts',
             MassOperation(
                 'send_shifts',
                 'labour-admin-mass-send-shifts-modal',
                 'Lähetä vuorot kaikille vuoroja odottaville, joille ne on määritelty...',
                 num_would_send_shifts,
             )),
        ])

        vars.update(
            export_formats=EXPORT_FORMATS,
            job_category_accepted_filters=job_category_accepted_filters,
            job_category_filters=job_category_filters,
            mass_operations=mass_operations,
            night_work_filter=night_work_filter,
            num_all_signups=num_all_signups,
            num_signups=signups.count(),
            personnel_class_filters=personnel_class_filters,
            signups=signups,
            sorter=sorter,
            state_filter=state_filter,
            css_to_show_filter_panel='in' if any(
                f.selected_slug != f.default for f in [
                    job_category_filters,
                    job_category_accepted_filters,
                    personnel_class_filters,
                    state_filter,
                    sorter,
                ]) else '',
            now=now(),
        )

        html_template = HTML_TEMPLATES[format]

        return render(request, html_template, vars)
    elif format in CSV_EXPORT_FORMATS:
        filename = "{event.slug}_signups_{timestamp}.{format}".format(
            event=event,
            timestamp=now().strftime('%Y%m%d%H%M%S'),
            format=format,
        )

        emit('core.person.exported', request=request, event=event)

        return csv_response(
            event,
            SignupClass,
            signups,
            dialect=CSV_EXPORT_FORMATS[format],
            filename=filename,
            m2m_mode='separate_columns',
        )
    else:
        raise NotImplementedError(format)