diff --git a/integreat_cms/cms/fixtures/test_data.json b/integreat_cms/cms/fixtures/test_data.json
index e420f1084c..873ad8574f 100644
--- a/integreat_cms/cms/fixtures/test_data.json
+++ b/integreat_cms/cms/fixtures/test_data.json
@@ -997,6 +997,21 @@
"created_date": "2024-08-06T13:23:45.256Z"
}
},
+ {
+ "model": "cms.contact",
+ "pk": 4,
+ "fields": {
+ "title": "",
+ "name": "",
+ "location": 6,
+ "email": "generalcontactinformation@example.com",
+ "phone_number": "0123456789",
+ "website": "https://integreat-app.de/",
+ "archived": false,
+ "last_updated": "2024-08-06T13:23:45.256Z",
+ "created_date": "2024-08-06T13:23:45.256Z"
+ }
+ },
{
"model": "cms.recurrencerule",
"pk": 1,
diff --git a/integreat_cms/cms/models/contact/contact.py b/integreat_cms/cms/models/contact/contact.py
index c07395bc12..ecbba18787 100644
--- a/integreat_cms/cms/models/contact/contact.py
+++ b/integreat_cms/cms/models/contact/contact.py
@@ -2,6 +2,7 @@
from django.db.models import Q
from django.utils import timezone
from django.utils.functional import cached_property
+from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _
from ..abstract_base_model import AbstractBaseModel
diff --git a/integreat_cms/cms/templates/pois/poi_form.html b/integreat_cms/cms/templates/pois/poi_form.html
index e06df4ab7b..e8d38faf3a 100644
--- a/integreat_cms/cms/templates/pois/poi_form.html
+++ b/integreat_cms/cms/templates/pois/poi_form.html
@@ -167,6 +167,9 @@
{% include "./poi_form_sidebar/contact_box.html" with box_id="poi-contact" %}
+ {% if poi_form.instance.id and perms.cms.view_contact %}
+ {% include "./poi_form_sidebar/related_contacts_box.html" with box_id="poi-related-contacts" %}
+ {% endif %}
{% include "./poi_form_sidebar/opening_hours_box.html" with box_id="poi-opening-hours" no_padding=True %}
{% include "./poi_form_sidebar/category_box.html" with box_id="poi-category" %}
{% include "./poi_form_sidebar/icon_box.html" with box_id="poi-icon" %}
diff --git a/integreat_cms/cms/templates/pois/poi_form_sidebar/related_contacts_box.html b/integreat_cms/cms/templates/pois/poi_form_sidebar/related_contacts_box.html
new file mode 100644
index 0000000000..cd8022ef9e
--- /dev/null
+++ b/integreat_cms/cms/templates/pois/poi_form_sidebar/related_contacts_box.html
@@ -0,0 +1,28 @@
+{% extends "../../_collapsible_box.html" %}
+{% load i18n %}
+{% load widget_tweaks %}
+{% block collapsible_box_icon %}
+ message-square
+{% endblock collapsible_box_icon %}
+{% block collapsible_box_title %}
+ {% trans "Related contacts" %}
+{% endblock collapsible_box_title %}
+{% block collapsible_box_content %}
+ {% with poi_form.instance.contacts.all as contacts %}
+
+
+ {% if contacts %}
+ {% trans "This location is currently referred to in those contacts." %}
+ {% else %}
+ {% trans "This location is not currently referred to in any contact." %}
+ {% endif %}
+
+ {% for contact in contacts %}
+
+ {{ contact }}
+
+ {% endfor %}
+
+ {% endwith %}
+{% endblock collapsible_box_content %}
diff --git a/integreat_cms/locale/de/LC_MESSAGES/django.po b/integreat_cms/locale/de/LC_MESSAGES/django.po
index 0341c202e8..bc52cb5658 100644
--- a/integreat_cms/locale/de/LC_MESSAGES/django.po
+++ b/integreat_cms/locale/de/LC_MESSAGES/django.po
@@ -2259,7 +2259,8 @@ msgstr "Sprachen und Übersetzungen kopieren"
msgid ""
"Disable to skip copying of the language tree and all content translations."
msgstr ""
-"Abwählen, um das Kopieren des Sprachbaums und aller Inhaltsübersetzungen zu überspringen."
+"Abwählen, um das Kopieren des Sprachbaums und aller Inhaltsübersetzungen zu "
+"überspringen."
#: cms/forms/regions/region_form.py
msgid "Page based offers cloning behavior"
@@ -7706,6 +7707,18 @@ msgstr "Nur Koordinaten übernehmen"
msgid "Please choose one option or cancel"
msgstr "Bitte eine Option auswählen oder abbrechen"
+#: cms/templates/pois/poi_form_sidebar/related_contacts_box.html
+msgid "Related contacts"
+msgstr "Zugehörige Kontakte"
+
+#: cms/templates/pois/poi_form_sidebar/related_contacts_box.html
+msgid "This location is currently referred to in those contacts."
+msgstr "Dieser Ort wird in folgenden Kontakten verwendet."
+
+#: cms/templates/pois/poi_form_sidebar/related_contacts_box.html
+msgid "This location is not currently referred to in any contact."
+msgstr "Zur Zeit gibt es keine Kontakte zu diesem Ort."
+
#: cms/templates/pois/poi_list.html cms/templates/pois/poi_list_archived.html
msgid "Archived locations"
msgstr "Archivierte Orte"
@@ -11009,17 +11022,18 @@ msgstr ""
"Diese Seite konnte nicht importiert werden, da sie zu einer anderen Region "
"gehört ({})."
+#~ msgid "General contact information"
+#~ msgstr "Allgemeine Kontaktinformationen"
+
#~ msgid "{}{}"
#~ msgstr "{}{}"
#~ msgid " "
#~ msgstr " "
-#, python-format
#~ msgid "%s %s"
#~ msgstr "%s %s"
-#, python-format
#~ msgid "%s with %s"
#~ msgstr "%s mit %s"
diff --git a/tests/cms/views/contacts/test_contact_actions.py b/tests/cms/views/contacts/test_contact_actions.py
index 2cbb3e91e7..2b8810a31e 100644
--- a/tests/cms/views/contacts/test_contact_actions.py
+++ b/tests/cms/views/contacts/test_contact_actions.py
@@ -9,12 +9,12 @@ def test_copying_contact_works(
load_test_data: None,
login_role_user: tuple[Client, str],
) -> None:
- assert Contact.objects.all().count() == 3
+ assert Contact.objects.all().count() == 4
contact = Contact.objects.get(id=1)
contact.copy()
- assert Contact.objects.all().count() == 4
+ assert Contact.objects.all().count() == 5
@pytest.mark.django_db
@@ -22,12 +22,12 @@ def test_deleting_contact_works(
load_test_data: None,
login_role_user: tuple[Client, str],
) -> None:
- assert Contact.objects.all().count() == 3
+ assert Contact.objects.all().count() == 4
contact = Contact.objects.get(id=1)
contact.delete()
- assert Contact.objects.all().count() == 2
+ assert Contact.objects.all().count() == 3
@pytest.mark.django_db
@@ -35,13 +35,13 @@ def test_archiving_contact_works(
load_test_data: None,
login_role_user: tuple[Client, str],
) -> None:
- assert Contact.objects.all().count() == 3
+ assert Contact.objects.all().count() == 4
contact = Contact.objects.get(id=1)
assert contact.archived is False
contact.archive()
- assert Contact.objects.all().count() == 3
+ assert Contact.objects.all().count() == 4
assert contact.archived is True
@@ -50,11 +50,11 @@ def test_restoring_contact_works(
load_test_data: None,
login_role_user: tuple[Client, str],
) -> None:
- assert Contact.objects.all().count() == 3
+ assert Contact.objects.all().count() == 4
contact = Contact.objects.get(id=2)
assert contact.archived is True
contact.restore()
- assert Contact.objects.all().count() == 3
+ assert Contact.objects.all().count() == 4
assert contact.archived is False
diff --git a/tests/cms/views/poi/test_poi_form.py b/tests/cms/views/poi/test_poi_form.py
index 41d6411616..717e02ad9f 100644
--- a/tests/cms/views/poi/test_poi_form.py
+++ b/tests/cms/views/poi/test_poi_form.py
@@ -218,3 +218,106 @@ def test_poi_in_use_not_bulk_archived(
# Check the POI is not archived
assert not POI.objects.filter(id=poi_id).first().archived
+
+
+@pytest.mark.django_db
+def test_poi_form_shows_associated_contacts(
+ load_test_data: None,
+ login_role_user: tuple[Client, str],
+ settings: SettingsWrapper,
+) -> None:
+ """
+ POI "Draft location" (id=6) has three related contacts. Test whether they are shown in the POI form.
+ """
+ client, role = login_role_user
+
+ # Choose a POI which has related contacts
+ POI_ID = 6
+
+ # Set the language setting to English so assertion does not fail because of corresponding German sentence appearing instead the english one.
+ settings.LANGUAGE_CODE = "en"
+
+ poi = POI.objects.filter(id=POI_ID).first()
+ related_contacts = list(poi.contacts.all())
+
+ assert len(related_contacts) > 0
+
+ edit_poi = reverse(
+ "edit_poi",
+ kwargs={
+ "poi_id": poi.id,
+ "region_slug": poi.region.slug,
+ "language_slug": poi.region.default_language.slug,
+ },
+ )
+ response = client.get(edit_poi)
+
+ if role == ANONYMOUS:
+ assert response.status_code == 302
+ assert (
+ response.headers.get("location") == f"{settings.LOGIN_URL}?next={edit_poi}"
+ )
+ # probably needs adjustment after #2958
+ elif role in HIGH_PRIV_STAFF_ROLES:
+ for contact in related_contacts:
+ if contact.title and contact.name:
+ assert f"{contact.title} {contact.name}" in response.content.decode(
+ "utf-8"
+ )
+ else:
+ assert "General contact information" in response.content.decode("utf-8")
+ else:
+ assert (
+ "This location is currently referred to in those contacts."
+ not in response.content.decode("utf-8")
+ )
+
+
+@pytest.mark.django_db
+def test_poi_form_shows_no_associated_contacts(
+ load_test_data: None,
+ login_role_user: tuple[Client, str],
+ settings: SettingsWrapper,
+) -> None:
+ """
+ POI "Test location" (id=4) has no related contacts. Test whether the correct message is shown in the POi form.
+ """
+ client, role = login_role_user
+
+ # Choose a POI which has related contacts
+ POI_ID = 4
+
+ # Set the language setting to English so assertion does not fail because of corresponding German sentence appearing instead the english one.
+ settings.LANGUAGE_CODE = "en"
+
+ poi = POI.objects.filter(id=POI_ID).first()
+ related_contacts = list(poi.contacts.all())
+
+ assert len(related_contacts) == 0
+
+ edit_poi = reverse(
+ "edit_poi",
+ kwargs={
+ "poi_id": poi.id,
+ "region_slug": poi.region.slug,
+ "language_slug": poi.region.default_language.slug,
+ },
+ )
+ response = client.get(edit_poi)
+
+ if role == ANONYMOUS:
+ assert response.status_code == 302
+ assert (
+ response.headers.get("location") == f"{settings.LOGIN_URL}?next={edit_poi}"
+ )
+ # probably needs adjustment after #2958
+ elif role in HIGH_PRIV_STAFF_ROLES:
+ assert (
+ "This location is not currently referred to in any contact."
+ in response.content.decode("utf-8")
+ )
+ else:
+ assert (
+ "This location is not currently referred to in any contact."
+ not in response.content.decode("utf-8")
+ )