diff --git a/people/forms.py b/people/forms.py index 282a3cb..22fe9f5 100644 --- a/people/forms.py +++ b/people/forms.py @@ -101,9 +101,14 @@ class OrganisationAnswerSetForm(forms.ModelForm, DynamicAnswerSetBase): 'website', 'countries', 'hq_country', + 'is_partner_organisation', 'latitude', 'longitude', ] + labels = { + 'is_partner_organisation': + f'Is this organisation a {settings.PARENT_PROJECT_NAME} partner organisation?' + } widgets = { 'countries': Select2MultipleWidget(), 'hq_country': Select2Widget(), diff --git a/people/migrations/0043_organisationanswerset_is_partner_organisation.py b/people/migrations/0043_organisationanswerset_is_partner_organisation.py new file mode 100644 index 0000000..c0e5cad --- /dev/null +++ b/people/migrations/0043_organisationanswerset_is_partner_organisation.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.10 on 2021-03-09 09:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('people', '0042_is_hardcoded_questions'), + ] + + operations = [ + migrations.AddField( + model_name='organisationanswerset', + name='is_partner_organisation', + field=models.BooleanField(default=False), + ), + ] diff --git a/people/models/organisation.py b/people/models/organisation.py index 3874425..d43fc1b 100644 --- a/people/models/organisation.py +++ b/people/models/organisation.py @@ -88,6 +88,10 @@ class OrganisationAnswerSet(AnswerSet): help_text=( 'In which country does this organisation have its main location?')) + is_partner_organisation = models.BooleanField(default=False, + blank=False, + null=False) + latitude = models.FloatField(blank=True, null=True) longitude = models.FloatField(blank=True, null=True) diff --git a/people/templates/people/organisation/list.html b/people/templates/people/organisation/list.html index c205d31..518f6e7 100644 --- a/people/templates/people/organisation/list.html +++ b/people/templates/people/organisation/list.html @@ -15,13 +15,11 @@ href="{% url 'people:organisation.create' %}">New Organisation - {% regroup organisation_list.all by current_answers.hq_country as countries %} - - {% for country in countries %} - + {% for country, organisations in orgs_by_country.items %} + - {% for organisation in country.list %} + {% for organisation in organisations %}
{{ country.grouper.name|default:"Unknown" }}
{{ country }}
{{ organisation }} diff --git a/people/views/organisation.py b/people/views/organisation.py index ae4d14b..b561118 100644 --- a/people/views/organisation.py +++ b/people/views/organisation.py @@ -1,5 +1,6 @@ import typing +from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin from django.utils import timezone from django.views.generic import CreateView, DetailView, ListView, UpdateView @@ -14,15 +15,79 @@ class OrganisationCreateView(LoginRequiredMixin, CreateView): form_class = forms.OrganisationForm +def try_copy_by_key(src_dict: typing.Mapping[str, typing.Any], + dest_dict: typing.MutableMapping[str, typing.Any], + key: str) -> None: + """Copy a value by key from one dictionary to another. + + If the key does not exist, skip it. + """ + value = src_dict.get(key, None) + if value is not None: + dest_dict[key] = value + + class OrganisationListView(LoginRequiredMixin, ListView): """View displaying a list of :class:`organisation` objects.""" model = models.Organisation template_name = 'people/organisation/list.html' + @staticmethod + def sort_organisation_countries( + orgs_by_country: typing.MutableMapping[str, typing.Any] + ) -> typing.Dict[str, typing.Any]: + """Sort dictionary of organisations by country. + + Sort order: + - Project partners + - International organisations + - Organisations by country alphabetically + - Organisations with unknown country + """ + orgs_sorted = {} + + try_copy_by_key(orgs_by_country, orgs_sorted, + f'{settings.PARENT_PROJECT_NAME} partners') + try_copy_by_key(orgs_by_country, orgs_sorted, 'International') + + special = { + f'{settings.PARENT_PROJECT_NAME} partners', 'International', + 'Unknown' + } + for country in sorted(k for k in orgs_by_country.keys() + if k not in special): + orgs_sorted[country] = orgs_by_country[country] + + try_copy_by_key(orgs_by_country, orgs_sorted, 'Unknown') + + return orgs_sorted + def get_context_data(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: context = super().get_context_data(**kwargs) + orgs_by_country = {} + for organisation in self.get_queryset().all(): + answers = organisation.current_answers + + country = 'Unknown' + if len(answers.countries) == 1: + country = answers.countries[0].name + + elif len(answers.countries) > 1: + country = 'International' + + if answers.is_partner_organisation: + country = f'{settings.PARENT_PROJECT_NAME} partners' + + orgs = orgs_by_country.get(country, []) + orgs.append(organisation) + orgs_by_country[country] = orgs + + # Sort into meaningful order + context['orgs_by_country'] = self.sort_organisation_countries( + orgs_by_country) + context['existing_relationships'] = set( self.request.user.person.organisation_relationship_targets. values_list('pk', flat=True))