From 0e4b67afd0be3973b2bbef2bec47ab712ddbafa3 Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Thu, 15 Feb 2018 17:02:48 +0000
Subject: [PATCH] Basic setup for rendering the user's response

---
 .../0020_applicationsubmission_form_fields.py | 25 +++++++++++++++++++
 opentech/apply/funds/models.py                | 20 +++++++++++++++
 .../funds/applicationsubmission_detail.html   |  4 +--
 .../funds/includes/submission_field.html      |  4 +++
 .../tests/test_question_serialisation.py      | 19 ++++++++++++++
 5 files changed, 70 insertions(+), 2 deletions(-)
 create mode 100644 opentech/apply/funds/migrations/0020_applicationsubmission_form_fields.py
 create mode 100644 opentech/apply/funds/templates/funds/includes/submission_field.html
 create mode 100644 opentech/apply/funds/tests/test_question_serialisation.py

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 000000000..1fc6aa2ca
--- /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 7a1ec0461..6b3c65f7b 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 8b90ebb51..a1ef36dcc 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 000000000..1e3ed69ee
--- /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 000000000..a4affcbf4
--- /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())
-- 
GitLab