Skip to content

Commit 09a9ef7

Browse files
authored
Merge pull request #1103 from maykinmedia/feature/2180-qmatic-reschedule-or-remove-appointment
✨ [#2180] Implement reschedule and delete for Qmatic appointments
2 parents 4928b5d + 1385366 commit 09a9ef7

File tree

5 files changed

+52
-12
lines changed

5 files changed

+52
-12
lines changed

src/open_inwoner/accounts/tests/test_profile_views.py

+9
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,7 @@ def setUp(self):
11571157
self.user = DigidUserFactory()
11581158

11591159
self.config = QmaticConfig.get_solo()
1160+
self.config.booking_base_url = "https://qmatic.local/"
11601161
self.api_root = "https://qmatic.local/api/"
11611162
self.service = ServiceFactory.create(
11621163
api_root=self.api_root, api_type=APITypes.orc
@@ -1258,6 +1259,10 @@ def test_render_list_if_appointments_are_found(self, m):
12581259
self.assertEqual(PQ(passport_appointment[3]).text(), "Locatie\nHoofdkantoor")
12591260
self.assertEqual(PQ(passport_appointment[4]).text(), "Amsterdam")
12601261
self.assertEqual(PQ(passport_appointment[5]).text(), "Dam 1")
1262+
self.assertEqual(
1263+
PQ(cards[0]).find("a").attr("href"),
1264+
f"{self.config.booking_base_url}{self.appointment_passport.publicId}",
1265+
)
12611266

12621267
id_card_appointment = PQ(cards[1]).find("ul").children()
12631268

@@ -1269,3 +1274,7 @@ def test_render_list_if_appointments_are_found(self, m):
12691274
self.assertEqual(PQ(id_card_appointment[3]).text(), "Locatie\nHoofdkantoor")
12701275
self.assertEqual(PQ(id_card_appointment[4]).text(), "New York")
12711276
self.assertEqual(PQ(id_card_appointment[5]).text(), "Wall Street 1")
1277+
self.assertEqual(
1278+
PQ(cards[1]).find("a").attr("href"),
1279+
f"{self.config.booking_base_url}{self.appointment_idcard.publicId}",
1280+
)

src/open_inwoner/qmatic/client.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class BranchDetail(BaseModel):
6666

6767

6868
class Appointment(JSONEncoderMixin, BaseModel):
69+
url: str | None
6970
services: list[QmaticService]
7071
title: str
7172
start: datetime
@@ -135,10 +136,16 @@ def list_appointments_for_customer(
135136
if response.status_code == 404:
136137
return []
137138
response.raise_for_status()
139+
config = QmaticConfig.get_solo()
138140
try:
139-
return [
141+
appointments = [
140142
Appointment(**entry) for entry in response.json()["appointmentList"]
141143
]
144+
for appointment in appointments:
145+
appointment.url = (
146+
f"{config.booking_base_url}{quote(appointment.publicId)}"
147+
)
148+
return appointments
142149
except ValidationError:
143150
logger.exception(
144151
"Something went wrong while deserializing appointment data"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 4.2.10 on 2024-03-21 10:19
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("qmatic", "0001_initial"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="qmaticconfig",
15+
name="booking_base_url",
16+
field=models.URLField(
17+
blank=True,
18+
help_text="The base URL where the user can reschedule or delete their appointment",
19+
max_length=1000,
20+
verbose_name="Booking base URL",
21+
),
22+
),
23+
]

src/open_inwoner/qmatic/models.py

+8
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ class QmaticConfig(SingletonModel):
2727
"Example: https://example.com:8443/calendar-backend/public/api/v1/"
2828
),
2929
)
30+
booking_base_url = models.URLField(
31+
verbose_name=_("Booking base URL"),
32+
max_length=1000,
33+
help_text=_(
34+
"The base URL where the user can reschedule or delete their appointment"
35+
),
36+
blank=True,
37+
)
3038

3139
objects = QmaticConfigManager()
3240

src/open_inwoner/templates/pages/profile/appointments.html

+4-11
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,11 @@ <h2 class="card__heading-2">{{ appointment.title }}</h2>
2424
{% list_item text=appointment.branch.addressLine2 compact=True strong=False %}
2525
{% endrender_list %}
2626

27-
<span class="link link--icon link--secondary"
28-
aria-label="{% trans "Wijzig afspraak" %}"
29-
title="{% trans "Wijzig afspraak" %}">
30-
<span class="link__text">{% trans "Wijzig afspraak" %}</span>
27+
<a href="{{ appointment.url }}" class="link link--icon link--secondary"
28+
title="{% trans "Wijzig of annuleer afspraak" %}">
29+
<span class="link__text">{% trans "Wijzig of annuleer afspraak" %}</span>
3130
{% icon icon="arrow_forward" icon_position="after" primary=True outlined=True %}
32-
</span>
33-
<span class="link link--icon link--secondary"
34-
aria-label="{% trans "Annuleer afspraak" %}"
35-
title="{% trans "Annuleer afspraak" %}">
36-
<span class="link__text">{% trans "Annuleer afspraak" %}</span>
37-
{% icon icon="arrow_forward" icon_position="after" primary=True outlined=True %}
38-
</span>
31+
</a>
3932
</div>
4033
</div>
4134
{% endrender_column %}

0 commit comments

Comments
 (0)