Skip to content

Commit

Permalink
[#2223] Merge develop into branch
Browse files Browse the repository at this point in the history
  • Loading branch information
KasperBrandt committed Jun 27, 2016
2 parents c1045c4 + 41c2e41 commit e673a8f
Show file tree
Hide file tree
Showing 15 changed files with 678 additions and 16 deletions.
7 changes: 5 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ install:

before_script:
- psql -c 'CREATE DATABASE travis_test;' -U postgres
- python manage.py migrate --noinput
- python manage.py runserver &

script:
- python manage.py test akvo.rsr.tests.iati_import
- coverage run --source=akvo manage.py test akvo.rsr.tests.iati_import
- python manage.py collectstatic --noinput
- python manage.py test --noinput akvo.rsr.tests
- coverage run --source=akvo manage.py test akvo.rsr.tests

after_success:
- coveralls
Expand Down
3 changes: 3 additions & 0 deletions akvo/rest/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@
url(r'^project/(?P<project_pk>[0-9]+)/import_results/$',
views.project_editor_import_results,
name='project_editor_import_results'),
url(r'^project/(?P<project_pk>[0-9]+)/reorder_items/$',
views.project_editor_reorder_items,
name='project_editor_reorder_items'),
url(r'^project/(?P<project_pk>[0-9]+)/add_validation/(?P<validation_pk>[0-9]+)/$',
views.project_editor_add_validation,
name='project_editor_add_validation'),
Expand Down
1 change: 1 addition & 0 deletions akvo/rest/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
from .project import ProjectViewSet, ProjectExtraViewSet, ProjectIatiExportViewSet, ProjectUpViewSet
from .project_editor import (project_editor,
log_project_addition,
project_editor_reorder_items,
project_editor_upload_file,
project_editor_import_results,
project_editor_add_validation,
Expand Down
68 changes: 67 additions & 1 deletion akvo/rest/views/project_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import datetime
import decimal
import collections

from akvo.rsr.fields import (LatitudeField, LongitudeField, ProjectLimitedTextField,
ValidXMLCharField, ValidXMLTextField)
Expand Down Expand Up @@ -427,7 +428,7 @@ def project_editor(request, pk=None):
# it will definitely be able to create the indicator id, etc.

for i in range(4):
for key in data.keys():
for key in sorted(data.keys()):
# The keys in form data are of format "rsr_project.title.1234".
# Separated by .'s, the data contains the model name, field name and object id list
model, field, id_list = split_key(key)
Expand Down Expand Up @@ -571,6 +572,71 @@ def project_editor(request, pk=None):
)


@api_view(['POST'])
@permission_classes((IsAuthenticated,))
def project_editor_reorder_items(request, project_pk=None):
"""API call to reorder results or indicators"""

errors, item_list, item_selected, swap_id = [], [], None, -1

item_type = request.POST.get('item_type', False)
item_id = request.POST.get('item_id', False)
item_direction = request.POST.get('item_direction', False)

if item_type == 'result':
item_selected = Result.objects.get(id=item_id)
item_list = Result.objects.filter(project_id=project_pk)
elif item_type == 'indicator':
item_selected = Indicator.objects.get(id=item_id)
item_list = Indicator.objects.filter(result_id=item_selected.result_id)
else:
errors += ['Invalid item type']

if not errors:
# assign order if it doesn't already exist
if item_list and not item_list[0].order:
for i, item in enumerate(item_list):
item.order = i
item.save()

if item_type == 'result':
item_original_order = Result.objects.get(id=item_id).order
else:
item_original_order = Indicator.objects.get(id=item_id).order

if item_direction == 'up' and not item_original_order < 1:
item_swap = item_list.get(order=item_original_order - 1)
item_swap.order = item_original_order
item_swap.save()

swap_id = item_swap.id

if item_selected:
item_selected.order = item_original_order-1
item_selected.save()

elif item_direction == 'down' and not item_original_order >= len(item_list) - 1:
item_swap = item_list.get(order=item_original_order + 1)
item_swap.order = item_original_order
item_swap.save()

swap_id = item_swap.id

if item_selected:
item_selected.order = item_original_order + 1
item_selected.save()

else:
errors += ['Unable to reorder the selected item, it may already be at top/bottom of '
'list.']

return Response(
{
'errors': errors,
'swap_id': swap_id,
}
)

@api_view(['POST'])
@permission_classes((IsAuthenticated, ))
def project_editor_upload_file(request, pk=None):
Expand Down
26 changes: 26 additions & 0 deletions akvo/rsr/migrations/0078_auto_20160613_1428.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

dependencies = [
('rsr', '0077_auto_20160608_1227'),
]

operations = [
migrations.AddField(
model_name='indicator',
name='order',
field=models.PositiveSmallIntegerField(null=True, verbose_name='indicator order', blank=True),
preserve_default=True,
),
migrations.AddField(
model_name='result',
name='order',
field=models.PositiveSmallIntegerField(null=True, verbose_name='result order', blank=True),
preserve_default=True,
),
]
21 changes: 21 additions & 0 deletions akvo/rsr/models/indicator.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class Indicator(models.Model):
_(u'baseline comment'), blank=True, max_length=2000,
help_text=_(u'Here you can provide extra information on the baseline value, if needed.')
)
order = models.PositiveSmallIntegerField(_(u'indicator order'), null=True, blank=True)

def __unicode__(self):
indicator_unicode = self.title if self.title else u'%s' % _(u'No indicator title')
Expand Down Expand Up @@ -100,6 +101,11 @@ def save(self, *args, **kwargs):
for child_result in self.result.child_results.all():
child_result.project.add_indicator(child_result, self)

if Indicator.objects.filter(result_id=self.result.id).exists():
prev_indicator = Indicator.objects.filter(result_id=self.result.id).reverse()[0]
if prev_indicator.order:
self.order = prev_indicator.order + 1

super(Indicator, self).save(*args, **kwargs)

def clean(self):
Expand Down Expand Up @@ -129,6 +135,20 @@ def clean(self):
if validation_errors:
raise ValidationError(validation_errors)

def delete(self, *args, **kwargs):
"""
Check if indicator is ordered manually, and cascade following indicators if needed
"""
if self.order:
sibling_indicators = Indicator.objects.filter(result_id=self.result.id)

if not self == sibling_indicators.reverse()[0]:
for ind in range(self.order + 1, len(sibling_indicators)):
sibling_indicators[ind].order -= 1
sibling_indicators[ind].save()

super(Indicator, self).delete(*args, **kwargs)

def iati_measure(self):
return codelist_value(IndicatorMeasure, self, 'measure')

Expand Down Expand Up @@ -193,6 +213,7 @@ def baseline(self):

class Meta:
app_label = 'rsr'
ordering = ['order', 'id']
verbose_name = _(u'indicator')
verbose_name_plural = _(u'indicators')

Expand Down
22 changes: 22 additions & 0 deletions akvo/rsr/models/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Result(models.Model):
parent_result = models.ForeignKey('self', blank=True, null=True, default=None,
help_text=_(u'The parent result of this result.'),
related_name='child_results')
order = models.PositiveSmallIntegerField(_(u'result order'), null=True, blank=True)

def __unicode__(self):
result_unicode = self.title if self.title else u'%s' % _(u'No result title')
Expand All @@ -72,6 +73,12 @@ def save(self, *args, **kwargs):
child_result.description = self.description

child_result.save()

if not self.pk and Result.objects.filter(project_id=self.project.id).exists():
prev_result = Result.objects.filter(project_id=self.project.id).reverse()[0]
if prev_result.order:
self.order = prev_result.order + 1

super(Result, self).save(*args, **kwargs)

def clean(self):
Expand Down Expand Up @@ -101,6 +108,20 @@ def clean(self):
if validation_errors:
raise ValidationError(validation_errors)

def delete(self, *args, **kwargs):
"""
Check if indicator is ordered manually, and cascade following indicators if needed
"""
if self.order:
sibling_results = Result.objects.filter(project_id=self.project.id)

if not self == sibling_results.reverse()[0]:
for ind in range(self.order + 1, len(sibling_results)):
sibling_results[ind].order -= 1
sibling_results[ind].save()

super(Result, self).delete(*args, **kwargs)

def iati_type(self):
return codelist_value(ResultType, self, 'type')

Expand Down Expand Up @@ -131,5 +152,6 @@ def child_projects(self):

class Meta:
app_label = 'rsr'
ordering = ['order', 'id']
verbose_name = _(u'result')
verbose_name_plural = _(u'results')
Loading

0 comments on commit e673a8f

Please sign in to comment.