From c32bd81b4e78345a9e7138ff769ba1ee03435fea Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Mon, 15 Jan 2018 17:30:00 +0000
Subject: [PATCH] Make the funding model abstract

---
 opentech/public/people/models.py              | 28 ++------------
 .../people/templates/people/person_page.html  | 14 +------
 .../migrations/0002_projectfunding.py         | 34 +++++++++++++++++
 opentech/public/projects/models.py            | 10 ++++-
 .../templates/projects/project_page.html      |  1 +
 opentech/public/utils/models.py               | 38 +++++++++++++++++++
 .../templates/utils/includes/funding.html     | 13 +++++++
 7 files changed, 99 insertions(+), 39 deletions(-)
 create mode 100644 opentech/public/projects/migrations/0002_projectfunding.py
 create mode 100644 opentech/public/utils/templates/utils/includes/funding.html

diff --git a/opentech/public/people/models.py b/opentech/public/people/models.py
index 04ca3f7e4..b6ca87aa2 100644
--- a/opentech/public/people/models.py
+++ b/opentech/public/people/models.py
@@ -13,13 +13,12 @@ from wagtail.wagtailadmin.edit_handlers import (
     FieldRowPanel,
     InlinePanel,
     MultiFieldPanel,
-    PageChooserPanel,
     StreamFieldPanel
 )
 from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
 
 from opentech.public.utils.blocks import StoryBlock
-from opentech.public.utils.models import BasePage
+from opentech.public.utils.models import BasePage, BaseFunding, FundingMixin
 
 
 class SocialMediaProfile(models.Model):
@@ -72,25 +71,8 @@ class PersonPagePersonType(models.Model):
         return self.person_type.title
 
 
-class Funding(Orderable):
+class Funding(BaseFunding):
     page = ParentalKey('PersonPage', related_name='funding')
-    value = models.PositiveIntegerField()
-    year = models.PositiveIntegerField()
-    duration = models.PositiveIntegerField(help_text='In months')
-    source = models.ForeignKey(
-        'wagtailcore.Page',
-        on_delete=models.PROTECT,
-    )
-
-    panels = [
-        FieldRowPanel([
-            FieldPanel('year'),
-            FieldPanel('value'),
-            FieldPanel('duration'),
-        ]),
-        # This is stubbed as we need to be able to select from multiple
-        PageChooserPanel('source'),
-    ]
 
 
 class PersonContactInfomation(Orderable):
@@ -132,7 +114,7 @@ class PersonContactInfomation(Orderable):
             })
 
 
-class PersonPage(BasePage):
+class PersonPage(FundingMixin, BasePage):
     subpage_types = []
     parent_page_types = ['PersonIndexPage']
 
@@ -170,10 +152,6 @@ class PersonPage(BasePage):
         InlinePanel('funding', label='Funding'),
     ]
 
-    @property
-    def total_funding(self):
-        return sum(funding.value for funding in self.funding.all())
-
 
 class PersonIndexPage(BasePage):
     subpage_types = ['PersonPage']
diff --git a/opentech/public/people/templates/people/person_page.html b/opentech/public/people/templates/people/person_page.html
index 342ddc2c7..93755fa58 100644
--- a/opentech/public/people/templates/people/person_page.html
+++ b/opentech/public/people/templates/people/person_page.html
@@ -52,18 +52,8 @@
                 <h3>{{ item.get_service_display }}</h3>
                 <p>{{ item.profile_url }}</p>
             {% endfor %}
-            <h2>Funding to date</h2>
-            {% for funding in page.funding.all %}
-            <table>
-                <tr>
-                    <td>{{ funding.year }}</td>
-                    <td>${{ funding.value }}</td>
-                    <td>{{ funding.duration }} months</td>
-                    <td><a href="{% pageurl funding.source %}">{{ funding.source }}</a></td>
-                </tr>
-            </table>
-            {% endfor %}
-            <p>Total Funding: {{ page.total_funding }}</p>
+
+            {% include "utils/includes/funding.html" %}
         </div>
     </section>
 
diff --git a/opentech/public/projects/migrations/0002_projectfunding.py b/opentech/public/projects/migrations/0002_projectfunding.py
new file mode 100644
index 000000000..56cd4bf2a
--- /dev/null
+++ b/opentech/public/projects/migrations/0002_projectfunding.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.8 on 2018-01-15 17:12
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import modelcluster.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('wagtailcore', '0040_page_draft_title'),
+        ('projects', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ProjectFunding',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
+                ('value', models.PositiveIntegerField()),
+                ('year', models.PositiveIntegerField()),
+                ('duration', models.PositiveIntegerField(help_text='In months')),
+                ('page', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='funding', to='projects.ProjectPage')),
+                ('source', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='wagtailcore.Page')),
+            ],
+            options={
+                'ordering': ['sort_order'],
+                'abstract': False,
+            },
+        ),
+    ]
diff --git a/opentech/public/projects/models.py b/opentech/public/projects/models.py
index 3535dc2cb..b74a31b8c 100644
--- a/opentech/public/projects/models.py
+++ b/opentech/public/projects/models.py
@@ -18,7 +18,9 @@ from wagtail.wagtailsearch import index
 
 from opentech.public.utils.blocks import StoryBlock
 from opentech.public.utils.models import (
+    BaseFunding,
     BasePage,
+    FundingMixin,
     RelatedPage,
 )
 
@@ -76,7 +78,11 @@ class ProjectPageRelatedPage(RelatedPage):
     ]
 
 
-class ProjectPage(BasePage):
+class ProjectFunding(BaseFunding):
+    page = ParentalKey('ProjectPage', related_name='funding')
+
+
+class ProjectPage(FundingMixin, BasePage):
     subpage_types = []
     parent_page_types = ['ProjectIndexPage']
 
@@ -93,7 +99,6 @@ class ProjectPage(BasePage):
     # Fields to add:
     # otf_status
     # status
-    # funding
 
     search_fields = BasePage.search_fields + [
         index.SearchField('introduction'),
@@ -106,6 +111,7 @@ class ProjectPage(BasePage):
         StreamFieldPanel('body'),
         InlinePanel('contact_details', label="Contact Details"),
         InlinePanel('related_pages', label="Related pages"),
+        InlinePanel('funding', label="Funding"),
     ]
 
 
diff --git a/opentech/public/projects/templates/projects/project_page.html b/opentech/public/projects/templates/projects/project_page.html
index a6740d230..bb064432c 100644
--- a/opentech/public/projects/templates/projects/project_page.html
+++ b/opentech/public/projects/templates/projects/project_page.html
@@ -29,5 +29,6 @@
 
         </div>
     </div>
+    {% include "utils/includes/funding.html" %}
 
 {% endblock content %}
diff --git a/opentech/public/utils/models.py b/opentech/public/utils/models.py
index 08d72f3bb..d24701745 100644
--- a/opentech/public/utils/models.py
+++ b/opentech/public/utils/models.py
@@ -3,6 +3,7 @@ from django.db import models
 
 from wagtail.wagtailadmin.edit_handlers import (
     FieldPanel,
+    FieldRowPanel,
     MultiFieldPanel,
     PageChooserPanel,
     StreamFieldPanel,
@@ -259,3 +260,40 @@ class BasePage(SocialFields, ListingFields, Page):
         SocialFields.promote_panels +
         ListingFields.promote_panels
     )
+
+
+class BaseFunding(Orderable):
+    value = models.PositiveIntegerField()
+    year = models.PositiveIntegerField()
+    duration = models.PositiveIntegerField(help_text='In months')
+    source = models.ForeignKey(
+        'wagtailcore.Page',
+        on_delete=models.PROTECT,
+    )
+
+    panels = [
+        FieldRowPanel([
+            FieldPanel('year'),
+            FieldPanel('value'),
+            FieldPanel('duration'),
+        ]),
+        # This is stubbed as we need to be able to select from multiple
+        PageChooserPanel('source'),
+    ]
+
+    class Meta(Orderable.Meta):
+        abstract = True
+
+
+class FundingMixin(models.Model):
+    '''Impliments the funding total calulation
+
+    You still need to include the InlinePanel('funding') in the child class
+    '''
+
+    class Meta:
+        abstract = True
+
+    @property
+    def total_funding(self):
+        return sum(funding.value for funding in self.funding.all())
diff --git a/opentech/public/utils/templates/utils/includes/funding.html b/opentech/public/utils/templates/utils/includes/funding.html
new file mode 100644
index 000000000..d858ce5dc
--- /dev/null
+++ b/opentech/public/utils/templates/utils/includes/funding.html
@@ -0,0 +1,13 @@
+{% load wagtailcore_tags %}
+<h2>Funding to date</h2>
+{% for funding in page.funding.all %}
+<table>
+    <tr>
+        <td>{{ funding.year }}</td>
+        <td>${{ funding.value }}</td>
+        <td>{{ funding.duration }} months</td>
+        <td><a href="{% pageurl funding.source %}">{{ funding.source }}</a></td>
+    </tr>
+</table>
+{% endfor %}
+<p>Total Funding: {{ page.total_funding }}</p>
-- 
GitLab