Skip to content

Commit

Permalink
[#2189] Merge branch '#1804-iati-countries' into #2189-iati-status-field
Browse files Browse the repository at this point in the history
  • Loading branch information
KasperBrandt committed Jun 1, 2016
2 parents 02b9cb0 + 4fd7e4e commit 9aaa593
Show file tree
Hide file tree
Showing 36 changed files with 699 additions and 167 deletions.
9 changes: 2 additions & 7 deletions akvo/cordaid_org_country_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,8 @@ def import_countries(xml_file):
org = internal_org_id.referenced_org
for location in element.find("location"):
iso_code = location.findtext("iso_code").capitalize()
try:
org.country = Country.objects.get(iso_code=iso_code)
org.save()
print("Updated Organisation {org_id} with country data.".format(org_id=org.id))
except:
print("Failed to update Organisation {org_id}. Non-existant country code: {iso_code}.".format(
org_id=org.id, iso_code=iso_code))
org.iati_country = iso_code.upper()
org.save()


if __name__ == "__main__":
Expand Down
3 changes: 0 additions & 3 deletions akvo/iati/imports/mappers/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ def do_import(self):

country_code = self.get_child_elem_attrib(
location, 'administrative', 'country', 'country_code').lower()
if not country_code and len(self.parent_elem.findall('recipient-country')) == 1:
country_code = self.get_child_elem_attrib(
self.parent_elem, 'recipient-country', 'code', 'country_code').lower()

country = None
if country_code:
Expand Down
2 changes: 1 addition & 1 deletion akvo/rest/serializers/employment.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
class EmploymentSerializer(BaseRSRSerializer):

organisation_name = serializers.Field(source='organisation.long_name')
country_name = serializers.Field(source='country.name')
country_name = serializers.Field(source='iati_country')
group_name = serializers.Field(source='group.name')

class Meta:
Expand Down
46 changes: 7 additions & 39 deletions akvo/rest/serializers/typeahead.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,67 +6,35 @@
see < http://www.gnu.org/licenses/agpl.html >.
"""

from akvo.rsr.models import Organisation, Project, ProjectUpdate
from akvo.codelists.models import Country

from rest_framework import serializers
# from akvo.codelists.models import SectorCategory
from akvo.rsr.models import Country, Organisation, Project, ProjectUpdate


class TypeaheadCountrySerializer(serializers.ModelSerializer):

class Meta:
model = Country
fields = (
'id',
'name',
'iso_code',
'continent_code',
)
fields = ('code', 'name')


class TypeaheadOrganisationSerializer(serializers.ModelSerializer):

class Meta:
model = Organisation
fields = (
'id',
'name',
'long_name',
)
fields = ('id', 'name', 'long_name')


class TypeaheadProjectSerializer(serializers.ModelSerializer):

class Meta:
model = Project
fields = (
'id',
# 'project_plan_summary',
# 'subtitle',
'title',
)
fields = ('id', 'title')


class TypeaheadProjectUpdateSerializer(serializers.ModelSerializer):

class Meta:
model = ProjectUpdate
fields = (
'id',
'project',
'title'
)

# class TypeaheadSectorSerializer(serializers.ModelSerializer):

# class Meta:
# model = Project
# depth = 1
# fields = (
# 'id',
# 'sectors',
# )
# # fields = (
# # 'id',
# # # 'categories',
# # 'name',
# # )
fields = ('id', 'project', 'title')
9 changes: 7 additions & 2 deletions akvo/rest/views/typeahead.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
TypeaheadOrganisationSerializer,
TypeaheadProjectSerializer,
TypeaheadProjectUpdateSerializer)
from akvo.rsr.models import Country, Organisation, Project, ProjectUpdate

from akvo.codelists.models import Country, Version
from akvo.rsr.models import Organisation, Project, ProjectUpdate

from django.conf import settings

from rest_framework.decorators import api_view
from rest_framework.response import Response
Expand All @@ -26,7 +30,8 @@ def rejig(queryset, serializer):

@api_view(['GET'])
def typeahead_country(request):
countries = Country.objects.all()
iati_version = Version.objects.get(code=settings.IATI_VERSION)
countries = Country.objects.filter(version=iati_version)
return Response(
rejig(countries, TypeaheadCountrySerializer(countries, many=True))
)
Expand Down
11 changes: 5 additions & 6 deletions akvo/rest/views/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,10 @@ def request_organisation(request, pk=None):
if serializer.is_valid():
try:
organisation = Organisation.objects.get(pk=serializer.data['organisation'])
if serializer.data['country']:
country = Country.objects.get(pk=serializer.data['country'])
else:
country = None
employment = Employment(
user=user,
organisation=organisation,
country=country,
country=serializer.data['country'],
job_title=serializer.data['job_title'],
is_approved=False,
)
Expand All @@ -125,7 +121,10 @@ def request_organisation(request, pk=None):
return Response({'detail': _(u'User already linked to this organisation')},
status=status.HTTP_409_CONFLICT)

serializer.data['country_full'] = CountrySerializer(country).data
if serializer.data['country']:
serializer.data['country_full'] = employment.iati_country().name
else:
serializer.data['country_full'] = ''
serializer.data['organisation_full'] = OrganisationSerializer(organisation).data
serializer.data['id'] = employment.pk

Expand Down
5 changes: 3 additions & 2 deletions akvo/rsr/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def get_readonly_fields(self, request, obj=None):
class OrganisationLocationInline(NestedStackedInline):
model = get_model('rsr', 'organisationlocation')
fields = ('latitude', 'longitude', 'city', 'state', 'address_1', 'address_2', 'postcode',
'country')
'iati_country')
fk_name = 'location_target'

def get_extra(self, request, obj=None, **kwargs):
Expand Down Expand Up @@ -1353,7 +1353,8 @@ class KeywordAdmin(admin.ModelAdmin):

class EmploymentAdmin(admin.ModelAdmin):
model = get_model('rsr', 'Employment')
list_display = ('__unicode__', 'user', 'organisation', 'is_approved', 'country', 'job_title')
list_display = ('__unicode__', 'user', 'organisation', 'is_approved', 'iati_country',
'job_title')
list_filter = ('is_approved', 'organisation')
search_fields = ('organisation__name', 'organisation__long_name', 'user__username')

Expand Down
25 changes: 14 additions & 11 deletions akvo/rsr/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ def remove_empty_querydict_items(request_get):


def walk(node):
"""Walks the m49 tree and return countires"""
"""Walks the m49 tree and return countries"""

if isinstance(node, basestring):
return [node.lower()]
return [node, ]
elif isinstance(node, int):
return walk(deepcopy(M49_HIERARCHY)[node])
else:
Expand All @@ -57,11 +57,19 @@ def walk(node):


def filter_m49(queryset, value):
"""Filters countries from the m49 list"""
"""Filters countries from the m49 list, for projects."""
if not value:
return queryset
countries = walk(deepcopy(M49_HIERARCHY)[int(value)])
return queryset.filter(primary_location__country__iso_code__in=countries)
return queryset.filter(recipient_countries__country__in=countries)


def filter_m49_orgs(queryset, value):
"""Filters countries from the m49 list, for projects."""
if not value:
return queryset
countries = walk(deepcopy(M49_HIERARCHY)[int(value)])
return queryset.filter(locations__iati_country__in=countries)


def get_id_for_iso(i):
Expand Down Expand Up @@ -165,11 +173,6 @@ class Meta:

class ProjectUpdateFilter(django_filters.FilterSet):

location = django_filters.ChoiceFilter(
choices=M49_CODES,
label=_(u'location'),
action=filter_m49)

partner = django_filters.ChoiceFilter(
choices=get_orgs(),
label=_(u'organisation'),
Expand All @@ -188,15 +191,15 @@ class ProjectUpdateFilter(django_filters.FilterSet):

class Meta:
model = ProjectUpdate
fields = ['location', 'partner', 'sector', 'title', ]
fields = ['partner', 'sector', 'title', ]


class OrganisationFilter(django_filters.FilterSet):

location = django_filters.ChoiceFilter(
choices=M49_CODES,
label=_(u'location'),
action=filter_m49)
action=filter_m49_orgs)

name = django_filters.CharFilter(
lookup_type='icontains',
Expand Down
151 changes: 151 additions & 0 deletions akvo/rsr/migrations/0071_auto_20160525_1036.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.core.exceptions import MultipleObjectsReturned
from django.db import models, migrations


def remove_country_from_validation_sets(apps, schema_editor):
"""
Removes the rsr_projectlocation.country field from all validation sets.
"""
ProjectEditorValidationSet = apps.get_model("rsr", "ProjectEditorValidationSet")
validations_to_be_deleted = []

for validation_set in ProjectEditorValidationSet.objects.all():
for validation in validation_set.validations.all():
if 'rsr_projectlocation.country' in validation.validation:
validations_to_be_deleted.append(validation)

for delete_validation in validations_to_be_deleted:
delete_validation.delete()


def add_country_to_rsr_validation_set(apps, schema_editor):
"""
Adds the rsr_projectlocation.country field to the RSR validation set, as mandatory field.
"""
ProjectEditorValidationSet = apps.get_model("rsr", "ProjectEditorValidationSet")
ProjectEditorValidation = apps.get_model("rsr", "ProjectEditorValidation")
try:
rsr_validation_set = ProjectEditorValidationSet.objects.get(pk=1)
ProjectEditorValidation.objects.get_or_create(
validation_set=rsr_validation_set,
validation='rsr_projectlocation.country',
action=1
)
except (ProjectEditorValidationSet.DoesNotExist, MultipleObjectsReturned):
# The RSR validation set (id = 1) can not be deleted and should always exist
pass


def do_not_hide_recipient_countries_and_regions(apps, schema_editor):
"""
In the RSR validations set (id is always 1), remove the settings to hide the
rsr_recipientcountry and rsr_recipientregion models. Do hide some of the specific fields in
these models, such as the free text, percentage, vocabulary and vocabulary_uri.
"""
ProjectEditorValidationSet = apps.get_model("rsr", "ProjectEditorValidationSet")
ProjectEditorValidation = apps.get_model("rsr", "ProjectEditorValidation")
validations_to_be_deleted = []
validations_to_be_added = [
['rsr_recipientcountry', ['percentage', 'text']],
['rsr_recipientregion', ['percentage', 'text', 'region_vocabulary',
'region_vocabulary_uri']],
]

try:
rsr_validation_set = ProjectEditorValidationSet.objects.get(id=1)
for validation in rsr_validation_set.validations.all():
if validation.validation in ["rsr_recipientcountry", "rsr_recipientregion"] and \
validation.action == 2:
validations_to_be_deleted.append(validation)

for delete_validation in validations_to_be_deleted:
delete_validation.delete()

for add_validation in validations_to_be_added:
model_name = add_validation[0]
field_names = add_validation[1]
for field_name in field_names:
ProjectEditorValidation.objects.get_or_create(
validation_set=rsr_validation_set,
validation="{0}.{1}".format(model_name, field_name),
action=2
)
except (ProjectEditorValidationSet.DoesNotExist, MultipleObjectsReturned):
# The RSR validation set (id = 1) can not be deleted and should always exist
pass


def hide_recipient_countries_and_regions(apps, schema_editor):
"""
In the RSR validations set (id is always 1), re-add the settings to hide the
rsr_recipientcountry and rsr_recipientregion models.
"""
ProjectEditorValidationSet = apps.get_model("rsr", "ProjectEditorValidationSet")
ProjectEditorValidation = apps.get_model("rsr", "ProjectEditorValidation")

try:
rsr_validation_set = ProjectEditorValidationSet.objects.get(pk=1)
ProjectEditorValidation.objects.get_or_create(
validation_set=rsr_validation_set,
validation='rsr_recipientcountry',
action=2
)
ProjectEditorValidation.objects.get_or_create(
validation_set=rsr_validation_set,
validation='rsr_recipientregion',
action=2
)
except (ProjectEditorValidationSet.DoesNotExist, MultipleObjectsReturned):
# The RSR validation set (id = 1) can not be deleted and should always exist
pass


def convert_locations_to_recipient_countries(apps, schema_editor):
"""
For each project retrieve the country code from the location and add a new recipient country
object if it does not exist yet.
"""
Project = apps.get_model("rsr", "Project")
RecipientCountry = apps.get_model("rsr", "RecipientCountry")

for project in Project.objects.all():
country_codes = []
for location in project.locations.all():
country = location.country
if country:
country_codes.append(country.iso_code.upper())

for country_code in list(set(country_codes)):
try:
RecipientCountry.objects.get_or_create(project=project, country=country_code)
except MultipleObjectsReturned:
# This could happen when a project has the same country specified as a recipient
# country multiple times
pass


def revert_locations_to_recipient_countries(apps, schema_editor):
"""
Unfortunately we can't be sure which recipient country stems from a location, or whether it
already existed originally. Therefore we can only ignore it.
"""
pass


class Migration(migrations.Migration):

dependencies = [
('rsr', '0070_auto_20160519_1205'),
]

operations = [
migrations.RunPython(remove_country_from_validation_sets,
add_country_to_rsr_validation_set),
migrations.RunPython(do_not_hide_recipient_countries_and_regions,
hide_recipient_countries_and_regions),
migrations.RunPython(convert_locations_to_recipient_countries,
revert_locations_to_recipient_countries),
]
Loading

0 comments on commit 9aaa593

Please sign in to comment.