Thursday, September 10, 2026
12 changes · saas-19.1
Enhancements to existing features
This change updates a Belgian payroll rule parameter related to training time off thresholds. It helps keep payroll calculations aligned with the latest required value for Belgian HR payroll processing.
Original PR description
add new value to the training_time_off_threshold salary rule param. task-6545545 Forward-Port-Of: odoo/enterprise#131080
Obox actions are now kept for 24 hours instead of 3 hours. This gives teams more time to investigate issues and understand what happened up to a day later.
Original PR description
We now keep obox actions for 24h instead of 3h to be able to debug until one day after.
Resolved issues and error corrections
Spreadsheet cells now display correctly when opened in Hoot debug test mode. The fix disables cell animations during these tests because the test environment cannot run them reliably, improving test accuracy without changing normal user behavior.
Original PR description
If you try to open a spreadsheet in debug mode in the Hoot tests, you will often end up with cells with wrong displayed data. That's because cell animations don't work in hoot (it patches `requestAnimationFrame`), so we end up with cell animations stuck in the first frame of the animation. We can simply disable the cell animations in the Hoot tests, as animations are not relevant to the tests. Task: [4909027](https://www.odoo.com/odoo/2328/tasks/4909027) Forward-Port-Of: odoo/odoo#216620
Code cleanup and technical improvements
The accounting test suite was cleaned by removing duplicate helper code and outdated commented sections. This is an internal maintenance change that helps keep future development and testing easier without changing day-to-day product behavior.
Original PR description
This commit cleans up the test suite within the `account_accountant` module by removing redundant methods and old commented code. no-task Forward-Port-Of: odoo/enterprise#130857 Forward-Port-Of: odoo/enterprise#130644
Documentation and clarification updates
A contributor license agreement record was added for Victor Hachard. This keeps Odoo's contribution records up to date and confirms the contributor's legal permission to submit work to the project.
Original PR description
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Signing against 17.0 so the signature is forward-ported to all newer versions, as advised in #139403. Forward-Port-Of: odoo/odoo#287231
This fix stops non-product display lines from sales orders being selected or copied into manufacturing stock movements. It helps keep manufacturing and inventory records accurate by ensuring only valid sales order lines are linked during manufacturing confirmation.
Original PR description
Issue: ====== before this commit, user was able to select a display SOL and at MO confirmation the SOL was copied to the stock move, so we end up with a stock move linked to a display SOL, which is not correct. Solution: ========= - add a domain on the SOL field as first guard layer - add check on the SOL on MO confirmation to prevent copying a display SOL to the stock move opw-6473017 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287309 Forward-Port-Of: odoo/odoo#286534
The Missing E-Invoice check now opens only the invoices that were actually identified as missing an e-invoice. This prevents users from seeing unrelated or overly broad invoice lists, making follow-up work clearer and less error-prone.
Original PR description
The `missing_einvoice` check passed custom `views` but no explicit `domain`, so its action ignored the `moves` recordset and instead opened all matching `account.move` records — an unfiltered list when no invoices were missing, and every eligible invoice (not just the flagged ones) otherwise.
Guard the action to only build when `moves` is non-empty, and pass `domain=[('id', 'in', moves.ids)]` so it's always scoped to the invoices actually found.
task-6544790
Forward-Port-Of: odoo/enterprise#130483This update removes references to an old developer option that no longer exists. It prevents confusion for administrators and developers using configuration tools, with no expected impact on day-to-day business workflows.
Original PR description
The feature was removed in odoo/odoo#115076 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283352
This fix prevents the main company folder used for projects from being archived by mistake. It helps keep project document organization intact and avoids disruption for teams relying on the shared project folder structure.
Original PR description
The company's project folder is supposed to be [impossible](https://github.com/odoo/enterprise/blob/20cc61e69aa3f6a59de1e962b25ce11fa402bf22/documents_project/models/documents_document.py#L44) to archive, by using the `_unlink_except_company_folders` logic. However, the method that adds the company field to the list of fields to check was missing, so it was still possible to archive a folder set as projects folder. Forward-Port-Of: odoo/enterprise#120605
Sold-out event tickets or time slots now correctly show that no seats can be ordered, instead of being treated as if the normal maximum order limit still applied. This prevents future booking flows from accidentally allowing unavailable tickets to appear orderable.
Original PR description
### Steps to reproduce: event = env['event.event'].create({ 'name': 'Repro Event', 'date_begin': '2026-09-01 08:00:00', 'date_end': '2026-09-01 18:00:00', }) ticket =…
### Steps to reproduce:
event = env['event.event'].create({
'name': 'Repro Event',
'date_begin': '2026-09-01 08:00:00',
'date_end': '2026-09-01 18:00:00',
})
ticket = env['event.event.ticket'].create({
'event_id': event.id,
'name': 'VIP',
'seats_limited': True,
'seats_max': 1,
})
env['event.registration'].create({
'event_id': event.id,
'event_ticket_id': ticket.id,
'name': 'Attendee 1',
'state': 'open',
})
ticket.seats_available -> 0
ticket.is_sold_out -> True
result = ticket._get_current_limit_per_order(event=event) print(result) # {ticket.id: 30} -- expected {ticket.id: 0}
### Issue and Expected
`_get_current_limit_per_order()` used `if not seats_available:` to detect the "no limit" case returned by `_get_seats_availability()`. That check is truthy for both `None` (genuinely no limit) and the integer `0` (fully booked), so a sold-out ticket/slot combination was incorrectly treated as unlimited and returned `limit_max_per_order or EVENT_MAX_TICKETS` (e.g. 30) instead of `0`.
### Fix
`_get_seats_availability()` explicitly documents `None` as the "no limit" sentinel, with `0` meaning "constrained, zero seats left". Use `seats_available is None` to preserve that distinction instead of a falsy check.
No functional regression was found in the current website_event flow: sold-out slots/tickets are filtered or re-derived independently before reaching this value in every existing UI path. This fixes the underlying contract of the method itself, so future or additional callers don't inherit the wrong value.
https://github.com/odoo/odoo/issues/284098
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#284100The appointments calendar now opens on the nearest upcoming booking instead of jumping to the farthest future booking. This helps users quickly see the most relevant schedule when managing appointment types, without affecting booking list behavior.
Original PR description
Problem: The bookings calendar of an appointment type opens on the week of the most distant booking instead of the next one, even when a booking exists later the same day. Cause:…
Problem: The bookings calendar of an appointment type opens on the week of the most distant booking instead of the next one, even when a booking exists later the same day. Cause: `action_calendar_meetings` sets the landing date from `appointments[0].start`, where `appointments` is `self.meeting_ids.filtered_domain(domain)`. `calendar.event` is ordered on `start desc` and a one2many is read in the order of its comodel, so the first record is the furthest booking rather than the next one. The original `search([...], order='start')` was replaced by the one2many in 14b5caccc325 (odoo/enterprise#23191). Solution: Sort the filtered bookings on `start` in `action_calendar_meetings`. That method is the only place the initial date is built, and `action_calendar_event_view_request` reuses it for the gantt start date, so both entry points are covered. `calendar.event` keeps its `start desc` order, which the booking list views rely on. Steps to reproduce: - Go to Appointments. - Open the appointment type "Schedule a Demo" and click Appointments. - Click New, set the date to later today, save and go back. - Click New, set the date to one year from now, save and go back. - Go back to Appointments, reopen "Schedule a Demo" and click Appointments. - Switch to the calendar view. - Observe that the calendar opens on the week of the booking one year from now. Ticket [link](https://www.odoo.com/odoo/project.task/6480029) opw-6480029 Forward-Port-Of: odoo/enterprise#129000
ERPly S.R.L. has signed Odoo's Corporate Contributor License Agreement, confirming the legal terms for its contributions. This clears the licensing check for a related contribution whose other validation steps had already passed.
Original PR description
ERPly S.R.L. (Santo Domingo, Dominican Republic) signs the Corporate Contributor License Agreement v1.0. This unblocks the `legal/cla` check on #286565, where every other CI check already passes. Signed by Rob Cruz (rob.cruz@erply.do, @rob-erply), acting on behalf of ERPly S.R.L. Forward-Port-Of: odoo/odoo#286665