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 "Een overzicht van uw afspraken" %}
+ + {% render_grid %} + {% for appointment in appointments %} + {% render_column start=forloop.counter_0|multiply:4 span=4 %} +{% 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 @@