Skip to content

Adds reservation cancellation path to resources#2550

Open
Tschuppi81 wants to merge 19 commits into
masterfrom
feature/ogc-3064-cancel-reservation
Open

Adds reservation cancellation path to resources#2550
Tschuppi81 wants to merge 19 commits into
masterfrom
feature/ogc-3064-cancel-reservation

Conversation

@Tschuppi81

@Tschuppi81 Tschuppi81 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Reservation: Adds reservation cancellation path to resources

TYPE: Feature
LINK: ogc-3064

@linear

linear Bot commented Jun 29, 2026

Copy link
Copy Markdown

OGC-3064

@Tschuppi81 Tschuppi81 force-pushed the feature/ogc-3064-cancel-reservation branch from c5c6960 to 80c2aac Compare June 29, 2026 14:19
@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.40559% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.55%. Comparing base (c4d89df) to head (a70be16).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/onegov/org/views/reservation.py 95.09% 5 Missing ⚠️
src/onegov/town6/views/ticket.py 75.00% 2 Missing ⚠️
src/onegov/org/models/ticket.py 92.85% 1 Missing ⚠️
Additional details and impacted files
Files with missing lines Coverage Δ
src/onegov/org/forms/__init__.py 100.00% <100.00%> (ø)
src/onegov/org/forms/resource.py 80.22% <100.00%> (+0.07%) ⬆️
src/onegov/org/forms/resource_recipient.py 96.07% <100.00%> (+0.07%) ⬆️
src/onegov/org/forms/ticket.py 97.43% <100.00%> (+0.56%) ⬆️
src/onegov/org/models/recipient.py 100.00% <100.00%> (ø)
src/onegov/org/views/resource_recipient.py 88.23% <ø> (ø)
src/onegov/org/views/ticket.py 85.45% <ø> (ø)
src/onegov/reservation/models/resource.py 90.77% <100.00%> (+0.04%) ⬆️
src/onegov/org/models/ticket.py 89.14% <92.85%> (+0.04%) ⬆️
src/onegov/town6/views/ticket.py 79.16% <75.00%> (-0.53%) ⬇️
... and 1 more

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c4d89df...a70be16. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Daverball Daverball left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently this seems to be limited to cancelling all reservations in a ticket, which should cover individual reservations nicely, but does that cover 90+% of customer requests or is it more common, or almost as common that for large half year reservations, they want to cancel a single date?

If so, we probably need to allow customers to select which dates they want to cancel, which would also necessarily change the UI in the ticket.

@Tschuppi81

Copy link
Copy Markdown
Contributor Author

Now cancellation requests can select single reservations to be cancelled and the manager sees the request cancellation dates, then approve it.

@Tschuppi81 Tschuppi81 requested a review from Daverball July 7, 2026 06:15

@Daverball Daverball left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall, although we should consider if and how we should notify a ticket's assignee and/or resource recipients.

There's also couple of minor improvement suggestions and a couple of questionable conditions, that make the feature less flexible.

Comment thread src/onegov/org/forms/resource.py Outdated
Comment thread src/onegov/org/models/ticket.py Outdated
Comment thread src/onegov/org/views/reservation.py Outdated
Comment thread src/onegov/org/views/reservation.py
Comment thread src/onegov/org/views/reservation.py
Tschuppi81 and others added 2 commits July 7, 2026 08:31
Co-authored-by: David Salvisberg <david.salvisberg@seantis.ch>
Co-authored-by: David Salvisberg <david.salvisberg@seantis.ch>
@Tschuppi81 Tschuppi81 force-pushed the feature/ogc-3064-cancel-reservation branch from 999ca4a to 79501c1 Compare July 7, 2026 12:58
Comment thread src/onegov/org/views/reservation.py Outdated
@Tschuppi81

Copy link
Copy Markdown
Contributor Author

Now, as I review the changes i think the reply_to address shall not be notified about cancellation requests, as it is meant to reply to from an email. As we now have the ability to subscribe to cancellation request we should rather keep it separate.

@Daverball Daverball left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

There's still a couple of things we should consider. E.g. what happens if a customer requests a cancellation and by the time the ticket gets processed the reservation has already happened.

Technically it's harmless to cancel past reservations. But for billing purposes, if there's a mix of past reservations that were cancelled too late and future ones that can still be cancelled. You may want only the future ones to get cancelled, when cancellation gets approved. It might be fine to teach supporters to manually cancel reservations that can still be cancelled and reject the request, but it's definitely worth a discussion whether that's good enough, especially since the customer-facing notifications are going to be confusing, so they'd probably also want to mute the ticket and then send a manual message at the end.

Comment thread src/onegov/org/forms/ticket.py
Comment thread src/onegov/org/views/reservation.py
Comment thread src/onegov/org/views/reservation.py Outdated
Comment thread src/onegov/org/views/reservation.py Outdated
Comment thread src/onegov/org/views/reservation.py Outdated
Comment thread src/onegov/org/upgrade.py Outdated
Comment thread src/onegov/org/upgrade.py Outdated
Comment on lines +978 to +989
stmt = update(ResourceRecipient.__table__).where( # type: ignore[arg-type]
and_(
ResourceRecipient.content['customer_messages'].as_boolean()
.is_(True),
ResourceRecipient.type == 'resource',
)
).values(
content=func.jsonb_set(
ResourceRecipient.content,
array(['cancellation_requests']),
func.to_jsonb(true()),
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one of those cases where I would just write the update statement in raw SQL, it's far easier to get it right that way, we don't want any ambiguity about what the statement looks like at the end and whether or not it will have parameter bindings or is fully baked.

In this case the query should be fully baked, but I think this will probably result in a query with parameter bindings.

See e.g. the following upgrade task:

@upgrade_task('Translate default views to their new names')
def translate_default_views_to_their_new_names(
context: UpgradeContext
) -> None:
if context.has_table('resources'):
context.operations.execute(text("""
UPDATE resources SET content = jsonb_set(
content, '{default_view}', '"dayGridMonth"'
) WHERE content->>'default_view' = 'month';
"""))
context.operations.execute(text("""
UPDATE resources SET content = jsonb_set(
content, '{default_view}', '"timeGridWeek"'
) WHERE content->>'default_view' = 'agendaWeek';
"""))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants