Skip to content

Commit edd404a

Browse files
authored
Reservation: Adds reservation cancellation path to resources
TYPE: Feature LINK: ogc-3064
1 parent 7b3dff2 commit edd404a

40 files changed

Lines changed: 2781 additions & 833 deletions

src/onegov/org/forms/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
from onegov.org.forms.text_module import TextModuleForm
5555
from onegov.org.forms.ticket import (
5656
InternalTicketChatMessageForm, ExtendedInternalTicketChatMessageForm)
57+
from onegov.org.forms.ticket import RequestCancellationForm
5758
from onegov.org.forms.ticket import TicketAssignmentForm
5859
from onegov.org.forms.ticket import TicketChangeTagForm
5960
from onegov.org.forms.ticket import TicketChatMessageForm
@@ -115,6 +116,7 @@
115116
'PublicRequestMTANForm',
116117
'ReservationAdjustmentForm',
117118
'ReservationForm',
119+
'RequestCancellationForm',
118120
'ResourceChangeUrlForm',
119121
'ResourceCleanupForm',
120122
'ResourceExportForm',

src/onegov/org/forms/resource.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,12 @@ class ResourceBaseForm(Form):
381381
),
382382
)
383383

384+
allow_cancellation_requests = BooleanField(
385+
label=_('Enable cancel reservation'),
386+
fieldset=_('Cancellation'),
387+
default=False,
388+
)
389+
384390
def on_request(self) -> None:
385391
if hasattr(self.model, 'type'):
386392
if self.model.type != 'room':

src/onegov/org/forms/resource_recipient.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ class ResourceRecipientForm(Form):
8787
'be sent to the above recipient.'),
8888
)
8989

90+
cancellation_requests = BooleanField(
91+
label=_('Cancellation Requests'),
92+
fieldset=_('Notifications *'),
93+
description=_('When a customer requests to cancel a reservation, a '
94+
'notification will be sent to the above recipient.'),
95+
)
96+
9097
send_on = MultiCheckboxField(
9198
label=_('Send on'),
9299
fieldset='Tage und Ressourcen',
@@ -145,6 +152,7 @@ def ensure_at_least_one_notification(self) -> bool | None:
145152
or self.customer_messages.data
146153
or self.internal_notes.data
147154
or self.rejected_reservations.data
155+
or self.cancellation_requests.data
148156
):
149157
self.request.alert(_('Please add at least one notification.'))
150158
return False

src/onegov/org/forms/ticket.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
from __future__ import annotations
22

3+
import sedate
4+
35
from onegov.chat import MessageFile
46
from onegov.core.security import Private
57
from onegov.form import Form
68
from onegov.form.fields import (ChosenSelectField,
79
ChosenSelectMultipleEmailField, PanelField)
10+
from onegov.form.fields import MultiCheckboxField
811
from onegov.form.fields import TextAreaFieldWithTextModules
912
from onegov.form.fields import UploadFileWithORMSupport
1013
from onegov.form.filters import strip_whitespace
@@ -17,6 +20,7 @@
1720
from wtforms.fields import BooleanField
1821
from wtforms.fields import TextAreaField
1922
from functools import cached_property
23+
from wtforms.validators import DataRequired
2024
from wtforms.validators import InputRequired
2125
from wtforms.validators import Length
2226
from wtforms.validators import Optional
@@ -25,6 +29,7 @@
2529

2630
from typing import TYPE_CHECKING
2731
if TYPE_CHECKING:
32+
from onegov.org.models.ticket import ReservationTicket
2833
from onegov.org.request import OrgRequest
2934

3035

@@ -180,3 +185,40 @@ def on_request(self) -> None:
180185
for tag in (item.keys() if isinstance(item, dict) else (item,))
181186
]
182187
choices.insert(0, ('', ''))
188+
189+
190+
class RequestCancellationForm(Form):
191+
"""Cancellation request form for reservation tickets.
192+
193+
Shows reservation checkboxes when there are multiple reservations,
194+
allowing the user to select which ones to cancel. For a single
195+
reservation the checkbox field is removed and the form acts as a
196+
plain confirmation.
197+
"""
198+
199+
if TYPE_CHECKING:
200+
model: ReservationTicket
201+
202+
reservation_ids = MultiCheckboxField(
203+
label=_('Select reservations to cancel'),
204+
coerce=int,
205+
validators=[DataRequired()],
206+
)
207+
208+
def on_request(self) -> None:
209+
now = sedate.utcnow()
210+
reservations = [
211+
r for r in self.model.handler.reservations
212+
if r.start is not None and r.start > now
213+
]
214+
215+
if len(reservations) <= 1:
216+
self.delete_field('reservation_ids')
217+
return
218+
219+
self.reservation_ids.choices = [
220+
(r.id, self.model.handler.get_reservation_title(r))
221+
for r in reservations
222+
]
223+
if not self.request.POST:
224+
self.reservation_ids.data = [r.id for r in reservations]

0 commit comments

Comments
 (0)