Daily updates from Odoo
Friday, September 26, 2025
27 changes · saas-18.4
Enhancements to existing features
Bank reconciliation no longer uses a fixed matching tolerance for invoices. Instead, businesses can control the tolerance through a system setting, with existing and new databases defaulting to no tolerance unless enabled.
Original PR description
This commit: https://github.com/odoo/enterprise/commit/9bea3f2c517e77fdb822eb53b9648e9fc5478dac introduce a tolerance. If an invoice has a bigger amount than the bank line but within the tolerance of 3%, reconcile the invoice automatically and leave the difference in the suspense account. The statement line will be partially matched. This commit will change that tolerance to use a system parameter instead. For old DB the tolerance is at 0 and for new DB a system parameter (0 by default) will be put so that people that want to use it can. task-5106655 Forward-Port-Of: odoo/enterprise#95301
Employee version records now track changes to most business-relevant HR fields across payroll, contracts, salary, attendance, holidays, signing, and local payroll modules. This helps businesses keep a clearer history of employee data changes for compliance, review, and accountability.
Original PR description
Most fields in hr.version represent business-relevant employee data that should be tracked to ensure a complete audit trail. This commit adds `tracking=True` by default on hr.version fields across community and enterprise modules. task-5022109
Employee version records now automatically track changes to most business-relevant fields. This strengthens audit trails and makes it easier for HR teams to understand when important employee information changed.
Original PR description
Most fields in hr.version represent business-relevant employee data that should be tracked to ensure a complete audit trail. This commit adds `tracking=True` by default on hr.version fields across community and enterprise modules. task-5022109
This update makes internal web automation errors easier to diagnose by including the original technical trace when a run step fails. It helps support and development teams find the source of issues faster, reducing time spent investigating unclear browser error messages.
Original PR description
Because it only embeds the error message, and because it ultimately gets `console.error`-ed, an error during a `run()` function is currently extremely unhelpful e.g.
Cannot read properties of undefined (reading 'ownerDocument')
might be all you get. And despite what one might assume, browsers (or at least chrome) don't seem to chain stacktraces when using `{cause}`, so even printing stacktraces on `console.error` does not yield useful information, the stacktrace point to `performAction` instead of a useful location.
So use the `Error#stack` if it's available. In chrome that includes both the error message and the full stack, so a formatted error message is unnecessary. Fall back on a formatted error message if the error has no stack for some reason.
Forward-Port-Of: odoo/odoo#227169Point of Sale now avoids loading large sets of product attribute values until they are actually needed. This reduces unnecessary data loading and can improve startup performance for stores with many product options, without changing how products are linked or sold.
Original PR description
Before this commit, when loading PoS, all product template attribute value (ptav) IDs linked to a product attribute were loaded. This caused performance issues when attributes had a large number of values, even though they were not needed at that stage. With this commit, the values are no longer preloaded, since the reverse fields in ptav and ptal are fetched when needed, ensuring they can still be linked correctly without degrading performance. opw-5006818 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226999 Forward-Port-Of: odoo/odoo#224497
Payroll report views have been tightened so users can no longer edit payslip line or worked days report data from reporting screens. This helps preserve payroll data integrity while making the reports easier to browse and search.
Original PR description
-In payslip line report, some fields can be edited, which should not be allowed. -Views have been adjusted to prevent the navigation from pivot to list view. -Search view has been modified for easier data reaching. Forward-Port-Of: odoo/enterprise#94284
Resolved issues and error corrections
The Helpdesk performance dashboard now correctly opens the SLA Success Rate view. Managers can see closed tickets from the last seven days that were resolved within SLA, making performance reporting accurate and actionable.
Original PR description
**Steps to Reproduce** - Install the Helpdesk module. - Check the My Performance section. - Click on SLA Success Rate. **Issue:** Clicking on SLA Success Rate does nothing. It should display the closed tickets from the past seven days that were resolved within the SLA. **Cause:** Missed a domain filter, so no data is returned or shown. **Fix:** - Add the correct domain filter to show closed tickets. - And also modified compute method as well, so both are aligned. The problem arises in this [commit](https://github.com/odoo/enterprise/pull/76079/files#diff-e145df8bcc8742bcac578d5b05b6fc1aeaef55d236952a2a58d61ac92ce84a67R258-R260) task-4781994 Forward-Port-Of: odoo/enterprise#85412
Italian ENASARCO taxes are now treated correctly as both withholding and pension fund contributions in electronic invoices. This ensures the required information appears in the proper XML sections and reduces reporting errors after installing the Italian localization modules.
Original PR description
* = l10n_it, l10n_it_edi, l10n_it_edi_withholding The ENASARCO tax works both as a Withholding (negative) tax and as a Pension Fund tax. It must appear in the XML in both sections DatiRitenuta and CassaPrevidenziale. - We modified the master data to amend this error. Now the correct Withholding type appears right after installing the module. - Since there was an explicit check on taxes being both, we removed it. - Removed an exception where ENASARCO taxes were allowed to have positive values Forward-Port-Of: odoo/odoo#228322 Forward-Port-Of: odoo/odoo#226357
Vendor bill imports for Chilean electronic invoices now correctly treat lines marked with exemption code 6 as negative amounts. This prevents overstated bills and improves compliance with Chilean electronic invoicing rules.
Original PR description
### Issue: When, in a DTE file, a line has the code 6 in `IndExe`. The amount of the line is supposed to be negative. (See the [doc](https://www.sii.cl/factura_electronica/formato_dte.pdf) page 31/32) ### Steps to reproduce: - Install 'l10n_cl_edi' and switrch to a Chilean company - Have a DTE file with a line having '6' in `IndExe`: - In Accounting > Vendor > Bills, click the button "Upload" and select the DTE file - The imported move has positive values on the every lines ### Cause: The values of `IndExe` are not considered. ### Solution: Add a condition changing the sign of `price_unit` when 6 is in `IndExe` opw-4954723 Forward-Port-Of: odoo/enterprise#93393
Razorpay payments now use a single authentication method instead of mixing account keys with an access token. This prevents mobile checkout failures and 403 errors for merchants who configured both connection options.
Original PR description
In a specific context, Razorpay rejects connections using both Key ID/Secret and an access token simultaneously. To reproduce, it's require a real production Razorpay account since Oauth is not available in test mode. Step to reproduce: - Configure Key ID/Secret and connect via OAuth on the Razorpay payment provider. - On iOS/Android, making a payment on the website triggers a "403 Forbidden" error because Razorpay redirect to `/payment/razorpay/return` and the signature from Razorpay not correspond to the expected signature computed with the Key Secret. This fix prioritizes call with Key ID/Secret over token authentication. if not configured. opw-5100194 opw-4989944 opw-5039880
The IoT box remote debugging dialog now always shows the generate password button. This removes an outdated restriction so users can access the password action when needed.
Original PR description
Since we recently removed the check for the requests sent to the iot box controllers the generate password button being invisible doesn't make sense anymore. This PR makes it always visible Forward-Port-Of: odoo/odoo#228602
The project creation wizard now displays the Customer field neatly on one line when Billable is enabled. This keeps the form visually consistent and easier to read for users creating billable projects.
Original PR description
**Steps to Reproduce:** - Go to the Projects app - Click "Create" to open the wizard - Enable the "Billable" option - Observe the alignment of the "Customer" field that appears **Issue:** The…
**Steps to Reproduce:** - Go to the Projects app - Click "Create" to open the wizard - Enable the "Billable" option - Observe the alignment of the "Customer" field that appears **Issue:** The "Customer" label and input field are stacked vertically, with the input's underline (green line) positioned below the label, leading to uneven spacing and misalignment compared to other fields. **Current behaviour:** - The "Customer" field is visually misaligned , its label and input are not horizontally aligned, causing UI inconsistency. **Expected behaviour:** - The "Customer" label and input field should align horizontally on a single line, with the input's underline matching the label's baseline. **Fix:** The layout is updated using proper flexbox classes to ensure the "Customer" label and input field appear on the same line with proper vertical alignment. Task-4949146 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221242
Belgian point-of-sale users now see a clear “Device disconnected” message when the blackbox device is unplugged or loses connection. This avoids confusing staff with a vague unknown error and helps them understand the issue faster.
Original PR description
When the blackbox is being disconnected the user gets "unknown blackbox error" instead of "Device disconnected" explicit message. This PR removes this vague error message introduced in https://github.com/odoo/enterprise/pull/93468 Forward-Port-Of: odoo/enterprise#95489
This fix stops two users or browser sessions from accidentally creating separate invoices for the same Point of Sale order at the same time. If invoicing is already underway, users see an error, and if an invoice already exists, the system opens it instead of creating another one.
Original PR description
This fix prevents multiple users from generating separate invoices for the same POS order simultaneously. Steps to reproduce: 1. Create a new POS order. 2. Open two tabs (or two POS sessions). 3. Generate an invoice in the first tab. 4. Immediately try to generate an invoice in the second tab. 5. Two invoices will be generated. With this fix: - If a user attempts to generate an invoice while another is already in progress, an error message is shown. - If the invoice has already been generated, the existing invoice view is opened instead of creating a duplicate. opw-5004504 Forward-Port-Of: odoo/odoo#223845
Users with view-only access can now mark documents as favorites using the keyboard shortcut without hitting an access error. This makes the Documents app shortcut behavior consistent with the regular favorite button and avoids an unnecessary interruption in daily document navigation.
Original PR description
steps to reproduce =================== - Select a document where you have viewer permission. - Try to toggle the favorite through a hotkey. - Access Error when toggling favorite. Technical =========== - To maintain compatibility with stable versions and avoid changing the return type of the existing method, created the helper method, which will call `toggle_favorited` as we need to handle it for multiple records. After this commit ================== - This commit handles the accessError for shortcut flow. As in 18.3 we already have documents_favorite widget https://github.com/odoo/enterprise/pull/82639 which will work for manually favoriting the document, but it is not handling the shortcut flow. Task-4910326 Forward-Port-Of: odoo/enterprise#89928
Recruitment offers now handle cases where an employee signs multiple contracts from the same offer without causing an error. The system uses the most recently signed contract, helping HR teams complete hiring workflows smoothly.
Original PR description
Issue: - In recruitment, if an employee sign multiple contract from a same offer, we are getting singleton error. Fix: - To fix this we will take the latest signed contract into consideration. task: 5089959
Vendor bill matching now handles cases where a purchase order and vendor bill use the same individual contact linked to a company. This prevents an error during matching and lets purchasing teams reconcile bills reliably when vendors are represented by individual contacts.
Original PR description
**Issue** When both a Purchase Order and a Vendor Bill are created using the same individual contact linked to a company, Bill Matching fails with a traceback. **Steps to Reproduce** 1. Create an…
**Issue** When both a Purchase Order and a Vendor Bill are created using the same individual contact linked to a company, Bill Matching fails with a traceback. **Steps to Reproduce** 1. Create an individual contact and link it to a company. 2. Create a Purchase Order with the individual as a vendor. 3. Create a Vendor Bill with the same individual as the vendor. 4. Try to perform Bill Matching. 5. A `ValueError: Expected singleton: res.partner(...)` is raised. Video for reference: https://drive.google.com/file/d/1qVnPLpk8jyMTKz-6AVLSaN2nVVeWiF4y/view **Root Cause** Purchase Orders store the partner exactly as selected (the individual contact), while Vendor Bills are normalized internally to the parent company (`commercial_partner_id`). This creates a mismatch in the Bill Matching logic, where records reference both the individual and the company, leading to an invalid recordset and the singleton error. **Fix** Always normalize vendors to their `commercial_partner_id` during Bill Matching. This ensures that both Purchase Orders and Vendor Bills consistently reference the same partner, avoiding mismatches between individual contacts and their parent company. Opw-5050339 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226130
New users can now load demo data in the Attendance app without hitting an access error. This makes it easier for teams to try or evaluate Attendance features without needing administrator intervention.
Original PR description
Currently, an error occurs when a new user tries to load demo data in the ``Attendance`` module. Steps to reproduce: --- - Install ``hr_attendance`` module (without demo data) - Create NEW user >…
Currently, an error occurs when a new user tries to load demo data in the ``Attendance`` module.
Steps to reproduce:
---
- Install ``hr_attendance`` module (without demo data)
- Create NEW user > Login with new user
- Open ``Attendance`` and Click ``Load Demo Data``
Traceback:
---
```
AccessError
You are not allowed to create 'Resource Working Time' (resource.calendar) records.
This operation is allowed for the following groups:
- Administration/Settings
Contact your administrator to request access if necessary.
ParseError
while parsing /home/odoo/src/odoo/saas-18.1/addons/hr_attendance/data/scenarios/hr_attendance_scenario.xml:5, somewhere inside <record id="resource_calendar_std_38h" model="resource.calendar" forcecreate="1">
<field name="name">Standard 32 hours/week (4 work days, friday free)</field>
<field name="company_id" eval="False"/>
<field name="hours_per_day">8</field>
<field name="attendance_ids" eval="[(5, 0, 0), (0, 0, {'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}), (0, 0, {'name': 'Monday Lunch', 'dayofweek': '0', 'hour_from': 12, 'hour_to': 13, 'day_period': 'lunch'}), (0, 0, {'name': 'Monday Afternoon', 'dayofweek': '0', 'hour_from': 13, 'hour_to': 17, 'day_period': 'afternoon'}), (0, 0, {'name': 'Tuesday Morning', 'dayofweek': '1', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}), (0, 0, {'name': 'Tu...
ValueError
ParseError('while parsing /home/odoo/src/odoo/saas-18.1/addons/hr_attendance/data/scenarios/hr_attendance_scenario.xml:5, somewhere inside\n<record id="resource_calendar_std_38h" model="resource.calendar" forcecreate="1">\n <field name="name">Standard 32 hours/week (4 work days, friday free)</field>\n <field name="company_id" eval="False"/>\n <field name="hours_per_day">8</field>\n <field name="attendance_ids" eval="[(5, 0, 0), (0, 0, {\'name\': \'Monday Morning\', \'dayofweek\': \'0\', \'hour_from\': 8, \'hour_to\': 12, \'day_period\': \'morning\'}), (0, 0, {\'name\': \'Monday Lunch\', \'dayofweek\': \'0\', \'hour_from\': 12, \'hour_to\': 13, \'day_period\': \'lunch\'}), (0, 0, {\'name\': \'Monday Afternoon\', \'dayofweek\': \'0\', \'hour_from\': 13, \'hour_to\': 17, \'day_period\': \'afternoon\'}), (0, 0, {\'name\': \'Tuesday Morning\', \'dayofweek\': \'1\', \'hour_from\': 8, \'hour...
```
This error occurs because the new user has not been granted administrative rights.
This commit resolves the issue by granting the user superuser rights.
sentry-6110523247
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#195714This fixes an issue where a completed manufacturing backorder could incorrectly change an earlier operation from cancelled to in progress. It helps production teams see the correct work order status and avoid confusion when tracking partially completed manufacturing orders.
Original PR description
In this bug, in backorder created for later work opertions, the `state` of initial operation is changed to `progress` after, the backorder is `done`. To produce the bug: 1- Create a Bill of Materials with at least two operations at two work centers 2- Create a manufacturing order and confirm it. 3- Complete the first operation and edit the quantity on the second operation so there is a backorder for the remaining quantity 4- In the second work order, the first operation initially appears as `Cancelled`. Once the second operation is completed, it will change to `In progress`. opw-4931653 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222075
New users can now load demo data in the Appraisal app without encountering an error. This helps evaluators and administrators test or explore the appraisal workflow smoothly, even when the module was installed without demo data initially.
Original PR description
Currently, an error occurs when a new user tries to load demo data in the `Appraisal` module. Steps to reproduce: --- - Install `hr_appraisal` module (without demo data) - Create NEW user > Login…
Currently, an error occurs when a new user tries to load demo data in the `Appraisal` module.
Steps to reproduce:
---
- Install `hr_appraisal` module (without demo data)
- Create NEW user > Login with new user
- Open `Appraisal` and Click `Load Demo Data`
Traceback:
---
```py
ParseError: <record id="calendar_event_appraisal_1" model="calendar.event" forcecreate="1">
<field name="user_id" ref="base.user_admin"/>
<field name="name">Appraisal of Emma Granger</field>
<field name="partner_ids" eval="[(6,0,[ref('hr.work_contact_sj'), ref('hr.work_contact_mw'), ref('hr.work_contact_eg')])]"/>
<field name="start" eval="(DateTime.now() + relativedelta(months=1)).strftime('%Y-%m-%d 07:00:00')"/>
<field name="stop" eval="(DateTime.now() + relativedelta(months=1)).strftime('%Y-%m-%d 09:00:00')"/>
<field name="res_model_id" ref="hr_appraisal.model_hr_appraisal"/>
<field name="res_model">hr.appraisal</field>
<field name="res_id" ref="hr_appraisal.hr_appraisal_1"/>
</record>
ValueError: ParseError('while parsing /home/odoo/odoo/enterprise/hr_appraisal/data/scenarios/hr_appraisal_scenario.xml:561, somewhere inside\n<record id="calendar_event_appraisal_1" model="calendar.event" forcecreate="1">\n <field name="user_id" ref="base.user_admin"/>\n <field name="name">Appraisal of Emma Granger</field>\n <field name="partner_ids" eval="[(6,0,[ref(\'hr.work_contact_sj\'), ref(\'hr.work_contact_mw\'), ref(\'hr.work_contact_eg\')])]"/>\n <field name="start" eval="(DateTime.now() + relativedelta(months=1)).strftime(\'%Y-%m-%d 07:00:00\')"/>\n <field name="stop" eval="(DateTime.now() + relativedelta(months=1)).strftime(\'%Y-%m-%d 09:00:00\')"/>\n <field name="res_model_id" ref="hr_appraisal.model_hr_appraisal"/>\n <field name="res_model">hr.appraisal</field>\n <field name="res_id" ref="hr_appraisal.hr_appraisal_1"/>\n </record>') while evaluating
'action = model._load_demo_data()'
```
This error occurs because the new user has not been granted administrative rights.
This commit resolves the issue by granting the user superuser rights.
sentry-6110523247
Forward-Port-Of: odoo/enterprise#93461This fix prevents images inserted into an empty formatted line in the HTML editor from being removed when the content is cleaned up. Users can now add images from placeholders without losing them after clicking elsewhere, improving editing reliability.
Original PR description
Problem: When an image is added inside a `data-oe-zws-empty-inline`, it is removed along with its parent during normalization. Solution: During normalization, replace `data-oe-zws-empty-inline` with the image inside instead of removing both. Steps to reproduce: - Press CTRL+B in an empty line - Press Enter - Click on "Insert image, ..." from the placeholder - Choose an image - Click in the previous paragraph - The image disappears without this fix task-5051343 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224922
This fix adjusts how hidden cursor markers are added around Knowledge comments so they do not multiply during editing. It helps prevent editor crashes or save/history errors when users work with comments in Knowledge articles.
Original PR description
Context: `\ufeff` characters are used in the editor to handle how the cursor behaves when using arrow keys. In the case of knowledge comments, we want to have 2 cursor positions at each comment…
Context: `\ufeff` characters are used in the editor to handle how the cursor behaves when using arrow keys. In the case of knowledge comments, we want to have 2 cursor positions at each comment boundary. I.e.: at the first beacon, we want a cursor position before the anchor (outside of the comment), and one after (inside of the comment). Issue: Since this [commit], empty links receive 2 `zwnbsp` nodes to allow the user to type inside, instead of 1 previously. However knowledge comments beacons are not editable and only need one `zwnbsp`, since we never want to type inside. Furthermore, having 2 and nothing in between them would cause an issue when their content is normalized, which may lead to a traceback: - `link_plugin` executes `selection.anchorNode.parentNode.normalize();` which merges 2 FEFF together. However the function `isZwnbsp` does return true for one text node with 2 FEFF characters. This means that during the next "add feffs" phase, new text nodes with one `FEFF` characters will be added, creating a growing loop generating new `FEFF` at every normalization phase. - Furthermore, merging the nodes in one text node may not result in a new step in some cases, which prevent the `history_plugin` from registering the new node in time in its `nodeMap`, which may lead to a serialization traceback. Resolution: This commit stops using the deprecated `padLinkWithZwnbsp` method to ensure that there are 3 `zwnbsp` characters for each beacon: 2 around it, and one inside. [commit]: https://github.com/odoo/odoo/commit/f0eaeb6 task-5046068
Point of Sale now recalculates the amount due when an already partially refunded order is refunded again. This prevents customers or cashiers from paying the original total instead of the correct remaining balance.
Original PR description
Before this commit, refunding a partially refunded order did not update the total price based on the remaining lines. As a result, it was possible to pay the original total amount instead of the correct remaining amount. opw-5100790 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228186
Paid self-order restaurant orders are now sent to the preparation display before the receipt print prompt can interrupt the cashier screen. This prevents kitchen or preparation staff from waiting on orders just because a receipt printing dialog was left open.
Original PR description
Steps to reproduce: ------------------- 1. Enable self orderdering, and set an online payment method 2. Open 3 tabs: the main PoS one, the self order one, and the preparation display one (we have to…
Steps to reproduce: ------------------- 1. Enable self orderdering, and set an online payment method 2. Open 3 tabs: the main PoS one, the self order one, and the preparation display one (we have to setup the prep display too) 3. In the self order tab, make an order and pay for it Observe that in the main tab, a receipt modal (window.print) appears, and the order is not sent to the payment display (on the third tab) until we either dismiss or accept the printing popup on the main tab. Reason: ------- If there is no printing device connected, we fallback to printing the receipt with `window.print`; this operation blocks the execution of the code that follows it, in our case sending the order to the preparation display, until we either dismiss or confirm the printing popup. Now if the user is not paying attention to the main tab (only looking at the preparation display for instance), the order will not appear in the prep display. Fix: ---- In the case of fallbacking to web printing, we execute the print in a `setTimeout`, so to not block the code that comes after it. opw-5039685 Forward-Port-Of: odoo/odoo#225742
Updating the color of a blog tag now refreshes existing blog posts that use it, so the public blog page displays the new color as expected. This prevents outdated tag colors from remaining visible due to cached page content.
Original PR description
Steps to reproduce: - Go to the /blog page - See that some posts use some tags - Go to Configuration > Tags - Change the color of an existing tag - Go back to the /blog page => The color of the tag is not updated for existing posts using it. This is a t-cache issue, which unfortunately is difficult to fix in stable (as it would require modifying multiple nodes in qweb). As a workaround, and knowing that the t-cache system was fully removed in 19.0 at [1], this fixes the bug with a hack: on tag update, make a dummy update to the related blog posts already using it. Tag updates should be quite rare anyway. [1]: https://github.com/odoo/odoo/commit/1cf06a5688e6aa80175d5a28a83b639d0eb925a7 task-4045724 Forward-Port-Of: odoo/odoo#228428
Fixed an issue that could cause an error when users confirmed several Brazilian electronic invoices at the same time. This makes bulk invoice processing more reliable and helps avoid interruptions in billing workflows.
Original PR description
opw-5107516 Forward-Port-Of: odoo/enterprise#95511
Documentation and clarification updates
The corporate contributor license agreement records were updated to add new members to the Adhoc CLA. This is an administrative legal update that helps keep contribution permissions and compliance documentation current.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228593 Forward-Port-Of: odoo/odoo#226715