Skip to content

[19.0][MIG] resource_booking: Migration to 19.0#217

Open
dnplkndll wants to merge 112 commits into
OCA:19.0from
ledoent:19.0-mig-resource_booking
Open

[19.0][MIG] resource_booking: Migration to 19.0#217
dnplkndll wants to merge 112 commits into
OCA:19.0from
ledoent:19.0-mig-resource_booking

Conversation

@dnplkndll
Copy link
Copy Markdown
Contributor

@dnplkndll dnplkndll commented May 16, 2026

Port of resource_booking from 18.0 to 19.0. Follows the OCA migration guide.

Supersedes #187 (open since 2025-10-19, original author unreachable).

Non-mechanical adaptations worth flagging

  • Intervals moved from odoo.addons.resource.models.utilsodoo.tools.intervals.
  • _sql_constraints list rewritten as models.Constraint(...) declarations (Odoo 19 SQL constraint API).
  • Portal controller drops datetime.utcfromtimestamp (deprecated in Python 3.12) for datetime.fromtimestamp(..., tz=timezone.utc).replace(tzinfo=None).
  • Portal template's t-field="meeting.display_time" switched to t-out calling a new booking._get_portal_display_time() helper — Odoo 19 dropped the computed calendar.event.display_time field.
  • Tour step in resource_booking_tour.esm.js annotated with expectUnloadPage: true per Odoo 19's tour framework's new contract for click-triggers that navigate.

18.0 fixes forward-ported into [MIG]

The cherry-pick replay included [FIX] commits that the [MIG] commit accidentally dropped (written against an older baseline). All four are now in [MIG]:

  • #183: restore _get_intervals(tz) + TZ-aware slot conversion so portal slots always display in the booking type's time zone. WorkIntervals (removed in 19.0 with hr_work_entry_contract) replaced by Intervals.
  • #189: inject event_tz from the resource calendar on meeting creation only (cannot be changed on write) so the calendar event carries the correct time zone from the start.
  • #214: set description on the meeting only when requester_advice is filled — unconditional assignment caused test_resource_booking_schedule_unschedule to fail after [PERF] models: Do not cache HTML fields on record creation odoo/odoo#223875 (Text → HTML field type mismatch on write).
  • #219: honor all-day calendar events when computing busy slots. expression.OR (removed in 19.0) replaced by Domain.OR from odoo.fields; interval rendered from start_date/stop_date in the analyzer's tz.

@dnplkndll dnplkndll force-pushed the 19.0-mig-resource_booking branch 3 times, most recently from 21d0bd2 to aa94567 Compare May 16, 2026 10:45
dnplkndll added a commit to ledoent/calendar that referenced this pull request May 16, 2026
Odoo 19.0+ HttpCase tour tests leave renderer/websocket chrome
subprocesses that don't exit when the parent is killed; Odoo's own
test framework reports them via WARNING "Killing chrome descendants-
or-self of N: M remaining". These are benign cleanup notifications
emitted AFTER the test result line, not test failures.

Without this ignore pattern, any 19.0 PR that includes tour tests
in resource_booking (test_portal_no_bookings, test_portal_list_with_
bookings, etc.) deterministically fails CI even when 0 tests fail.

This is an OCA-CI configuration fix, not a module change. Will be
split into its own PR once verified on the OCA#217 retrigger.
@victoralmau
Copy link
Copy Markdown
Member

Please, cherry-pick #222 to commit history before migration commit.

@dnplkndll dnplkndll force-pushed the 19.0-mig-resource_booking branch from 1b3bac2 to 52a2f0d Compare May 18, 2026 17:38
@dnplkndll
Copy link
Copy Markdown
Contributor Author

Done — cherry-picked both commits from #222 (0a4d552 [FIX] + 64d0441 [IMP]) in front of the migration commit, also rebased onto current upstream/19.0 to absorb #223 (copier-template 1.42 update).

Side-effect note: my original [FIX] checklog: ignore chrome-zombie warnings… commit dropped during the rebase — upstream now has a broader WARNING .* Killing chrome descendants-or-self .* pattern in checklog-odoo.cfg that supersedes the narrower one I had, so the commit was redundant. Net result: 7 commits ahead of 19.0 instead of 8.

CI re-running on the force-push. Branch: https://github.com/ledoent/calendar/tree/19.0-mig-resource_booking

@pedrobaeza
Copy link
Copy Markdown
Member

The commit history is incomplete (it's not from the beginning), and now that you are rebuilding it, you can include the merging PR #219

@dnplkndll
Copy link
Copy Markdown
Contributor Author

@pedrobaeza @victoralmau

ready for review

Copy link
Copy Markdown
Contributor

@carlos-lopez-tecnativa carlos-lopez-tecnativa left a comment

Choose a reason for hiding this comment

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

Please check whether it is necessary to include this PR #225

Additionally, please squash the administrative commits, such as those shown in the screenshot.

Image

Comment thread resource_booking/models/resource_booking.py Outdated
Comment thread resource_booking/models/resource_booking.py
Comment thread resource_booking/models/resource_booking_combination.py
Jairo Llopis and others added 14 commits May 28, 2026 14:35
This module adds a new app to allow you to book resource combinations in given
schedules.

Example use cases:

* Management of consultations in a clinic.
* Salesman appointments.
* Classroom and projector reservations.
* Hotel room booking.

Among the things you can do:

* Specify the type of booking, which includes a calendar of availability.
* Specify which resources can be booked together. All of them must be free to be booked.
* Place pending bookings, effectively giving permissions to someone to see the availability calendar and choose one slot.
* Partners can do that from their portals.
* If a partner has no user, he can still do the same via a tokenized URL.
* Backend users can also do that from the backend.
* Booking lifecycle with computed states.
* Automatic meeting creation and deletion.
* Automatic conflict detection.
* Deadline to block modifications.

@Tecnativa TT28201
Currently translated at 100.0% (190 of 190 strings)

Translation: calendar-12.0/calendar-12.0-resource_booking
Translate-URL: https://translation.odoo-community.org/projects/calendar-12-0/calendar-12-0-resource_booking/es/
…ating calendars

Without this patch, users couldn't change a calendar schedule if there were past or unconfirmed bookings that wouldn't fit in it.

Excluding those bookings from the check fixes the situation.

We also check that, to confirm a booking, it must fit in the calendar (because now it can happen that, in the time that has passed since the booking was scheduled until it is confirmed, the calendar changes).

@Tecnativa TT29509
The notifications emitted to the resource booking requester must always be in the same TZ as the resource booking itself.

For example, if you book one hotel room in the other side of the world, a notification in your own TZ is confusing.

Besides, res.partner created from website_sale are created with `tz=False`, making it even more confusing.

@Tecnativa TT30331
The constraint that checks the schedule of a resource booking is currently being applied to all the bookings, including past ones.
As the resource combination or associated calendars might change regularly and trigger a recomputation of this, such change might take a very long time.
Plus, the calendar restrictions might change, trigger a recompute of the constraint and detect bookings that can't be assigned, which makes no sense when they already happened.

This applies it only to future bookings, ignoring past ones.

TT30478
It's very unlikely that you need to book resources in a seconds-based precision.

This simplifies portal UI. Still, declared as a variable in case you need some customizations downstream.

@Tecnativa TT31063
- Standard v13 changes.
- Some onchanges removed in favor of computes.

@Tecnativa TT30987
From now on, `resource.booking.type` duration represents the default duration that will be applied to new `resource.booking` of that type, instead of the hardcoded duration for every new booking.

This means that you can create a new booking in pending state and define a custom duration before sending the portal link to customer.

Thus, the available schedule slots in portal will be based on the type duration, whereas only those that have enough time left to complete the booking duration will be displayed.

@Tecnativa TT30987
…cation

Thanks to this patch, you will be able to more predictably block the chosen resource combination, with the added checkbox.

Also, the location field is propagated to `resource.booking` records, and synced from there to `calendar.event` if needed. This way, you can alter the location before sending the portal invitation.

@Tecnativa TT30987
The filter wasn't working fine due to the `auto_join=True` set in `meeting_id`. It was never displaying pending bookings.

Besides, it wasn't necessary to keep it as a field because it was displayed nowhere and the search could be done directly in the view. This way, there's less python code to maintain and we disable the possibility of having a negative domain, which enters doomed scenarios when x2many fields are involved (see odoo/odoo#43957).

@Tecnativa TT30987
Adding `.with_context(exclude_public_holidays=True)` in needed places to let `hr_holidays_public` do its magic and never allow allocating a booking during a public holidays when that module is properly installed and configured.

@Tecnativa TT30987
- Allow users to optionally define a name for the resource booking.
- Display that name in portal if set.
- Sync it with meeting name when creating it.

@Tecnativa TT30987
mymage and others added 22 commits May 28, 2026 14:35
Currently translated at 100.0% (218 of 218 strings)

Translation: calendar-17.0/calendar-17.0-resource_booking
Translate-URL: https://translation.odoo-community.org/projects/calendar-17-0/calendar-17-0-resource_booking/it/
- Adapt the portal design to the new style and complete the migration to BS5.
- Add support for creating bookings from mail.activity.schedule; this model is used when a user creates an activity from the chatter or the activity view.
- Compute some fields using _read_group.
- Remove the obsolete _availability_is_fitting_legacy function.
- Prevent displaying two buttons to cancel the booking
Currently translated at 100.0% (217 of 217 strings)

Translation: calendar-18.0/calendar-18.0-resource_booking
Translate-URL: https://translation.odoo-community.org/projects/calendar-18-0/calendar-18-0-resource_booking/it/
Since this commit odoo/odoo@1f3a15a, when Odoo starts without tests enabled and the Form class is used in business code, an error appears in the log.
This commit removes the usage of Form, which is not necessary anymore because no onchange methods depend on the start field—all are computed now.
Currently translated at 100.0% (218 of 218 strings)

Translation: calendar-18.0/calendar-18.0-resource_booking
Translate-URL: https://translation.odoo-community.org/projects/calendar-18-0/calendar-18-0-resource_booking/es/
Currently translated at 6.8% (15 of 218 strings)

Translation: calendar-18.0/calendar-18.0-resource_booking
Translate-URL: https://translation.odoo-community.org/projects/calendar-18-0/calendar-18-0-resource_booking/ca/
Currently translated at 100.0% (217 of 217 strings)

Translation: calendar-18.0/calendar-18.0-resource_booking
Translate-URL: https://translation.odoo-community.org/projects/calendar-18-0/calendar-18-0-resource_booking/it/
Odoo added this new key in commit
odoo/odoo@c840bde.

To prevent the test from failing, we updated the data accordingly.
…ission issues

Steps to reproduce:

- Install `resource_booking` and `hr` modules.
- Create a user with "Employee Officer: Manage all employees" rights
  (without the "Resource Booking User" role).
- Go to Employees and create a record.

Since `hr.employee` inherits from `resource.resource`, the constraint
`_check_bookings_scheduling` is executed.
When the search is performed, an error is raised due to missing permissions.

This commit fixes the issue by using `sudo()` for booking searches.
…ctly

When using a booking type with a resource calendar that has a different time zone than the resource itself, the slots are returned with mixed time zones.
This commit normalizes the behavior and ensures that slots are always returned in the time zone of the booking type.

Steps to reproduce:

Create a resource with the time zone America/Guayaquil, and a calendar that starts from 06:00 to 15:00.

Create a resource booking type with a new calendar that starts from 09:00 to 16:00, and set the time zone to Europe/Madrid.

Before this commit, the slot displayed in the portal was 06:00, but it should have been 12:00.
After this commit, the slot is displayed in the correct time zone (Madrid) at 12:00.

Note: The 06:00 in America/Guayaquil corresponds to 12:00 in Madrid standard time, not during daylight saving time. The tests use a freeze date in February.
The resources parameter must be a recordset, not a list. Before this commit, this was not a problem, but in this commit odoo/odoo@79a559c
, Odoo began expecting a recordset to call the function _get_calendar_att.
This change was introduced during the migration to V15 in this commit OCA@b7a6f5b
, so we updated the parameter to pass it as a record.
When a user had no resource_booking permissions and opened a calendar event linked to a resource booking, he got an unnecessary access error.
…he field is set

For a curious reason, the test_resource_booking_schedule_unschedule test fails after this PR: odoo/odoo#223875
The requester_advice field is of type Text, but in calendar.event the description field is HTML. I tried changing the field type to HTML, but the error still occurs, so another approach is to only pass the field when it is filled.
…t read access

A user landing on /my that lacks resource.booking read access (e.g. an
internal user not in resource_booking.group_user, an internal account
created by another website-facing module) used to hit a hard AccessError:

- _prepare_home_portal_values called search_count([]) unguarded, breaking
  the entire portal home page when "booking_count" was in counters.
- portal_my_bookings called search_count([]) unguarded, breaking the
  /my/bookings listing for the same users.

Both paths now check Booking.has_access("read") and degrade gracefully
(zero counter, empty list page) instead of raising. Portal users with
the dedicated ACL row keep the existing behavior unchanged.

Distinct from upstream 1c59c21 ([FIX] resource_booking: access error on
normal calendar) which fixed a different surface: the calendar event
form's resource_booking_ids field now hidden via groups= for users
without booking permissions. The portal AccessError addressed here is
a separate bug.

Co-Authored-By: Brenden Eshbach <brenden@techsystech.com>
…slots

All-day calendar events store dates in start_date/stop_date and may have
no start/stop datetimes (or values outside the analyzer's UTC window
once timezone-shifted). The previous busy-events query filtered solely
on start/stop, so a user's all-day event (PTO, off-site, etc.) would
not block booking slots on that day.

Extend the conflicting-events search with an OR predicate on
start_date/stop_date for allday events, and render their busy interval
from start_date through stop_date+1 in the analyzer's tz so a single
all-day event blocks the full local day across calendar tz boundaries.

Co-Authored-By: Brenden Eshbach <brenden@techsystech.com>
…ests

Two follow-ups from review of the no-access fix:

- portal_my_bookings: unify the no-access branch with the normal path.
  Previously the no-access branch returned an empty dict for `pager`,
  which is technically harmless because the current template doesn't
  read pager, but is fragile against future template inheritance. Now
  has_access is computed once, search_count is gated, and the rest of
  the function (real portal.pager(total=0), recordset, session, render)
  runs through the single existing code path.
- Tests: replace fragile "no Traceback in response" assertions with
  positive DOM markers. Home test now asserts the .o_portal_my_home /
  .o_portal_wrap wrapper renders; listing test asserts the empty-state
  alert string from the QWeb template appears. Both confirm the
  template actually rendered rather than just "did not crash".
Signed-off-by: Don Kendall <dkendall@ledoweb.com>
@dnplkndll dnplkndll force-pushed the 19.0-mig-resource_booking branch 2 times, most recently from 76f8f01 to 530d7a6 Compare May 28, 2026 20:56
Copy link
Copy Markdown
Contributor

@carlos-lopez-tecnativa carlos-lopez-tecnativa left a comment

Choose a reason for hiding this comment

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

If you removed the test, please add a justification to explain the reason for the change. Or was it dropped by mistake? If so, please restore it in the corresponding commit.

Comment thread resource_booking/tests/test_backend.py Outdated
Comment thread resource_booking/tests/test_backend.py Outdated
dnplkndll and others added 2 commits May 29, 2026 14:37
Forward-port of fixes dropped when [MIG] was written against an older
18.0 baseline:

- OCA#183: restore _get_intervals(tz) + TZ-aware slot conversion so that
  portal slots always display in the booking type's time zone
  (Intervals replaces WorkIntervals from removed hr_work_entry_contract)
- OCA#189: inject event_tz from the resource calendar on meeting creation
  so the calendar event carries the correct time zone from first write
- OCA#214: set description on meeting only when requester_advice is set;
  unconditional assignment broke test_resource_booking_schedule_unschedule
  after odoo/odoo#223875 (Text vs HTML type mismatch)
- OCA#219: honor all-day calendar events when computing busy slots using
  Domain.OR (replaces removed odoo.osv.expression) with start_date/
  stop_date predicate; render full-day interval from analyzer's tz

Signed-off-by: Don Kendall <dkendall@ledoweb.com>
OCA#225

Remove the obsolete `test: true` key from portal frontend tours to avoid
asset loading errors in Odoo 19.

Co-authored-by: Pilar Vargas <pilar.vargas@tecnativa.com>
Signed-off-by: Don Kendall <dkendall@ledoweb.com>
@dnplkndll dnplkndll force-pushed the 19.0-mig-resource_booking branch 3 times, most recently from b6bfdfd to 7e90449 Compare May 29, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.