Skip to content

fix(schedule): charge credits for custom-layout reservations - #1879

Open
abu-tahir-0 wants to merge 2 commits into
LibreBooking:developfrom
abu-tahir-0:fix/1871-custom-layout-credits
Open

abu-tahir-0 wants to merge 2 commits into
LibreBooking:developfrom
abu-tahir-0:fix/1871-custom-layout-credits

Conversation

@abu-tahir-0

Copy link
Copy Markdown

Description

Reservations on a custom-layout schedule were always charged 0 credits. CustomScheduleLayout::GetSlotCount() returned an empty SlotCount, so ReservationSeries::TotalSlots() read OffPeak/Peak off an int (two warnings per instance) and every reservation cost nothing.

Peak times were also evaluated in the server's default timezone on custom layouts: ScheduleLayout::$layoutTimezone is only set by AppendGenericPeriod(), which CustomScheduleLayout overrides as a no-op. The loaded custom slots carry the schedule timezone, so the peak classification is now done against the slot's timezone.

The change counts the reservable periods of the reservation's day that the instance fully covers and splits them into peak and off-peak, following ScheduleLayout::GetSlotCount(). Custom layouts still use GetLayout() for their slots, and the cache key stays the date.

This changes billing: sites that use credits together with custom layouts will start charging for those reservations, which is the intended fix for the issue and worth a release note.

Related issues

Closes: #1871

Checklist

  • I understand that I will likely get a faster and better review if I join the LibreBooking Discord to discuss this pull request. Joining is not required, but it is highly recommended.
  • This PR targets the develop branch.
  • The PR title and commit messages follow the Conventional Commits format.
  • The PR contains no merge commits.
  • I added or updated tests where applicable.
  • I updated the documentation where applicable.

Testing

vendor/bin/phpunit --filter 'testCustomScheduleLayout' tests/Application/Schedule/ScheduleLayoutTest.php

  • On develop, the four new behaviour tests fail (counts are 0,0 and the instance is charged 0).
  • With this branch: OK (6 tests, 8 assertions).

The tests cover fully covered slots, partially covered slots, a day with no custom slots, the peak/off-peak split when the server timezone differs from the schedule timezone, and ReservationSeries::CalculateCredits().

Full unit suite: 2134 tests, with the same 40 errors and 3 failures as before the change. Those are Missing config file failures from this checkout (lib/Config/Configuration.php), unrelated to the change.

php-cs-fixer dry-run and phpstan analyse Domain/ScheduleLayout.php report no issues.

@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

Thank you for opening your first pull request in LibreBooking! 🎉

LibreBooking is maintained by volunteers. You will likely get a
faster and better review if you join our
Discord to discuss this pull
request. If a decision is reached on Discord, please post a short
summary here so it is not lost.

CustomScheduleLayout::GetSlotCount() returned an empty SlotCount, so a
reservation on a custom-layout schedule was always charged 0 credits
and ReservationSeries::TotalSlots() read properties off an int.

Count the reservable periods of the reservation's day that the
reservation fully covers, and split them into peak and off-peak slots.
Custom layouts never set ScheduleLayout::$layoutTimezone, so the peak
times, which were parsed in the server default, are moved to the slot's
timezone before the comparison; otherwise peak hours are evaluated
against the server clock.

This changes billing for sites that use credits together with custom
layouts: those reservations are no longer free.
@abu-tahir-0
abu-tahir-0 force-pushed the fix/1871-custom-layout-credits branch from 068f80d to da6dd6b Compare November 10, 2026 03:23

This branch has not been deployed

No deployments
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.

Custom-layout schedules: credits never charged and peak times use server timezone

1 participant