diff --git a/opentech/apply/funds/migrations/0020_applicationsubmission_form_fields.py b/opentech/apply/funds/migrations/0020_applicationsubmission_form_fields.py new file mode 100644 index 0000000000000000000000000000000000000000..1fc6aa2ca9d5c5ee898914d6414fb36926a5d8c7 --- /dev/null +++ b/opentech/apply/funds/migrations/0020_applicationsubmission_form_fields.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.8 on 2018-02-13 15:10 +from __future__ import unicode_literals + +from django.db import migrations +import opentech.apply.categories.blocks +import wagtail.wagtailcore.blocks +import wagtail.wagtailcore.blocks.static_block +import wagtail.wagtailcore.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('funds', '0019_protect_submission'), + ] + + operations = [ + migrations.AddField( + model_name='applicationsubmission', + name='form_fields', + field=wagtail.wagtailcore.fields.StreamField((('text_markup', wagtail.wagtailcore.blocks.RichTextBlock(group='Other', label='Paragraph')), ('char', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('format', wagtail.wagtailcore.blocks.ChoiceBlock(choices=[('email', 'Email'), ('url', 'URL')], label='Format', required=False)), ('default_value', wagtail.wagtailcore.blocks.CharBlock(label='Default value', required=False))), group='Fields')), ('text', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.TextBlock(label='Default value', required=False))), group='Fields')), ('number', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.CharBlock(label='Default value', required=False))), group='Fields')), ('checkbox', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('default_value', wagtail.wagtailcore.blocks.BooleanBlock(required=False))), group='Fields')), ('radios', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.CharBlock(label='Choice')))), group='Fields')), ('dropdown', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.CharBlock(label='Choice')))), group='Fields')), ('checkboxes', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('checkboxes', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.CharBlock(label='Checkbox')))), group='Fields')), ('date', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.DateBlock(required=False))), group='Fields')), ('time', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.TimeBlock(required=False))), group='Fields')), ('datetime', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.DateTimeBlock(required=False))), group='Fields')), ('image', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False))), group='Fields')), ('file', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False))), group='Fields')), ('rich_text', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.TextBlock(label='Default value', required=False))), group='Fields')), ('category', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(help_text='Leave blank to use the default Category label', label='Label', required=False)), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Leave blank to use the default Category help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('category', opentech.apply.categories.blocks.ModelChooserBlock('categories.Category')), ('multi', wagtail.wagtailcore.blocks.BooleanBlock(label='Multi select', required=False))), group='Custom')), ('title', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('info', wagtail.wagtailcore.blocks.static_block.StaticBlock())), group='Required')), ('value', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('info', wagtail.wagtailcore.blocks.static_block.StaticBlock())), group='Required')), ('email', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('info', wagtail.wagtailcore.blocks.static_block.StaticBlock())), group='Required')), ('address', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('info', wagtail.wagtailcore.blocks.static_block.StaticBlock())), group='Required')), ('full_name', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('info', wagtail.wagtailcore.blocks.static_block.StaticBlock())), group='Required'))), default=[]), + preserve_default=False, + ), + ] diff --git a/opentech/apply/funds/models.py b/opentech/apply/funds/models.py index 7a1ec0461e3d517d13358d44d33c28a5faf43590..6b3c65f7b0aca45cebca9a9a05b84df06ff903c7 100644 --- a/opentech/apply/funds/models.py +++ b/opentech/apply/funds/models.py @@ -84,6 +84,7 @@ class SubmittableStreamForm(AbstractStreamForm): return self.get_submission_class().objects.create( form_data=cleaned_data, + form_fields=self.get_defined_fields(), **self.get_submit_meta_data(user=user), ) @@ -439,7 +440,10 @@ class JSONOrderable(models.QuerySet): class ApplicationSubmission(WorkflowHelpers, AbstractFormSubmission): + field_template = 'funds/includes/submission_field.html' + form_data = JSONField(encoder=DjangoJSONEncoder) + form_fields = StreamField(CustomFormFieldsBlock()) page = models.ForeignKey('wagtailcore.Page', on_delete=models.PROTECT) round = models.ForeignKey('wagtailcore.Page', on_delete=models.PROTECT, related_name='submissions', null=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True) @@ -473,6 +477,22 @@ class ApplicationSubmission(WorkflowHelpers, AbstractFormSubmission): return super().save(*args, **kwargs) + def render(self): + text = list() + for field in self.form_fields: + try: + data = self.form_data[field.id] + except KeyError: + pass # It was a named field or a paragraph + else: + form_field = field.block.get_field(field.value) + context = { + 'field': form_field, + 'value': mark_safe(data), + } + text.append(render_to_string(self.field_template, context)) + return mark_safe(''.join(text)) + def get_data(self): # Updated for JSONField form_data = self.form_data diff --git a/opentech/apply/funds/templates/funds/applicationsubmission_detail.html b/opentech/apply/funds/templates/funds/applicationsubmission_detail.html index 8b90ebb51d5ba9991ecc19deae91ab24e761ceb2..a1ef36dcc465cb62d9aa329edc7e544831745530 100644 --- a/opentech/apply/funds/templates/funds/applicationsubmission_detail.html +++ b/opentech/apply/funds/templates/funds/applicationsubmission_detail.html @@ -15,12 +15,12 @@ <h2>Proposal Information</h2> <div> Requested Funding {{ object.value }} - Project Duration{{ object.value }} + Project Duration {{ object.value }} Legal Name {{ object.full_name }} Email {{ object.email }} </div> <div> - {{ object.form_data }} + {{ object.render }} </div> </div> <div> diff --git a/opentech/apply/funds/templates/funds/includes/submission_field.html b/opentech/apply/funds/templates/funds/includes/submission_field.html new file mode 100644 index 0000000000000000000000000000000000000000..1e3ed69ee2aefba197b24d5a027b670055df1ea2 --- /dev/null +++ b/opentech/apply/funds/templates/funds/includes/submission_field.html @@ -0,0 +1,4 @@ +<div> + <h5>{{ field.label }}</h5> + <div>{{ value }}</div> +</div> diff --git a/opentech/apply/funds/tests/test_question_serialisation.py b/opentech/apply/funds/tests/test_question_serialisation.py new file mode 100644 index 0000000000000000000000000000000000000000..a4affcbf41e732792b83a5b218fa3ca7b27fe30f --- /dev/null +++ b/opentech/apply/funds/tests/test_question_serialisation.py @@ -0,0 +1,19 @@ +from django.test import TestCase + +from .factories import ApplicationFormFactory, FundTypeFactory, RoundFactory, RoundFormFactory + + +class TestSerialisationQuestions(TestCase): + def setUp(self): + application_form = { + 'form_fields__0__email__': '', + 'form_fields__1__full_name__': '', + } + form = ApplicationFormFactory(**application_form) + fund = FundTypeFactory() + + self.round_page = RoundFactory(parent=fund) + RoundFormFactory(round=self.round_page, form=form) + + def test_convet_to_json(self): + print(self.round_page.serialise_form())