diff --git a/src/open_inwoner/accounts/views/__init__.py b/src/open_inwoner/accounts/views/__init__.py index 7fbe86a2cb..6413da04ad 100644 --- a/src/open_inwoner/accounts/views/__init__.py +++ b/src/open_inwoner/accounts/views/__init__.py @@ -36,6 +36,7 @@ from .password_reset import PasswordResetView from .profile import ( EditProfileView, + MyAppointmentsView, MyCategoriesView, MyDataView, MyNotificationsView, @@ -79,6 +80,7 @@ "MyNotificationsView", "MyProfileView", "NewsletterSubscribeView", + "MyAppointmentsView", "CustomRegistrationView", "NecessaryFieldsUserView", ] diff --git a/src/open_inwoner/accounts/views/profile.py b/src/open_inwoner/accounts/views/profile.py index da8a26ef0e..9e670f0371 100644 --- a/src/open_inwoner/accounts/views/profile.py +++ b/src/open_inwoner/accounts/views/profile.py @@ -1,6 +1,7 @@ from collections.abc import Generator from datetime import date from typing import Any +from urllib.parse import quote from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin @@ -29,6 +30,7 @@ from open_inwoner.openklant.clients import build_client from open_inwoner.openklant.wrap import get_fetch_parameters from open_inwoner.plans.models import Plan +from open_inwoner.qmatic.client import QmaticClient from open_inwoner.questionnaire.models import QuestionnaireStep from open_inwoner.utils.views import CommonPageMixin, LogMixin @@ -336,3 +338,25 @@ def form_valid(self, form): self.request.user, _("users newsletter subscriptions were modified") ) return HttpResponseRedirect(self.get_success_url()) + + +class MyAppointmentsView( + LogMixin, LoginRequiredMixin, CommonPageMixin, BaseBreadcrumbMixin, TemplateView +): + template_name = "pages/profile/appointments.html" + + def get_context_data(self, **kwargs) -> dict[str, Any]: + context = super().get_context_data(**kwargs) + # TODO email should be verified + client = QmaticClient() + context["appointments"] = client.list_appointments_for_customer( + quote(self.request.user.email) + ) + return context + + @cached_property + def crumbs(self): + return [ + (_("Mijn profiel"), reverse("profile:detail")), + (_("Mijn afspraken"), reverse("profile:appointments")), + ] diff --git a/src/open_inwoner/cms/profile/admin.py b/src/open_inwoner/cms/profile/admin.py index 2f346e9013..b536762733 100644 --- a/src/open_inwoner/cms/profile/admin.py +++ b/src/open_inwoner/cms/profile/admin.py @@ -19,4 +19,5 @@ def get_config_fields(self): "questions", "ssd", "newsletters", + "appointments", ) diff --git a/src/open_inwoner/cms/profile/cms_appconfig.py b/src/open_inwoner/cms/profile/cms_appconfig.py index 3c5194701f..8b592a219f 100644 --- a/src/open_inwoner/cms/profile/cms_appconfig.py +++ b/src/open_inwoner/cms/profile/cms_appconfig.py @@ -66,3 +66,8 @@ class ProfileConfig(AppHookConfig): default=False, help_text=_("Designates whether 'Nieuwsbrieven' section is rendered or not."), ) + appointments = models.BooleanField( + verbose_name=_("Mijn afspraken"), + default=False, + help_text=_("Designates whether 'Mijn afspraken' section is rendered or not."), + ) diff --git a/src/open_inwoner/cms/profile/migrations/0009_profileconfig_appointments.py b/src/open_inwoner/cms/profile/migrations/0009_profileconfig_appointments.py new file mode 100644 index 0000000000..42782281fc --- /dev/null +++ b/src/open_inwoner/cms/profile/migrations/0009_profileconfig_appointments.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.10 on 2024-03-18 13:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("profile", "0008_profileconfig_newsletters"), + ] + + operations = [ + migrations.AddField( + model_name="profileconfig", + name="appointments", + field=models.BooleanField( + default=False, + help_text="Designates whether 'Mijn afspraken' section is rendered or not.", + verbose_name="Mijn afspraken", + ), + ), + ] diff --git a/src/open_inwoner/cms/profile/urls.py b/src/open_inwoner/cms/profile/urls.py index c84b501600..ea5f33cfa4 100644 --- a/src/open_inwoner/cms/profile/urls.py +++ b/src/open_inwoner/cms/profile/urls.py @@ -17,6 +17,7 @@ DocumentPrivateMediaView, EditProfileView, InviteAcceptView, + MyAppointmentsView, MyCategoriesView, MyDataView, MyNotificationsView, @@ -107,5 +108,6 @@ NewsletterSubscribeView.as_view(), name="newsletters", ), + path("appointments", MyAppointmentsView.as_view(), name="appointments"), path("", MyProfileView.as_view(), name="detail"), ] diff --git a/src/open_inwoner/conf/fixtures/django-admin-index.json b/src/open_inwoner/conf/fixtures/django-admin-index.json index 1e9e913ca8..6cce45ede2 100644 --- a/src/open_inwoner/conf/fixtures/django-admin-index.json +++ b/src/open_inwoner/conf/fixtures/django-admin-index.json @@ -325,6 +325,10 @@ "openzaak", "catalogusconfig" ], + [ + "qmatic", + "qmaticconfig" + ], [ "openzaak", "openzaakconfig" diff --git a/src/open_inwoner/templates/pages/profile/appointments.html b/src/open_inwoner/templates/pages/profile/appointments.html new file mode 100644 index 0000000000..e50db09cc5 --- /dev/null +++ b/src/open_inwoner/templates/pages/profile/appointments.html @@ -0,0 +1,52 @@ +{% extends 'master.html' %} +{% load i18n tz form_tags anchor_menu_tags list_tags icon_tags grid_tags utils %} + +{% block content %} + +

{% trans "Mijn afspraken" %}

+ +{% if appointments %} +

{% trans "Een overzicht van uw afspraken" %}

+ + {% render_grid %} + {% for appointment in appointments %} + {% render_column start=forloop.counter_0|multiply:4 span=4 %} +
+
+ {% render_list %} + +

{{ appointment.title }}

+ {% timezone appointment.branch.timeZone %} + {% list_item text=appointment.start|date:"l j F Y H:i" compact=True strong=False %} + {% endtimezone %} + {% list_item text=appointment.notes compact=True strong=False %} + {% list_item text=appointment.branch.name caption=_("Locatie") compact=True strong=False %} + {% list_item text=appointment.branch.addressCity compact=True strong=False %} + {% list_item text=appointment.branch.addressLine2 compact=True strong=False %} +
+ {% endrender_list %} + + + {% trans "Wijzig afspraak" %} + {% icon icon="arrow_forward" icon_position="after" primary=True outlined=True %} + + + {% trans "Annuleer afspraak" %} + {% icon icon="arrow_forward" icon_position="after" primary=True outlined=True %} + +
+
+ {% endrender_column %} + + {% endfor %} + {% endrender_grid %} + +{% else %} +

{% trans "Geen afspraken beschikbaar" %}

+{% endif %} + +{% endblock %} diff --git a/src/open_inwoner/templates/pages/profile/me.html b/src/open_inwoner/templates/pages/profile/me.html index 3ca980489a..95c2e55c38 100644 --- a/src/open_inwoner/templates/pages/profile/me.html +++ b/src/open_inwoner/templates/pages/profile/me.html @@ -101,7 +101,7 @@

{% trans "Voorkeuren voor meldingen" %} - {% if view.config.mentors or view.config.my_contacts or view.config.actions or view.config.ssd or view.config.selfdiagnose or view.config.newsletters %} + {% if view.config.mentors or view.config.my_contacts or view.config.actions or view.config.ssd or view.config.selfdiagnose or view.config.newsletters or view.config.appointments %} {# Overview #}

{% trans "Overzicht" %}

@@ -262,8 +262,21 @@

{% trans "Zelftest" %}

{% trans "Nieuwsbrieven" %}

- - {% trans "Beijk nieuwsbrieven" %} + + {% trans "Bekijk nieuwsbrieven" %} + {% icon icon="arrow_forward" icon_position="after" primary=True outlined=True %} + + + + {% endif %} + {% if view.config.appointments %} + +
+

{% trans "Mijn afspraken" %} +

+ + + {% trans "Bekijk afspraken" %} {% icon icon="arrow_forward" icon_position="after" primary=True outlined=True %}