Skip to content

Commit

Permalink
Add form for contact information
Browse files Browse the repository at this point in the history
Co-authored-by: David Venhoff <[email protected]>
  • Loading branch information
2 people authored and MizukiTemma committed Sep 16, 2024
1 parent 127d22a commit afbd95d
Show file tree
Hide file tree
Showing 20 changed files with 813 additions and 107 deletions.
6 changes: 3 additions & 3 deletions integreat_cms/cms/fixtures/test_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,7 @@
"fields": {
"title": "Integrationsbeauftragte",
"name": "Martina Musterfrau",
"poi": 6,
"location": 6,
"email": "[email protected]",
"phone_number": "0123456789",
"website": "",
Expand All @@ -973,7 +973,7 @@
"fields": {
"title": "Integrationsberaterin",
"name": "Melanie Musterfrau",
"poi": 6,
"location": 6,
"email": "[email protected]",
"phone_number": "0987654321",
"website": "www.random-page.com",
Expand All @@ -988,7 +988,7 @@
"fields": {
"title": "Integrationsbeauftragte",
"name": "Mariana Musterfrau",
"poi": 6,
"location": 6,
"email": "[email protected]",
"phone_number": "0123456789",
"website": "https://integreat-app.de/",
Expand Down
1 change: 1 addition & 0 deletions integreat_cms/cms/forms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from __future__ import annotations

from .chat.chat_message_form import ChatMessageForm
from .contacts.contact_form import ContactForm
from .events.event_filter_form import EventFilterForm
from .events.event_form import EventForm
from .events.event_translation_form import EventTranslationForm
Expand Down
3 changes: 3 additions & 0 deletions integreat_cms/cms/forms/contacts/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Forms for creating and modifying contact objects
"""
106 changes: 106 additions & 0 deletions integreat_cms/cms/forms/contacts/contact_form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from django import forms
from django.utils.translation import gettext_lazy as _

from ...models import Contact
from ..custom_model_form import CustomModelForm

if TYPE_CHECKING:
from typing import Any

logger = logging.getLogger(__name__)


class ContactForm(CustomModelForm):
"""
Form for creating and modifying contact objects
"""

class Meta:
"""
This class contains additional meta configuration of the form class, see the :class:`django.forms.ModelForm`
for more information.
"""

#: The model of this :class:`django.forms.ModelForm`
model = Contact
#: The fields of the model which should be handled by this form
fields = [
"title",
"name",
"location",
"email",
"email_from_location",
"phone_number",
"phone_number_from_location",
"website",
"website_from_location",
]

def clean(self) -> dict[str, Any]:
"""
Validate the fields
:return: The cleaned form data
"""
cleaned_data = super().clean()

related_location = self.instance.region.pois.filter(
id=self.data["location"]
).first()

email_from_location = self.data.get("email_from_location", None)
phone_number_from_location = self.data.get("phone_number_from_location", None)
website_from_location = self.data.get("website_from_location", None)

if related_location is None:
self.add_error(
None,
forms.ValidationError(
_("Location cannot be empty."),
code="invalid",
),
)
else:
if email_from_location and not self.data["email"] == related_location.email:
self.add_error(
"email",
forms.ValidationError(
_(
"E-mail address does not match with that of the selected location. Please check again."
),
code="invalid",
),
)
if (
phone_number_from_location
and not self.data["phone_number"] == related_location.phone_number
):
self.add_error(
"phone_number",
forms.ValidationError(
_(
"Phone number does not match with that of the selected location. Please check again."
),
code="invalid",
),
)
if (
website_from_location
and not self.data["website"] == related_location.website
):
self.add_error(
"website",
forms.ValidationError(
_(
"Website URL does not match with that of the selected location. Please check again."
),
code="invalid",
),
)

return cleaned_data
66 changes: 66 additions & 0 deletions integreat_cms/cms/migrations/0103_update_contact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Generated by Django 4.2.13 on 2024-08-20 16:10

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
"""
Make the field name not mandatory.
Rename the field from "poi" to "location".
Add new fields to save whether the information must be taken over from the location.
"""

dependencies = [
("cms", "0102_alter_contact_poi"),
]

operations = [
migrations.AlterField(
model_name="contact",
name="name",
field=models.CharField(blank=True, max_length=200, verbose_name="name"),
),
migrations.RenameField(
model_name="contact",
old_name="poi",
new_name="location",
),
migrations.AlterField(
model_name="contact",
name="location",
field=models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="contacts",
to="cms.poi",
verbose_name="location",
),
),
migrations.AddField(
model_name="contact",
name="email_from_location",
field=models.BooleanField(
default=True,
help_text="Will be taken over from the location.",
verbose_name="E-mail from location",
),
),
migrations.AddField(
model_name="contact",
name="phone_number_from_location",
field=models.BooleanField(
default=True,
help_text="Will be taken over from the location.",
verbose_name="phone number from location",
),
),
migrations.AddField(
model_name="contact",
name="website_from_location",
field=models.BooleanField(
default=True,
help_text="Will be taken over from the location.",
verbose_name="website from location",
),
),
]
30 changes: 25 additions & 5 deletions integreat_cms/cms/models/contact/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,38 @@ class Contact(AbstractBaseModel):
"""

title = models.CharField(max_length=200, verbose_name=_("title"))
name = models.CharField(max_length=200, verbose_name=_("name"))
poi = models.ForeignKey(
POI, on_delete=models.PROTECT, verbose_name=_("POI"), related_name="contacts"
name = models.CharField(max_length=200, blank=True, verbose_name=_("name"))
location = models.ForeignKey(
POI,
on_delete=models.PROTECT,
verbose_name=_("location"),
related_name="contacts",
)
email = models.EmailField(
blank=True,
verbose_name=_("email address"),
)
email_from_location = models.BooleanField(
default=True,
verbose_name=_("E-mail from location"),
help_text=_("Will be taken over from the location."),
)
phone_number = models.CharField(
max_length=250, blank=True, verbose_name=_("phone number")
max_length=250,
blank=True,
verbose_name=_("phone number"),
)
phone_number_from_location = models.BooleanField(
default=True,
verbose_name=_("phone number from location"),
help_text=_("Will be taken over from the location."),
)
website = models.URLField(blank=True, max_length=250, verbose_name=_("website"))
website_from_location = models.BooleanField(
default=True,
verbose_name=_("website from location"),
help_text=_("Will be taken over from the location."),
)
archived = models.BooleanField(
default=False,
verbose_name=_("archived"),
Expand All @@ -46,7 +66,7 @@ def region(self) -> Region:
:return: Region this contact belongs to
"""
return self.poi.region
return self.location.region

def __str__(self) -> str:
"""
Expand Down
25 changes: 17 additions & 8 deletions integreat_cms/cms/templates/ajax_poi_form/poi_box.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,24 @@
{{ title }}
{% endblock collapsible_box_title %}
{% block collapsible_box_content %}
{% render_field form.has_not_location class+='inline-block' %}
<label class="secondary !inline"
for="{{ form.has_not_location.id_for_label }}">
{{ form.has_not_location.label }}
</label>
{% if current_menu_item == "events_form" %}
{% render_field form.has_not_location class+='inline-block' %}
<label class="secondary !inline"
for="{{ form.has_not_location.id_for_label }}">
{{ form.has_not_location.label }}
</label>
{% endif %}
{% if current_menu_item == "contacts" %}
<div class="help-text mt-4 font-bold">
{{ help_text }}
</div>
{% endif %}
<div id="location-block"
class="{% if form.has_not_location.value %}hidden{% endif %}">
<label for="{{ form.location.id_for_label }}">
{{ form.location.label }}
</label>
{% translate "Name of event location" as poi_title_placeholder %}
{% translate "Name of location" as poi_title_placeholder %}
<div class="relative my-2">
<input id="poi-query-input"
type="search"
Expand All @@ -34,14 +41,16 @@
data-default-placeholder="{{ poi_title_placeholder }}" />
<div class="absolute inset-y-0 right-0 flex items-center px-2 text-gray-800">
<button id="poi-remove"
title="{% translate "Remove location from event" %}"
title="{% translate "Remove location" %}"
{% if form.disabled %}disabled{% endif %}>
<i icon-name="trash-2" class="h-5 w-5"></i>
</button>
</div>
</div>
<p class="text-sm italic block mt-2 mb-2">
{% translate "Create an event location or start typing the name of an existing location. Only published locations can be set as event venues" %}.
{% if current_menu_item == "events_form" %}
{{ help_text }}
{% endif %}
</p>
<div class="relative" id="poi-query-result">
{% include "_poi_query_result.html" %}
Expand Down
Loading

0 comments on commit afbd95d

Please sign in to comment.