Repository: akvo/akvo-rsr

Issue:
Move away from upload_file end-point to /rest/v1/project end-point



Discussion:

Resolving patch:
diff --git a/akvo/rest/serializers/project_document.py b/akvo/rest/serializers/project_document.py
--- a/akvo/rest/serializers/project_document.py
+++ b/akvo/rest/serializers/project_document.py
@@ -30,6 +30,7 @@ def to_internal_value(self, data):
 
 class ProjectDocumentSerializer(ProjectDocumentRawSerializer):
 
+    document = serializers.FileField(required=False, allow_null=True)
     document_show_link = serializers.ReadOnlyField()
     language_label = serializers.ReadOnlyField(source='iati_language_unicode')
     title_language_label = serializers.ReadOnlyField(source='iati_title_language_unicode')
diff --git a/akvo/rsr/views/py_reports.py b/akvo/rsr/views/py_reports.py
--- a/akvo/rsr/views/py_reports.py
+++ b/akvo/rsr/views/py_reports.py
@@ -8,7 +8,6 @@
 """
 
 import os
-import pdfkit
 
 from akvo.rsr.models import Project, Country, Organisation
 from akvo.rsr.staticmap import get_staticmap_url, Coordinate, Size
@@ -24,16 +23,6 @@
 from weasyprint.fonts import FontConfiguration
 
 
-DEFAULT_PDF_OPTIONS = {
-    'page-size': 'A4',
-    'orientation': 'Portrait',
-    'margin-left': '0.28in',
-    'margin-top': '1in',
-    'margin-right': '0.28in',
-    'margin-bottom': '1in',
-}
-
-
 def check(request):
     is_reports_container = os.getenv('IS_REPORTS_CONTAINER', '').strip()
     is_requesting_pdf = request.GET.get('pdf', None)
@@ -72,12 +61,13 @@ def render_organisation_projects_results_indicators_map_overview(request, org_id
         Coordinate(p.primary_location.latitude, p.primary_location.longitude)
         for p
         in projects
+        if p.primary_location
     ]
 
     now = datetime.today()
 
     html = render_to_string(
-        'reports/wp-organisation-projects-results-indicators-map-overview.html',
+        'reports/organisation-projects-results-indicators-map-overview.html',
         context={
             'title': 'Results and indicators overview for projects in {}'.format(country.name),
             'staticmap': get_staticmap_url(coordinates, Size(900, 600)),
@@ -91,7 +81,7 @@ def render_organisation_projects_results_indicators_map_overview(request, org_id
                 in projects
             ],
             'show_comment': show_comment,
-            'today': now.strftime('%d-%b-%Y')
+            'today': now.strftime('%d-%b-%Y'),
         }
     )
 
@@ -101,13 +91,8 @@ def render_organisation_projects_results_indicators_map_overview(request, org_id
     filename = '{}-{}-{}-projects-results-indicators-overview.pdf'.format(
         now.strftime('%Y%b%d'), organisation.id, country.iso_code
     )
-    response = HttpResponse(content_type='application/pdf')
-    response['Content-Disposition'] = 'attachment; filename="' + filename + '"'
 
-    font_config = FontConfiguration()
-    HTML(string=html).write_pdf(response, font_config=font_config)
-
-    return response
+    return _make_pdf_response(html, filename)
 
 
 @login_required
@@ -134,42 +119,39 @@ def render_project_results_indicators_map_overview(request, project_id):
     if project.children().count():
         for child in project.children_all().published():
             locations.append(child.primary_location)
-    coordinates = [Coordinate(l.latitude, l.longitude) for l in locations]
+    coordinates = [Coordinate(l.latitude, l.longitude) for l in locations if l]
+
+    now = datetime.today()
 
     html = render_to_string(
         'reports/project-results-indicators-map-overview.html',
         context={
             'project': project,
-            'location': ", ".join([_f for _f in [project_location.city, getattr(project_location.country, 'name', None)] if _f]),
+            'location': ", ".join([
+                _f
+                for _f
+                in [project_location.city, getattr(project_location.country, 'name', None)]
+                if _f
+            ]),
             'staticmap': get_staticmap_url(coordinates, Size(900, 600)),
             'results': _transform_project_results(project, start_date, end_date),
             'show_comment': show_comment,
+            'today': now.strftime('%d-%b-%Y'),
         }
     )
 
     if request.GET.get('show-html', ''):
         return HttpResponse(html)
 
-    now = datetime.today()
+    filename = '{}-{}-results-indicators-overview.pdf'.format(now.strftime('%Y%b%d'), project.id)
 
-    return _make_pdf_response(
-        html,
-        options={
-            'footer-left': 'Akvo RSR Report {}'.format(now.strftime('%d-%b-%Y')),
-            'footer-right': '[page]',
-            'footer-font-size': 8,
-            'footer-font-name': 'Roboto Condensed',
-            'footer-spacing': 10,
-        },
-        filename='{}-{}-results-indicators-overview.pdf'.format(now.strftime('%Y%b%d'), project.id)
-    )
+    return _make_pdf_response(html, filename)
 
 
-def _make_pdf_response(html, options={}, filename='reports.pdf'):
-    opts = DEFAULT_PDF_OPTIONS.copy()
-    opts.update(options)
+def _make_pdf_response(html, filename='reports.pdf'):
+    font_config = FontConfiguration()
+    pdf = HTML(string=html).write_pdf(font_config=font_config)
 
-    pdf = pdfkit.from_string(html, False, options=opts)
     response = HttpResponse(pdf, content_type='application/pdf')
     response['Content-Disposition'] = 'attachment; filename="' + filename + '"'
 


Test patch:
diff --git a/akvo/rsr/tests/rest/test_project_document.py b/akvo/rsr/tests/rest/test_project_document.py
--- a/akvo/rsr/tests/rest/test_project_document.py
+++ b/akvo/rsr/tests/rest/test_project_document.py
@@ -80,3 +80,16 @@ def test_update_project_document_with_categories(self):
         self.assertEqual(response.status_code, 200)
         response_categories = response.data['categories']
         self.assertEqual(sorted(response_categories), sorted(updated_data['categories']))
+
+    def test_patch_to_remove_document(self):
+        # Given
+        document = ProjectDocument.objects.create(project=self.project, document='foo.jpg')
+        url = '/rest/v1/project_document/{}/?format=json'.format(document.id)
+        data = {'document': None, 'project_editor_change': True}
+
+        # When
+        response = self.c.patch(url, data=json.dumps(data), content_type='application/json')
+
+        # Then
+        self.assertEqual(response.status_code, 200)
+        self.assertIsNone(response.data['document'])