Daily updates from Odoo
Tuesday, December 16, 2025
7 changes · 17.0
Resolved issues and error corrections
This update resolves an issue impacting Swiss payroll calculations, specifically related to overtime payments (ST-Aperiodic) and the calculation of LPP (Lohn- und Produktivitäts-Pauschale). The changes ensure accurate reporting of these key payroll components, aligning with Swiss tax regulations.
This update addresses an issue where runbot reports weren't accurately capturing errors or warnings during test module runs. The change restores logging to provide better reporting, while maintaining a standard experience for local testing. This ensures more reliable and comprehensive test results.
Original PR description
One of the changes in #118332 was to let exceptions bubble up to the interpreter in case of error, to improve the experience while running the script locally. This turns out to have downgraded runbot reporting significantly as it doesn't account for stderr / log tracebacks if it got error-level (and possibly even warning-level) logs during the run. Hopefully get the best of both world (and shorten tracebacks slightly) by restoring `logging.exception` at the script level but triggering an abnormal exit for local CLI utility. Forward-Port-Of: odoo/odoo#239995
This update fixes a bug that prevented users from uploading images when quoting tweets within the Odoo Enterprise application. The change allows users to attach images to quoted tweets, enhancing the functionality and user experience. This resolves an issue identified in a previous version.
Original PR description
Bug === Since odoo/odoo@e8567dadbdaaec6e5be8f66f12e2b02da321f999 , it's not possible to upload an image when we quote a tweet. Now, the file data is supposed to be managed in the onChange event, and we can not rely on the input value. Task-3339389
This update fixes an issue where Sendcloud delivery address parsing incorrectly handled addresses with multiple dashes or slashes, such as those common in Austria. The change improves the accuracy of address recognition, ensuring correct delivery address formatting and preventing potential delivery errors. This ensures accurate address data is used when creating shipments.
Original PR description
Issue ----- When creating a sendcloud delivery, addresses containing multiple dashes or slashes (eg Austrian addresses) have their number incorrectly parsed. Examples: Innsbruck Straße 8/1/13 -> 8/11 (should be 8/11/13) 7-3/11A Hochköning Straße -> 7-3 (should be 7-3/11A) Fix ----- Update part of the regex pattern from `\d+[-\/]?\d*` to `\d+(?:[-\/]?\d+)*` in order to match multiple occurences of one of '-', '\' or '/' followed by some number. ----- Ticket: opw-5366863
This update ensures that rental orders created from leads automatically include the tags associated with the original lead. Previously, rental orders lacked this tag inheritance, which is now corrected through a code adjustment. This improves data organization and reporting for rental agreements.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a lead with tags; 2. convert lead to rental order. Issue ----- The new rental order has no tags. Cause ----- Tags are added to regular sales orders via the `_prepare_opportunity_quotation_context` method, but rental orders use `_get_action_rental_context` instead, which is virtually identical, but adds the `in_rental_app` context value, and doesn't include `default_tag_ids`. Solution -------- Rather than having duplicate code, make `_get_action_rental_context` retrieve the base context from `_prepare_opportunity_quotation_context`, then adding `in_rental_app=True`. opw-4549941
This update corrects a bug in the accrual plan calculation, preventing future leave requests from being blocked when remaining leave balances are below the cap. The fix involves a temporary workaround to avoid an infinite loop during calculations, ensuring accurate future leave availability.
Original PR description
Accrual plan for leave days gets blocked, even when the remaining leave balance is below the cap. As a result, no additional leaves are accrued beyond a certain point, even though they should be. #…
Accrual plan for leave days gets blocked, even when the remaining leave balance is below the cap. As a result, no additional leaves are accrued beyond a certain point, even though they should be.
# Steps to reproduce:
Go to time off app
* Create a new leave type.
* Create a new accrual plan with:
- one milestone :
- 2 days accrued per month
- Cap: 10 days
- start accruing 1 days after
- No expiration
- Carry over: All
* Create and validate a leave allocation
- 1 year ago
- new leave type
- new accrual plan
* Take the maximum number of leaves available.
* Advance the computer calendar by 1 year.
* Again, take the maximum number of leaves.
* Advance the computer calendar by another year.
* Try to take a future leave.
-> Issue: It’s not possible to take a future leave, the number of accrued days has stopped increasing. The accrual plan appears blocked.
Objective : The accrual plan should continue to allocate leave days even if leaves have been consumed regularly, as long as the remaining leaves are under the cap.
## Issue
Before going further: the property `leaves_taken` of the `hr.leave.allocation` is supposed to contain the number of leaves this allocation cover until "today".
In the `_test_get_allocation_future_leaves1` added test, in the last line of the test :
`assert_virtual_leaves_equal(self, leave_type_day, 2, self.employee_emp, date='2023-02-01')`
When calling `get_allocation_data` with a `target_date` set in the future, the result is wrong. Here is how it works :
`get_allocation_data`
...
.....`_get_consumed_leaves` (1)
...........`_get_future_leaves_on` (2)
...............`_process_accrual_plans` (3)
....................`_compute_leaves` (4)
.........................`_get_consumed_leaves` (5)
..............................`get_future_leaves_on` (6)
...................................`process_accrual_plans` (7)
**A)** The method **(2)** try to calculate the added number of days each allocation will have on `target_date`. So it creates a copy of the allocation in memory using the 'new' method:
`fake_allocation = self.env['hr.leave.allocation'].with_context(default_date_from=accrual_date).new(origin=self)`
It will then update it to `target_date` using `_process_accrual_plans` and will return the difference of days between the
updated `fake_allocation` and the current allocation (`self`)
**B)** Before iterating over each accrual date, the `_process_accrual_plans` **(3)** will get the `leaves_taken` property which is a computed field. It will trigger `_compute_leaves`.
**C)** The method **(4)** will call `_get_consumed_leaves`, and so the nightmare begins.
**D)** The method **(6)** will create a second `fake_allocation` based on the origin of the first `fake_allocation` (see **A)**).
**E)** This time, `_process_accrual_plans` **(7)** will also look at the `leaves_taken`, but won't trigger the `_compute_leaves` probably because the current allocation is a `fake_allocation` of a `fake_allocation`, and one property of the `new` method is that `Two new records with the same origin record are considered equal.`. Therefore, the `leaves_taken` is considered to be already computed (but it's not).
So `_process_accrual_plans` read the `leaves_taken` which is 0 (probably the default value of `leaves_taken`), but it should be 20 !
**F)** As the value of `leaves_taken` is wrong, the fake_allocation n°2 is also wrong, and its `number_of_day` is 10 but the `number_of_days` of the origin allocation is 20. So `get_future_leaves_on` **(6)** will return -10 which makes no sense, and all the previous calls computations will be wrong. And the final `virtual_remaining_leaves` value will be 0 instead of 2.
## Source of the issue
In the `_process_accrual_plans` method, for each allocation, `leaves_taken` is only computed once at the start of the loop over the allocation "important" dates (see `nextcall` property of `hr.leave.allocation`). At this moment, the method calculates the `leaves_taken` the allocation will have on the `accrual_date` parameter. Yet, this property can change depending on the date the allocation is on (`nextcall` property) which leads to some issues in the computation of the `allocation.number_of_days`.
## Solution
For each allocation, compute the `leaves_taken` at every iteration trough the values of `nextcall`. BUT, this can trigger an infinite loop as computing `leaves_taken` calls `_get_consumed_leaves` which calls `_get_future_leaves_on`, which calls `_process_accrual_plans` ... To avoid this, this PR add the context variable `precomputed_allocations` (will be converted into a function parameter in master) which will prevent `_get_consumed_leaves` from calling `_get_future_leaves_on` for the allocations already up to date (contained by this very `precomputed_allocations` context variable).
**For r+: Needs a few changes at 18.0 (hours per day of employee is retrieved differently for example)**
opw-4934391
opw-5226806This update resolves an error that occurred when generating payslips for employees on weekends, specifically when a public holiday fell on a Saturday. The fix ensures the system correctly verifies the holiday's presence in the employee's schedule before generating the payslip, preventing errors and ensuring accurate payroll calculations.
Original PR description
## Short functional explanation of the error Let's say we have created a public holiday on a Saturday, which is out of an employee's schedule as they work from monday to friday. When trying to create…
## Short functional explanation of the error Let's say we have created a public holiday on a Saturday, which is out of an employee's schedule as they work from monday to friday. When trying to create a payslip for this employee for the month the public holiday occurs, it will show an error. ## Reproduction Steps 1. Create a public holiday on a Saturday. Set the Working Hours to a schedule not including Saturdays. Set the Work Entry Type as Generic Time Off. 2. Click on the Configuration tab > Time Off Types. 3. Create a Time Off type. Set the Requires Allocation field at No Limit, and the Work Entry Type field at Generic Time Off. 4. Click on the Management tab, then Time Off. 5. Click on New. Make sure to select an employee who has the same working schedule as the one you set for the public holiday, and that on their contract, their Work Entry Source is set to Working Schedule. Set the Time Off Type field to the one you just created. 6. Save and click Approve. 7. Go to Payroll. In Contracts, make sure that the employee's contract is running, and that their contract type is Full-Time. 8. Click on the Payslips tab > to pay. 9. Click on New and select the employee for which you just created a time off. ### Expected behavior The payslip is created. ### Unexpected behavior An Odoo Error Occurs. ## Origin of the issue In the code, we don't verify that the holiday is present in the employee schedule before computing the name of the payslip: https://github.com/odoo/enterprise/blob/a7e954dbe4a68b1770341e754101319a89e4de9e/hr_payroll/models/hr_payslip_worked_days.py#L87-L92 We simply check if one holiday exists, which is the case as a public holiday is applied to every employee. Therefore, we need one more check. __ opw-5269302