Source code for org.views.survey_definition

import morepath

from webob.exc import HTTPForbidden

from onegov.core.security import Private, Public
from onegov.core.utils import normalize_for_url
from onegov.form.collection import SurveyCollection
from onegov.form.models.definition import SurveyDefinition
from onegov.form.models.submission import SurveySubmission
from onegov.gis import Coordinates
from onegov.org import _, OrgApp
from onegov.core.elements import Confirm, Intercooler, Link
from onegov.org.forms.form_definition import SurveyDefinitionForm
from onegov.org.layout import (FormEditorLayout,
                               SurveySubmissionLayout)


from typing import TypeVar, TYPE_CHECKING

if TYPE_CHECKING:
    from onegov.core.types import RenderData
    from onegov.form import Form
    from onegov.org.request import OrgRequest
    from webob import Response

[docs] SurveyDefinitionT = TypeVar('SurveyDefinitionT', bound=SurveyDefinition)
@OrgApp.form( model=SurveyCollection, name='new', template='form.pt', permission=Private, form=SurveyDefinitionForm )
[docs] def handle_new_survey_definition( self: SurveyCollection, request: 'OrgRequest', form: SurveyDefinitionForm, layout: FormEditorLayout | None = None ) -> 'RenderData | Response': if form.submitted(request): assert form.title.data is not None assert form.definition.data is not None if self.definitions.by_name(normalize_for_url(form.title.data)): request.alert(_('A survey with this name already exists')) else: definition = self.definitions.add( title=form.title.data, definition=form.definition.data, ) form.populate_obj(definition) request.success(_('Added a new survey')) return morepath.redirect(request.link(definition)) layout = layout or FormEditorLayout(self, request) layout.breadcrumbs = [ Link(_('Homepage'), layout.homepage_url), Link(_('Surveys'), request.class_link(SurveyCollection)), Link(_('New Survey'), request.link(self, name='new')) ] layout.edit_mode = True return { 'layout': layout, 'title': _('New Survey'), 'form': form, 'form_width': 'large', }
@OrgApp.form( model=SurveyDefinition, template='form.pt', permission=Public, form=lambda self, request: self.form_class )
[docs] def handle_defined_survey( self: SurveyDefinition, request: 'OrgRequest', form: 'Form', layout: SurveySubmissionLayout | None = None ) -> 'RenderData | Response': """ Renders the empty survey and takes input, even if it's not valid, stores it as a pending submission and redirects the user to the view that handles pending submissions. """ collection = SurveyCollection(request.session) enabled = False hint = [('stop', _('Please choose a submission window'))] if not self.current_submission_window: enabled = True hint = [] elif not request.is_manager: raise HTTPForbidden() if enabled and request.POST: submission = collection.submissions.add( self.name, form) return morepath.redirect(request.link(submission)) layout = layout or SurveySubmissionLayout(self, request) return { 'layout': layout, 'title': self.title, 'form': enabled and form, 'definition': self, 'form_width': 'small', 'lead': layout.linkify(self.meta.get('lead')), 'text': self.text, 'people': getattr(self, 'people', None), 'files': getattr(self, 'files', None), 'contact': getattr(self, 'contact_html', None), 'coordinates': getattr(self, 'coordinates', Coordinates()), 'hints': hint, 'hints_callout': not enabled, }
@OrgApp.form( model=SurveyDefinition, template='form.pt', permission=Private, form=SurveyDefinitionForm, name='edit' )
[docs] def handle_edit_survey_definition( self: SurveyDefinition, request: 'OrgRequest', form: SurveyDefinitionForm, layout: FormEditorLayout | None = None ) -> 'RenderData | Response': info = _('This field cannot be edited because there are submissions ' 'associated with this survey. If you want to edit the definition ' 'please delete all submissions.') if self.submissions: form.definition.description = info form.definition.render_kw = { 'rows': 32, 'disabled': 'true', 'title': request.translate(info) } form.definition.validators = [] if form.submitted(request): if self.submissions: form.definition.data = self.definition assert form.definition.data is not None form.populate_obj(self) request.success(_('Your changes were saved')) return morepath.redirect(request.link(self)) elif not request.POST: form.process(obj=self) collection = SurveyCollection(request.session) layout = layout or FormEditorLayout(self, request) layout.breadcrumbs = [ Link(_('Homepage'), layout.homepage_url), Link(_('Surveys'), request.link(collection)), Link(self.title, request.link(self)), Link(_('Edit'), request.link(self, name='edit')) ] layout.edit_mode = True return { 'layout': layout, 'title': self.title, 'form': form, 'form_width': 'large', }
@OrgApp.html(model=SurveyDefinition, template='survey_results.pt', permission=Private, name='results')
[docs] def view_survey_results( self: SurveyDefinition, request: 'OrgRequest', layout: SurveySubmissionLayout | None = None ) -> 'RenderData': submissions = self.submissions results = self.get_results(request) aggregated = ['MultiCheckboxField', 'CheckboxField', 'RadioField'] form = request.get_form(self.form_class) all_fields = form._fields all_fields.pop('csrf_token', None) fields = all_fields.values() layout = layout or SurveySubmissionLayout(self, request) layout.breadcrumbs.append(Link(_('Results'), '#')) layout.editbar_links = [ Link( text=_('Export'), url=request.link(self, name='export'), attrs={'class': 'export-link'} ), Link( text=_('Delete Submissions'), url=layout.csrf_protected_url( request.link(self, name='delete-submissions')), attrs={'class': 'delete-link'}, traits=( Confirm( _( 'Do you really want to delete ' 'all submissions?' ), _('All submissions associated with this survey will be ' 'deleted.'), _('Delete submissions'), _('Cancel') ), Intercooler( request_method='DELETE', redirect_after=request.link(self) )) )] return { 'layout': layout, 'title': _('Results'), 'results': results, 'fields': fields, 'aggregated': aggregated, 'submission_count': len(submissions), 'submission_windows': self.submission_windows }
@OrgApp.view( model=SurveyDefinition, request_method='DELETE', permission=Private )
[docs] def delete_survey_definition( self: SurveyDefinition, request: 'OrgRequest' ) -> None: """ Deletes the survey along with all its submissions. """ request.assert_valid_csrf_token() SurveyCollection(request.session).definitions.delete( self.name, with_submission_windows=True, )
@OrgApp.view( model=SurveyDefinition, request_method='DELETE', name='delete-submissions', permission=Private )
[docs] def delete_survey_entries( self: SurveyDefinition, request: 'OrgRequest' ) -> None: """ Deletes all survey submissions. """ request.assert_valid_csrf_token() submissions = request.session.query(SurveySubmission) submissions = submissions.filter(SurveySubmission.name == self.name) submissions.delete()