Commit 6f91940f authored by Luko van der Maas's avatar Luko van der Maas
Browse files

Merge branch 'feature/address-country' into 'master'

Add country field to user profiles

Closes #810

See merge request !1140
parents e8a43b4f 068d974b
...@@ -18,6 +18,14 @@ Subpackages ...@@ -18,6 +18,14 @@ Subpackages
Submodules Submodules
---------- ----------
utils.countries module
----------------------
.. automodule:: utils.countries
:members:
:undoc-members:
:show-inheritance:
utils.exception\_filter module utils.exception\_filter module
------------------------------ ------------------------------
......
...@@ -7,8 +7,8 @@ msgid "" ...@@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-07-11 20:07+0200\n" "POT-Creation-Date: 2019-01-24 22:35+0100\n"
"PO-Revision-Date: 2016-11-14 22:05+0100\n" "PO-Revision-Date: 2019-01-24 22:44+0100\n"
"Last-Translator: Joost Rijneveld <joost@joostrijneveld.nl>\n" "Last-Translator: Joost Rijneveld <joost@joostrijneveld.nl>\n"
"Language-Team: \n" "Language-Team: \n"
"Language: nl\n" "Language: nl\n"
...@@ -16,6 +16,7 @@ msgstr "" ...@@ -16,6 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.2\n"
#: templates/registration/logged_out.html #: templates/registration/logged_out.html
msgid "Logout" msgid "Logout"
...@@ -180,3 +181,207 @@ msgstr "Wachtwoord vergeten" ...@@ -180,3 +181,207 @@ msgstr "Wachtwoord vergeten"
#: templates/registration/password_reset_subject.txt #: templates/registration/password_reset_subject.txt
msgid "[THALIA] Password reset request" msgid "[THALIA] Password reset request"
msgstr "[THALIA] Verzoek tot wachtwoordherstel" msgstr "[THALIA] Verzoek tot wachtwoordherstel"
#: utils/countries.py
msgid "Åland Islands"
msgstr "Aland-eilanden"
#: utils/countries.py
msgid "Albania"
msgstr "Albanië"
#: utils/countries.py
msgid "Andorra"
msgstr "Andorra"
#: utils/countries.py
msgid "Austria"
msgstr "Oostenrijk"
#: utils/countries.py
msgid "Belarus"
msgstr "Wit-Rusland"
#: utils/countries.py
msgid "Belgium"
msgstr "België"
#: utils/countries.py
msgid "Bosnia and Herzegovina"
msgstr "Bosnië en Herzegovina"
#: utils/countries.py
msgid "Bulgaria"
msgstr "Bulgarije"
#: utils/countries.py
msgid "Croatia"
msgstr "Kroatië"
#: utils/countries.py
msgid "Czechia"
msgstr "Tsjechië"
#: utils/countries.py
msgid "Denmark"
msgstr "Denemarken"
#: utils/countries.py
msgid "Estonia"
msgstr "Estland"
#: utils/countries.py
msgid "Faroe Islands"
msgstr "Faeröer"
#: utils/countries.py
msgid "Finland"
msgstr "Finland"
#: utils/countries.py
msgid "France"
msgstr "Frankrijk"
#: utils/countries.py
msgid "Germany"
msgstr "Duitsland"
#: utils/countries.py
msgid "Gibraltar"
msgstr "Gibraltar"
#: utils/countries.py
msgid "Greece"
msgstr "Griekenland"
#: utils/countries.py
msgid "Guernsey"
msgstr "Guernsey"
#: utils/countries.py
msgid "Vatican City"
msgstr "Vaticaanstad"
#: utils/countries.py
msgid "Hungary"
msgstr "Hongarije"
#: utils/countries.py
msgid "Iceland"
msgstr "IJsland"
#: utils/countries.py
msgid "Ireland"
msgstr "Ierland"
#: utils/countries.py
msgid "Isle of Man"
msgstr "Man (eiland)"
#: utils/countries.py
msgid "Italy"
msgstr "Italië"
#: utils/countries.py
msgid "Jersey"
msgstr "Jersey"
#: utils/countries.py
msgid "Latvia"
msgstr "Letland"
#: utils/countries.py
msgid "Liechtenstein"
msgstr "Liechtenstein"
#: utils/countries.py
msgid "Lithuania"
msgstr "Litouwen"
#: utils/countries.py
msgid "Luxembourg"
msgstr "Luxemburg"
#: utils/countries.py
msgid "Macedonia (FYROM)"
msgstr "Macedonië (VJRM)"
#: utils/countries.py
msgid "Malta"
msgstr "Malta"
#: utils/countries.py
msgid "Moldova"
msgstr "Moldavië"
#: utils/countries.py
msgid "Monaco"
msgstr "Monaco"
#: utils/countries.py
msgid "Montenegro"
msgstr "Montenegro"
#: utils/countries.py
msgid "Netherlands"
msgstr "Nederland"
#: utils/countries.py
msgid "Norway"
msgstr "Noorwegen"
#: utils/countries.py
msgid "Poland"
msgstr "Polen"
#: utils/countries.py
msgid "Portugal"
msgstr "Portugal"
#: utils/countries.py
msgid "Romania"
msgstr "Roemenië"
#: utils/countries.py
msgid "Russian Federation"
msgstr "Rusland"
#: utils/countries.py
msgid "San Marino"
msgstr "San Marino"
#: utils/countries.py
msgid "Serbia"
msgstr "Servië"
#: utils/countries.py
msgid "Slovakia"
msgstr "Slowakije"
#: utils/countries.py
msgid "Slovenia"
msgstr "Slovenië"
#: utils/countries.py
msgid "Spain"
msgstr "Spanje"
#: utils/countries.py
msgid "Svalbard and Jan Mayen"
msgstr "Spitsbergen en Jan Mayen"
#: utils/countries.py
msgid "Sweden"
msgstr "Zweden"
#: utils/countries.py
msgid "Switzerland"
msgstr "Zwitserland"
#: utils/countries.py
msgid "Ukraine"
msgstr "Oekraïne"
#: utils/countries.py
msgid "United Kingdom"
msgstr "Verenigd Koninkrijk"
...@@ -23,11 +23,11 @@ class MembershipInline(admin.StackedInline): ...@@ -23,11 +23,11 @@ class MembershipInline(admin.StackedInline):
class ProfileInline(admin.StackedInline): class ProfileInline(admin.StackedInline):
fields = ('starting_year', 'programme', 'address_street', fields = ('starting_year', 'programme', 'address_street',
'address_street2', 'address_postal_code', 'address_city', 'address_street2', 'address_postal_code', 'address_city',
'student_number', 'phone_number', 'receive_optin', 'address_country', 'student_number', 'phone_number',
'receive_newsletter', 'birthday', 'show_birthday', 'receive_optin', 'receive_newsletter', 'birthday',
'direct_debit_authorized', 'bank_account', 'initials', 'show_birthday', 'direct_debit_authorized', 'bank_account',
'nickname', 'display_name_preference', 'profile_description', 'initials', 'nickname', 'display_name_preference',
'website', 'photo', 'emergency_contact', 'profile_description', 'website', 'photo', 'emergency_contact',
'emergency_contact_phone_number', 'language', 'emergency_contact_phone_number', 'language',
'event_permissions') 'event_permissions')
model = models.Profile model = models.Profile
...@@ -131,7 +131,8 @@ class UserAdmin(BaseUserAdmin): ...@@ -131,7 +131,8 @@ class UserAdmin(BaseUserAdmin):
filename="addresses.csv"' filename="addresses.csv"'
writer = csv.writer(response) writer = csv.writer(response)
writer.writerow([_('First name'), _('Last name'), _('Address'), writer.writerow([_('First name'), _('Last name'), _('Address'),
_('Address line 2'), _('Postal code'), _('City')]) _('Address line 2'), _('Postal code'), _('City'),
_('Country')])
for user in queryset.exclude(profile=None): for user in queryset.exclude(profile=None):
writer.writerow([user.first_name, writer.writerow([user.first_name,
user.last_name, user.last_name,
...@@ -139,6 +140,7 @@ class UserAdmin(BaseUserAdmin): ...@@ -139,6 +140,7 @@ class UserAdmin(BaseUserAdmin):
user.profile.address_street2, user.profile.address_street2,
user.profile.address_postal_code, user.profile.address_postal_code,
user.profile.address_city, user.profile.address_city,
user.profile.get_address_country_display(),
]) ])
return response return response
address_csv_export.short_description = _('Download address label for ' address_csv_export.short_description = _('Download address label for '
......
...@@ -118,9 +118,10 @@ class ProfileEditSerializer(serializers.ModelSerializer): ...@@ -118,9 +118,10 @@ class ProfileEditSerializer(serializers.ModelSerializer):
model = Profile model = Profile
fields = ('pk', 'email', 'first_name', 'last_name', 'address_street', fields = ('pk', 'email', 'first_name', 'last_name', 'address_street',
'address_street2', 'address_postal_code', 'address_city', 'address_street2', 'address_postal_code', 'address_city',
'phone_number', 'show_birthday', 'website', 'photo', 'address_country', 'phone_number', 'show_birthday',
'emergency_contact', 'emergency_contact_phone_number', 'website', 'photo', 'emergency_contact',
'profile_description', 'nickname', 'display_name_preference', 'emergency_contact_phone_number', 'profile_description',
'nickname', 'display_name_preference',
'language', 'receive_optin', 'receive_newsletter', 'language', 'receive_optin', 'receive_newsletter',
'display_name', 'avatar', 'birthday', 'starting_year', 'display_name', 'avatar', 'birthday', 'starting_year',
'programme', 'membership_type', 'achievements', 'societies') 'programme', 'membership_type', 'achievements', 'societies')
......
...@@ -84,6 +84,8 @@ def send_information_request(dry_run=False): ...@@ -84,6 +84,8 @@ def send_information_request(dry_run=False):
'address_postal_code': 'address_postal_code':
member.profile.address_postal_code, member.profile.address_postal_code,
'address_city': member.profile.address_city, 'address_city': member.profile.address_city,
'address_country':
member.profile.get_address_country_display(),
'phone_number': member.profile.phone_number, 'phone_number': member.profile.phone_number,
'birthday': member.profile.birthday, 'birthday': member.profile.birthday,
'email': member.email, 'email': member.email,
......
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
"address_street2": "", "address_street2": "",
"address_postal_code": "1245 TG", "address_postal_code": "1245 TG",
"address_city": "Nijmegen", "address_city": "Nijmegen",
"address_country": "NL",
"phone_number": "", "phone_number": "",
"emergency_contact": "", "emergency_contact": "",
"emergency_contact_phone_number": "", "emergency_contact_phone_number": "",
...@@ -108,6 +109,7 @@ ...@@ -108,6 +109,7 @@
"address_street2": "", "address_street2": "",
"address_postal_code": "2545 TG", "address_postal_code": "2545 TG",
"address_city": "Nijmegen", "address_city": "Nijmegen",
"address_country": "NL",
"phone_number": "", "phone_number": "",
"emergency_contact": "", "emergency_contact": "",
"emergency_contact_phone_number": "", "emergency_contact_phone_number": "",
...@@ -134,6 +136,7 @@ ...@@ -134,6 +136,7 @@
"address_street2": "", "address_street2": "",
"address_postal_code": "6525 TE", "address_postal_code": "6525 TE",
"address_city": "Nijmegen", "address_city": "Nijmegen",
"address_country": "NL",
"phone_number": "", "phone_number": "",
"emergency_contact": "", "emergency_contact": "",
"emergency_contact_phone_number": "", "emergency_contact_phone_number": "",
...@@ -160,6 +163,7 @@ ...@@ -160,6 +163,7 @@
"address_street2": "", "address_street2": "",
"address_postal_code": "6525 TE", "address_postal_code": "6525 TE",
"address_city": "Nijmegen", "address_city": "Nijmegen",
"address_country": "NL",
"phone_number": "", "phone_number": "",
"emergency_contact": "", "emergency_contact": "",
"emergency_contact_phone_number": "", "emergency_contact_phone_number": "",
......
...@@ -11,8 +11,9 @@ from .models import Profile ...@@ -11,8 +11,9 @@ from .models import Profile
class ProfileForm(forms.ModelForm): class ProfileForm(forms.ModelForm):
class Meta: class Meta:
fields = ['address_street', 'address_street2', fields = ['address_street', 'address_street2',
'address_postal_code', 'address_city', 'phone_number', 'address_postal_code', 'address_city', 'address_country',
'emergency_contact', 'emergency_contact_phone_number', 'phone_number', 'emergency_contact',
'emergency_contact_phone_number',
'show_birthday', 'website', 'show_birthday', 'website',
'profile_description', 'nickname', 'profile_description', 'nickname',
'display_name_preference', 'photo', 'language', 'display_name_preference', 'photo', 'language',
......
...@@ -7,8 +7,8 @@ msgid "" ...@@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-12-17 15:31+0100\n" "POT-Creation-Date: 2019-01-24 22:37+0100\n"
"PO-Revision-Date: 2018-12-17 15:32+0100\n" "PO-Revision-Date: 2019-01-24 22:45+0100\n"
"Last-Translator: Thom Wiggers <thom@thomwiggers.nl>\n" "Last-Translator: Thom Wiggers <thom@thomwiggers.nl>\n"
"Language-Team: \n" "Language-Team: \n"
"Language: nl\n" "Language: nl\n"
...@@ -74,6 +74,10 @@ msgstr "Postcode" ...@@ -74,6 +74,10 @@ msgstr "Postcode"
msgid "City" msgid "City"
msgstr "Woonplaats" msgstr "Woonplaats"
#: admin.py models.py
msgid "Country"
msgstr "Land"
#: admin.py #: admin.py
msgid "Download address label for selected users" msgid "Download address label for selected users"
msgstr "Download adreslabels voor geselecteerde gebruikers" msgstr "Download adreslabels voor geselecteerde gebruikers"
...@@ -774,6 +778,7 @@ msgid "" ...@@ -774,6 +778,7 @@ msgid ""
" %(address_street2)s\n" " %(address_street2)s\n"
" %(address_postal_code)s\n" " %(address_postal_code)s\n"
" %(address_city)s\n" " %(address_city)s\n"
" %(address_country)s\n"
"Phone: %(phone_number)s\n" "Phone: %(phone_number)s\n"
"Date of birth: %(birthday)s\n" "Date of birth: %(birthday)s\n"
"Email address: %(email)s\n" "Email address: %(email)s\n"
...@@ -806,6 +811,8 @@ msgstr "" ...@@ -806,6 +811,8 @@ msgstr ""
" %(address_street2)s\n" " %(address_street2)s\n"
" %(address_postal_code)s\n" " %(address_postal_code)s\n"
" %(address_city)s\n" " %(address_city)s\n"
"\n"
" %(address_country)s\n"
"Telefoonnummer: %(phone_number)s\n" "Telefoonnummer: %(phone_number)s\n"
"Geboortedatum: %(birthday)s\n" "Geboortedatum: %(birthday)s\n"
"Emailadres: %(email)s\n" "Emailadres: %(email)s\n"
......
...@@ -3,6 +3,7 @@ import logging ...@@ -3,6 +3,7 @@ import logging
from django.conf import settings from django.conf import settings
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.template.defaultfilters import date from django.template.defaultfilters import date
from django.utils import translation
from requests import HTTPError from requests import HTTPError
from members.models import Member from members.models import Member
...@@ -39,35 +40,36 @@ class Command(BaseCommand): ...@@ -39,35 +40,36 @@ class Command(BaseCommand):
} }
replace_commands = [] replace_commands = []
for member in Member.current_members.all(): with translation.override('nl'):
code = current_relations.pop(member.pk, None) for member in Member.current_members.all():
profile = member.profile code = current_relations.pop(member.pk, None)
profile = member.profile
fields = { fields = {
'website_id': member.pk, 'website_id': member.pk,
'voornaam': member.first_name, 'voornaam': member.first_name,
'naam': member.last_name[:100], # Conscribo maxlength: 100 'naam': member.last_name[:100], # api maxlength: 100
'einddatum_lidmaatschap': 'einddatum_lidmaatschap':
date(member.current_membership.until, 'Y-m-d'), date(member.current_membership.until, 'Y-m-d'),
'e_mailadres': member.email, 'e_mailadres': member.email,
'eerste_adresregel': profile.address_street, 'eerste_adresregel': profile.address_street,
'tweede_adresregel': profile.address_street2, 'tweede_adresregel': profile.address_street2,
'postcode': profile.address_postal_code, 'postcode': profile.address_postal_code,
'plaats': profile.address_city, 'plaats': profile.address_city,
'land': 'Nederland', 'land': profile.get_address_country_display(),
'bankrekeningnummer': { 'bankrekeningnummer': {
'name': f'${profile.initials} ${member.last_name}', 'name': f'${profile.initials} ${member.last_name}',
'bic': '', 'bic': '',
'iban': profile.bank_account, 'iban': profile.bank_account,
}, },
} }
replace_commands.append(ApiCommand( replace_commands.append(ApiCommand(
command='ReplaceRelation', command='ReplaceRelation',
entityType='lid_2', entityType='lid_2',
fields=fields, fields=fields,
code=code, code=code,
)) ))
replace_responses = api.multi_request(replace_commands) replace_responses = api.multi_request(replace_commands)
for response in replace_responses: for response in replace_responses:
......
# Generated by Django 2.1.5 on 2019-01-24 21:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('members', '0028_auto_20181217_1518'),
]
operations = [
migrations.AddField(
model_name='profile',
name='address_country',
field=models.CharField(
choices=[('AX', 'Åland Islands'), ('AL', 'Albania'),
('AD', 'Andorra'), ('AT', 'Austria'),
('BY', 'Belarus'), ('BE', 'Belgium'),
('BA', 'Bosnia and Herzegovina'), ('BG', 'Bulgaria'),
('HR', 'Croatia'), ('CZ', 'Czechia'),
('DK', 'Denmark'), ('EE', 'Estonia'),
('FO', 'Faroe Islands'), ('FI', 'Finland'),
('FR', 'France'), ('DE', 'Germany'),
('GI', 'Gibraltar'), ('GR', 'Greece'),
('GG', 'Guernsey'), ('VA', 'Vatican City'),
('HU', 'Hungary'), ('IS', 'Iceland'),
('IE', 'Ireland'), ('IM', 'Isle of Man'),
('IT', 'Italy'), ('JE', 'Jersey'), ('LV', 'Latvia'),
('LI', 'Liechtenstein'), ('LT', 'Lithuania'),
('LU', 'Luxembourg'), ('MK', 'Macedonia (FYROM)'),
('MT', 'Malta'), ('MD', 'Moldova'), ('MC', 'Monaco'),
('ME', 'Montenegro'), ('NL', 'Netherlands'),
('NO', 'Norway'), ('PL', 'Poland'),
('PT', 'Portugal'), ('RO', 'Romania'),
('RU', 'Russian Federation'), ('SM', 'San Marino'),
('RS', 'Serbia'), ('SK', 'Slovakia'),
('SI', 'Slovenia'), ('ES', 'Spain'),
('SJ', 'Svalbard and Jan Mayen'), ('SE', 'Sweden'),
('CH', 'Switzerland'), ('UA', 'Ukraine'),
('GB', 'United Kingdom')],
default='NL', max_length=2, null=True,
verbose_name='Country'),
preserve_default=False,
),
]
...@@ -19,6 +19,7 @@ from localflavor.generic.countries.sepa import IBAN_SEPA_COUNTRIES ...@@ -19,6 +19,7 @@ from localflavor.generic.countries.sepa import IBAN_SEPA_COUNTRIES
from localflavor.generic.models import IBANField from localflavor.generic.models import IBANField
from activemembers.models import MemberGroup, MemberGroupMembership from activemembers.models import MemberGroup, MemberGroupMembership
from utils import countries
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -265,6 +266,13 @@ class Profile(models.Model): ...@@ -265,6 +266,13 @@ class Profile(models.Model):
null=True, null=True,
) )
address_country = models.CharField(