diff --git a/client/src/components/onboarding/OrganisationAddress.vue b/client/src/components/onboarding/OrganisationAddress.vue index 37c943bf..0ccf8b8a 100644 --- a/client/src/components/onboarding/OrganisationAddress.vue +++ b/client/src/components/onboarding/OrganisationAddress.vue @@ -141,7 +141,11 @@ const orgAddress = computed({ autocomplete="country-name" class="block w-full border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6" > - diff --git a/client/src/components/onboarding/PersonalAddress.vue b/client/src/components/onboarding/PersonalAddress.vue index b3ae2371..8490bb19 100644 --- a/client/src/components/onboarding/PersonalAddress.vue +++ b/client/src/components/onboarding/PersonalAddress.vue @@ -153,7 +153,11 @@ const address = computed({ autocomplete="country-name" class="block w-full border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6" > - diff --git a/client/src/components/personalProfile/ProfileEdit.vue b/client/src/components/personalProfile/ProfileEdit.vue index ca96484a..77d0da8d 100644 --- a/client/src/components/personalProfile/ProfileEdit.vue +++ b/client/src/components/personalProfile/ProfileEdit.vue @@ -20,23 +20,25 @@ const formData = ref({ street_number: user.street_number, postal_code: user.postal_code, city: user.city, - country_id: user.country?.id, + country_code: user.country?.country_code, organisation: user.organisation, organisation_street: user.organisation_street, organisation_street_number: user.organisation_street_number, organisation_postal_code: user.organisation_postal_code, organisation_city: user.organisation_city, - organisation_country_id: user.organisation_country?.id, + organisation_country_code: user.organisation_country?.country_code, invoice_address: user.invoice_address, }); async function save() { - const { country_id, organisation_country_id, ...profileData } = formData.value; + const { country_code, organisation_country_code, ...profileData } = formData.value; const typedProfileData: Partial = { ...profileData }; - typedProfileData.country = countries.value.find((c) => c.id === country_id); + typedProfileData.country = countries.value.find( + (c) => c.country_code === country_code + ); typedProfileData.organisation_country = countries.value.find( - (c) => c.id === organisation_country_id + (c) => c.country_code === organisation_country_code ); await user.updateUserProfile(typedProfileData); @@ -219,12 +221,16 @@ async function avatarUpload(e: Event) { @@ -325,13 +331,17 @@ async function avatarUpload(e: Event) { diff --git a/client/src/services/entities.ts b/client/src/services/entities.ts index 3ca68a71..2de7f01c 100644 --- a/client/src/services/entities.ts +++ b/client/src/services/entities.ts @@ -8,7 +8,8 @@ export type Organisation = { }; export type Country = { - id: number; + country_code: string; + vbv_country_id: number; name: string; }; diff --git a/server/config/settings/test_cypress_datatrans.py b/server/config/settings/test_cypress_datatrans.py index fa5fd0f7..e56165d2 100644 --- a/server/config/settings/test_cypress_datatrans.py +++ b/server/config/settings/test_cypress_datatrans.py @@ -6,9 +6,7 @@ from dotenv import dotenv_values script_path = os.path.abspath(__file__) script_dir = os.path.dirname(script_path) -dev_env = dotenv_values( - f"{script_dir}/../../../env_secrets/caprover_vbv-develop.env" -) +dev_env = dotenv_values(f"{script_dir}/../../../env_secrets/caprover_vbv-develop.env") os.environ["IT_APP_ENVIRONMENT"] = "local" diff --git a/server/vbv_lernwelt/api/tests/test_entities_api.py b/server/vbv_lernwelt/api/tests/test_entities_api.py index ba1d0f9f..49fd2579 100644 --- a/server/vbv_lernwelt/api/tests/test_entities_api.py +++ b/server/vbv_lernwelt/api/tests/test_entities_api.py @@ -42,58 +42,32 @@ class EntitiesViewTest(APITestCase): }, ) - countries = response.data["countries"] - - self.assertEqual( - countries[0], - { - "id": 1, - "name": "Afghanistan", - }, - ) - - def test_list_country_entities_ordered_by_country_id(self) -> None: - # GIVEN - url = reverse("list_entities") - - first_country = Country.objects.get(country_id=1) - - # WHEN - response = self.client.get(url) - - # THEN - self.assertEqual(response.status_code, status.HTTP_200_OK) - - countries = response.data["countries"] - - self.assertEqual( - countries[0], - { - "id": first_country.country_id, - "name": first_country.name_de, - }, - ) - def test_list_country_entities_ordered_by_order_id(self) -> None: - # GIVEN url = reverse("list_entities") - switzerland = Country.objects.get(name_de="Schweiz") - switzerland.order_id = 1 - switzerland.save() - - # WHEN response = self.client.get(url) - - # THEN - self.assertEqual(response.status_code, status.HTTP_200_OK) - countries = response.data["countries"] - self.assertEqual( countries[0], { - "id": switzerland.country_id, - "name": switzerland.name_de, + "country_code": "CH", + "vbv_country_id": 209, + "name": "Schweiz", + }, + ) + + usa = Country.objects.get(country_code="US") + usa.order_id = 0.5 + usa.save() + + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + countries = response.data["countries"] + self.assertEqual( + countries[0], + { + "country_code": "US", + "vbv_country_id": usa.vbv_country_id, + "name": usa.name_de, }, ) diff --git a/server/vbv_lernwelt/core/admin.py b/server/vbv_lernwelt/core/admin.py index bb09bea4..8c44c349 100644 --- a/server/vbv_lernwelt/core/admin.py +++ b/server/vbv_lernwelt/core/admin.py @@ -123,7 +123,8 @@ class OrganisationAdmin(admin.ModelAdmin): class CountryAdmin(admin.ModelAdmin): list_display = ( "order_id", - "country_id", + "country_code", + "vbv_country_id", "name_de", "name_fr", "name_it", diff --git a/server/vbv_lernwelt/core/migrations/0007_auto_20240220_1058.py b/server/vbv_lernwelt/core/migrations/0007_auto_20240220_1058.py index 6992cfd0..b0e42af3 100644 --- a/server/vbv_lernwelt/core/migrations/0007_auto_20240220_1058.py +++ b/server/vbv_lernwelt/core/migrations/0007_auto_20240220_1058.py @@ -2,6 +2,15 @@ from django.db import migrations, models +from vbv_lernwelt.core.model_utils import countries + + +def populate_country_order_id(apps, schema_editor): + Country = apps.get_model("core", "Country") + for country in Country.objects.all(): + country.order_id = countries[country.country_id].get("order_id", 20.0) + country.save(update_fields=["order_id"]) + class Migration(migrations.Migration): dependencies = [ @@ -22,4 +31,5 @@ class Migration(migrations.Migration): name="order_id", field=models.FloatField(default=20), ), + migrations.RunPython(populate_country_order_id), ] diff --git a/server/vbv_lernwelt/core/migrations/0008_user_abacus_debitor_number.py b/server/vbv_lernwelt/core/migrations/0008_user_abacus_debitor_number.py index c944304a..469abd26 100644 --- a/server/vbv_lernwelt/core/migrations/0008_user_abacus_debitor_number.py +++ b/server/vbv_lernwelt/core/migrations/0008_user_abacus_debitor_number.py @@ -4,15 +4,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('core', '0007_auto_20240220_1058'), + ("core", "0007_auto_20240220_1058"), ] operations = [ migrations.AddField( - model_name='user', - name='abacus_debitor_number', + model_name="user", + name="abacus_debitor_number", field=models.BigIntegerField(blank=True, null=True, unique=True), ), ] diff --git a/server/vbv_lernwelt/core/migrations/0009_country_refactor.py b/server/vbv_lernwelt/core/migrations/0009_country_refactor.py new file mode 100644 index 00000000..9814b783 --- /dev/null +++ b/server/vbv_lernwelt/core/migrations/0009_country_refactor.py @@ -0,0 +1,112 @@ +# Generated by Django 3.2.20 on 2024-05-30 10:34 + +from django.db import migrations, models + +from vbv_lernwelt.core.model_utils import countries + + +def populate_country_code(apps, schema_editor): + Country = apps.get_model("core", "Country") + for country in Country.objects.all(): + country.country_code = countries[country.country_id]["country_code"] + country.save(update_fields=["country_code"]) + + +def migrate_user_country(apps, schema_editor): + User = apps.get_model("core", "User") + Country = apps.get_model("core", "Country") + for user in User.objects.all(): + if user.old_country: + country = Country.objects.get(vbv_country_id=user.old_country) + user.country = country + if user.old_organisation_country: + country = Country.objects.get(vbv_country_id=user.old_organisation_country) + user.organisation_country = country + user.save(update_fields=["country", "organisation_country"]) + + +class Migration(migrations.Migration): + dependencies = [ + ("core", "0008_user_abacus_debitor_number"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="country", + field=models.IntegerField(null=True, blank=True), + ), + migrations.AlterField( + model_name="user", + name="organisation_country", + field=models.IntegerField(null=True, blank=True), + ), + migrations.AddField( + model_name="country", + name="country_code", + field=models.CharField(max_length=2, null=True), + ), + migrations.RunPython(populate_country_code), + migrations.AlterField( + model_name="country", + name="country_id", + field=models.IntegerField(), + ), + migrations.RenameField( + model_name="country", old_name="country_id", new_name="vbv_country_id" + ), + migrations.AlterField( + model_name="country", + name="country_code", + field=models.CharField(max_length=2, primary_key=True, serialize=False), + ), + migrations.RenameField( + model_name="user", + old_name="country", + new_name="old_country", + ), + migrations.RenameField( + model_name="user", + old_name="organisation_country", + new_name="old_organisation_country", + ), + migrations.AddField( + model_name="user", + name="country", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=models.deletion.SET_NULL, + related_name="user_country", + to="core.country", + ), + ), + migrations.AddField( + model_name="user", + name="organisation_country", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=models.deletion.SET_NULL, + related_name="organisation_country", + to="core.country", + ), + ), + migrations.RunPython(migrate_user_country), + migrations.RemoveField( + model_name="user", + name="old_country", + ), + migrations.RemoveField( + model_name="user", + name="old_organisation_country", + ), + migrations.AlterModelOptions( + name="country", + options={ + "ordering": ["order_id", "vbv_country_id"], + "verbose_name": "Country", + "verbose_name_plural": "Countries", + }, + ), + ] diff --git a/server/vbv_lernwelt/core/model_utils.py b/server/vbv_lernwelt/core/model_utils.py index 4098996a..634d9024 100644 --- a/server/vbv_lernwelt/core/model_utils.py +++ b/server/vbv_lernwelt/core/model_utils.py @@ -185,402 +185,829 @@ def migrate_avatars(apps=None, schema_editor=None): countries = { - 1: {"de": "Afghanistan", "fr": "Afghanistan", "it": "Afghanistan"}, - 2: {"de": "Albanien", "fr": "Albanie", "it": "Albania"}, - 3: {"de": "Algerien", "fr": "Algérie", "it": "Algeria"}, - 5: {"de": "Andorra", "fr": "Andorra", "it": "Andorra"}, - 6: {"de": "Angola", "fr": "Angola", "it": "Angola"}, + 1: { + "de": "Afghanistan", + "fr": "Afghanistan", + "it": "Afghanistan", + "country_code": "AF", + }, + 2: {"de": "Albanien", "fr": "Albanie", "it": "Albania", "country_code": "AL"}, + 3: {"de": "Algerien", "fr": "Algérie", "it": "Algeria", "country_code": "DZ"}, + 5: {"de": "Andorra", "fr": "Andorra", "it": "Andorra", "country_code": "AD"}, + 6: {"de": "Angola", "fr": "Angola", "it": "Angola", "country_code": "AO"}, 9: { "de": "Antigua und Barbuda", "fr": "Antigua et Barbuda", "it": "Antigua e Barbuda", + "country_code": "AG", }, - 10: {"de": "Argentinien", "fr": "Argentine", "it": "Argentina"}, - 11: {"de": "Armenien", "fr": "Armenia", "it": "Armenia"}, - 13: {"de": "Australien", "fr": "Australie", "it": "Australia"}, - 14: {"de": "Österreich", "fr": "Autriche", "it": "Austria"}, - 15: {"de": "Aserbaidschan", "fr": "Azerbaïdjan", "it": "Azerbaijan"}, - 16: {"de": "Bahamas", "fr": "Bahamas", "it": "Bahamas"}, - 17: {"de": "Bahrain", "fr": "Bahrain", "it": "Bahrain"}, - 18: {"de": "Bangladesh", "fr": "Bangladesh", "it": "Bangladesh"}, - 19: {"de": "Barbados", "fr": "Barbados", "it": "Barbados"}, - 20: {"de": "Belarus", "fr": "Belarus", "it": "Belarus"}, - 21: {"de": "Belgien", "fr": "Belgique", "it": "Belgio"}, - 22: {"de": "Belize", "fr": "Belize", "it": "Belize"}, - 23: {"de": "Benin", "fr": "Benin", "it": "Benin"}, - 25: {"de": "Bhutan", "fr": "Bhutan", "it": "Bhutan"}, - 26: {"de": "Bolivien", "fr": "Bolivia", "it": "Bolivia"}, + 10: { + "de": "Argentinien", + "fr": "Argentine", + "it": "Argentina", + "country_code": "AR", + }, + 11: {"de": "Armenien", "fr": "Armenia", "it": "Armenia", "country_code": "AM"}, + 13: { + "de": "Australien", + "fr": "Australie", + "it": "Australia", + "country_code": "AU", + }, + 14: { + "de": "Österreich", + "fr": "Autriche", + "it": "Austria", + "country_code": "AT", + "order_id": 4.0, + }, + 15: { + "de": "Aserbaidschan", + "fr": "Azerbaïdjan", + "it": "Azerbaijan", + "country_code": "AZ", + }, + 16: {"de": "Bahamas", "fr": "Bahamas", "it": "Bahamas", "country_code": "BS"}, + 17: {"de": "Bahrain", "fr": "Bahrain", "it": "Bahrain", "country_code": "BH"}, + 18: { + "de": "Bangladesh", + "fr": "Bangladesh", + "it": "Bangladesh", + "country_code": "BD", + }, + 19: {"de": "Barbados", "fr": "Barbados", "it": "Barbados", "country_code": "BB"}, + 20: {"de": "Belarus", "fr": "Belarus", "it": "Belarus", "country_code": "BY"}, + 21: {"de": "Belgien", "fr": "Belgique", "it": "Belgio", "country_code": "BE"}, + 22: {"de": "Belize", "fr": "Belize", "it": "Belize", "country_code": "BZ"}, + 23: {"de": "Benin", "fr": "Benin", "it": "Benin", "country_code": "BJ"}, + 25: {"de": "Bhutan", "fr": "Bhutan", "it": "Bhutan", "country_code": "BT"}, + 26: {"de": "Bolivien", "fr": "Bolivia", "it": "Bolivia", "country_code": "BO"}, 27: { "de": "Bosnien und Herzegowina", "fr": "Bosnia et Herzegowina", "it": "Bosnia e Herzegovina", + "country_code": "BA", }, - 28: {"de": "Botswana", "fr": "Botswana", "it": "Botswana"}, - 30: {"de": "Brasilien", "fr": "Brésil", "it": "Brasile"}, - 32: {"de": "Brunei", "fr": "Brunei", "it": "Brunei"}, - 33: {"de": "Bulgarien", "fr": "Bulgarie", "it": "Bulgaria"}, - 34: {"de": "Burkina Faso", "fr": "Burkina Faso", "it": "Burkina Faso"}, - 35: {"de": "Burundi", "fr": "Burundi", "it": "Burundi"}, - 36: {"de": "Kambodscha", "fr": "Cambodia", "it": "Cambogia"}, - 37: {"de": "Kamerun", "fr": "Cameroon", "it": "Camerun"}, - 38: {"de": "Kanada", "fr": "Canada", "it": "Canada"}, - 39: {"de": "Kap Verde", "fr": "Cap Vert", "it": "Capo Verde"}, + 28: {"de": "Botswana", "fr": "Botswana", "it": "Botswana", "country_code": "BW"}, + 30: {"de": "Brasilien", "fr": "Brésil", "it": "Brasile", "country_code": "BR"}, + 32: {"de": "Brunei", "fr": "Brunei", "it": "Brunei", "country_code": "BN"}, + 33: {"de": "Bulgarien", "fr": "Bulgarie", "it": "Bulgaria", "country_code": "BG"}, + 34: { + "de": "Burkina Faso", + "fr": "Burkina Faso", + "it": "Burkina Faso", + "country_code": "BF", + }, + 35: {"de": "Burundi", "fr": "Burundi", "it": "Burundi", "country_code": "BI"}, + 36: {"de": "Kambodscha", "fr": "Cambodia", "it": "Cambogia", "country_code": "KH"}, + 37: {"de": "Kamerun", "fr": "Cameroon", "it": "Camerun", "country_code": "CM"}, + 38: {"de": "Kanada", "fr": "Canada", "it": "Canada", "country_code": "CA"}, + 39: {"de": "Kap Verde", "fr": "Cap Vert", "it": "Capo Verde", "country_code": "CV"}, 41: { "de": "Zentralafrikanische Republik", "fr": "Centrafricaine (République)", "it": "Repubblica Centrafricana", + "country_code": "CF", }, - 42: {"de": "Tschad", "fr": "Tchad", "it": "Ciad"}, - 43: {"de": "Chile", "fr": "Chile", "it": "Cile"}, - 44: {"de": "Volksrepublik China", "fr": "Chine (Rép. pop.)", "it": "Cina"}, - 47: {"de": "Kolumbien", "fr": "Colombia", "it": "Colombia"}, - 48: {"de": "Komoren", "fr": "Comoros", "it": "Comoros"}, + 42: {"de": "Tschad", "fr": "Tchad", "it": "Ciad", "country_code": "TD"}, + 43: {"de": "Chile", "fr": "Chile", "it": "Cile", "country_code": "CL"}, + 44: { + "de": "Volksrepublik China", + "fr": "Chine (Rép. pop.)", + "it": "Cina", + "country_code": "CN", + }, + 47: {"de": "Kolumbien", "fr": "Colombia", "it": "Colombia", "country_code": "CO"}, + 48: {"de": "Komoren", "fr": "Comoros", "it": "Comoros", "country_code": "KM"}, 49: { "de": "Kongo, Republik", "fr": "Congo, Republic of the", "it": "Congo, Repubblica del", + "country_code": "CG", }, 50: { "de": "Kongo, Demokratische Republik", "fr": "Congo, The Democratic Republic of the", "it": "Congo, Repubblica Democratica del", + "country_code": "CD", }, - 51: {"de": "Grenada", "fr": "Grenade", "it": "Grenada"}, - 52: {"de": "Costa Rica", "fr": "Costa Rica", "it": "Costa Rica"}, - 53: {"de": "Elfenbeinküste", "fr": "Côte d´Ivoire", "it": "Costa d´Avorio"}, - 54: {"de": "Kroatien", "fr": "Croatia", "it": "Croazia"}, - 55: {"de": "Kuba", "fr": "Cuba", "it": "Cuba"}, - 56: {"de": "Zypern", "fr": "Cyprus", "it": "Cipro"}, + 51: {"de": "Grenada", "fr": "Grenade", "it": "Grenada", "country_code": "GD"}, + 52: { + "de": "Costa Rica", + "fr": "Costa Rica", + "it": "Costa Rica", + "country_code": "CR", + }, + 53: { + "de": "Elfenbeinküste", + "fr": "Côte d´Ivoire", + "it": "Costa d´Avorio", + "country_code": "CI", + }, + 54: {"de": "Kroatien", "fr": "Croatia", "it": "Croazia", "country_code": "HR"}, + 55: {"de": "Kuba", "fr": "Cuba", "it": "Cuba", "country_code": "CU"}, + 56: {"de": "Zypern", "fr": "Cyprus", "it": "Cipro", "country_code": "CY"}, 57: { "de": "Tschechische Republik", "fr": "Czech Rebublic", "it": "Repubblica Ceca", + "country_code": "CZ", }, - 58: {"de": "Dänemark", "fr": "Danemark", "it": "Danimarca"}, - 59: {"de": "Dschibuti", "fr": "Djibouti", "it": "Gibuti"}, - 60: {"de": "Dominica", "fr": "Dominique", "it": "Dominica"}, + 58: {"de": "Dänemark", "fr": "Danemark", "it": "Danimarca", "country_code": "DK"}, + 59: {"de": "Dschibuti", "fr": "Djibouti", "it": "Gibuti", "country_code": "DJ"}, + 60: {"de": "Dominica", "fr": "Dominique", "it": "Dominica", "country_code": "DM"}, 61: { "de": "Dominikanische Republik", "fr": "République Dominicaine", "it": "Repubblica Dominicana", + "country_code": "DO", + }, + 62: { + "de": "Ost Timor", + "fr": "Timor Oriental", + "it": "Timor Est", + "country_code": "TL", + }, + 63: {"de": "Ecuador", "fr": "Équateur", "it": "Ecuador", "country_code": "EC"}, + 64: {"de": "Ägypten", "fr": "Égyptien", "it": "Egitto", "country_code": "EG"}, + 65: { + "de": "El Salvador", + "fr": "Salvador", + "it": "El Salvador", + "country_code": "SV", }, - 62: {"de": "Ost Timor", "fr": "Timor Oriental", "it": "Timor Est"}, - 63: {"de": "Ecuador", "fr": "Équateur", "it": "Ecuador"}, - 64: {"de": "Ägypten", "fr": "Égyptien", "it": "Egitto"}, - 65: {"de": "El Salvador", "fr": "Salvador", "it": "El Salvador"}, 66: { "de": "Äquatorialguniea", "fr": "Guinée équatoriale", "it": "Guinea Equatoriale", + "country_code": "GQ", }, - 67: {"de": "Eritrea", "fr": "Érythrée", "it": "Eritrea"}, - 68: {"de": "Estland", "fr": "Estonia", "it": "Estonia"}, - 69: {"de": "Äthiopien", "fr": "Éthiopie", "it": "Etiopia"}, - 72: {"de": "Fidschi-Inseln", "fr": "Iles Fidji", "it": "Isole Figi"}, - 73: {"de": "Finnland", "fr": "Finlande", "it": "Finlandia"}, - 74: {"de": "Frankreich", "fr": "France", "it": "Francia"}, - 79: {"de": "Gabun", "fr": "Gabon", "it": "Gabon"}, - 80: {"de": "Gambia", "fr": "Gambie", "it": "Gambia"}, - 81: {"de": "Georgien", "fr": "Géorgie", "it": "Georgia"}, - 82: {"de": "Deutschland", "fr": "Allemagne", "it": "Germania"}, - 83: {"de": "Ghana", "fr": "Ghana", "it": "Ghana"}, - 85: {"de": "Griechenland", "fr": "Grèce", "it": "Grecia"}, - 90: {"de": "Guatemala", "fr": "Guatemala", "it": "Guatemala"}, - 92: {"de": "Guinea", "fr": "Guinée", "it": "Guinea"}, - 93: {"de": "Guinea-Bissau", "fr": "Guinée-Bissau", "it": "Guinea-Bissau"}, - 94: {"de": "Guyana", "fr": "Guyana", "it": "Guyana"}, - 95: {"de": "Haiti", "fr": "Haïti", "it": "Haiti"}, - 97: {"de": "Honduras", "fr": "Honduras", "it": "Honduras"}, - 99: {"de": "Ungarn", "fr": "Hongrie", "it": "Ungheria"}, - 100: {"de": "Island", "fr": "Icelande", "it": "Islanda"}, - 101: {"de": "Indien", "fr": "India", "it": "India"}, - 102: {"de": "Indonesien", "fr": "Indonésie", "it": "Indonesia"}, - 103: {"de": "Iran", "fr": "Iran", "it": "Iran"}, - 104: {"de": "Irak", "fr": "Irak", "it": "Iraq"}, - 105: {"de": "Irland", "fr": "Irlande", "it": "Irlanda"}, - 107: {"de": "Israel", "fr": "Israël", "it": "Israele"}, - 108: {"de": "Italien", "fr": "Italie", "it": "Italia"}, - 109: {"de": "Jamaika", "fr": "Jamaïque", "it": "Giamaica"}, - 110: {"de": "Japan", "fr": "Japon", "it": "Giappone"}, - 112: {"de": "Jordanien", "fr": "Jordanie", "it": "Giordania"}, - 113: {"de": "Kasachstan", "fr": "Kazakstan", "it": "Kazakistan"}, - 114: {"de": "Kenia", "fr": "Kénia", "it": "Kenia"}, - 115: {"de": "Kiribati", "fr": "Kiribati", "it": "Kiribati"}, + 67: {"de": "Eritrea", "fr": "Érythrée", "it": "Eritrea", "country_code": "ER"}, + 68: {"de": "Estland", "fr": "Estonia", "it": "Estonia", "country_code": "EE"}, + 69: {"de": "Äthiopien", "fr": "Éthiopie", "it": "Etiopia", "country_code": "ET"}, + 72: { + "de": "Fidschi-Inseln", + "fr": "Iles Fidji", + "it": "Isole Figi", + "country_code": "FJ", + }, + 73: {"de": "Finnland", "fr": "Finlande", "it": "Finlandia", "country_code": "FI"}, + 74: { + "de": "Frankreich", + "fr": "France", + "it": "Francia", + "country_code": "FR", + "order_id": 5.0, + }, + 79: {"de": "Gabun", "fr": "Gabon", "it": "Gabon", "country_code": "GA"}, + 80: {"de": "Gambia", "fr": "Gambie", "it": "Gambia", "country_code": "GM"}, + 81: {"de": "Georgien", "fr": "Géorgie", "it": "Georgia", "country_code": "GE"}, + 82: { + "de": "Deutschland", + "fr": "Allemagne", + "it": "Germania", + "country_code": "DE", + "order_id": 2.0, + }, + 83: {"de": "Ghana", "fr": "Ghana", "it": "Ghana", "country_code": "GH"}, + 85: {"de": "Griechenland", "fr": "Grèce", "it": "Grecia", "country_code": "GR"}, + 90: {"de": "Guatemala", "fr": "Guatemala", "it": "Guatemala", "country_code": "GT"}, + 92: {"de": "Guinea", "fr": "Guinée", "it": "Guinea", "country_code": "GN"}, + 93: { + "de": "Guinea-Bissau", + "fr": "Guinée-Bissau", + "it": "Guinea-Bissau", + "country_code": "GW", + }, + 94: {"de": "Guyana", "fr": "Guyana", "it": "Guyana", "country_code": "GY"}, + 95: {"de": "Haiti", "fr": "Haïti", "it": "Haiti", "country_code": "HT"}, + 97: {"de": "Honduras", "fr": "Honduras", "it": "Honduras", "country_code": "HN"}, + 99: {"de": "Ungarn", "fr": "Hongrie", "it": "Ungheria", "country_code": "HU"}, + 100: {"de": "Island", "fr": "Icelande", "it": "Islanda", "country_code": "IS"}, + 101: {"de": "Indien", "fr": "India", "it": "India", "country_code": "IN"}, + 102: { + "de": "Indonesien", + "fr": "Indonésie", + "it": "Indonesia", + "country_code": "ID", + }, + 103: {"de": "Iran", "fr": "Iran", "it": "Iran", "country_code": "IR"}, + 104: {"de": "Irak", "fr": "Irak", "it": "Iraq", "country_code": "IQ"}, + 105: {"de": "Irland", "fr": "Irlande", "it": "Irlanda", "country_code": "IE"}, + 107: {"de": "Israel", "fr": "Israël", "it": "Israele", "country_code": "IL"}, + 108: { + "de": "Italien", + "fr": "Italie", + "it": "Italia", + "country_code": "IT", + "order_id": 6.0, + }, + 109: {"de": "Jamaika", "fr": "Jamaïque", "it": "Giamaica", "country_code": "JM"}, + 110: {"de": "Japan", "fr": "Japon", "it": "Giappone", "country_code": "JP"}, + 112: {"de": "Jordanien", "fr": "Jordanie", "it": "Giordania", "country_code": "JO"}, + 113: { + "de": "Kasachstan", + "fr": "Kazakstan", + "it": "Kazakistan", + "country_code": "KZ", + }, + 114: {"de": "Kenia", "fr": "Kénia", "it": "Kenia", "country_code": "KE"}, + 115: {"de": "Kiribati", "fr": "Kiribati", "it": "Kiribati", "country_code": "KI"}, 116: { "de": "Korea, Demokratische Volksrepublik", "fr": "Corée du Nord", "it": "Corea, Repubblica Popolare Democratica", + "country_code": "KP", }, 117: { - "de": "Korea, Republik (auch: Südkorea)", + "de": "Korea, Republik (auch: Südkorea)", "fr": "Corée du Sud", "it": "Corea, Repubblica (anche: Corea del Sud)", + "country_code": "KR", + }, + 118: {"de": "Kuwait", "fr": "Koweït", "it": "Kuwait", "country_code": "KW"}, + 119: { + "de": "Kirgisistan", + "fr": "Kirgistan", + "it": "Kirghizistan", + "country_code": "KG", + }, + 120: {"de": "Laos", "fr": "Laos", "it": "Laos", "country_code": "LA"}, + 121: {"de": "Lettland", "fr": "Lettonie", "it": "Lettonia", "country_code": "LV"}, + 122: {"de": "Libanon", "fr": "Lebanon", "it": "Libano", "country_code": "LB"}, + 123: {"de": "Lesotho", "fr": "Lesotho", "it": "Lesotho", "country_code": "LS"}, + 124: {"de": "Liberia", "fr": "Liberia", "it": "Liberia", "country_code": "LR"}, + 125: {"de": "Libyen", "fr": "Libye", "it": "Libia", "country_code": "LY"}, + 126: { + "de": "Liechtenstein", + "fr": "Liechtenstein", + "it": "Liechtenstein", + "country_code": "LI", + "order_id": 3.0, + }, + 127: {"de": "Litauen", "fr": "Lituanie", "it": "Lituania", "country_code": "LT"}, + 128: { + "de": "Luxembourg", + "fr": "Luxembourg", + "it": "Lussemburgo", + "country_code": "LU", }, - 118: {"de": "Kuwait", "fr": "Koweït", "it": "Kuwait"}, - 119: {"de": "Kirgisistan", "fr": "Kirgistan", "it": "Kirghizistan"}, - 120: {"de": "Laos", "fr": "Laos", "it": "Laos"}, - 121: {"de": "Lettland", "fr": "Lettonie", "it": "Lettonia"}, - 122: {"de": "Libanon", "fr": "Lebanon", "it": "Libano"}, - 123: {"de": "Lesotho", "fr": "Lesotho", "it": "Lesotho"}, - 124: {"de": "Liberia", "fr": "Liberia", "it": "Liberia"}, - 125: {"de": "Libyen", "fr": "Libye", "it": "Libia"}, - 126: {"de": "Liechtenstein", "fr": "Liechtenstein", "it": "Liechtenstein"}, - 127: {"de": "Litauen", "fr": "Lituanie", "it": "Lituania"}, - 128: {"de": "Luxembourg", "fr": "Luxembourg", "it": "Lussemburgo"}, 130: { "de": "Nordmazedonien", "fr": "Macédoine du Nord", "it": "Macedonia del Nord", + "country_code": "MK", }, - 131: {"de": "Madagaskar", "fr": "Madagascar", "it": "Madagascar"}, - 132: {"de": "Malawi", "fr": "Malawi", "it": "Malawi"}, - 133: {"de": "Malaysia", "fr": "Malaisie", "it": "Malesia"}, - 134: {"de": "Malediven", "fr": "Maldives", "it": "Maldive"}, - 135: {"de": "Mali", "fr": "Mali", "it": "Mali"}, - 136: {"de": "Malta", "fr": "Malte", "it": "Malta"}, - 137: {"de": "Marshall Inseln", "fr": "Iles Marshall", "it": "Isole Marshall"}, - 139: {"de": "Mauretanien", "fr": "Mauritanie", "it": "Mauritania"}, - 140: {"de": "Mauritius", "fr": "Ile Maurice", "it": "Mauritius"}, - 142: {"de": "Mexico", "fr": "Mexique", "it": "Messico"}, - 143: {"de": "Mikronesien", "fr": "Micronésie", "it": "Micronesia"}, - 144: {"de": "Moldavien", "fr": "Moldavie", "it": "Moldova"}, - 145: {"de": "Monaco", "fr": "Monaco", "it": "Monaco"}, - 146: {"de": "Mongolei", "fr": "Mongolie", "it": "Mongolia"}, - 148: {"de": "Marokko", "fr": "Morocco", "it": "Marocco"}, - 149: {"de": "Mosambik", "fr": "Mozambique", "it": "Mozambico"}, - 150: {"de": "Myanmar", "fr": "Myanmar", "it": "Myanmar"}, - 151: {"de": "Namibia", "fr": "Namibie", "it": "Namibia"}, - 152: {"de": "Nauru", "fr": "Nauru", "it": "Nauru"}, - 153: {"de": "Nepal", "fr": "Népal", "it": "Nepal"}, - 154: {"de": "Niederlande", "fr": "Pays-Bas", "it": "Paesi Bassi"}, - 157: {"de": "Neuseeland", "fr": "Nouvelle-Zélande", "it": "Nuova Zelanda"}, - 158: {"de": "Nicaragua", "fr": "Nicaragua", "it": "Nicaragua"}, - 159: {"de": "Niger", "fr": "Niger", "it": "Niger"}, - 160: {"de": "Nigeria", "fr": "Nigeria", "it": "Nigeria"}, - 164: {"de": "Norwegen", "fr": "Norvège", "it": "Norvegia"}, - 165: {"de": "Oman", "fr": "Oman", "it": "Oman"}, - 166: {"de": "Pakistan", "fr": "Pakistan", "it": "Pakistan"}, - 167: {"de": "Palau", "fr": "Palau", "it": "Palau"}, - 168: {"de": "Panama", "fr": "Panama", "it": "Panama"}, + 131: { + "de": "Madagaskar", + "fr": "Madagascar", + "it": "Madagascar", + "country_code": "MG", + }, + 132: {"de": "Malawi", "fr": "Malawi", "it": "Malawi", "country_code": "MW"}, + 133: {"de": "Malaysia", "fr": "Malaisie", "it": "Malesia", "country_code": "MY"}, + 134: {"de": "Malediven", "fr": "Maldives", "it": "Maldive", "country_code": "MV"}, + 135: {"de": "Mali", "fr": "Mali", "it": "Mali", "country_code": "ML"}, + 136: {"de": "Malta", "fr": "Malte", "it": "Malta", "country_code": "MT"}, + 137: { + "de": "Marshall Inseln", + "fr": "Iles Marshall", + "it": "Isole Marshall", + "country_code": "MH", + }, + 139: { + "de": "Mauretanien", + "fr": "Mauritanie", + "it": "Mauritania", + "country_code": "MR", + }, + 140: { + "de": "Mauritius", + "fr": "Ile Maurice", + "it": "Mauritius", + "country_code": "MU", + }, + 142: {"de": "Mexico", "fr": "Mexique", "it": "Messico", "country_code": "MX"}, + 143: { + "de": "Mikronesien", + "fr": "Micronésie", + "it": "Micronesia", + "country_code": "FM", + }, + 144: {"de": "Moldavien", "fr": "Moldavie", "it": "Moldova", "country_code": "MD"}, + 145: {"de": "Monaco", "fr": "Monaco", "it": "Monaco", "country_code": "MC"}, + 146: {"de": "Mongolei", "fr": "Mongolie", "it": "Mongolia", "country_code": "MN"}, + 148: {"de": "Marokko", "fr": "Morocco", "it": "Marocco", "country_code": "MA"}, + 149: { + "de": "Mosambik", + "fr": "Mozambique", + "it": "Mozambico", + "country_code": "MZ", + }, + 150: {"de": "Myanmar", "fr": "Myanmar", "it": "Myanmar", "country_code": "MM"}, + 151: {"de": "Namibia", "fr": "Namibie", "it": "Namibia", "country_code": "NA"}, + 152: {"de": "Nauru", "fr": "Nauru", "it": "Nauru", "country_code": "NR"}, + 153: {"de": "Nepal", "fr": "Népal", "it": "Nepal", "country_code": "NP"}, + 154: { + "de": "Niederlande", + "fr": "Pays-Bas", + "it": "Paesi Bassi", + "country_code": "NL", + }, + 157: { + "de": "Neuseeland", + "fr": "Nouvelle-Zélande", + "it": "Nuova Zelanda", + "country_code": "NZ", + }, + 158: { + "de": "Nicaragua", + "fr": "Nicaragua", + "it": "Nicaragua", + "country_code": "NI", + }, + 159: {"de": "Niger", "fr": "Niger", "it": "Niger", "country_code": "NE"}, + 160: {"de": "Nigeria", "fr": "Nigeria", "it": "Nigeria", "country_code": "NG"}, + 164: {"de": "Norwegen", "fr": "Norvège", "it": "Norvegia", "country_code": "NO"}, + 165: {"de": "Oman", "fr": "Oman", "it": "Oman", "country_code": "OM"}, + 166: {"de": "Pakistan", "fr": "Pakistan", "it": "Pakistan", "country_code": "PK"}, + 167: {"de": "Palau", "fr": "Palau", "it": "Palau", "country_code": "PW"}, + 168: {"de": "Panama", "fr": "Panama", "it": "Panama", "country_code": "PA"}, 170: { "de": "Papua-Neuguinea", "fr": "Papouasie Nouvelle-Guinée", "it": "Papua Nuova Guinea", + "country_code": "PG", }, - 171: {"de": "Paraguay", "fr": "Paraguay", "it": "Paraguay"}, - 172: {"de": "Peru", "fr": "Pérou", "it": "Perù"}, - 173: {"de": "Philippinen", "fr": "Philippines", "it": "Filippine"}, - 175: {"de": "Polen", "fr": "Pologne", "it": "Polonia"}, - 176: {"de": "Portugal", "fr": "Portugal", "it": "Portogallo"}, - 178: {"de": "Katar", "fr": "Qatar", "it": "Qatar"}, - 180: {"de": "Rumänien", "fr": "Roumanie", "it": "Romania"}, - 181: {"de": "Russische Föderation", "fr": "Russie", "it": "Russia"}, - 182: {"de": "Ruanda", "fr": "Ruanda", "it": "Ruanda"}, + 171: {"de": "Paraguay", "fr": "Paraguay", "it": "Paraguay", "country_code": "PY"}, + 172: {"de": "Peru", "fr": "Pérou", "it": "Perù", "country_code": "PE"}, + 173: { + "de": "Philippinen", + "fr": "Philippines", + "it": "Filippine", + "country_code": "PH", + }, + 175: {"de": "Polen", "fr": "Pologne", "it": "Polonia", "country_code": "PL"}, + 176: {"de": "Portugal", "fr": "Portugal", "it": "Portogallo", "country_code": "PT"}, + 178: {"de": "Katar", "fr": "Qatar", "it": "Qatar", "country_code": "QA"}, + 180: {"de": "Rumänien", "fr": "Roumanie", "it": "Romania", "country_code": "RO"}, + 181: { + "de": "Russische Föderation", + "fr": "Russie", + "it": "Russia", + "country_code": "RU", + }, + 182: {"de": "Ruanda", "fr": "Ruanda", "it": "Ruanda", "country_code": "RW"}, 183: { "de": "Saint Kitts und Nevis", "fr": "Saint-Kitts-et-Nevis", "it": "Saint Kitts e Nevis", + "country_code": "KN", + }, + 184: { + "de": "St. Lucia", + "fr": "Sainte-Lucie", + "it": "Santa Lucia", + "country_code": "LC", }, - 184: {"de": "St. Lucia", "fr": "Sainte-Lucie", "it": "Santa Lucia"}, 185: { "de": "St. Vincent und die Grenadinen", "fr": "Saint-Vincent-et-Les Grenadines", "it": "Saint Vincent e Grenadine", + "country_code": "VC", + }, + 186: {"de": "Samoa", "fr": "Samoa", "it": "Samoa", "country_code": "WS"}, + 187: { + "de": "San Marino", + "fr": "San Marino", + "it": "San Marino", + "country_code": "SM", }, - 186: {"de": "Samoa", "fr": "Samoa", "it": "Samoa"}, - 187: {"de": "San Marino", "fr": "San Marino", "it": "San Marino"}, 188: { "de": "Sao Tome und Principe", "fr": "Sao Tomé-et-Principe", "it": "São Tomé e Principe", + "country_code": "ST", }, - 189: {"de": "Saudi-Arabien", "fr": "Arabie Saoudite", "it": "Arabia Saudita"}, - 190: {"de": "Senegal", "fr": "Sénégal", "it": "Senegal"}, - 191: {"de": "Seychellen", "fr": "Seychelles", "it": "Seychelles"}, - 192: {"de": "Sierra Leone", "fr": "Sierra Leone", "it": "Sierra Leone"}, - 193: {"de": "Singapur", "fr": "Singapour", "it": "Singapore"}, - 194: {"de": "Slowakei", "fr": "Slovaquie", "it": "Slovacchia"}, - 195: {"de": "Slowenien", "fr": "Slovénie", "it": "Slovenia"}, - 196: {"de": "Salomonen", "fr": "Iles Salomon", "it": "Salomone"}, - 197: {"de": "Somalia", "fr": "Somalie", "it": "Somalia"}, - 198: {"de": "Südafrika", "fr": "Afrique du Sud", "it": "Africa del Sud"}, - 200: {"de": "Spanien", "fr": "Espagne", "it": "Spagna"}, - 201: {"de": "Sri Lanka", "fr": "Sri Lanka", "it": "Sri Lanka"}, - 204: {"de": "Sudan", "fr": "Soudan", "it": "Sudan"}, - 205: {"de": "Suriname", "fr": "Suriname", "it": "Suriname"}, - 207: {"de": "Swasiland", "fr": "Swaziland", "it": "Swaziland"}, - 208: {"de": "Schweden", "fr": "Suède", "it": "Svezia"}, - 209: {"de": "Schweiz", "fr": "Suisse", "it": "Svizzera"}, - 210: {"de": "Syrien", "fr": "Syrie", "it": "Siria"}, - 211: {"de": "Taiwan", "fr": "Taïwan", "it": "Taiwan"}, - 212: {"de": "Tadschikistan", "fr": "Tadjikistan", "it": "Tagikistan"}, - 213: {"de": "Tansania", "fr": "Tanzanie", "it": "Tanzania"}, - 214: {"de": "Thailand", "fr": "Thaïlande", "it": "Tailandia"}, - 215: {"de": "Togo", "fr": "Togo", "it": "Togo"}, - 217: {"de": "Tonga", "fr": "Tonga", "it": "Tonga"}, + 189: { + "de": "Saudi-Arabien", + "fr": "Arabie Saoudite", + "it": "Arabia Saudita", + "country_code": "SA", + }, + 190: {"de": "Senegal", "fr": "Sénégal", "it": "Senegal", "country_code": "SN"}, + 191: { + "de": "Seychellen", + "fr": "Seychelles", + "it": "Seychelles", + "country_code": "SC", + }, + 192: { + "de": "Sierra Leone", + "fr": "Sierra Leone", + "it": "Sierra Leone", + "country_code": "SL", + }, + 193: {"de": "Singapur", "fr": "Singapour", "it": "Singapore", "country_code": "SG"}, + 194: { + "de": "Slowakei", + "fr": "Slovaquie", + "it": "Slovacchia", + "country_code": "SK", + }, + 195: {"de": "Slowenien", "fr": "Slovénie", "it": "Slovenia", "country_code": "SI"}, + 196: { + "de": "Salomonen", + "fr": "Iles Salomon", + "it": "Salomone", + "country_code": "SB", + }, + 197: {"de": "Somalia", "fr": "Somalie", "it": "Somalia", "country_code": "SO"}, + 198: { + "de": "Südafrika", + "fr": "Afrique du Sud", + "it": "Africa del Sud", + "country_code": "ZA", + }, + 200: {"de": "Spanien", "fr": "Espagne", "it": "Spagna", "country_code": "ES"}, + 201: { + "de": "Sri Lanka", + "fr": "Sri Lanka", + "it": "Sri Lanka", + "country_code": "LK", + }, + 204: {"de": "Sudan", "fr": "Soudan", "it": "Sudan", "country_code": "SD"}, + 205: {"de": "Suriname", "fr": "Suriname", "it": "Suriname", "country_code": "SR"}, + 207: { + "de": "Swasiland", + "fr": "Swaziland", + "it": "Swaziland", + "country_code": "SZ", + }, + 208: {"de": "Schweden", "fr": "Suède", "it": "Svezia", "country_code": "SE"}, + 209: { + "de": "Schweiz", + "fr": "Suisse", + "it": "Svizzera", + "country_code": "CH", + "order_id": 1.0, + }, + 210: {"de": "Syrien", "fr": "Syrie", "it": "Siria", "country_code": "SY"}, + 211: {"de": "Taiwan", "fr": "Taïwan", "it": "Taiwan", "country_code": "TW"}, + 212: { + "de": "Tadschikistan", + "fr": "Tadjikistan", + "it": "Tagikistan", + "country_code": "TJ", + }, + 213: {"de": "Tansania", "fr": "Tanzanie", "it": "Tanzania", "country_code": "TZ"}, + 214: {"de": "Thailand", "fr": "Thaïlande", "it": "Tailandia", "country_code": "TH"}, + 215: {"de": "Togo", "fr": "Togo", "it": "Togo", "country_code": "TG"}, + 217: {"de": "Tonga", "fr": "Tonga", "it": "Tonga", "country_code": "TO"}, 218: { "de": "Trinidad und Tobago", "fr": "Trinité-et-Tobago", "it": "Trinidad e Tobago", + "country_code": "TT", }, - 219: {"de": "Tunesien", "fr": "Tunisie", "it": "Tunisia"}, - 220: {"de": "Türkei", "fr": "Turchia", "it": "Turchia"}, - 221: {"de": "Turkmenistan", "fr": "Turkménistan", "it": "Turkmenistan"}, - 223: {"de": "Tuvalu", "fr": "Tuvalu", "it": "Tuvalu"}, - 224: {"de": "Uganda", "fr": "Ouganda", "it": "Uganda"}, - 225: {"de": "Ukraine", "fr": "Ukraine", "it": "Ucraina"}, + 219: {"de": "Tunesien", "fr": "Tunisie", "it": "Tunisia", "country_code": "TN"}, + 220: {"de": "Türkei", "fr": "Turchia", "it": "Turchia", "country_code": "TR"}, + 221: { + "de": "Turkmenistan", + "fr": "Turkménistan", + "it": "Turkmenistan", + "country_code": "TM", + }, + 223: {"de": "Tuvalu", "fr": "Tuvalu", "it": "Tuvalu", "country_code": "TV"}, + 224: {"de": "Uganda", "fr": "Ouganda", "it": "Uganda", "country_code": "UG"}, + 225: {"de": "Ukraine", "fr": "Ukraine", "it": "Ucraina", "country_code": "UA"}, 226: { "de": "Vereinigte Arabische Emirate", "fr": "Émirats Arabes Unis", "it": "Emirati Arabi Uniti", + "country_code": "AE", }, - 227: {"de": "Großbritannien", "fr": "Royaume-Uni", "it": "Regno Unito"}, - 228: {"de": "USA", "fr": "États-Unis", "it": "Stati Uniti d´ America"}, - 230: {"de": "Uruguay", "fr": "Uruguay", "it": "Uruguay"}, - 231: {"de": "Usbekistan", "fr": "Ouzbékistan", "it": "Uzbekistan"}, - 232: {"de": "Vanuatu", "fr": "Vanuatu", "it": "Vanuatu"}, - 233: {"de": "Vatikanstadt", "fr": "Vatican", "it": "Città del Vaticano"}, - 234: {"de": "Venezuela", "fr": "Venezuela", "it": "Venezuela"}, - 235: {"de": "Vietnam", "fr": "Viêtnam", "it": "Vietnam"}, - 239: {"de": "Sahara", "fr": "Sahara", "it": "Sahara"}, - 240: {"de": "Jemen", "fr": "Yémen", "it": "Yemen"}, - 241: {"de": "Serbien", "fr": "Serbie", "it": "Serbia"}, - 242: {"de": "Montenegro", "fr": "Monténégro", "it": "Montenegro"}, - 243: {"de": "Sambia", "fr": "Zambie", "it": "Zambia"}, - 244: {"de": "Simbabwe", "fr": "Zimbabwe", "it": "Zimbabwe"}, - 245: {"de": "Hong Kong", "fr": "Hong Kong", "it": "Hong Kong"}, - 246: {"de": "Falkland Inseln", "fr": "Îles Malouines", "it": "Isole Falkland"}, - 247: {"de": "Aruba", "fr": "Aruba", "it": "Aruba"}, - 248: {"de": "Bermuda", "fr": "Bermudes", "it": "Bermuda"}, + 227: { + "de": "Großbritannien", + "fr": "Royaume-Uni", + "it": "Regno Unito", + "country_code": "GB", + }, + 228: { + "de": "USA", + "fr": "États-Unis", + "it": "Stati Uniti d´ America", + "country_code": "US", + }, + 230: {"de": "Uruguay", "fr": "Uruguay", "it": "Uruguay", "country_code": "UY"}, + 231: { + "de": "Usbekistan", + "fr": "Ouzbékistan", + "it": "Uzbekistan", + "country_code": "UZ", + }, + 232: {"de": "Vanuatu", "fr": "Vanuatu", "it": "Vanuatu", "country_code": "VU"}, + 233: { + "de": "Vatikanstadt", + "fr": "Vatican", + "it": "Città del Vaticano", + "country_code": "VA", + }, + 234: { + "de": "Venezuela", + "fr": "Venezuela", + "it": "Venezuela", + "country_code": "VE", + }, + 235: {"de": "Vietnam", "fr": "Viêtnam", "it": "Vietnam", "country_code": "VN"}, + 239: {"de": "Sahara", "fr": "Sahara", "it": "Sahara", "country_code": "EH"}, + 240: {"de": "Jemen", "fr": "Yémen", "it": "Yemen", "country_code": "YE"}, + 241: {"de": "Serbien", "fr": "Serbie", "it": "Serbia", "country_code": "RS"}, + 242: { + "de": "Montenegro", + "fr": "Monténégro", + "it": "Montenegro", + "country_code": "ME", + }, + 243: {"de": "Sambia", "fr": "Zambie", "it": "Zambia", "country_code": "ZM"}, + 244: {"de": "Simbabwe", "fr": "Zimbabwe", "it": "Zimbabwe", "country_code": "ZW"}, + 245: { + "de": "Hong Kong", + "fr": "Hong Kong", + "it": "Hong Kong", + "country_code": "HK", + }, + 246: { + "de": "Falkland Inseln", + "fr": "Îles Malouines", + "it": "Isole Falkland", + "country_code": "FK", + }, + 247: {"de": "Aruba", "fr": "Aruba", "it": "Aruba", "country_code": "AW"}, + 248: {"de": "Bermuda", "fr": "Bermudes", "it": "Bermuda", "country_code": "BM"}, 249: { "de": "Britische Jungferninseln", "fr": "Îles Vierges britanniques", "it": "Isole Vergini britanniche", + "country_code": "VG", + }, + 250: {"de": "Curaçao", "fr": "Curaçao", "it": "Curaçao", "country_code": "CW"}, + 251: {"de": "Anguilla", "fr": "Anguilla", "it": "Anguilla", "country_code": "AI"}, + 252: { + "de": "Montserrat", + "fr": "Montserrat", + "it": "Montserrat", + "country_code": "MS", }, - 250: {"de": "Curaçao", "fr": "Curaçao", "it": "Curaçao"}, - 251: {"de": "Anguilla", "fr": "Anguilla", "it": "Anguilla"}, - 252: {"de": "Montserrat", "fr": "Montserrat", "it": "Montserrat"}, 253: { "de": "Bonaire, Sint Eustatius und Saba", "fr": "Bonaire, Saint-Eustache et Saba", "it": "Bonaire, Sint Eustatius e Saba", + "country_code": "BQ", + }, + 254: { + "de": "Cayman Inseln", + "fr": "Îles Caïmans", + "it": "Isole Cayman", + "country_code": "KY", + }, + 255: { + "de": "Sint Maarten", + "fr": "Saint-Martin", + "it": "Sint Maarten", + "country_code": "SX", }, - 254: {"de": "Cayman Inseln", "fr": "Îles Caïmans", "it": "Isole Cayman"}, - 255: {"de": "Sint Maarten", "fr": "Saint-Martin", "it": "Sint Maarten"}, 256: { "de": "Turks- und Caicos-Inseln", "fr": "Îles Turks et Caïques", "it": "Turks e Caicos", + "country_code": "TC", + }, + 257: { + "de": "Saint-Barth", + "fr": "Saint-Barthélemy", + "it": "Saint-Barth", + "country_code": "BL", }, - 257: {"de": "Saint-Barth", "fr": "Saint-Barthélemy", "it": "Saint-Barth"}, 258: { "de": "Palästinensisches Gebiet", "fr": "Territoires palestiniens occupés", "it": "Territori palestinesi", + "country_code": "PS", + }, + 259: {"de": "Kosovo", "fr": "Kosovo", "it": "Kosovo", "country_code": "XK"}, + 260: { + "de": "Gibraltar", + "fr": "Gibraltar", + "it": "Gibilterra", + "country_code": "GI", + }, + 261: { + "de": "Neukaledonien", + "fr": "Nouvelle-Calédonie", + "it": "Nuova Caledonia", + "country_code": "NC", }, - 259: {"de": "Kosovo", "fr": "Kosovo", "it": "Kosovo"}, - 260: {"de": "Gibraltar", "fr": "Gibraltar", "it": "Gibilterra"}, - 261: {"de": "Neukaledonien", "fr": "Nouvelle-Calédonie", "it": "Nuova Caledonia"}, 262: { "de": "Französisch-Polynesien", "fr": "Polynésie française", "it": "Polinesia francese", + "country_code": "PF", }, 310: { "de": "Niederländische Antillen", "fr": "Antilles néerlandaises", "it": "Antille olandesi", + "country_code": "AN", + }, + 311: { + "de": "Antarktika", + "fr": "Antarctique", + "it": "Antartide", + "country_code": "AQ", }, - 311: {"de": "Antarktika", "fr": "Antarctique", "it": "Antartide"}, 312: { "de": "Amerikanisch-Samoa", "fr": "Samoa américaines", "it": "Samoa americane", + "country_code": "AS", + }, + 313: {"de": "Åland", "fr": "Åland", "it": "Åland", "country_code": "AX"}, + 314: { + "de": "Bouvetinsel", + "fr": "Île Bouvet", + "it": "Isola Bouvet", + "country_code": "BV", + }, + 315: { + "de": "Kokosinseln", + "fr": "Îles Cocos", + "it": "Isole Cocos (Keeling)", + "country_code": "CC", + }, + 316: { + "de": "Cookinseln", + "fr": "Îles Cook", + "it": "Isole Cook", + "country_code": "CK", }, - 313: {"de": "Åland", "fr": "Åland", "it": "Åland"}, - 314: {"de": "Bouvetinsel", "fr": "Île Bouvet", "it": "Isola Bouvet"}, - 315: {"de": "Kokosinseln", "fr": "Îles Cocos", "it": "Isole Cocos (Keeling)"}, - 316: {"de": "Cookinseln", "fr": "Îles Cook", "it": "Isole Cook"}, 317: { "de": "Clipperton-Insel", "fr": "Île de Clipperton", "it": "Isola di Clipperton", + "country_code": "CP", + }, + 318: { + "de": "Weihnachtsinsel", + "fr": "Île Christmas", + "it": "Isola di Natale", + "country_code": "CX", + }, + 319: { + "de": "Färöer-Inseln", + "fr": "Îles Féroé", + "it": "Isole Färöer", + "country_code": "FO", }, - 318: {"de": "Weihnachtsinsel", "fr": "Île Christmas", "it": "Isola di Natale"}, - 319: {"de": "Färöer-Inseln", "fr": "Îles Féroé", "it": "Isole Färöer"}, 320: { "de": "Französisch-Guayana", "fr": "Guyane française", "it": "Guyana francese", + "country_code": "GF", + }, + 321: {"de": "Guernsey", "fr": "Guernsey", "it": "Guernsey", "country_code": "GG"}, + 322: { + "de": "Grönland", + "fr": "Groenland", + "it": "Groenlandia", + "country_code": "GL", + }, + 323: { + "de": "Guadeloupe", + "fr": "Guadeloupe", + "it": "Guadalupa", + "country_code": "GP", }, - 321: {"de": "Guernsey", "fr": "Guernsey", "it": "Guernsey"}, - 322: {"de": "Grönland", "fr": "Groenland", "it": "Groenlandia"}, - 323: {"de": "Guadeloupe", "fr": "Guadeloupe", "it": "Guadalupa"}, 324: { "de": "Südgeorgien und die Südlichen Sandwichinseln", "fr": "Géorgie du Sud et Îles Sandwich du Sud", "it": "Georgia del Sud e Sandwich Australi", + "country_code": "GS", }, - 325: {"de": "Guam", "fr": "Guam", "it": "Guam"}, + 325: {"de": "Guam", "fr": "Guam", "it": "Guam", "country_code": "GU"}, 326: { "de": "Heard und McDonaldinseln", "fr": "Îles Heard et McDonald", "it": "Isola Heard e Isole McDonald", + "country_code": "HM", + }, + 327: { + "de": "Insel Man", + "fr": "Île de Man", + "it": "Isola di Man", + "country_code": "IM", }, - 327: {"de": "Insel Man", "fr": "Île de Man", "it": "Isola di Man"}, 328: { "de": "Britisches Territorium im Indischen Ozean", "fr": "Territoire britannique de l´océan Indien", "it": "Territori Britannici dell´Oceano Indiano", + "country_code": "IO", }, - 329: {"de": "Jersey", "fr": "Jersey", "it": "Jersey"}, - 330: {"de": "Saint-Martin", "fr": "Saint-Martin", "it": "Saint Martin"}, - 331: {"de": "Macau", "fr": "Macao", "it": "Macao"}, + 329: {"de": "Jersey", "fr": "Jersey", "it": "Jersey", "country_code": "JE"}, + 330: { + "de": "Saint-Martin", + "fr": "Saint-Martin", + "it": "Saint Martin", + "country_code": "MF", + }, + 331: {"de": "Macau", "fr": "Macao", "it": "Macao", "country_code": "MO"}, 332: { "de": "Nördliche Marianen", "fr": "Îles Mariannes du Nord", "it": "Isole Marianne Settentrionali", + "country_code": "MP", }, - 333: {"de": "Martinique", "fr": "Martinique", "it": "Martinica"}, - 334: {"de": "Norfolkinsel", "fr": "Île Norfolk", "it": "Isola Norfolk"}, - 335: {"de": "Niue", "fr": "Niue", "it": "Niue"}, + 333: { + "de": "Martinique", + "fr": "Martinique", + "it": "Martinica", + "country_code": "MQ", + }, + 334: { + "de": "Norfolkinsel", + "fr": "Île Norfolk", + "it": "Isola Norfolk", + "country_code": "NF", + }, + 335: {"de": "Niue", "fr": "Niue", "it": "Niue", "country_code": "NU"}, 336: { "de": "Saint-Pierre und Miquelon", "fr": "Saint-Pierre-et-Miquelon", "it": "Saint-Pierre e Miquelon", + "country_code": "PM", + }, + 337: { + "de": "Pitcairninseln", + "fr": "Îles Pitcairn", + "it": "Isole Pitcairn", + "country_code": "PN", + }, + 338: { + "de": "Puerto Rico", + "fr": "Porto Rico", + "it": "Porto Rico", + "country_code": "PR", + }, + 339: { + "de": "La Réunion", + "fr": "La Réunion", + "it": "Isola della Riunione", + "country_code": "RE", }, - 337: {"de": "Pitcairninseln", "fr": "Îles Pitcairn", "it": "Isole Pitcairn"}, - 338: {"de": "Puerto Rico", "fr": "Porto Rico", "it": "Porto Rico"}, - 339: {"de": "La Réunion", "fr": "La Réunion", "it": "Isola della Riunione"}, 340: { "de": "St. Helena, Ascension und Tristan da Cunha", "fr": "Sainte-Hélène, Ascension et Tristan da Cunha", "it": "Sant´Elena, Ascensione e Tristan da Cunha", + "country_code": "SH", }, 341: { "de": "Spitzbergen, Jan Mayen", "fr": "Spitzberg, Jan Mayen", "it": "Svalbard e Jan Mayen", + "country_code": "SJ", + }, + 342: { + "de": "Südsudan", + "fr": "Sud-Soudan", + "it": "Sudan del Sud", + "country_code": "SS", }, - 342: {"de": "Südsudan", "fr": "Sud-Soudan", "it": "Sudan del Sud"}, 343: { "de": "Französische Süd- und Antarktisgebiete", "fr": "Terres australes et antarctiques françaises", "it": "Territori australi e antartico francese", + "country_code": "TF", }, - 344: {"de": "Tokelau", "fr": "Tokelau", "it": "Tokelau"}, + 344: {"de": "Tokelau", "fr": "Tokelau", "it": "Tokelau", "country_code": "TK"}, 345: { "de": "United States Minor Outlying Islands", "fr": "Îles mineures éloignées des États-Unis", "it": "Isole Minori Esterne degli Stati Uniti", + "country_code": "UM", }, 346: { "de": "Amerikanische Jungferninseln", "fr": "Îles Vierges américaines", "it": "Isole Vergini Americane", + "country_code": "VI", }, - 347: {"de": "Wallis und Futuna", "fr": "Wallis et Futuna", "it": "Wallis e Futuna"}, - 348: {"de": "Mayotte", "fr": "Mayotte", "it": "Mayotte"}, + 347: { + "de": "Wallis und Futuna", + "fr": "Wallis et Futuna", + "it": "Wallis e Futuna", + "country_code": "WF", + }, + 348: {"de": "Mayotte", "fr": "Mayotte", "it": "Mayotte", "country_code": "YT"}, } @@ -591,13 +1018,29 @@ def add_countries(apps=None, schema_editor=None): else: Country = apps.get_model("core", "Country") + has_country_code = any( + field.name == "country_code" for field in Country._meta.get_fields() + ) + for country_id, country_name in countries.items(): - Country.objects.get_or_create( - country_id=country_id, - name_de=country_name["de"], - name_fr=country_name["fr"], - name_it=country_name["it"], - ) + country_code = country_name["country_code"] + + if has_country_code: + Country.objects.get_or_create( + country_code=country_code, + vbv_country_id=country_id, + name_de=country_name["de"], + name_fr=country_name["fr"], + name_it=country_name["it"], + order_id=country_name.get("order_id", 20.0), + ) + else: + Country.objects.get_or_create( + country_id=country_id, + name_de=country_name["de"], + name_fr=country_name["fr"], + name_it=country_name["it"], + ) def remove_countries(apps=None, schema_editor=None): @@ -606,7 +1049,6 @@ def remove_countries(apps=None, schema_editor=None): from vbv_lernwelt.core.models import Country else: Country = apps.get_model("core", "Country") - for country_id in countries.keys(): Country.objects.filter( country_id=country_id, diff --git a/server/vbv_lernwelt/core/models.py b/server/vbv_lernwelt/core/models.py index f75b5d5c..c6f12b88 100644 --- a/server/vbv_lernwelt/core/models.py +++ b/server/vbv_lernwelt/core/models.py @@ -25,19 +25,20 @@ class Organisation(models.Model): class Country(models.Model): - country_id = models.IntegerField(primary_key=True) + country_code = models.CharField(max_length=2, primary_key=True) + vbv_country_id = models.IntegerField(primary_key=False) name_de = models.CharField(max_length=255) name_fr = models.CharField(max_length=255) name_it = models.CharField(max_length=255) order_id = models.FloatField(default=20) def __str__(self): - return f"{self.name_de} ({self.country_id})" + return f"{self.name_de} ({self.country_code}) ({self.vbv_country_id})" class Meta: verbose_name = "Country" verbose_name_plural = "Countries" - ordering = ["order_id", "country_id"] + ordering = ["order_id", "vbv_country_id"] class User(AbstractUser): diff --git a/server/vbv_lernwelt/core/serializers.py b/server/vbv_lernwelt/core/serializers.py index e836dd52..435ed187 100644 --- a/server/vbv_lernwelt/core/serializers.py +++ b/server/vbv_lernwelt/core/serializers.py @@ -14,12 +14,11 @@ def create_json_from_objects(objects, serializer_class, many=True) -> str: class CountrySerializer(serializers.ModelSerializer): - id = serializers.IntegerField(source="country_id", read_only=True) name = serializers.SerializerMethodField() class Meta: model = Country - fields = ["id", "name"] + fields = ["country_code", "vbv_country_id", "name"] def get_name(self, obj): language = self.context.get("langauge") @@ -32,11 +31,15 @@ class CountrySerializer(serializers.ModelSerializer): return obj.name_de def to_internal_value(self, data): - country_id = data.get("id") - if country_id is not None: + country_code = data.get("country_code") + if country_code is not None: try: - country = Country.objects.get(country_id=country_id) - return {"id": country.country_id, "name": self.get_name(country)} + country = Country.objects.get(country_code=country_code) + return { + "country_code": country.country_code, + "vbv_country_id": country.vbv_country_id, + "name": self.get_name(country), + } except Country.DoesNotExist: raise serializers.ValidationError({"id": "Invalid country ID"}) return super().to_internal_value(data) @@ -105,14 +108,14 @@ class UserSerializer(serializers.ModelSerializer): setattr(instance, attr, value) if country_data is not None: - country_id = country_data.get("id") - country_instance = Country.objects.filter(country_id=country_id).first() + country_code = country_data.get("country_code") + country_instance = Country.objects.filter(country_code=country_code).first() instance.country = country_instance if organisation_country_data is not None: - organisation_country_id = organisation_country_data.get("id") + organisation_country_code = organisation_country_data.get("country_code") organisation_country_instance = Country.objects.filter( - country_id=organisation_country_id + country_code=organisation_country_code ).first() instance.organisation_country = organisation_country_instance diff --git a/server/vbv_lernwelt/shop/README.md b/server/vbv_lernwelt/shop/README.md index 008a056b..95fed595 100644 --- a/server/vbv_lernwelt/shop/README.md +++ b/server/vbv_lernwelt/shop/README.md @@ -74,3 +74,6 @@ After everything runs fine, we should be able to remove the following deprecated 8. `IT_OAUTH_SCOPE` +### Datatrans Test Credit Card + +5100 0010 0000 0014 06/25 123 diff --git a/server/vbv_lernwelt/shop/migrations/0009_alter_checkoutinformation_product_price.py b/server/vbv_lernwelt/shop/migrations/0009_alter_checkoutinformation_product_price.py index 01f1b3a8..1a75c7ae 100644 --- a/server/vbv_lernwelt/shop/migrations/0009_alter_checkoutinformation_product_price.py +++ b/server/vbv_lernwelt/shop/migrations/0009_alter_checkoutinformation_product_price.py @@ -3,6 +3,16 @@ from django.db import migrations, models +def add_default_shop_product(apps, schema_editor): + Product = apps.get_model("shop", "Product") + Product.objects.create( + sku="vv-de", + name="Versicherungsvermittler/-in VBV", + description="Versicherungsvermittler/-in VBV DE", + price=324_00, + ) + + class Migration(migrations.Migration): dependencies = [ ("shop", "0008_auto_20231117_0905"), @@ -16,4 +26,5 @@ class Migration(migrations.Migration): help_text="The total price of the product in centimes -> 1000 = 10.00 CHF" ), ), + migrations.RunPython(add_default_shop_product), ] diff --git a/server/vbv_lernwelt/shop/migrations/0013_checkoutinformation_abacus_order_id.py b/server/vbv_lernwelt/shop/migrations/0013_checkoutinformation_abacus_order_id.py index b133a813..52682190 100644 --- a/server/vbv_lernwelt/shop/migrations/0013_checkoutinformation_abacus_order_id.py +++ b/server/vbv_lernwelt/shop/migrations/0013_checkoutinformation_abacus_order_id.py @@ -4,15 +4,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0012_delete_country'), + ("shop", "0012_delete_country"), ] operations = [ migrations.AddField( - model_name='checkoutinformation', - name='abacus_order_id', + model_name="checkoutinformation", + name="abacus_order_id", field=models.BigIntegerField(blank=True, null=True, unique=True), ), ] diff --git a/server/vbv_lernwelt/shop/tests/test_invoice.py b/server/vbv_lernwelt/shop/tests/test_invoice.py index 48ac5f4d..ea16936b 100644 --- a/server/vbv_lernwelt/shop/tests/test_invoice.py +++ b/server/vbv_lernwelt/shop/tests/test_invoice.py @@ -7,10 +7,10 @@ from vbv_lernwelt.core.admin import User from vbv_lernwelt.core.create_default_users import create_default_users from vbv_lernwelt.shop.invoice.abacus import ( AbacusInvoiceCreator, - render_invoice_xml, - render_customer_xml, - create_invoice_xml, create_customer_xml, + create_invoice_xml, + render_customer_xml, + render_invoice_xml, ) from vbv_lernwelt.shop.invoice.repositories import InvoiceRepository from vbv_lernwelt.shop.models import CheckoutInformation diff --git a/server/vbv_lernwelt/shop/views.py b/server/vbv_lernwelt/shop/views.py index 06672826..c685a195 100644 --- a/server/vbv_lernwelt/shop/views.py +++ b/server/vbv_lernwelt/shop/views.py @@ -275,7 +275,9 @@ def update_user_address(user: User, checkout_info: CheckoutInformation): user.city = checkout_info.city if checkout_info.country: - user.country = Country.objects.filter(country_id=checkout_info.country).first() + user.country = Country.objects.filter( + country_code=checkout_info.country + ).first() if ( checkout_info.company_name @@ -292,7 +294,7 @@ def update_user_address(user: User, checkout_info: CheckoutInformation): user.organisation_city = checkout_info.company_city user.organisation_country = Country.objects.filter( - country_id=checkout_info.company_country + country_code=checkout_info.company_country ).first() user.invoice_address = User.INVOICE_ADDRESS_ORGANISATION