Daily updates from Odoo
Navigate
Branch
Thursday, October 9, 2025
205 changes
16 changes
Resolved issues and error corrections
This fixes a typo in the UAE payroll configuration where a salary rule was incorrectly labeled "Out of version" instead of "Out of Contract". The correction helps payroll users see the intended wording and avoid confusion when reviewing salary rules.
Original PR description
fix an accidental change during a forward port from "Out of Contract" to "Out of version" task-5075058
Stripe payments now handle currencies like the Ugandan shilling that use special decimal rules in Stripe. This prevents valid orders from being sent with the wrong amount and rejected at checkout.
Original PR description
Steps: - Activate the 'UGX' currency. - Make a sale order with amount 100 with 'UGX' currency - Try to pay that order (100 USh) using card Issue: - stripe throws the following error - > 'The Checkout Session's total amount must convert to at least 50 cents. 1.00 USh converts to approximately €0.00.' - Hence 100 USh sent was identified as 1 USh by stripe. This confirms issue with decimals and currency mapping. Cause: - 'UGX' is zero-decimal currency but stripe identify it as two-decimal. Fix: - Update mapping for such special currency cases for stripe that don't follow general rules opw-5075707 Forward-Port-Of: odoo/odoo#227688
This change updates the mail module's automated tests so saving email HTML fields waits until the save action is actually available. This helps reduce false failures in Odoo's runbot test system and improves confidence in build results.
Original PR description
This commit tries to solve runbot issues with mail html fields widget. It seems clicking on the save button manually is not generating a call to the backend. This could be due to the fact the button is not enabled due to the data being invalid. Therefore using the clickSave util could be useful in those situation since waiting that the button becomes enabled. This solution is not 100% sure to fix the issue in all cases but manually disabling the button is creating the issue we can observe in those runbots. There is a good chance it might work. fixes-runbot-231582 fixes-runbot-233049 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227484
Some tests were loading Chart.js using loadJS, without the corresponding bundle. That means that the test that comes after could fail if they required treemap/geo charts, as they weren't loaded in ChartJs. Task: [5003595](https://www.odoo.com/odoo/2328/tasks/5003595) Forward-Port-Of: odoo/enterprise#94769
Original PR description
Some tests were loading Chart.js using loadJS, without the corresponding bundle. That means that the test that comes after could fail if they required treemap/geo charts, as they weren't loaded in ChartJs. Task: [5003595](https://www.odoo.com/odoo/2328/tasks/5003595) Forward-Port-Of: odoo/enterprise#94769
The employee form now displays the private address city, state, and ZIP fields in better horizontal alignment. This makes the Swiss payroll employee form easier to read and use, reducing visual confusion when entering address details.
Original PR description
Wrap private address city, state, and zip fields in a flexbox container to ensure proper horizontal alignment on the employee form view. task-5082714 Forward-Port-Of: odoo/enterprise#94779
The employee form layout now keeps the private address city, state, and zip fields aligned on the same row. This improves readability and reduces visual confusion when viewing or editing employee address details.
Original PR description
Wrap private address city, state, and zip fields in a flexbox container to ensure proper horizontal alignment on the employee form view. task-5082714 Forward-Port-Of: odoo/odoo#226935
This fix prevents an error that could occur when an administrator clears browser data in Chrome while Live Chat is installed. It adds a safeguard so the Live Chat storage cleanup handles Chrome's empty storage notification correctly, improving reliability without changing user-facing features.
Original PR description
**Steps to reproduce:** Install 'Live Chat' Open Chrome Log in as 'Admin' Clear browser data **Current behavior before PR:** Clearing data triggers a storage event where the key parameter is null. An event listener attempts to call a method on this null key, leading to a runtime error. **Desired behavior after PR is merged:** A check has been added to ensure the key is not null, preventing the error. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230298
This fixes an issue where some nested website product description text could not be translated when using multiple languages. Businesses can now maintain complete localized shop content, improving consistency for international customers.
Original PR description
Scenario: - enable second language on website - go to /shop/1 and try to translate description_ecommerce Result: this is not translatable Cause: Since at least…
Scenario:
- enable second language on website
- go to /shop/1 and try to translate description_ecommerce
Result: this is not translatable
Cause:
Since at least b455ea85853dfc19ed01e33986ad270cf80ee5d6 the
contenteditable attribute in ContentEditablePlugin is not set on an
element if it has a contenteditable ancestor.
TranslationPlugin disable all editable nodes containing editable nodes.
So with this combination, if we had a node for example:
```
<div class="oe_editable" data-oe-model="product.template" data-oe-id="1"
data-oe-field="description_ecommerce" data-oe-type="html">
<div>
<span class="oe_editable" data-oe-model="product.template"
data-oe-id="1" data-oe-field="description_ecommerce">
test
</span>
</div>
</div>
```
the contenteditable was added to the parent div.oe_editable, but was
removed by TranslationPlugin so the "test" text was not translatable.
Fix: move the code that adds data-oe-readonly class in the
after_setup_editor_handlers so it is run before contenteditable
attributes are set.
opw-5128618Vendor credit notes created through purchase order matching now show the correct positive quantity when reversing over-billed purchase items. This prevents confusing negative quantities and helps keep purchase billing corrections accurate.
Original PR description
Steps to reproduce:- - Create a Purchase Order with Product A(invoicing policy: received quantities) and Quantity 3. - Create Vendor Bill with Product A and Quantity 3 and match it with the PO. - Receive only 2 on PO. - Now on PO, Quantity: 3, Received:2, Billed:3 - Create a Vendor Credit Note for that partner, add an empty line and save. - Click on PO Matching at the top. - Select line from Vendor Credit Note and line from PO, click match. Problem: In Vendor Credit Note Quantity: -1 (which should be 1) Before this commit: When credit note values are prepared from purchase order, quantity to invoice on purchase order is set as quantity on credit note. After this commit: When credit note values are prepared from purchase order, inverse(-ve) of quantity to invoice on purchase order is set as quantity on credit note. task-4975200 Forward-Port-Of: odoo/odoo#230487 Forward-Port-Of: odoo/odoo#221203
The vendor on-time rate report now shows purchase delivery data even when ordered products do not have a product category. This restores the graph on vendor records and gives purchasing teams a complete view of supplier delivery performance.
Original PR description
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and…
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and validate the generated receipt. 5-In the vendor form view, click the On-time Rate smart button → no graph is visible. **Issue:** https://github.com/odoo/odoo/blob/77b3956ed5635d79ae8dc19423140dc6a10098f1/addons/purchase_stock/report/vendor_delay_report.py#L46-L50 ``` The On-time Rate graph is not displayed in the Vendor Delay report. ``` **Cause:** - From version 18.2, `categ_id` was removed as a required field. The report query still uses an inner join on `categ_id`, which excludes products without a category and prevents data from being generated. - Commit which make `categ_id` non require - https://github.com/odoo/odoo/pull/166323/commits/b039caecbeb04057fbccb1cc88d03a4946f88e8e **Solution:** - Replace the inner join with a left join so that products without a `categ_id` are also included in the report (with null values when the category is not set). **opw** - 4991367 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230388 Forward-Port-Of: odoo/odoo#225557
This update ensures the right domestic fiscal position is selected for companies in the UAE, Italy, Mexico, and Cambodia. This helps apply the correct domestic taxes and removes a duplicate Italian setup that could cause confusion or incorrect tax behavior.
Original PR description
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the…
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the following localizations: **AE** Sequences are added making Dubai the domestic fiscal position. However this needs to be improved to automatically prioritize the fiscal position based on the company's state. **IT** (l10n_it_edi_doi) An additional domestic fiscal position was mistakenly added. The correct domestic FP is defined in it's dependency module l10n_it. The duplicate FP is removed. **MX** Sequences are added **KH** Sequences are added No Task - l10n's identified by the fiscal position checks in `test_all_l10n` 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#230654
Spreadsheet-related tests now load the full chart library setup they depend on. This prevents later tests from failing unpredictably when they need specialized chart types such as treemap or geographic charts, improving reliability without changing user-facing behavior.
Original PR description
Some tests were loading Chart.js using loadJS, without the corresponding bundle. That means that the test that comes after could fail if they required treemap/geo charts, as they weren't loaded in ChartJs. Task: [5003595](https://www.odoo.com/web#id=5003595&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form)
The restaurant appointment feature has been updated so its floor screen stays compatible with recent core point-of-sale changes. This helps prevent display or navigation issues for businesses using restaurant tables together with appointments.
Original PR description
This commit adapts an overriding method to reflect changes in the base method done in this pr https://github.com/odoo/odoo/pull/176016. Forward-Port-Of: odoo/enterprise#91334
This fixes several display issues when opening a single bank statement line from a reconciled entry. The reconciliation screen now restores the summary when filters are cleared, avoids expanding unrelated lines, hides an irrelevant Statement button for single-line views, and opens the ledger using the correct journal context.
Original PR description
When you open a statement line from a reconciled move, it opens the bank reconciliation widget with only the selected statement line, which is unfolded by default. However, there are a few issues with this behavior, which are fixed in this commit: 1 - When entering the bank reconciliation widget, the initial line is unfolded. If you remove the filter, all the other lines become unfolded as well. This should not be the case; only the original line should remain unfolded. 2 - By default, the statement summary line is hidden. When the filter is removed, the summary remains hidden. We now ensure the summary is displayed again when the filter is cleared. 3 - The Statement button on the statement line (which is meant to create a new statement) doesn't make any sense when there is only one line. It is now hidden in this case. task-5108118 Forward-Port-Of: odoo/enterprise#95558
Odoo Studio now identifies custom fields using their stored status rather than relying on naming rules. This keeps custom field behavior reliable as older name-based checks are phased out and reduces duplicate configuration work in related apps.
Original PR description
With the fields method `_is_manual_name` being deprecated, checking whether a field is manual can be done through the state instead of the field name. This avoids the need to override the definition of a custom field name in another place in the applications that need to do it. Related https://github.com/odoo/odoo/pull/224524
Test data for Hong Kong payroll accounting now includes required leave allocation records. This prevents validation errors in automated checks, helping keep payroll-related releases stable.
Original PR description
Issue: Unit tests are failing because test data was created without leave allocations, leading to validation errors. Fix: Added leave allocation data for time off types which requiring allocation in some tests. build_error-230409 Forward-Port-Of: odoo/enterprise#96060 Forward-Port-Of: odoo/enterprise#93160
12 changes
Resolved issues and error corrections
Fixes an issue where users could see an error message after successfully reconciling the last available batch payment in the bank reconciliation widget. The reconciliation itself worked, but the confusing traceback interrupted the workflow; this change keeps the screen stable when no batch payments remain.
Original PR description
…batch In the bank reconciliation widget, after reconciling the last batch payment, a traceback will be shown to the user. Steps to reproduce: - Create and confirm a customer payment - Create a batch…
…batch
In the bank reconciliation widget, after reconciling the last batch payment, a traceback will be shown to the user.
Steps to reproduce:
- Create and confirm a customer payment
- Create a batch payment including the above payment (ensure this is the only batch payment available for reconciliation)
- Open Bank reconciliation widget
- Create a Bank transaction to reconcile with the batch payment
- Add the batch payment and click "Validate"
Issue: Reconciliation succeeds, but a traceback will be shown:
```
OwlError: The following error occurred in onWillUnmount: "Cannot set properties of undefined (setting 'exportState')"
Error
at wrapError (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11557:23) (/web/static/lib/owl/owl.js:2685)
at onWillUnmount (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11626:34) (/web/static/lib/owl/owl.js:2754)
at BankRecBatchPaymentsRenderer.setup (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:217012:9) (/account_accountant_batch_payment/static/src/components/bank_reconciliation/batch_payments_list_view.js:11)
at new ComponentNode (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11305:28) (/web/static/lib/owl/owl.js:2433)
at http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:14948:28 (/web/static/lib/owl/owl.js:6076)
at BankRecEmbeddedListController.slot7 (eval at compile (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:14679:20), <anonymous>:128:32) (/web/static/lib/owl/owl.js:5807)
at callSlot (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11922:37) (/web/static/lib/owl/owl.js:3050)
at Layout.template (eval at compile (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:14679:20), <anonymous>:39:10) (/web/static/lib/owl/owl.js:5807)
at Fiber._render (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:10655:38) (/web/static/lib/owl/owl.js:1783)
at Fiber.render (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:10647:18) (/web/static/lib/owl/owl.js:1775)
Caused by: TypeError: Cannot set properties of undefined (setting 'exportState')
at BankRecBatchPaymentsRenderer.saveSearchState (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:217039:32) (/account_accountant_batch_payment/static/src/components/bank_reconciliation/batch_payments_list_view.js:38)
at BankRecBatchPaymentsRenderer.<anonymous> (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11571:26) (/web/static/lib/owl/owl.js:2699)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11400:24) (/web/static/lib/owl/owl.js:2528)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode.beforeRemove (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11534:18) (/web/static/lib/owl/owl.js:2662)
```
This occurs because we want to hide the Batch Payments tab from the reconciliation widget when no more batches are available for reconciliation but the `saveSearchState` still expects the batch payments to be defined in the view.
opw-4830466
Forward-Port-Of: odoo/enterprise#96598Stripe payments now handle currencies like the Ugandan shilling that use different decimal rules in Stripe than in standard currency settings. This prevents valid payments from being rejected or sent with the wrong amount, improving checkout reliability for affected currencies.
Original PR description
Steps: - Activate the 'UGX' currency. - Make a sale order with amount 100 with 'UGX' currency - Try to pay that order (100 USh) using card Issue: - stripe throws the following error - > 'The Checkout Session's total amount must convert to at least 50 cents. 1.00 USh converts to approximately €0.00.' - Hence 100 USh sent was identified as 1 USh by stripe. This confirms issue with decimals and currency mapping. Cause: - 'UGX' is zero-decimal currency but stripe identify it as two-decimal. Fix: - Update mapping for such special currency cases for stripe that don't follow general rules opw-5075707 Forward-Port-Of: odoo/odoo#227688
Tables pasted from tools like Google Docs now keep the expected formatting and structure in Odoo's HTML editor. This prevents invisible or incomplete tables and makes pasted content easier to edit reliably.
Original PR description
### Purpose of this PR: - Ensure that pasted table elements get the standard classes: `table, table-bordered, and o_table.` - When content is pasted from other source (e.g., Google Docs inside iframe), attribute nodes coming from another JavaScript context do not match the `Attr` prototype of the current context. Use `item.nodeType === Node.ATTRIBUTE_NODE` instead of `instanceof Attr` to detect attribute nodes. - Insert a base container into empty `<td>` elements when pasting tables from external sources. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230425 Forward-Port-Of: odoo/odoo#230208
This fix prevents Live Chat from showing a runtime error in Chrome when an administrator clears browser data. It adds a safeguard for missing storage information, improving reliability during routine browser maintenance.
Original PR description
**Steps to reproduce:** Install 'Live Chat' Open Chrome Log in as 'Admin' Clear browser data **Current behavior before PR:** Clearing data triggers a storage event where the key parameter is null. An event listener attempts to call a method on this null key, leading to a runtime error. **Desired behavior after PR is merged:** A check has been added to ensure the key is not null, preventing the error. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230298
The payroll test data for Hong Kong was updated to include required leave allocations. This prevents internal validation errors and helps keep automated checks reliable for future updates.
Original PR description
Issue: Unit tests are failing because test data was created without leave allocations, leading to validation errors. Fix: Added leave allocation data for time off types which requiring allocation in some tests. build_error-230409 Forward-Port-Of: odoo/enterprise#96060 Forward-Port-Of: odoo/enterprise#93160
This fix keeps the restaurant floor screen working correctly when appointments are used, following related updates in the core point-of-sale system. It helps prevent disruptions for restaurants that manage table service and bookings through Odoo.
Original PR description
This commit adapts an overriding method to reflect changes in the base method done in this pr https://github.com/odoo/odoo/pull/176016. Forward-Port-Of: odoo/enterprise#91334
The bank reconciliation widget now keeps existing invoice matches when users choose a write-off account that has a default tax. This prevents matched bills from disappearing during reconciliation, reducing rework and avoiding confusion for accounting users.
Original PR description
In the Bank reconciliation widget, users can click a button to set the account to write off the remaining balance. However, if the chosen account has a default tax set, the widget will lose any existing matches with invoices. Steps to reproduce: - Have an account with a default tax - Create a bill with a total - Create a bank statement for a greater amount - Open the bank reconciliation widget - In the created statement, first add the bill, then click 'Set Account,' and choose the account with tax Issue: Bill matching will be lost. This occurs because we remove and recreate the matching line, but we don't keep the line to be reconciled. opw-5002624
This update adjusts how a setting is written in the sales timesheet invoice wizard so it can be safely read by Python-based customizations. It helps prevent errors for businesses using customized invoice workflows, with no expected change to normal user behavior.
Original PR description
Versions -------- - 17.0+ Issue ----- Some customizations may parse XML views using Python, in which case the `date_start_invoice_timesheet` field could return an error, as the `options` attribute uses a Javascript boolean `true`. Solution -------- Use `'true'`, which will get parsed as `true` in JS via `archParseBoolean`. Forward-Port-Of: odoo/odoo#230278
Fixes a checkout issue where valid promotions or coupons could be removed because the storefront and payment confirmation used different time zones or timing. This helps prevent paid orders from getting stuck as unconfirmed and ensures expired coupon discounts are removed before payment is finalized.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a database with GeoIP enabled; 2. have a promotion program that gives a discount on a specific product; 3. use a VPN to browse /shop from California…
Versions -------- - 17.0+ Steps ----- 1. Have a database with GeoIP enabled; 2. have a promotion program that gives a discount on a specific product; 3. use a VPN to browse /shop from California before 7:00 UTC; 4. add the product to your cart; 5. go to checkout; 6. pay for the order. Issue ----- Order cannot be confirmed due to incomplete payment. Cause ----- The `_frontend_pre_dispatch` method of `website` adds a timezone value to the context based on the request's `geoip`. This context value then gets used to find applicable loyalty programs via `Date.context_today`, and applies them to the order. Then after payment was initiated, the order gets validated again using server time (UTC), which now considers the applied program expired, and removes the reward before confirming the order. Consequently, with the discount removed, the paid amount no longer matches the order total, thus the order remains unconfirmed. Solution -------- If the order has a confirmed transaction, use its `create_date` to verify loyalty expiration dates. For time zone, instead of `Date.context_today`, using whatever `tz` value is in the context, use a helper function which retrieves the current day in the company's timezone. For website orders, if defined, use the eCommerce salesperson's time zone instead. Also fix an issue where expired coupon lines weren't getting removed from the order. opw-4765873 opw-4781346 opw-4939268 Forward-Port-Of: odoo/odoo#229749 Forward-Port-Of: odoo/odoo#222428
This fix prevents the editor from creating invalid page content when users change the style of text inside certain formatted elements. It helps ensure edited content keeps the expected layout and displays consistently in browsers.
Original PR description
Before this commit we would insert a block inside of a phrasing content if it's displayed as a block and we change its font style. For example, if we tried to modify text inside of a `<small>` that has `display: block` style, it would insert a new block inside of it. Steps to see the issue: - Have an open editor with `<small>Text</small>` content, that has `display: block` style - Select "Text" and change the font style to paragraph => It will be `<small><p>Text</p></small>` which is not valid HTML, and it will be parsed by a browser as `<small></small><p>Text</p>`, which is not the expected behavior. task-5123274 Forward-Port-Of: odoo/odoo#229043
Fixes an issue where custom hour or half-day selections could be cleared when employees changed the time off type. This helps avoid accidental changes to leave requests and reduces the need for users to re-enter their choices.
Original PR description
- made the value of checkboxes for `request_unit_half` and `request_unit_hours` stay the same when switching between timeoffs that can have hourly type task-id: 5085389 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228981
Product searches in Point of Sale now show all relevant matches instead of stopping at an exact match. This helps cashiers find similar or related products more reliably, reducing missed items during checkout.
Original PR description
The POS search only returned products with an exact match (when existing), ignoring other relevant products that partially matched the search string. Steps to reproduce: 1. Create a product "TEST" - Create a variant with attributes value including "TEST" and "OTHER". 2. Create a second product "TEST 2". 3. Open the POS. 4. Search for "TEST". 5. Only "TEST" is shown; "TEST 2" is missing, even with "Search more". To align with the behavior introduced in v18, I’ve removed the exact match condition, as it no longer appears necessary due to the absence of fuzzy search. I’ve also adjusted the logic to perform the search on `product.product` instead of `product.template`. opw-4958141 Forward-Port-Of: odoo/odoo#221520
34 changes
Enhancements to existing features
The US payroll demo data now includes a Developer USA employee record so demo payroll setup starts with the needed sample information. This helps demos run more reliably by ensuring salary structure defaults are applied after the demo record is available.
Original PR description
Added the Developer USA demo data record in the l10n_us_hr_payroll.xml file instead of leaving it empty for the sake of the demo data being added before triggering the _default_salary_structure function in hy_version.py Task ID: 5003603
Belgian payroll now uses a clearer residency status with Resident, Non-Resident, and Frontalier options. For Frontaliers, withholding tax exemption is applied automatically and locked in the interface, reducing manual errors while keeping flexibility for other employees.
Original PR description
- Add l10n_be_resident_situation field with 3 options: Resident, Non-Resident, Frontalier - Compute no_withholding_taxes automatically for Frontaliers with readonly UI behavior - Maintain backward compatibility with computed is_non_resident field - Update employee and contract template views to use new selection field - Update test data to use new field structure Frontaliers now automatically get no withholding taxes with a disabled checkbox, while Residents and Non-Residents can still manually control the setting. task-4936512
The Hong Kong payroll employee form now places employee name fields under the private contact information section instead of location information. This makes the information easier to find in the most relevant area and improves form organization for HR users.
Original PR description
before: the names were under location information after: moved the names under private contact information task-5042649
Pay Run cards now show icons and clearer, capitalized information text, making payroll runs easier to scan. The Pay Runs action also has a cleaner navigation path, improving consistency when users access this area.
Original PR description
- added icons in Pay Run card and capitalized the info texts - added path to Pay Runs action (as `pay-runs`) task-5109059
A new filter helps users quickly find salary offers that are waiting for their signature. This makes it easier to focus on pending actions and replaces an older default filter with the clearer, dedicated option.
Original PR description
Add filter for 'Waiting For Me' in salary offer search view, returning only offers with signature expected (half signed). Also context filter replaced with the newly introduced one Task ID: 5031087
Payslips that have been validated now show the status as "Done" instead of "Validated". This creates consistent wording between individual payslips and payroll runs, reducing confusion for payroll users.
Original PR description
If the payslip status is "validated", the display status for the payslip is "Validated". The display has been changed to "Done" to match with the payrun's status. Forward-Port-Of: odoo/enterprise#95182
Users can now duplicate existing records even when creating brand-new records is disabled. This gives businesses more precise control, allowing teams to reuse approved records while still preventing unrestricted new entries.
Original PR description
*: documents, web_studio This commit allows record duplication even when creation is disabled (create="0"). Duplication permissions should depend only on specific duplication rules (e.g., duplicate attribute) and server-side access rights — not on the create attribute. This makes sense in cases where users are allowed to duplicate existing records but not create new ones from scratch. task-5131124
The VoIP call history and softphone views now show clear icons when calls include recordings or AI-generated transcriptions. This helps users quickly identify which past conversations have supporting audio or text records available for review.
Original PR description
Task-4962728
Work entries now show where they came from, such as schedules, time off, planning, attendance, or manual creation. Access to work entries is also aligned with HR and payroll roles, helping teams review payroll-related records with clearer ownership and permissions.
Original PR description
- added Source field in `hr_work_entry_view_form` which takes value from:
- `resource_calendar_id` if the work entry has been generated from the working schedule
- `leave_id` if the work entry has been generated from a time off
- `planning_slot_id` if the work entry has been generated from a planning
- `attendance_id` if the work entry has been generated from attendance
- Manual if the work entry has been generated manually
- removed the expand button in the `hr_work_entry` pop up
- added inherited views for `hr_work_entry_view_form` in `hr_work_entry_attendance` and `hr_work_entry_palnning` to show corresponding fields
- changed access of the work entries smart button to be only `group_hr_manager` and then change to `group_hr_payroll_user` when payroll is installed
- removed access to work entries from `group_hr_manager` when payroll is installed
Task [link](https://www.odoo.com/odoo/project.task/5118852)
task-5118852Financial reports now use parent accounts to group and present accounting data, replacing the previous account group approach. This makes reports such as trial balance, aged partner balance, asset reports, and localizations more consistent and easier to interpret for finance teams.
Original PR description
WIP: implement parent account in reports Task: [5055586](https://www.odoo.com/odoo/project/967/tasks/5055586)
Cashiers can now use a dedicated Food Platform button on the POS ticket screen to quickly view orders received through UrbanPiper. This makes it easier to separate third-party delivery orders from in-store sales, while replacing the previous UrbanPiper search filter with a clearer workflow.
Original PR description
In this commit: =============== - Added a "Food Platform" filter button on the ticket screen to show only orders received from UrbanPiper. This helps cashiers quickly identify and manage third-party food platform orders separately from in-store orders. - Removed the UrbanPiper search filter since a dedicated filter button has now been added on the ticket screen for managing UrbanPiper orders. Task-5033759 Related PR: https://github.com/odoo/odoo/pull/224217
Desktop users can now copy the text of AI chat messages directly from the message actions. This makes it easier to reuse AI-generated responses outside the conversation without manual selection.
Original PR description
This commits enables the copy text message action on desktop. task-3509874
Payroll salary rules can now be created without assigning them to a category. This simplifies payroll setup by avoiding unnecessary one-off categories and makes salary rule management easier for teams.
Original PR description
**Issue** To simplify salary rule configuration and reduce unnecessary records the salary rule category field is made non-mandatory, to avoid creating categories that contain only a single rule and making the setup easier to manage. Task ID: 5126314
This update changes how accounting-related demo and localization data is loaded, making setup more consistent across modules. It mainly supports smoother testing and onboarding environments without changing day-to-day business workflows.
Original PR description
More information in community PR
This update changes Bangladesh payroll benefits so they are handled as employee properties rather than fixed payroll inputs. It makes benefit setup more flexible and helps payroll calculations retrieve configured values more reliably.
An unused field in the Appraisal Skills module was removed because it was no longer serving any purpose. This helps keep the module simpler to maintain without changing expected user behavior.
Original PR description
manager_ids is a computed field defined on hr.appraisal.skill model, but it's never used. task-5072467
Payroll users can now generate payslip PDFs more conveniently from list views, with small batches created immediately. Printed payslips are also saved directly on the employee payslip record, making documents easier to find and manage.
Resolved issues and error corrections
WhatsApp message read indicators can now be shared consistently across message previews and chat bubbles. This reduces duplicated logic and helps ensure users see the same read-status cues in more places.
Original PR description
Before [this](https://github.com/odoo/odoo/pull/230075), the `showSeenIndicator` was part of the `Message` component, since that is the only place it was used, but with the intended change it will now be used by the `NotificationItems` and `Chatbubble` to show in the message previews. As the `showSeenIndicator` was part of the message component we had to redifine this getter every time we had to use it. This commit moves it from message component to message model so that it can be reused anywhere it is needed. Community PR: https://github.com/odoo/odoo/pull/230075 task-4825814
This fix prevents invoices from failing during tax calculation when no external tax is found for a customer's ZIP code. The system now safely treats missing manual tax details as empty, allowing users to continue computing taxes without interruption.
Original PR description
Currently, an error occurs when computing taxes for an invoice. **Error:** `KeyError: 'manual_tax_amounts'` **Cause:** When a user clicks the `Compute Tax` button, the system calculates the tax for…
Currently, an error occurs when computing taxes for an invoice.
**Error:**
`KeyError: 'manual_tax_amounts'`
**Cause:**
When a user clicks the `Compute Tax` button, the system calculates the tax for that invoice, including the `manual_tax_amount` [1]. However, if no tax is found for a given customer ZIP code, the `tax_values_list` becomes empty [2]. As a result, `manual_tax_amounts` in the base line also becomes empty.
Later, when the system tries to fetch the `manual_tax_amounts` key from extra_tax_data, it raises a KeyError [2], because the key no longer exists.
Additionally, the condition in [3] indicates that there is no guarantee that the `manual_tax_amounts` key will always be present in the base_line.
**FIX:**
This commit ensures that if the manual_tax_amounts key does not exist, an empty dictionary {} is used instead. This prevents the KeyError from occurring during tax computation.
[1]- https://github.com/odoo/enterprise/blob/b17b6b4e5ca3085d831fc763457496b5c5b639c5/account_external_tax/models/account_external_tax_mixin.py#L155-L163
[2]- https://github.com/odoo/enterprise/blob/a51aee8f6e8bce2aa699d3199d6723495464a762/account_external_tax/models/account_external_tax_mixin.py#L88
[3]- https://github.com/odoo/odoo/blob/241c170dbece8c1652db9ca1aa935b2106ede532/addons/account/models/account_tax.py#L1330
sentry-6919182805
Forward-Port-Of: odoo/enterprise#96401This update changes how AI tool functions are called so they are easier to customize and stay aligned with newer Odoo versions. It helps reduce compatibility issues for future overrides without changing the user-facing AI experience.
Original PR description
To ease the override and compatibility with what is done in 19.0, we call the function with kwargs instead of args. Forward-Port-Of: odoo/enterprise#96630 Forward-Port-Of: odoo/enterprise#96528
Gantt group headers now keep the right size so they remain visible and aligned while users scroll. This prevents oversized headers from breaking the sticky behavior, especially on smaller mobile screens.
Original PR description
Gantt group headers could stop being sticky because their width was fixed based on the number and size of columns. Even though they were set to position: sticky, oversized headers could no longer remain aligned when scrolling, as they extended beyond the viewport and were constrained by the document width. This was especially noticeable on mobile, where group headers are often wider than the screen. The fix applies a max-width style to these headers, capping their size to the available space so they remain sticky without overflowing the document. task-4970992 Forward-Port-Of: odoo/enterprise#96612 Forward-Port-Of: odoo/enterprise#96015
The Mexican electronic invoicing module now preserves valid accented characters, including ü, in legal names. This prevents compliant customer or company names from being incorrectly altered and helps avoid issues with SAT invoice validation.
Original PR description
Previous commit (#95207) removed accents for names including character ü which indeed is a recognized character for SAT opw-5125107 Forward-Port-Of: odoo/enterprise#96043
The Indian payroll demo contract now uses Mitchell Admin as the HR Responsible instead of OdooBot. This makes the sample offer signing flow better match a realistic logged-in user scenario for demos and testing.
Original PR description
Currently, OdooBot is set as the HR Responsible in the default contract template demo data. To make the offer signing process more realistic and aligned with the login user, OdooBot is replaced with Mitchell Admin. task-5095841 Forward-Port-Of: odoo/enterprise#95176
Quality checks for products tracked by serial number now correctly remain failed when the check is failed from a receipt. This prevents defective items from being incorrectly marked as passed, improving inventory and quality control accuracy.
Original PR description
Serial number tracked product are marked as pass even when they fail a move_line type of check. ### Steps to reproduce: * Create a product tracked by serial number * For this product create a control…
Serial number tracked product are marked as pass even when they fail a move_line type of check. ### Steps to reproduce: * Create a product tracked by serial number * For this product create a control point: - Control per quantity - Operations : Receipts * Create a receipt for this product * Mark the receipt as Todo * Start the Quality check from the receipt, without using the smart button. * Fail the Quality check * The Quality check still passes ### Issue: When validating a quality check and it fails: https://github.com/odoo/enterprise/blob/d48228127c239e45938551d9bbac734afab8b31a/quality_control/wizard/quality_check_wizard.py#L84-L92 I will not go through the standard process with show_faillure_message where the user can select failed_qty, it directly goes to confirme_fail>_move_to_failure_location: https://github.com/odoo/enterprise/commit/49149580d34ec5583559fa0288356fec6cb2c514#diff-2ffdc2ffc25417076b580b772447514c7e9d8b3e2d2fff2d3100721eb5ccbaf4L455-R457 In our case since failed_qty is still at 0 this new condition transfer the quality check to pass. In the case of serial numbers, the quality check is done one by one, the failed_qty can be retrived from check.move_line_id.quantity opw-5015266 Forward-Port-Of: odoo/enterprise#92966
Payroll payment reports now handle employees who have multiple bank accounts, including accounts assigned a 0% salary split. This prevents report generation from failing and lets payroll teams produce the CSV reliably in split-payment setups.
Original PR description
-When generating a payment report CSV for user with multiple bank accounts that have a salary split of 100%/0%, a traceback occurs. -The logic has been adjusted so that bank account of 0% split percentage can be included in the payment report. Forward-Port-Of: odoo/enterprise#94468
When an employee contract is signed, the selected company car is now reliably recorded in the employee history even if the value was already present on the contract version. Offer summaries also show the selected car and bike names, making compensation details clearer for HR and employees.
Original PR description
As when signing the employee contract, the version related to that contract is already created and we just set the version active, the value of the car does not change, so the tracking is not triggered and it's not added into the chatter. This PR force the car_id and ordered_car_id to be tracked by adding the initial value the employee precommit tracking values, before the version is activated (so before the employee get the new values from the newly active version). Also, this PR adds the selected car and bike names to the offer summary. Task-4962922 Forward-Port-Of: odoo/enterprise#90915
The update moves HR-related scheduling tests into the HR-specific project module so builds no longer fail when the HR app is not installed. This keeps automated checks aligned with installed apps and improves reliability without changing user-facing behavior.
Original PR description
Steps to reproduce: - start test_auto_schedule_flex_resource when hr not installed. => `AttributeError: 'res.users' object has no attribute 'action_create_employee' Source: - action_create_employee comes from hr, but the test is in project_enterprise Fix: - tests related to hr moved to project_enterprise_hr Forward-Port-Of: odoo/enterprise#96365
The Time Off screens now correctly open the group request wizard from list, calendar, and Gantt views. This ensures managers can create group time off requests without the button failing or being ignored.
Original PR description
See https://github.com/odoo/odoo/pull/226574 **Issue** - When clicking header buttons other than approve/refuse in Time Off list view, the actions are not processed correctly. - Added New Group Time Off to calendar and gantt view **Steps to Reproduce** 1. Navigate to Time Off > Management > Time Off or Allocations 2. Switch to List view 3. Click on New Group button 4. Action is not executed properly **Root Cause** Previously, handleViewButtonClick only processed approve/refuse actions and ignored other header button actions. Now, non-leave actions are correctly forwarded to the default handler. Task ID: 5062846 Forward-Port-Of: odoo/enterprise#95153
Closing the AI chat window in Discuss is now covered by a test to ensure it does not cause a crash. This helps keep the messaging experience stable when users dismiss AI-assisted drafting.
Original PR description
https://github.com/odoo/odoo/pull/230609
fix an accidental change during a forward port from "Out of Contract" to "Out of version" task-5075058 Forward-Port-Of: odoo/enterprise#94144
Original PR description
fix an accidental change during a forward port from "Out of Contract" to "Out of version" task-5075058 Forward-Port-Of: odoo/enterprise#94144
The spreadsheet document tests now load the full chart support they need before running. This prevents later tests from failing unpredictably when they rely on specialized chart types such as treemap or geo charts.
Original PR description
Some tests were loading Chart.js using loadJS, without the corresponding bundle. That means that the test that comes after could fail if they required treemap/geo charts, as they weren't loaded in ChartJs. Task: [5003595](https://www.odoo.com/web#id=5003595&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) Forward-Port-Of: odoo/enterprise#96697
The payroll settings now show the Accounting section for every country, making the Batch account move lines option accessible to all users. SEPA-specific payroll settings remain limited to SEPA countries, so businesses outside SEPA can use the accounting batching option without seeing irrelevant payment settings.
Original PR description
Made the "Accounting" block visible for all countries and placed the Batch account move lines option inside it, instead of inside Payroll SEPA. As a result, Payroll SEPA remains visible only for SEPA countries, while Batch account move lines is now available for all. task-5138344
Features or functions removed from Odoo
The separate hourly cost module has been removed because its only employee field is now included directly in HR. This simplifies setup while keeping the field available only where it is needed, with minor impact on related planning and manufacturing workflows.
Original PR description
This removes the module hr_hourly_cost which was only adding 1 field to hr .employee. Now the field is already present in hr but invisible until needed. Task: 5076449
Miscellaneous changes
…ness" Unicity is not used in every day English
Original PR description
…ness" Unicity is not used in every day English
28 changes
Enhancements to existing features
Payslips that were previously shown as “Validated” will now appear as “Done”. This aligns the payslip status wording with the related payrun status, making payroll screens more consistent for users.
Original PR description
If the payslip status is "validated", the display status for the payslip is "Validated". The display has been changed to "Done" to match with the payrun's status.
When a user opens a project without their own top bar setup, Odoo now uses the project manager's configuration as a fallback. This helps keep project actions visible and consistent without requiring every user to configure the top bar manually.
Original PR description
If the current user doesn't have a top bar configuration yet for a given project, we fallback on the top bar configuration of the project manager to show the actions. task-5072899 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Documents folder action menu now opens immediately instead of waiting for all actions to load, with a spinner shown during loading. Selecting embedded folder actions also feels faster because changes appear right away, while server updates are batched to reduce delays and unnecessary calls.
Original PR description
The cogwheel which holds the folder actions was slow to open because it loads the actions at startup. To speedup it up, we backport the fix odoo/enterprise#90124 that allows the cogwheel to be open while loading the actions (instead of waiting that the actions are loaded). We also add a spinner while it is being loaded. When selecting action to embed for the folder, it was slow as well. To solve the problem, we toggle the action immediately (not waiting the answer of the server) and roll it back in case of failure. Finally, to limit the number of calls to the server, we only reload the search model if there are no pending toggle of action. So if you activate for example 5 actions in a row and the connection is slow enough, the search model will only be reloaded once instead of 5 times (when the 5 actions are toggled). Task-4828503 Forward-Port-Of: odoo/enterprise#94141
The HTML editor now supports simple Markdown-style shortcuts to create blockquotes and separators while typing. Separator placement has also been improved so inserted lines appear in the expected position based on where the cursor is, making content editing faster and more predictable.
Original PR description
### Desired behavior after PR is merged: - Adjust separator insertion logic based on cursor position: ```html <div>/separator[]</div> → before <div>/separator[]abc</div> → before <div>ab/separator[]c</div> → after <div>abc/separator[]</div> → after ``` - Refactor markdown shortcuts implementation by introducing `shorthands` resource containing objects with pattern and commandId keys. - In the shortcut_plugin, bind an onInput handler to process input events and match precedingText against the defined patterns, triggering the corresponding commands when matched. - Add support for > (blockquote) and --- (separator) markdown shortcuts. - Separator insertion behavior: ```html <div>--- []</div> → before <div>--- []abc</div> → before ``` task-4908567 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
A new test action on the IoT Box record helps users quickly check whether required communication methods are working. It also triggers a network quality check, making it easier to diagnose client-site connectivity issues before they disrupt device operations.
Original PR description
In order to ease debugging at client's, we introduce a test button on the IoT Box record that will first test communication protocols and display a notification for each non-working protocol, then request a network quality check on the IoT Box (ping to odoo.com + ping to gateway). Community PR: odoo/odoo#229655 Task: 5130809
The IoT system can now quickly check connection quality and show whether network performance is fast, normal, slow, or unreachable. This helps consultants diagnose connectivity issues more easily when working with IoT Boxes and receipt printing.
Original PR description
In order to ease network checks for consultants, we added a quick latency and packet loss check, formatting the output as "slow"/"normal"/ "fast" or "unreachable". We also add a way to test each protocol (webrtc, longpolling, websocket) and to check latency/packet lost, in order to add a `Test` button on the IoT Box record. Enterprise PR: odoo/enterprise#96298 Task: 5130809
Resolved issues and error corrections
Fixes an issue where Time Off list view header buttons, such as New Group, did not respond properly unless they were approve or refuse actions. This helps managers complete Time Off and allocation workflows from list, calendar, and Gantt views without blocked or ignored actions.
Original PR description
**Issue** When clicking header buttons other than approve/refuse in Time Off list view, the actions are not processed correctly. **Steps to Reproduce** 1. Navigate to Time Off > Management > Time Off or Allocations 2. Switch to List view 3. Click on New Group button 4. Action is not executed properly **Root Cause** Previously, handleViewButtonClick only processed approve/refuse actions and ignored other header button actions. Now, non-leave actions are correctly forwarded to the default handler. Task ID: 5062846 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes Nuvei payment handling so customers who return from the payment page without completing payment are not blocked by missing notification data. It also validates amounts correctly for Nuvei methods such as Webpay that require whole-number amounts, improving successful payment processing.
Original PR description
Since https://github.com/odoo/odoo/pull/163860, all notifications from providers are checked to see that they have the correct currency and amount in their flow before processing the notification. However, this has two issues with Nuvei: 1. The process when a customer hits "Go back" on the payment page instead of paying does not send any notification data. As such trying to compare these values will not work. 2. Certain payment methods within Nuvei use different decimal precision than the currencies on odoo. Webpay must always be in whole values even for USD, as such, we need to pass the correct number of precision digits to the validation method otherwise Webpay will never be able to go through. opw-5108631 Forward-Port-Of: odoo/odoo#230159
This fixes Brazilian Avalara tax calculations for service invoices so discounts are not subtracted twice. Businesses using this localization should see more accurate tax amounts on discounted service lines, reducing billing and compliance discrepancies.
Original PR description
Confusingly, Avalara's service API already accounts for the discount in lineNetFigure, whereas their goods API does not. In <saas-18.4 this was handled by _l10n_br_get_line_total(), but it got lost in the big refactor in saas-18.4 [1]. [1] https://github.com/odoo/enterprise/pull/82623 opw-5147143 Forward-Port-Of: odoo/enterprise#96585
Fixed an issue where computing taxes on an invoice could fail when no external tax was found for a customer's ZIP code. The system now safely continues with empty manual tax data, helping users complete invoice tax calculations without interruption.
Original PR description
Currently, an error occurs when computing taxes for an invoice. **Error:** `KeyError: 'manual_tax_amounts'` **Cause:** When a user clicks the `Compute Tax` button, the system calculates the tax for…
Currently, an error occurs when computing taxes for an invoice.
**Error:**
`KeyError: 'manual_tax_amounts'`
**Cause:**
When a user clicks the `Compute Tax` button, the system calculates the tax for that invoice, including the `manual_tax_amount` [1]. However, if no tax is found for a given customer ZIP code, the `tax_values_list` becomes empty [2]. As a result, `manual_tax_amounts` in the base line also becomes empty.
Later, when the system tries to fetch the `manual_tax_amounts` key from extra_tax_data, it raises a KeyError [2], because the key no longer exists.
Additionally, the condition in [3] indicates that there is no guarantee that the `manual_tax_amounts` key will always be present in the base_line.
**FIX:**
This commit ensures that if the manual_tax_amounts key does not exist, an empty dictionary {} is used instead. This prevents the KeyError from occurring during tax computation.
[1]- https://github.com/odoo/enterprise/blob/b17b6b4e5ca3085d831fc763457496b5c5b639c5/account_external_tax/models/account_external_tax_mixin.py#L155-L163
[2]- https://github.com/odoo/enterprise/blob/a51aee8f6e8bce2aa699d3199d6723495464a762/account_external_tax/models/account_external_tax_mixin.py#L88
[3]- https://github.com/odoo/odoo/blob/241c170dbece8c1652db9ca1aa935b2106ede532/addons/account/models/account_tax.py#L1330
sentry-6919182805
Forward-Port-Of: odoo/enterprise#96401The Time Off screens now correctly process the New Group action from list, calendar, and Gantt views. This lets managers create grouped time off requests without the button failing or being ignored.
Original PR description
See https://github.com/odoo/odoo/pull/226574 **Issue** - When clicking header buttons other than approve/refuse in Time Off list view, the actions are not processed correctly. - Added New Group Time Off to calendar and gantt view **Steps to Reproduce** 1. Navigate to Time Off > Management > Time Off or Allocations 2. Switch to List view 3. Click on New Group button 4. Action is not executed properly **Root Cause** Previously, handleViewButtonClick only processed approve/refuse actions and ignored other header button actions. Now, non-leave actions are correctly forwarded to the default handler. Task ID: 5062846
The purchase reporting view now correctly includes purchase order lines for products that do not have a category. This restores the vendor On-time Rate graph so purchasing teams can assess vendor delivery performance even when product category data is missing.
Original PR description
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and…
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and validate the generated receipt. 5-In the vendor form view, click the On-time Rate smart button → no graph is visible. **Issue:** https://github.com/odoo/odoo/blob/77b3956ed5635d79ae8dc19423140dc6a10098f1/addons/purchase_stock/report/vendor_delay_report.py#L46-L50 ``` The On-time Rate graph is not displayed in the Vendor Delay report. ``` **Cause:** - From version 18.2, `categ_id` was removed as a required field. The report query still uses an inner join on `categ_id`, which excludes products without a category and prevents data from being generated. - Commit which make `categ_id` non require - https://github.com/odoo/odoo/pull/166323/commits/b039caecbeb04057fbccb1cc88d03a4946f88e8e **Solution:** - Replace the inner join with a left join so that products without a `categ_id` are also included in the report (with null values when the category is not set). **opw** - 4991367 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230388 Forward-Port-Of: odoo/odoo#225557
Vendor credit notes matched to purchase orders now show the correct positive quantity when reversing over-billed purchase lines. This helps avoid confusing refund quantities and supports more accurate purchase billing records.
Original PR description
Steps to reproduce:- - Create a Purchase Order with Product A(invoicing policy: received quantities) and Quantity 3. - Create Vendor Bill with Product A and Quantity 3 and match it with the PO. - Receive only 2 on PO. - Now on PO, Quantity: 3, Received:2, Billed:3 - Create a Vendor Credit Note for that partner, add an empty line and save. - Click on PO Matching at the top. - Select line from Vendor Credit Note and line from PO, click match. Problem: In Vendor Credit Note Quantity: -1 (which should be 1) Before this commit: When credit note values are prepared from purchase order, quantity to invoice on purchase order is set as quantity on credit note. After this commit: When credit note values are prepared from purchase order, inverse(-ve) of quantity to invoice on purchase order is set as quantity on credit note. task-4975200 Forward-Port-Of: odoo/odoo#230487 Forward-Port-Of: odoo/odoo#221203
Clearing browser data in Chrome could cause Live Chat to run into an error in the background. This update adds a safeguard so the feature handles that browser event cleanly, improving reliability for users.
Original PR description
**Steps to reproduce:** Install 'Live Chat' Open Chrome Log in as 'Admin' Clear browser data **Current behavior before PR:** Clearing data triggers a storage event where the key parameter is null. An event listener attempts to call a method on this null key, leading to a runtime error. **Desired behavior after PR is merged:** A check has been added to ensure the key is not null, preventing the error. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230298
Customer statement emails sent from child invoice contacts now include the correct PDF details instead of an empty attachment. The Customer Statement button is also hidden when there are no transactions or no amount due, reducing confusion for accounting users.
Original PR description
**Steps to reproduce:** 1. Go to Accounting > Customers > create a company with child contact (invoice) (both having name and email). 2. Create an invoice with the child contact as customer and…
**Steps to reproduce:** 1. Go to Accounting > Customers > create a company with child contact (invoice) (both having name and email). 2. Create an invoice with the child contact as customer and confirm it. 3. Go to the child contact and open the Customer Statement smart button. 4. Download the PDF → data is shown correctly. 5. Send the statement → the attachment in the sent mail is empty. **Issue:** - When sending customer statements via email from a child contact, the generated PDF attachment contains no data, showing empty amounts and transactions. - Additionally, the "Customer Statement" button was still visible even when the total due was zero. **Cause:** - The button visibility condition checks for `total_due == 0.0 and not has_moves`, which didn’t properly cover all use cases. **Solution:** - Update button visibility condition to: `invisible="not has_moves or total_due == 0"` ensuring it is hidden when there are no moves or the total due is zero. **opw-5009182** Forward-Port-Of: odoo/enterprise#95356 Forward-Port-Of: odoo/enterprise#93162
This update adjusts the Mail module's automated test behavior so saving email HTML content waits for the save action to be available before proceeding. It helps reduce false test failures in Odoo's validation systems, improving release reliability without changing day-to-day user functionality.
Original PR description
This commit tries to solve runbot issues with mail html fields widget. It seems clicking on the save button manually is not generating a call to the backend. This could be due to the fact the button is not enabled due to the data being invalid. Therefore using the clickSave util could be useful in those situation since waiting that the button becomes enabled. This solution is not 100% sure to fix the issue in all cases but manually disabling the button is creating the issue we can observe in those runbots. There is a good chance it might work. fixes-runbot-231582 fixes-runbot-233049 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230375 Forward-Port-Of: odoo/odoo#227484
This update adjusts payroll accounting tests to match recent changes in how employee contract information is stored. It helps keep automated checks reliable without changing day-to-day payroll features for users.
Original PR description
Explanation: hr.contract is reworked into hr.version runbot-229897 Forward-Port-Of: odoo/enterprise#90357
The AI assistant now handles incomplete grouped search requests more safely when the language model leaves out required grouping or summary fields. This prevents terminal errors and keeps the chat experience stable for users making business data queries.
Original PR description
Currently, an error occurs when no groupby property is found in LLM response while trying to search records through the AI agent in the chat. Steps to replicate: - Install ai_app and sale_management.…
Currently, an error occurs when no groupby property is found in LLM response
while trying to search records through the AI agent in the chat.
Steps to replicate:
- Install ai_app and sale_management.
- Setup gemini key.
- In the systray click on AI icon.
- Type in:
`read group in res partner`
or
`read group in partners groupby None`
- Error will occur in terminal.
(If the error doesnt occur the first time, spam the above given prompt.)
Error:
`ValueError: TypeError("'NoneType' object is not iterable") while evaluating
"ai['result'] = record._ai_tool_read_group(model_name, domain, groupby, aggregates, having, offset, limit, order)"`
Cause:
- As the LLM response didnt incude groupby it was passed on as None to the orm,
which caused the `'NoneType' object is not iterable` at the line [1].
- The groupby was set `None` through line [2], the loop sets every param that
is not in the instance as None i.e. Every value that is in `ai_tool_schema`
but not received in LLM response is set as `None`.
Solution:
- The method `_ai_tool_read_group` now safely handles cases where `groupby` or
`aggregates` (similar error occurs when aggregates is none at [3]) are None.
- Fields are assigned default values before calling the method `_read_group`.
[1]: https://github.com/odoo/odoo/blob/c034fed2eeb194961af7e1b3c60203141784acf2/odoo/orm/models.py#L1919
[2]: https://github.com/odoo/enterprise/blob/7e6fe07512b7d897cf6315d45e6a1004e48ef45e/ai/utils/tools_schema/validators.py#L51
[3]: https://github.com/odoo/odoo/blob/c034fed2eeb194961af7e1b3c60203141784acf2/odoo/orm/models.py#L1923
sentry-6912361256An automated accounting reports test was adjusted to match the updated top bar behavior. This prevents a test from manually opening a menu that now opens automatically, helping keep quality checks reliable without changing user functionality.
Original PR description
As the dropdown of embedded actions of the top bar is now automatically opened when the top bar is enabled and there is only one visible action (see https://github.com/odoo/odoo/pull/208005), we remove a step that would manually open that dropdown. task-5072899
This fixes an issue where custom hour or half-day options could be unintentionally cleared when employees changed the type of time off request. It helps users keep their intended leave settings when switching between compatible time off types, reducing mistakes and rework.
Original PR description
- made the value of checkboxes for `request_unit_half` and `request_unit_hours` stay the same when switching between timeoffs that can have hourly type task-id: 5085389 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228981
The AI Copywriter dialog now shows its alternative writing mode labels in the user's selected language. This improves localization consistency and makes the tool clearer for non-English users.
Original PR description
Description of the issue/feature this PR addresses: The alternativemodes on the AI Copywriter dialog are not translated Current behavior before PR: <img width="1079" height="250" alt="image" src="https://github.com/user-attachments/assets/fced9432-b557-44de-9b7c-a31547b7a16b" /> Desired behavior after PR is merged: <img width="1078" height="250" alt="image" src="https://github.com/user-attachments/assets/1499836a-924e-425c-b328-27a378eae62a" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures the correct domestic fiscal position is selected for several country localizations, which helps apply the right local taxes. It adjusts fiscal position ordering for the UAE, Mexico, and Cambodia, and removes a duplicate Italian domestic fiscal position that could cause incorrect selection.
Original PR description
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the…
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the following localizations: **AE** Sequences are added making Dubai the domestic fiscal position. However this needs to be improved to automatically prioritize the fiscal position based on the company's state. **IT** (l10n_it_edi_doi) An additional domestic fiscal position was mistakenly added. The correct domestic FP is defined in it's dependency module l10n_it. The duplicate FP is removed. **MX** Sequences are added **KH** Sequences are added No Task - l10n's identified by the fiscal position checks in `test_all_l10n` 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#230654
This fixes a small formatting issue in the sales timesheet invoicing wizard that could cause errors for some customized systems. It improves compatibility for businesses using custom integrations or Python-based view processing without changing normal user workflows.
Original PR description
Versions -------- - 17.0+ Issue ----- Some customizations may parse XML views using Python, in which case the `date_start_invoice_timesheet` field could return an error, as the `options` attribute uses a Javascript boolean `true`. Solution -------- Use `'true'`, which will get parsed as `true` in JS via `archParseBoolean`. Forward-Port-Of: odoo/odoo#230278
This fix ensures outgoing stock movements are properly included when Odoo calculates product quantities in strict mode. Businesses should see more accurate inventory availability figures in affected stock workflows.
Original PR description
### Issue: Commit ba54310a11d2b702753d4b9b028a62dd00a91467 has altered the location domain for quantities computations. However, the `dest_loc_domain_out` has not been correctly replaced: https://github.com/odoo/odoo/blob/f173c738b1adcf85a80eb641ad307b7cccf17294/addons/stock/models/product.py#L319 Since the returned value used to be negated and is not anymore. This results in out moves being ignored by the `_compute_quantities` in `strict` mode. opw-4997982 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229734 Forward-Port-Of: odoo/odoo#229304
The Point of Sale customer details screen now shows only the information needed for checkout and related POS work. This reduces clutter for staff and helps avoid errors caused by back-office-only fields appearing in the POS interface.
Original PR description
Before this commit: ==================== The POS frontend used the main backend form view of res.partner, which displayed all partner details. Many of these fields and buttons were irrelevant for the POS and occasionally caused errors or tracebacks due to backend-specific features being exposed. After this commit: =================== The POS frontend now displays a simplified partner form with only the essential fields required for POS operations. Unnecessary backend details are hidden to improve usability and prevent potential errors. Task-5103953
This fixes an issue in Firefox where users could accidentally type into a website search bar while editing a page. The change keeps the search bar stable during editing, preventing accidental content changes and matching behavior seen in other browsers.
Original PR description
It's possible to type something inside of a searchbar while in the edit mode on Firefox, which is not the expected behavior and which is not the case in other browsers, for example, Chrome. Steps to see the issue: - Open Website and start editing - Drop a searchbar - Click on the input - Type something => It will remove the searchbar and add text to the searchbar button. This happens because of the different behavior on Chrome and Firefox of `pointer-events`. The searchbar input has `pointer-events` set to `none` and in Chrome it blocks any activity on the input, including `beforeinput` events, but Firefox doesn't. This commit fixes this problem making the searchbar input not `contenteditable`. task-5144517
Gantt group headers now keep the right size so they remain visible and aligned while users scroll. This prevents oversized headers from breaking the sticky behavior, especially on smaller mobile screens.
Original PR description
Gantt group headers could stop being sticky because their width was fixed based on the number and size of columns. Even though they were set to position: sticky, oversized headers could no longer remain aligned when scrolling, as they extended beyond the viewport and were constrained by the document width. This was especially noticeable on mobile, where group headers are often wider than the screen. The fix applies a max-width style to these headers, capping their size to the available space so they remain sticky without overflowing the document. task-4970992 Forward-Port-Of: odoo/enterprise#96612 Forward-Port-Of: odoo/enterprise#96015
This fix improves how Swiss payroll recalculates payslip issues, helping ensure payroll warnings and related checks stay accurate after changes. It reduces the risk of outdated or incorrect payslip information affecting payroll review and accounting workflows.
Original PR description
task-5150492
6 changes
Resolved issues and error corrections
Stripe payments now use the right amount conversion for currencies like the Ugandan shilling that Stripe treats differently from standard currency rules. This prevents valid customer payments from being rejected or sent with the wrong value.
Original PR description
Steps: - Activate the 'UGX' currency. - Make a sale order with amount 100 with 'UGX' currency - Try to pay that order (100 USh) using card Issue: - stripe throws the following error - > 'The Checkout Session's total amount must convert to at least 50 cents. 1.00 USh converts to approximately €0.00.' - Hence 100 USh sent was identified as 1 USh by stripe. This confirms issue with decimals and currency mapping. Cause: - 'UGX' is zero-decimal currency but stripe identify it as two-decimal. Fix: - Update mapping for such special currency cases for stripe that don't follow general rules opw-5075707 Forward-Port-Of: odoo/odoo#227688
The Indian payroll demo leave records were adjusted so they no longer block system upgrades. This prevents upgrade errors caused by demo leave entries that had already been validated, with no impact on real employee leave data.
Original PR description
Issue: - Validation Error: 'This modification is not allowed in the current state.' When trying to update validated leave records during upgrade. Reason: - In Indian leave records, some demo leave entries were in the `validate` state. - During the upgrade, changes in the leave type triggered updates to these records that were already validated. - Trying to update validated records caused constraint errors due to the validation state. Fix: - Removed the leave validation for these demo records as it was not necessary. - The records stay in the `confirm` state during upgrade, preventing validation errors and allowing the upgrade to proceed without impacting demo data. build_error-231279
This fix updates the sales timesheet invoice wizard so its settings are easier for custom tools to read correctly. It reduces the risk of errors for businesses using customizations that process Odoo screens outside the standard browser flow.
Original PR description
Versions -------- - 17.0+ Issue ----- Some customizations may parse XML views using Python, in which case the `date_start_invoice_timesheet` field could return an error, as the `options` attribute uses a Javascript boolean `true`. Solution -------- Use `'true'`, which will get parsed as `true` in JS via `archParseBoolean`. Forward-Port-Of: odoo/odoo#230278
This fixes an issue where cash basis journal entries could appear without their journal item number after posting an invoice. The change ensures the correct information is saved during numbering, improving accounting list accuracy and reducing confusion during review.
Original PR description
The name field of `account.move` became protected, which prevents the correct computation of the `move_name` field on `account.move.line`. As a result, move_name is not set for cash basis (CABA) journal items. The problem stems from flushing of whole recordset in the `_locked_increment` of sequence_mixin. This **PR** modifies the flush and allows only required fields to be flushed. Steps to reproduce (Runbot, v18): 1. Post an invoice that creates a CABA entry 2. Open the journal items list view 3. Number (move_name) is empty for the CABA-related lines **opw**-4747878
This fix ensures cash basis journal item lines show the correct journal entry name instead of a placeholder slash. It improves accounting list views by keeping related entry names in sync after sequence numbers are assigned.
Original PR description
Backport of #225558 to 18.0. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixed an issue where scanning two GS1 barcodes with the same serial number for different products caused an error and prevented the second item from being added. Inventory counts now correctly distinguish serial numbers by product, reducing scan interruptions and missing count lines.
Original PR description
**PROBLEM** When scanning two gs1 barcode with the same serial number, but for different products there is an error and the 2nd product is not added to the inventory count. **STEP TO REPRODUCE** 1.…
**PROBLEM** When scanning two gs1 barcode with the same serial number, but for different products there is an error and the 2nd product is not added to the inventory count. **STEP TO REPRODUCE** 1. install stock_barcode 2. activate the gs1 barcode and select the default gs1 nomenclature. 3. scan the following barcode - 01000000000001232180085 (product barcode: 0000000000123, serial: 80085). - 01000000000000482180085 (product barcode: 0000000000048, serial: 80085). 4. there is an unexpected error notification, and the 2nd product line isn't added. **CAUSE** In _processBarcode (barcode_model.py), we only check if: - there is already a line with serial tracking with a non-null qty - this line serial number is the same serial number that we are scanning **FIX** We should also verify if the product from the lines we are checking, and the line we want to create are the same. [opw-5076045](https://www.odoo.com/odoo/project/49/tasks/5076045) Forward-Port-Of: odoo/enterprise#96430
4 changes
New functionality added to Odoo
Adds Codaclean support so Belgian companies can automatically or manually fetch CODA bank files into Odoo bank journals through the IAP connection. This reduces manual bank statement handling and keeps accounting data updated on a twice-daily schedule once configured.
Original PR description
This module adds support for "codaclean" integration. CODA files can be periodically (or on demand) fetched from codaclean and imported into bank journals. The module only connects to the IAP server.…
This module adds support for "codaclean" integration. CODA files can be periodically (or on demand) fetched from codaclean and imported into bank journals. The module only connects to the IAP server. The IAP side does the actual calls to codaclean (with a secret API key). To use the module you have to create a connection to IAP / codaclean and set up a bank journal: - To manage the connection to IAP / codaclean go to Settings -> Accounting -> Codaclean -> Manage Connection - To set up the bank journal you need to configure the following in the "Journal Entries" tab on the journal: - Put the IBAN in the "Bank Account Number" field - Select "Codaclean Synchronization" for the "Bank Feeds" field Coda files will be automatically fetched 2 times per day via the scheduled action called "Accounting: Sync Coda Files from Codaclean". They can also be manually fetched by clicking "Fetch from Codaclean" below the journal on the accounting dashboard (only available when the journal and connection are setup correctly). On an empty journal we start fetching from 1 year ago. When the journal is not empty we start fetching after the last bank statement / bank statement line in the journal. task-4844423 backport of commit 518ab9e
Resolved issues and error corrections
Inventory barcode scanning now correctly accepts different products that happen to use the same serial number in GS1 barcodes. This prevents an error that previously stopped the second product from being added to an inventory count.
Original PR description
**PROBLEM** When scanning two gs1 barcode with the same serial number, but for different products there is an error and the 2nd product is not added to the inventory count. **STEP TO REPRODUCE** 1. install stock_barcode 2. activate the gs1 barcode and select the default gs1 nomenclature. 3. scan the following barcode - 01000000000001232180085 (product barcode: 0000000000123, serial: 80085). - 01000000000000482180085 (product barcode: 0000000000048, serial: 80085). 4. there is an unexpected error notification, and the 2nd product line isn't added. **CAUSE** In _processBarcode (barcode_model.py), we only check if: - there is already a line with serial tracking with a non-null qty - this line serial number is the same serial number that we are scanning **FIX** We should also verify if the product from the lines we are checking, and the line we want to create are the same. [opw-5076045](https://www.odoo.com/odoo/project/49/tasks/5076045)
Invoices resent after a salesperson is archived now keep showing the correct sender name and image in the message history. This prevents confusion for customers and staff by ensuring invoice communications remain tied to the intended salesperson.
Original PR description
Steps to Reproduce: ------------------------- 1. Create a user (e.g., Test 1) with an email 2. Create an invoice with Test 1 as the salesperson and confirm it 3. Click Send and send the mail. 4.…
Steps to Reproduce: ------------------------- 1. Create a user (e.g., Test 1) with an email 2. Create an invoice with Test 1 as the salesperson and confirm it 3. Click Send and send the mail. 4. Archive the Test 1 user 5. Go to Customers and copy any customer’s email 6. Update the email on Test 1’s partner record 7. Go to the same previously created invoice and repeat step 3 Observation: ------------------------- In the chatter, the displayed sender name and image change. They no longer correspond to Test 1’s partner, even though the salesperson is still the same. Issue: ------------------------- In the following code: https://github.com/odoo/odoo/blob/3a1ec3bad5d4884952e09ed4eaabccf10cebbddf/addons/account/models/account_move_send.py#L451-L467 the `active_test` context is missing. Because of this, the partner search method in ORM skips archived users https://github.com/odoo/odoo/blob/3a1ec3bad5d4884952e09ed4eaabccf10cebbddf/addons/mail/models/mail_thread.py#L1942-L1951 Solution: ------------------------- Set `active_test=False` in the context so that archived user's partner records are also considered when determining the sender. opw-5067129
Miscellaneous changes
No description available.