Daily updates from Odoo
Wednesday, November 5, 2025
207 changes
20 changes
Enhancements to existing features
The POS integration now sends each category’s parent information when syncing with Atlas, so category hierarchies are preserved more reliably. This helps keep menu structures aligned across systems while staying within UrbanPiper’s single sub-category limit.
Original PR description
In this commit: --- - The parent category of a POS category is now included during synchronization with the Atlas platform. - Added `parent_ref_id` in the category payload to maintain hierarchy. Note: The UrbanPiper platform only supports a single level of sub-categories. Extra: Added exception for `requests.exceptions.JSONDecodeError`. task-5169337 Forward-Port-Of: odoo/enterprise#97213
Resolved issues and error corrections
This change removes an extra test step that was no longer needed in the website product image removal flow. The newer website editor framework already handles the timing issue, so the test is simpler while keeping the relevant Python-side improvements.
Original PR description
Before #234150, the `remove_product_image_*` tours occasionally failed due to the incorrect assumption that removing an image from the DOM was immediately saved in the database. A fix was introduced by adding a final tour step to ensure that the asynchronous DOM save was completed before exiting the tour. This fix was later forward-ported to 18.4 with bb6825760095df30a3559bcbf69cfa17bf383654. However, in 18.4, the website editor framework was improved with the introduction of the `BuilderAction` class. The migration to this new framework already resolved the issues with the `remove_product_image_*` tours, rendering the fix in #234150 unnecessary. This commit reverts part of that fix by removing the final tour step while retaining some improvements in the Python code.
This fix ensures delivery fees on subscription invoices are no longer reduced when invoices are prorated. It helps businesses charge shipping at the correct fixed amount, avoiding underbilling on recurring deliveries.
Original PR description
Version - 18.0 Steps to reproduce: 1. Create a subscription with delivery product. 2. Select align to calendar in the recurring plan 2. Add shipping method by assigning a delivery product with recurring_invoice. 3. Create an invoice with prorated Issue: - Delivery products are considered service-type products and their price was prorated in invoice. Cause: - The proration logic treated delivery lines like normal recurring service products, instead of keeping their fixed charge. Solution: - Exclude delivery products from proration by setting their period ratio to 1. Co-authored-by: Darshan Patel dvpa@odoo.com Co-authored-by: Federico Braidi brfe@odoo.com task-4662188 Forward-Port-Of: odoo/enterprise#98687 Forward-Port-Of: odoo/enterprise#91133
This change corrects how inventory is balanced when a product is delivered with a lot or serial number from barcode scanning. It prevents stock from being assigned to an unnamed entry, which could later cause the lot-specific stock to remain unbalanced and create inaccurate inventory records.
Original PR description
Uecase to reproduce: - Create a quant with a product and 10 lot A - Create a delivery order - Open barcode - In barcode, deliver the product with lot C Current behavior: You have 2 quants: - 10 lot A - -1 without lot Expected behavior: - 10 lot A - -1 lot C It happens because the code try to balance negative quant for lot/sn in a stack of quants without lot/sn for the product. However in this case the barcode create a quant without quantity and without lot. In this case the system wants to update it due to an incorrect condition. It's an issue since in later receit with the correct lot. The quant will never be balanced and it will result with - -1 without - 1 lot C 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#231853
This change fixes a performance issue in the spreadsheet version history view by avoiding an extra company currency lookup. It makes the version history action load more efficiently and removes a bug that only appeared in that view.
Original PR description
The perfomance commit added in https://github.com/odoo/odoo/pull/151725 did not account for the version history action that does not inherit from `AbstractSpreadsheetAction`. this missing value trickled down to a bug only detectable in the VersionHistory action and which is addressed in https://github.com/odoo/odoo/pull/232985 This commit adds the same performance to VersionHistory action. Task-5187293 Forward-Port-Of: odoo/enterprise#98197 Forward-Port-Of: odoo/enterprise#98038
This fix prevents the Point of Sale from changing prices on all variants of a product when only one lot-tracked variant is added. It ensures each variant keeps its own correct price, avoiding pricing mistakes at checkout.
Original PR description
Before this commit, when a product had multiple variants with different prices and was tracked by lot, adding different variants in the PoS would incorrectly update all product prices. opw-5228830 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234332 Forward-Port-Of: odoo/odoo#234171
This change prevents a server error when sending a credit or debit note to DGI if the original document is not a valid electronic invoice. Instead of failing unexpectedly, Odoo now shows a proper message so the user can correct the document before retrying.
Original PR description
### Description of the issue/feature this PR addresses: When informing a Credit or Debit Note to DGI we always need to inform the related original document, Before this change is the related document…
### Description of the issue/feature this PR addresses:
When informing a Credit or Debit Note to DGI we always need to inform the related original document, Before this change is the related document is not a real CFE then will raise a traceback error
### Steps to reproduce:
1. Create an e-invoice and confirm in Odoo (without sending to DGI)
2. Create an e-credit note from the e-invoice created in (1) and confirm
3. Try to send the credit note to DGI
The result is a traceback:
```
RPC_ERROR
Odoo Server Error
Occured on 18.core.odoo.localhost on model account.move.send.wizard on 2025-10-21 20:47:48 GMT
Traceback (most recent call last):
File "/home/odoo/custom/odoo/odoo/http.py", line 2144, in _transactioning
return service_model.retrying(func, env=self.env)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/service/model.py", line 156, in retrying
result = func()
^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 2111, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 2359, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/addons/base/models/ir_http.py", line 333, in _dispatch
result = endpoint(**request.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 754, in route_wrapper
result = endpoint(self, *args, **params_ok)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/web/controllers/dataset.py", line 42, in call_button
action = call_kw(request.env[model], method, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/api.py", line 535, in call_kw
result = getattr(recs, name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/account/wizard/account_move_send_wizard.py", line 294, in action_send_and_print
attachments = self._generate_and_send_invoices(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/account/models/account_move_send.py", line 719, in _generate_and_send_invoices
self._generate_invoice_documents(moves_data, allow_fallback_pdf=allow_fallback_pdf)
File "/home/odoo/custom/odoo/addons/account/models/account_move_send.py", line 620, in _generate_invoice_documents
self._call_web_service_before_invoice_pdf_render(invoices_data_web_service)
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move_send.py", line 88, in _call_web_service_before_invoice_pdf_render
invoice._l10n_uy_edi_send()
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 813, in _l10n_uy_edi_send
request_data = move._l10n_uy_edi_prepare_req_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 787, in _l10n_uy_edi_prepare_req_data
xml_content = self._l10n_uy_edi_get_xml_content()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 773, in _l10n_uy_edi_get_xml_content
"referencia_lines": self._l10n_uy_edi_cfe_F_reference(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 381, in _l10n_uy_edi_cfe_F_reference
cfe_serie, cfe_number = self.l10n_uy_edi_document_id._get_doc_parts(related_cfe)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/l10n_uy_edi_document.py", line 215, in _get_doc_parts
return re.findall(r"([A-Z]{1,2})[-]*([0-9]{1,8})", record.l10n_latam_document_number)[-1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^
IndexError: list index out of range
The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
RPC_ERROR
at makeErrorFromResponse (http://18.core.odoo.localhost/web/assets/c15481d/web.assets_web.min.js:3162:163)
at XMLHttpRequest.<anonymous> (http://18.core.odoo.localhost/web/assets/c15481d/web.assets_web.min.js:3167:13)
```
### Desired behavior after PR is merged:
Now we ensure to show a proper message to the user to fix the problem: the original document should be a electronic one
<img width="1203" height="664" alt="after" src="https://github.com/user-attachments/assets/bb7b105e-12f0-4935-b6bc-37edb3bc3aca" />
References LATAM 1301 / ADHOC Task 54770
Forward-Port-Of: odoo/enterprise#90281This update corrects the invoice information sent to Chorus Pro so it complies with Peppol BIS3 rules. It also renames a label to better match Chorus Pro terminology, helping reduce invoice rejections and confusion for French e-invoicing users.
Original PR description
1. We didn't met one of the specific requirement of the BIS3 invoices to be sent through Chorus Pro. > The SIRET number for the final recipient, behind Chorus Pro should always be sent in the following tag: Invoice/cac:AccountingCustomerParty/PartyLegalEntity/CompanyID 2. One of the attributes of the CompanyID was set to schemeName which is not a valid attribute of the Peppol BIS3 specification. Fixed in 18.0+: https://github.com/odoo/odoo/commit/c3ae4b29c51c7b0cff11aac5f4bf4aab5fad16c9 task-none (possible opw-4972189, but might not be the only problem) Source: <img width="787" height="673" alt="image" src="https://github.com/user-attachments/assets/2a410fa8-572a-4738-aa5d-764e91271880" /> https://www.pagero.com/onboarding/aife/aife-en Forward-Port-Of: odoo/odoo#234034 Forward-Port-Of: odoo/odoo#229014
The edit favorite filter icon in the search menu no longer flickers when users hover over it. This makes the interface feel smoother and avoids small layout shifts in the popover.
Original PR description
This PR fixes an issue related to the edit favourite filter icon. Prior to this PR, the edit favourite filter icon used `d-none` by default and `display: block` on hover. Since `display: none` removes the element from the layout, the parent popover resized on hover, causing a flickering effect. This did not occur for filters with short labels (which had enough room for the icon) or for long labels (where the label was truncated). To prevent the flickering, the icon now uses `visibility: hidden/visible`, which keeps its space in the layout and avoids layout shifts. https://github.com/user-attachments/assets/5308c11e-8706-403c-80e3-fc05ab37a61d task-5237493 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234383
This update corrects how overtime one-time payments are handled in Swiss payroll transmission. It helps ensure these payments are sent accurately, reducing the risk of payroll errors or missing overtime compensation.
Original PR description
Forward-Port-Of: odoo/enterprise#98670
This change prevents the delivery date from being unintentionally reset when confirming certain invoices. It helps keep invoice and delivery information consistent for businesses using anglo-saxon accounting and delivery-based invoicing.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Enable anglo-saxon accounting; 2. have a product category with automated AVCO; 3. assign category to a deliverable product; 4. set product to invoice on…
Versions
--------
- 17.0+
Steps
-----
1. Enable anglo-saxon accounting;
2. have a product category with automated AVCO;
3. assign category to a deliverable product;
4. set product to invoice on delivery;
5. add product to a sales order;
6. confirm order & delivery;
7. create invoice;
8. change the delivery on the invoice;
7. confirm the invoice.
Issue
-----
The delivery date gets reset.
Cause
-----
Commit 818cf04f05767 added `delivery_date` as a permanently protected field when modifying moves or move lines, protecting the records on `write`. With anglo-saxon accounting however, new move lines are created when confirming an invoice, which in turn recalculate the delivery date, as `_get_protected_vals` isn't used for their move on `create`.
Solution
--------
Add `self.env['account.move'].protecting(_get_protected_vals({}, moves))` when creating new lines for a move, to avoid recomputing fields that should always be protected.
opw-4965036
Forward-Port-Of: odoo/odoo#231186The gradient color picker now displays custom text more clearly in dark mode. This improves readability and makes it easier for users to choose colors while editing website content.
Original PR description
Steps to Reproduce: 1. Go to `Website` and enter edit mode. 2. Drop any `text` snippet. 3. Select the text. 4. Open color picker from the toolbar and switch to `gradient` tab. Issue: The custom text in the gradient tab of the color picker was not clearly visible in dark mode. Reason: The background is already light, and in dark mode the text color was also light. This resulted in insufficient contrast, making the text hard to read. Fix: Set the text color to black when button has no background image. In case of button containing style of background-image, the text color will be same as earlier. | Before | After | |-----------------------------|---------------------------------| | <img width="483" height="274" alt="image" src="https://github.com/user-attachments/assets/911c53f2-bb0e-4d70-9fb2-078ac17388c1" /> | <img width="473" height="326" alt="image" src="https://github.com/user-attachments/assets/c976fb49-6c10-47c0-b559-6a58cfcbcdc2" /> |
This update fixes an error that could stop Romanian e-invoices from being sent when a payment account is linked to a bank. The system now correctly uses the right address field for banks, preventing the process from failing and allowing invoices to be submitted successfully.
Original PR description
Issue: When setting up a payment reference and linking a bank to an invoice, sending an E-Factura (SPV) triggers an exception: state_id not defined for res.bank. Repro Steps: 1- Create invoice for…
Issue:
When setting up a payment reference and linking a bank to an invoice, sending an E-Factura (SPV) triggers an exception: state_id not defined for res.bank.
Repro Steps:
1- Create invoice for romanian localization.
2- Link payment account to invoice.
3- Add bank to payment account.
4- Confirm and send invoice with "Send E-Factura SPV" checked.
Video:
https://drive.google.com/file/d/1rweJgknjbKrpouJRTQ2cluKHsIXNZtSz/view?usp=drive_link
Cause:
The state field is defined differently for res.bank and res.partner. res.partner uses state_id, while res.bank uses state. The code that retrieves addresses assumes the same field for both, leading to an exception when accessing state for res.bank.
Fix:
The fix checks the type of the input and selects the appropriate field (state or state_id) accordingly.
Test:
Linked the bank in the test suite. The test fails without this fix, confirming the issue is resolved.
opw-5099816
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fix prevents duplicated responses and ensures the payment interface receives the correct data from IoT drivers. It improves reliability when working with both newer and older driver versions, reducing checkout interruptions.
Original PR description
In order to accept values from both an up to date driver, and an old one, we selected either `data` or `data.result` in the callback. First issue here is that the first action was providing `data.result` to the callback, leading to `result` being undefined due to looking at `data.result.result`. Second issue is that we were calling `_keepListening` everytime we received a response from the driver, instead of only on specific cases such as timeout or first message received completely processed.
This change updates an internal website test helper so it works on a copy of the plugin list instead of modifying the original data directly. It helps keep test behavior predictable and reduces the risk of side effects in website-related tests.
Original PR description
The commit 25c602cff4db3f191434ab608ccdc51fa1ac75fb changed the internal of `addPlugin`, but did not follow the good practice of not mutating anything in a getter. In this commit, we instead create a mutated copy. task-5176469
Customers can no longer cancel self-ordering tickets once they have been sent to the kitchen display. This avoids a mismatch where the order looked canceled in the back office but the kitchen was not informed, reducing confusion and operational errors.
Original PR description
Currently, it is possible to cancel orders that have been sent to the kitchen display. However when doing so, the kitchen displayd does not receive any information about the cancellation. Steps to reproduce: ------------------- - Modify restaurant and enable self ordering - Open self an place an order (not paid but sent to kitchen) - Go back to "My orders" and cancel it > Order is cancelled in backend but not in the kitchen display Why the fix: ------------ When an order is sent to the kitchen the only way to cancel it should be by going to the register. Therefore now, if an order is present on the kitchen display we will not show the cancel button. opw-5030223 Enterprise: https://github.com/odoo/enterprise/pull/95770 Forward-Port-Of: odoo/odoo#232989 Forward-Port-Of: odoo/odoo#229039
Fixed an issue in the bank reconciliation screen where model buttons and partner counts could disappear after moving to another page. The widget now refreshes correctly as records change, so users can continue reconciling without missing guidance or counts.
Original PR description
Issue: when navigating through paginated records in the bank reconcilliation widget the functions `computeReconcileLineCountPerPartnerId` and `computeAvailableReconcileModels` were not re-executed. This caused reconciliation model buttons and partner counts to disappear on pages after the first. steps to Reproduce: 1 - In a database with >80 records to reconcile and pre-existing reconciliation models: 2 - Go to Accounting -> N to reconcile button. 3 - In Kanban view expand a record to view reconciliation model buttons (displays correctly). 4 - Navigate to the next page. - From the second page onward, reconciliation model buttons and partner counts are not displayed. fix: on top of the `onWillStart` hook, which runs at the view is first rendered, I added `onRootLoaded` to ensure computations run whenever the dependencies change, updating the widget correctly on pagination. opw-5083877 Forward-Port-Of: odoo/enterprise#98127
Payslips will now correctly display worked days for employees on fully flexible contracts, even when no working calendar is set. This prevents missing payroll information when work entries come from attendance or planning, so payroll calculations and reviews are more reliable.
Original PR description
**Issue:** Payslips show blank worked days for employees with contracts without a `resource_calendar_id` (fully flexible, despite having valid work entries **Cause:** `_get_worked_day_lines()` skips…
**Issue:** Payslips show blank worked days for employees with contracts without a `resource_calendar_id` (fully flexible, despite having valid work entries **Cause:** `_get_worked_day_lines()` skips worked day computation if the contract has no calendar https://github.com/odoo/enterprise/blob/1a10e0444fdb71a072262a1f14f0bfc766d109c6/hr_payroll/models/hr_payslip.py#L665-L674 **Steps to Reproduce:** - Assign an employee a fully flexible contract with attendance as work entry source. - Create work entries based on the attendance records of the employee record - Go to employees > contracts > new Payslip Worked Days section is empty, even though attendance shifts are showing up on top. **Fix:** removing the calendar requirement in the main method and adding a fallback calendar in the called utility method **Note:** same issue happens if work entry source of the contract is Planning opw-4931972 Forward-Port-Of: odoo/enterprise#97384 Forward-Port-Of: odoo/enterprise#93935
Customers can no longer cancel a self-order once it has been sent to the kitchen display. This avoids mismatches between the backend order status and what the kitchen sees, and guides customers to cancel through the register when needed.
Original PR description
Currently, it is possible to cancel orders that have been sent to the kitchen display. However when doing so, the kitchen displayd does not receive any information about the cancellation. Steps to reproduce: ------------------- - Modify restaurant and enable self ordering - Open self an place an order (not paid but sent to kitchen) - Go back to "My orders" and cancel it > Order is cancelled in backend but not in the kitchen display Why the fix: ------------ When an order is sent to the kitchen the only way to cancel it should be by going to the register. Therefore now, if an order is present on the kitchen display we will not show the cancel button. opw-5030223 Community: https://github.com/odoo/odoo/pull/229039 Forward-Port-Of: odoo/enterprise#98035 Forward-Port-Of: odoo/enterprise#95770
Features or functions removed from Odoo
The media dialog no longer offers video platforms that have become unreliable or deprecated, specifically Dailymotion’s old embed method and Youku. This helps prevent users from inserting videos that would later fail to display, while keeping the supported platform list accurate.
Original PR description
Specification: Improve `VideoSelector` Component. After this PR: - Dailymotion has deprecated its legacy embed endpoint starting September 23, 2024. Removed support for embedding Dailymotion videos in the media dialog. - Embedding Youku videos via iframe has become unreliable and no longer functions properly in the media dialog. Removed support for Youku embeds to prevent broken video content. - The supported platforms string now correctly lists YouTube, Vimeo, and Dailymotion, Instagram as supported platforms. task-4855038 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233962 Forward-Port-Of: odoo/odoo#214296
13 changes
Enhancements to existing features
This update creates a shared way to settle customer accounts in point of sale test tours and reuses it across existing scenarios. It helps keep customer selection and payment flow consistent when dialogs are closed and reopened, reducing the chance of test failures or missed customer data.
Original PR description
In this commit: --------------- - We have introduced a common function for settlement of customer accounts and replaced it in existing tours. task: 5028009 related PR: [95156](https://github.com/odoo/enterprise/pull/95156)
POS category synchronization now sends the parent category along with each category to Atlas, helping keep the category structure aligned between systems. This improves menu organization and reduces the chance of categories appearing in the wrong place after syncing. The update also handles a JSON parsing error more safely during requests.
Original PR description
In this commit: --- - The parent category of a POS category is now included during synchronization with the Atlas platform. - Added `parent_ref_id` in the category payload to maintain hierarchy. Note: The UrbanPiper platform only supports a single level of sub-categories. Extra: Added exception for `requests.exceptions.JSONDecodeError`. task-5169337 Forward-Port-Of: odoo/enterprise#97213
Resolved issues and error corrections
This fix corrects the mobile editor toolbar so it no longer switches to image controls when a text format like bold is applied. Users will now see the normal formatting toolbar and the active formatting button will be highlighted properly, making mobile editing clearer and more reliable.
Original PR description
**Current behavior before PR:** In mobile view, when applying the bold format using the toolbar button, the normal toolbar is incorrectly replaced by image toolbar. This occurs because `getFilteredTargetedNodes` returns an empty array, and as a result, the `isApplied` method evaluates to true since Array.every on an empty array returns true. **Desired behavior after PR:** This PR ensures that the toolbar remains in its normal state when a format is applied via the toolbar button. The corresponding format button (e.g., bold) is correctly highlighted. task-5123317 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229454
This update stops the same invoice from being settled more than once in Point of Sale. It helps avoid duplicate customer account entries and keeps the settlement process accurate, while also preserving the selected customer if an attempt fails.
Original PR description
Steps to reproduce: ------------------------- - Install POS. - Create an invoiced order and pay with customer account. - Settle the created invoices from customers list. - Try to settle the invoice again from the same order. Issue: ------- - The system allows settling the same invoice multiple times. Cause: --------- - There is no check in place to verify whether the invoice has already been under settlement process before settling it again. Fix: ----- - Add a validation step to ensure that if the same invoice is selected again, the system prevents duplication and it will show that already being settled. - Also if error occured due to second try of settlment will not lose the selected partner. task: 5028009 related PR: [227971](https://github.com/odoo/odoo/pull/227971)
This update prevents archived reconciliation rules from showing up when users match bank transactions. It helps keep the list clean and reduces the chance of selecting outdated rules by mistake.
Original PR description
Steps to reproduce: ------------------- 1. Install Accounting (with demo data). 2. Go to Accounting > Dashboard and open the "Bank" journal. 3. Click on any unreconciled line and open the dropdown menu. 4. Select “Manage models” and archive one of the reconcile models. 5. Return to the bank journal and open any unreconciled line. Issue: ------- Archived reconcile models are still shown in the available model list. Cause: ------ The [SQL query](https://github.com/odoo/enterprise/blob/6615de3100ac1192039a5f276df278c543f2fabb/account_accountant/models/account_reconcile_model.py#L47-L118 ) does not filter out inactive reconcile models. Solution: ---------- Add a condition to include only active models. opw-5189700
This change prevents an error when sending a credit or debit note to Uruguay’s tax authority if the original invoice is not a valid electronic document. Instead of failing with a server traceback, Odoo now shows a clear message so the user can correct the issue before resending. This improves reliability and makes the process easier to complete successfully.
Original PR description
### Description of the issue/feature this PR addresses: When informing a Credit or Debit Note to DGI we always need to inform the related original document, Before this change is the related document…
### Description of the issue/feature this PR addresses:
When informing a Credit or Debit Note to DGI we always need to inform the related original document, Before this change is the related document is not a real CFE then will raise a traceback error
### Steps to reproduce:
1. Create an e-invoice and confirm in Odoo (without sending to DGI)
2. Create an e-credit note from the e-invoice created in (1) and confirm
3. Try to send the credit note to DGI
The result is a traceback:
```
RPC_ERROR
Odoo Server Error
Occured on 18.core.odoo.localhost on model account.move.send.wizard on 2025-10-21 20:47:48 GMT
Traceback (most recent call last):
File "/home/odoo/custom/odoo/odoo/http.py", line 2144, in _transactioning
return service_model.retrying(func, env=self.env)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/service/model.py", line 156, in retrying
result = func()
^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 2111, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 2359, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/addons/base/models/ir_http.py", line 333, in _dispatch
result = endpoint(**request.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 754, in route_wrapper
result = endpoint(self, *args, **params_ok)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/web/controllers/dataset.py", line 42, in call_button
action = call_kw(request.env[model], method, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/api.py", line 535, in call_kw
result = getattr(recs, name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/account/wizard/account_move_send_wizard.py", line 294, in action_send_and_print
attachments = self._generate_and_send_invoices(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/account/models/account_move_send.py", line 719, in _generate_and_send_invoices
self._generate_invoice_documents(moves_data, allow_fallback_pdf=allow_fallback_pdf)
File "/home/odoo/custom/odoo/addons/account/models/account_move_send.py", line 620, in _generate_invoice_documents
self._call_web_service_before_invoice_pdf_render(invoices_data_web_service)
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move_send.py", line 88, in _call_web_service_before_invoice_pdf_render
invoice._l10n_uy_edi_send()
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 813, in _l10n_uy_edi_send
request_data = move._l10n_uy_edi_prepare_req_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 787, in _l10n_uy_edi_prepare_req_data
xml_content = self._l10n_uy_edi_get_xml_content()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 773, in _l10n_uy_edi_get_xml_content
"referencia_lines": self._l10n_uy_edi_cfe_F_reference(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 381, in _l10n_uy_edi_cfe_F_reference
cfe_serie, cfe_number = self.l10n_uy_edi_document_id._get_doc_parts(related_cfe)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/l10n_uy_edi_document.py", line 215, in _get_doc_parts
return re.findall(r"([A-Z]{1,2})[-]*([0-9]{1,8})", record.l10n_latam_document_number)[-1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^
IndexError: list index out of range
The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
RPC_ERROR
at makeErrorFromResponse (http://18.core.odoo.localhost/web/assets/c15481d/web.assets_web.min.js:3162:163)
at XMLHttpRequest.<anonymous> (http://18.core.odoo.localhost/web/assets/c15481d/web.assets_web.min.js:3167:13)
```
### Desired behavior after PR is merged:
Now we ensure to show a proper message to the user to fix the problem: the original document should be a electronic one
<img width="1203" height="664" alt="after" src="https://github.com/user-attachments/assets/bb7b105e-12f0-4935-b6bc-37edb3bc3aca" />
References LATAM 1301 / ADHOC Task 54770
Forward-Port-Of: odoo/enterprise#90281This fix improves the spreadsheet version history view by avoiding an unnecessary company currency request. As a result, the view should open more efficiently and with less backend processing, especially in cases where this action is used frequently.
Original PR description
The perfomance commit added in https://github.com/odoo/odoo/pull/151725 did not account for the version history action that does not inherit from `AbstractSpreadsheetAction`. this missing value trickled down to a bug only detectable in the VersionHistory action and which is addressed in https://github.com/odoo/odoo/pull/232985 This commit adds the same performance to VersionHistory action. Task-5187293 Forward-Port-Of: odoo/enterprise#98197 Forward-Port-Of: odoo/enterprise#98038
Fixed an issue where the image toolbar would not appear if the editor had lost focus, even though the user’s selection was still relevant. This makes image editing behave more reliably when switching between elements on the page.
Original PR description
Description of the issue: - The image toolbar failed to open when the editable had lost focus. - Previously, `focusEditable()` exited early if the active element was inside the editable, even when the actual document selection wasn’t. Solution: - Updated the condition in `focusEditable()` to also check whether the document selection is inside the editable. - Now it only returns early when both the active element and the selection are within the editable. task-5117272 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230549
This fix prevents the delivery date from being unintentionally changed when an invoice is confirmed after adjusting the delivery. It helps ensure sales and accounting documents stay consistent, avoiding confusion and rework for users.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Enable anglo-saxon accounting; 2. have a product category with automated AVCO; 3. assign category to a deliverable product; 4. set product to invoice on…
Versions
--------
- 17.0+
Steps
-----
1. Enable anglo-saxon accounting;
2. have a product category with automated AVCO;
3. assign category to a deliverable product;
4. set product to invoice on delivery;
5. add product to a sales order;
6. confirm order & delivery;
7. create invoice;
8. change the delivery on the invoice;
7. confirm the invoice.
Issue
-----
The delivery date gets reset.
Cause
-----
Commit 818cf04f05767 added `delivery_date` as a permanently protected field when modifying moves or move lines, protecting the records on `write`. With anglo-saxon accounting however, new move lines are created when confirming an invoice, which in turn recalculate the delivery date, as `_get_protected_vals` isn't used for their move on `create`.
Solution
--------
Add `self.env['account.move'].protecting(_get_protected_vals({}, moves))` when creating new lines for a move, to avoid recomputing fields that should always be protected.
opw-4965036
Forward-Port-Of: odoo/odoo#231186This fix removes a hardcoded 30-day assumption when calculating the minimum rental period on the website. As a result, customers can now correctly select rental dates in shorter months like February without being blocked by an incorrect end-date limit.
Original PR description
Issue: Currently minimum rental duration uses a hardcoded 30 days. This cause issue for non-30 days month e.g. Feb. which is 28 days. To reproduce: 1- Install `website_sale_renting` 2- From Setting,…
Issue: Currently minimum rental duration uses a hardcoded 30 days. This cause issue for non-30 days month e.g. Feb. which is 28 days. To reproduce: 1- Install `website_sale_renting` 2- From Setting, set `Minimum Rental Duration` to 1 month. 3- Create a rental product and from website, choose the date: - 01/02/2026 - 28/02/2026 4- This fails. The earliest end date it accepts is 03/03/2026. Cause: This is due to hardcoded 30 days: https://github.com/odoo/enterprise/blob/7ffb9f3cb0d818cf3616d6972df424bf0ca251a4/website_sale_renting/static/src/js/renting_mixin.js#L7-L12 https://github.com/odoo/enterprise/blob/7ffb9f3cb0d818cf3616d6972df424bf0ca251a4/website_sale_renting/static/src/js/renting_mixin.js#L47-L53 We can use luxon plus method instead. ```diff + const minEndDate = startDate.plus(Object.fromEntries([[unit, duration]])); ``` In all usages of `msecPerUnit` we can do the same. Also we can keep remove `msecPerUnit` from master. opw-5094534 Forward-Port-Of: odoo/enterprise#98828 Forward-Port-Of: odoo/enterprise#98168
Orders are now synchronized one at a time instead of in large batches. This reduces the risk of timeouts and synchronization errors, helping prevent lost or partially processed orders, including orders that need invoicing. The loyalty flow was also adjusted so coupon programs are confirmed correctly for each order.
Original PR description
`syncAllOrders` method is now splitting the list of orders to synchronize them one by one. This allows to have better control over each order synchronization and error handling. Some customer were experiencing issues when synchronizing too many orders at once, leading to lost orders or orders not being synchronized properly. For example, synchronizing orders that needs to be invoiced takes too long and can lead to timeout issues. By synchronizing orders one by one, we ensure that each order is properly synchronized before moving to the next one. --- Modification in `pos_loyalty` module to adapt to this change: The `confirm_coupon_programs` method is now called for each order individually, instead of being called once for all orders in the `payment_screen`. This ensures that coupon programs are confirmed correctly for each order even when orders synchronization is delayed Forward-Port-Of: odoo/odoo#232691 Forward-Port-Of: odoo/odoo#232073
This update corrects a linting check so that indexed relationships are properly recognized even when they come from inherited data models. It helps prevent missed indexing warnings, improving database performance checks and code quality.
Original PR description
Many2one fields that originated from an `inherits` model were not linted for indexing if they were an inverse to a One2many field, because those fields on the inverse model have `store=False`. The Many2one field that needs to be indexed is the one on the delegated model. This commit fixes this by always getting the `base_field` for the inverse field - if it's an inherited field, it will use the source field; if not, it will use the field itself. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents point of sale orders from getting stuck when the connection to the blackbox is unavailable during synchronization. If an order cannot be signed because the system is offline, it is returned to draft so the cashier can try again once the connection is restored.
Original PR description
When trying to sync orders while being offline, a `ConnectionLostError` is raised. This error was not handled in the pos_blackbox_be module. Now, if an order was not signed correctly by the blackbox, we put its state back to "draft", allowing the cashier to retry later (when the connection to bbox is re-established).
5 changes
Resolved issues and error corrections
The VIES summary report now shows invoice amounts in the company’s currency when invoices are issued in a foreign currency. This fixes incorrect totals and ensures the report matches the real accounting value.
Original PR description
**Issue** When an invoice is issued in a currency different from the company currency, the VIES summary report incorrectly displays the total value as if it were already converted. This results in…
**Issue** When an invoice is issued in a currency different from the company currency, the VIES summary report incorrectly displays the total value as if it were already converted. This results in incorrect totals in the report. **Steps to Reproduce:** 1. Install the Accounting app and the l10n_cz_reports_2025 module. 2. Go to Accounting > Customers > Invoices. 3. Create a new invoice using a currency other than CZK. 4. Add a product with Code Supply set to Gold and Transaction Code set to 0 Goods. Confirm the invoice. 5. Navigate to Accounting > Reporting > VIES Summary Report. 6. Observe that the total value is not correctly converted to the company currency. **Expected Behavior:** The total amounts in the VIES summary report should be correctly converted to the company currency if the invoice was created in a foreign currency. **Actual Behavior:** Amounts are displayed in the invoice currency without conversion, leading to incorrect totals when the invoice currency differs from the company currency. **Root Cause** The report fetches raw invoice data without handling currency conversion. Specifically, it retrieves the unconverted total value, even when the invoice currency differs from the company’s. **Fix** To solve the issue the balance field is used, which correctly reflects the value in the company currency. opw-4688638 Forward-Port-Of: odoo/enterprise#87663 Forward-Port-Of: odoo/enterprise#82978
This change prevents an error that could appear when opening an employee avatar popover if the employee is archived or missing data. It improves reliability in Planning by handling empty results gracefully instead of showing a traceback.
Original PR description
Purpose of this PR: A guard has been added in the override of `get_avatar_card_data` to handle empty results and prevent traceback errors when data is missing. community PR: [odoo/odoo#231184](https://github.com/odoo/odoo/pull/231184)
This fix prevents a server error when sending a credit or debit note to Uruguay’s tax authority if the original related document is not a valid electronic invoice. Instead of a traceback, users now see a proper message explaining what needs to be corrected before submission.
Original PR description
### Description of the issue/feature this PR addresses: When informing a Credit or Debit Note to DGI we always need to inform the related original document, Before this change is the related document…
### Description of the issue/feature this PR addresses:
When informing a Credit or Debit Note to DGI we always need to inform the related original document, Before this change is the related document is not a real CFE then will raise a traceback error
### Steps to reproduce:
1. Create an e-invoice and confirm in Odoo (without sending to DGI)
2. Create an e-credit note from the e-invoice created in (1) and confirm
3. Try to send the credit note to DGI
The result is a traceback:
```
RPC_ERROR
Odoo Server Error
Occured on 18.core.odoo.localhost on model account.move.send.wizard on 2025-10-21 20:47:48 GMT
Traceback (most recent call last):
File "/home/odoo/custom/odoo/odoo/http.py", line 2144, in _transactioning
return service_model.retrying(func, env=self.env)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/service/model.py", line 156, in retrying
result = func()
^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 2111, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 2359, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/addons/base/models/ir_http.py", line 333, in _dispatch
result = endpoint(**request.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 754, in route_wrapper
result = endpoint(self, *args, **params_ok)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/web/controllers/dataset.py", line 42, in call_button
action = call_kw(request.env[model], method, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/api.py", line 535, in call_kw
result = getattr(recs, name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/account/wizard/account_move_send_wizard.py", line 294, in action_send_and_print
attachments = self._generate_and_send_invoices(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/account/models/account_move_send.py", line 719, in _generate_and_send_invoices
self._generate_invoice_documents(moves_data, allow_fallback_pdf=allow_fallback_pdf)
File "/home/odoo/custom/odoo/addons/account/models/account_move_send.py", line 620, in _generate_invoice_documents
self._call_web_service_before_invoice_pdf_render(invoices_data_web_service)
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move_send.py", line 88, in _call_web_service_before_invoice_pdf_render
invoice._l10n_uy_edi_send()
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 813, in _l10n_uy_edi_send
request_data = move._l10n_uy_edi_prepare_req_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 787, in _l10n_uy_edi_prepare_req_data
xml_content = self._l10n_uy_edi_get_xml_content()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 773, in _l10n_uy_edi_get_xml_content
"referencia_lines": self._l10n_uy_edi_cfe_F_reference(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 381, in _l10n_uy_edi_cfe_F_reference
cfe_serie, cfe_number = self.l10n_uy_edi_document_id._get_doc_parts(related_cfe)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/l10n_uy_edi_document.py", line 215, in _get_doc_parts
return re.findall(r"([A-Z]{1,2})[-]*([0-9]{1,8})", record.l10n_latam_document_number)[-1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^
IndexError: list index out of range
The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
RPC_ERROR
at makeErrorFromResponse (http://18.core.odoo.localhost/web/assets/c15481d/web.assets_web.min.js:3162:163)
at XMLHttpRequest.<anonymous> (http://18.core.odoo.localhost/web/assets/c15481d/web.assets_web.min.js:3167:13)
```
### Desired behavior after PR is merged:
Now we ensure to show a proper message to the user to fix the problem: the original document should be a electronic one
<img width="1203" height="664" alt="after" src="https://github.com/user-attachments/assets/bb7b105e-12f0-4935-b6bc-37edb3bc3aca" />
References LATAM 1301 / ADHOC Task 54770
Forward-Port-Of: odoo/enterprise#90281This update fixes a performance issue in spreadsheet version history by preventing an unnecessary company currency lookup. As a result, opening or working with version history should be smoother and faster for users.
Original PR description
The perfomance commit added in https://github.com/odoo/odoo/pull/151725 did not account for the version history action that does not inherit from `AbstractSpreadsheetAction`. this missing value trickled down to a bug only detectable in the VersionHistory action and which is addressed in https://github.com/odoo/odoo/pull/232985 This commit adds the same performance to VersionHistory action. Task-5187293 Forward-Port-Of: odoo/enterprise#98197 Forward-Port-Of: odoo/enterprise#98038
Tax closing entries are now linked to the right tax report, so users no longer get different draft entries when opening the same closing action from related report views. This also prevents duplicate-looking closings across national variants by associating them with the generic tax report when appropriate.
Original PR description
To reproduce the issue, on a Belgian company: 1) From the Generic Tax Report, or any of its two grouped variants (Account>Tax or Tax>Account), click on the closing entry button. It generates a draft…
To reproduce the issue, on a Belgian company: 1) From the Generic Tax Report, or any of its two grouped variants (Account>Tax or Tax>Account), click on the closing entry button. It generates a draft move. Log a note on that move. 2) Open the national tax report of Belgium, for the same period as in 1). Click on the closing entry button again. ==> The draft move generated in 2) is NOT the same as the one generated in 1) (you can check that from the note logged in 1)). This is because tax_closing_report_id is too naively set on the account.move, to always match the report on which the button was clicked. This commit fixes that, ensuring we set the right report in the closing field. Something will be done in the migration script to 19.0 to set the report properly before creating the returns. The problem also occurs when multiple national variants are available : in this case each of those reports creates a distinct closing entry, with the exact same informations, giving the illusion we're doing per-report closings. In such cases, we associate the closing move to the Generic tax Report. opw-4858689 Forward-Port-Of: odoo/enterprise#95775
29 changes
Enhancements to existing features
The Windows IoT Box installer has been updated so new installations follow Odoo 19.0 by default. This helps keep newly installed devices aligned with the current release without extra manual setup.
Original PR description
Windows IoT Boxes are now following 19.0 by default after install.
This change adds a default set of attendance rules so employee attendances can be created even when no ruleset was previously defined. It includes rules for overtime and non-working days, helping avoid setup issues and ensuring attendance records work more smoothly.
Original PR description
## PR Purpose It's impossible to create an attendance for an employee without a ruleset. To solve this problem, this PR adds a default ruleset with 2 rules: one for overtime, and another one for non working days. Those data are the same as the data added in the upgrade/migrations/hr_attendance/saas~18.5.2.0 post-migrate script. [Task#5082628](https://www.odoo.com/odoo/all-tasks/5082628) [Community#228352](https://github.com/odoo/odoo/pull/228352) [Upgrade#8684](https://github.com/odoo/upgrade/pull/8684)
This change adds a default overtime ruleset for employee attendance records. It ensures attendances can be created even when no custom ruleset has been configured, preventing a setup issue and making the feature work out of the box.
Original PR description
## PR Purpose It's impossible to create an attendance for an employee without a ruleset. To solve this problem, this PR adds a default ruleset with 2 rules: one for overtime, and another one for non working days. Those data are the same as the data added in the upgrade/migrations/hr_attendance/saas~18.5.2.0 post-migrate script. [Task#5082628](https://www.odoo.com/odoo/all-tasks/5082628) [Enterprise#95421](https://github.com/odoo/enterprise/pull/95421) [Upgrade#8684](https://github.com/odoo/upgrade/pull/8684)
When POS categories are synced to Atlas, their parent category is now included as part of the transfer. This helps preserve the category structure more accurately across systems, so menu organization stays consistent.
Original PR description
In this commit: --- - The parent category of a POS category is now included during synchronization with the Atlas platform. - Added `parent_ref_id` in the category payload to maintain hierarchy. Note: The UrbanPiper platform only supports a single level of sub-categories. Extra: Added exception for `requests.exceptions.JSONDecodeError`. task-5169337 Forward-Port-Of: odoo/enterprise#97213
This change adds a queue for blackbox messages so the Point of Sale can send certain requests without waiting for an immediate response. It improves speed and reliability for operations like pro forma sales, helping staff continue working more smoothly even when the blackbox is busy.
Original PR description
In this commit, we introduce a queuing mechanism for blackbox messages to make all interactions with the blackbox faster and more reliable. This is particularly useful for messages that do not require the response from the blackbox to continue the workflow such as pro forma sales messages. Forward-Port-Of: odoo/enterprise#97293 Forward-Port-Of: odoo/enterprise#90747
Resolved issues and error corrections
In dark mode, the account reports info popover now uses a lighter text color so the formula is readable. This improves usability for users who view reports in dark mode, especially when checking details in debug mode.
Original PR description
When using the dark mode, the popover available only in debug mode on the account reports (when pressing the info button on the right of each line) used to display the formula with a dark color, making it hard to read.
Typing or pasting calculated dates into datetime fields now behaves correctly when the field loses focus. This fixes an issue where the wrong field elements were being handled, causing the edit button to reappear unexpectedly.
Original PR description
How to reproduce ================ Write an operation or calculation in datetime field like +1d or +=1d or copy/paste a value in field. As the focus is lost, button reappears in the field. Then, the getInputs method in useDateTimePicker hook must (as this name suggests it) return input elements. The fix ======= We filter on tagName === 'input' elements 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
This update prevents an error when changing the sales order linked to a delivery. It also keeps related delivery items aligned with the new sales order so the records stay consistent and easier to manage.
Original PR description
Steps to reproduce: - Create a Sale Order with at least one product line & confirm it. - Open the delivery - Change the picking's SO to another one Issue: A traceback will happen, as the `Command` expects an id, not a record Aside from the traceback, we need to think of what it implies to change the SO on a picking like this. If the move have a sale_line_id, it doesn't make sense to have some still related to one SO while the picking itself is linked to another one. Now tries to do a basic matching of the moves based on their product within the newly set Sale Order. sentry-6921046230 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an automated rental test so it can run in environments that do not include demo data. It removes the test’s dependency on accounting and stock settings that were not always available, preventing false failures during validation.
Original PR description
The test was failing in no-demo environments because it relied on accounting and stock configurations that were not present. When the test attempted to set property_valuation = 'real_time' on the product category, it triggered a ValidationError because the related stock accounts had not been properly set up for the test's transaction context. runbot-error-230417 Forward-Port-Of: odoo/enterprise#98155 Forward-Port-Of: odoo/enterprise#92292
This update prevents an error in the German fiscal certification flow when a POS order line is fully discounted. It ensures orders with a 100% discount are processed correctly, avoiding checkout interruptions for affected businesses.
Original PR description
Since this PR (https://github.com/odoo/enterprise/issues/83300), a division by zero error in Fiskaly POS certification when an order line has a 100% discount by directly setting gross_discount to price_subtotal_incl. Before this fix, applying a full discount led to a division by zero error : ``` File "/home/odoo/src/enterprise/19.0/l10n_de_pos_cert/models/pos_order_line.py", line 48, in prepare_line_data gross_discount = float_repr(round(self.price_subtotal_incl / (1 - self.discount / 100), 2) - self.price_subtotal_incl, precision) ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ ZeroDivisionError: float division by zero ```
This update corrects payroll export behavior so the fields chosen by the user are the ones included in the exported file. It prevents exports from falling back to incorrect default fields, making payroll data exports more reliable and accurate.
Original PR description
Since the introduction of payslip issues, the optional active fields were not correctly given back to the controller. This resulted in having the wrong default fields inside the export (not the ones selected). This commit fixes the issue by avoid using a proxy. task-5129681
This change fixes a problem where Gmail and Outlook could show the wrong error message when both features were installed. It also ensures users without an enterprise subscription see a generic message instead of triggering an unnecessary external service check.
Original PR description
Bug === When both module are installed, one overwrite the error messages of the other, because the methods have the same name. For database without enterprise, they won't have a subscription. We don't want to try reaching IAP in that case, and so we show a generic error message. For simplicity, we didn't make a bridge module just for that error, and we just check the version. Task-5113992
This fix prevents the Point of Sale from crashing when an order is validated with a customer record missing required information. Instead of failing, the system now shows the proper warning and opens the customer form so the missing details can be completed.
Original PR description
Before this commit, when validating an order, if the selected contact was missing a required field, the PoS would crash instead of displaying the correct notification and opening the partner edit form. opw-5222040
This change prevents an error from appearing when a new IoT Box record is created after connecting a device. It ensures the box version is checked only after it has been properly set, improving reliability during setup.
Original PR description
In order to avoid a traceback when creating the IoT Box record after connection, we need to ensure the version is set, before checking whether the first character is a "W".
This update makes the product image removal checks more reliable in the website shop. It adds a short wait so the system finishes saving before the test verifies the result, which prevents occasional false failures.
Original PR description
Versions -------- 18.0+ Issue ----- The `test_website_sale_add_and_remove_main_product_image_no_variant` and `test_website_sale_remove_main_product_image_with_variant` tours fail because the main…
Versions -------- 18.0+ Issue ----- The `test_website_sale_add_and_remove_main_product_image_no_variant` and `test_website_sale_remove_main_product_image_with_variant` tours fail because the main product image is not removed as expected after the tour completes. Cause ----- Both tours assume that once the product `<img>` element is removed from the DOM, the action is fully completed. The tour then ends, and the remaining Python code verifies the result. However, this assumption can lead to issues. If the save request takes longer than expected, the Python code may execute prematurely and fail. Solution -------- Add a step at the end of both tours to wait for the `<img>` element to be fully saved and updated in the preview DOM. Additionally, during debugging, it was observed that using an alias URL (i.e., a redirect) to an `ir.attachment` could introduce further issues or slow down the test due to the server fetching the image with a remote call. To address this, this commit replaces the alias URL with a simple binary attachment. opw-5159593 runbot-163025 runbot-163615 Forward-Port-Of: odoo/odoo#234150 Forward-Port-Of: odoo/odoo#233978
The receipt printer test now once again sends a confirmation event after printing the status page. This means users will see the expected “Test page printed” notification, making it clear that the test completed successfully.
Original PR description
**Steps to reproduce:** 1. Connect a receipt printer to an IoT box, and pair the IoT box with Odoo. 2. In the device form for the receipt printer, click the 'Test' button. **Expected behaviour:** - Status receipt is printed and a 'Test page printed' notification is shown on the screen. **Actual behaviour:** - Status receipt is printed but no notification is shown on the screen. In odoo/odoo#229731, a QR code was added to the test status receipt printer action. This was achieved by directly sending commands to the printer with the `escpos` library, bypassing the `print_raw` method. However, by bypassing the `print_raw` method it also bypassed the status events that are normally sent to inform the Odoo user of the outcome of the print. This commit adds back these events to the receipt test print action. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixed an issue where scanning a barcode in the product view could trigger a search using only part of the code. This ensures the full barcode is used, making scans more reliable and reducing incorrect matches.
Original PR description
Issue ----- When scanning a barcode in the product view, the search is made using only part of the barcode. Steps to reproduce ----- - Open the product view - Scan a barcode (eg 1234567890) > The search might only contain 12345678, 123456 or actually the full barcode Cause ----- When scanning a barcode, we receive all of the barcode characters followed by newline. When we receive the newline, we select the first item in the dropdown. The problem is that the search input changed but it hasn't been reflected yet in the items (a rendering is scheduled but hasn't been applied to the DOM yet). ----- Ticket: opw-4874425 Forward-Port-Of: odoo/odoo#234207 Forward-Port-Of: odoo/odoo#232270
Users can now create invoices linked to Point of Sale orders even when the invoice is still in draft, instead of being blocked. The system shows a warning to guide the user, which helps in countries where invoices must be adjusted before being sent to the tax authority.
Original PR description
After this commit, it becomes possible to make an invoice linked to a PoS order draft, showing only a warning notification instead of blocking the action. This is required in some localizations where invoices must be modified before being sent to the government. opw-5218715 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234041 Forward-Port-Of: odoo/odoo#233649
The attendance kiosk now keeps the barcode scanner available when the kiosk is set to “Barcode / RFID and Manual Selection.” This fixes a bug that prevented scanning in that mode, so users can continue using the scanner as intended.
Original PR description
Issue: In this bug, barcode scanner is disabled in barcode_manual kiosk mode. To reproduce: 1- Create a db with `hr_attendance` installed 2- Set `Kiosk Mode` to `Barcode / RFID AND Manual Selection` 3- Open `Kiosk Mode`. As you see the scanner is disabled. `t-att-disabled` shouldn't be set to `barcode_manual` as it should not be disabled in `barcode_manual` mode. Also there is no need of `t-att-disabled` attribute at all as: https://github.com/odoo/odoo/blob/f6b430245b98fb55cac7c8303b7f5bd8a3e1c84e/addons/hr_attendance/static/src/public_kiosk/public_kiosk_app.xml#L113-L114 the `KioskBarcodeScanner` will not be mounted if the mode is manual. opw-5153954
This fix restores consistent behavior in website test utilities by always adding plugins through the helper functions. It helps keep automated website tests reliable after a previous change had partially undone this behavior.
Original PR description
This commit is repeating caafc9a8e356a8693d9c4a20fa29e6ace8359a39, but after the merge of 179480d996a19dff4d56265a610259b1c6e33f99 that undid parts of it task-5176469
This update prevents a crash when the system tries to check for PDF indexing support but the PDF library is not installed. It makes attachment processing more reliable by safely handling missing optional dependencies.
Original PR description
The call to `importlib.util.find_spec('pdfminer.high_level')` introduced by https://github.com/odoo/odoo/pull/230123 crashes when the module is not available. One has to check for `'pdfminer'` first, and then `'pdfminer.high_level'`.This fix ensures the work center’s hourly cost is correctly included when an operation is marked done directly from the status widget. As a result, project profitability and gross margin calculations now reflect the true cost of the work order in this common workflow.
Original PR description
This PR fixes the problem of adding the hourly cost of the work center when marking an operation as done from the status widget. To reproduce the bug: 1- Create a work center with an hourly cost > 0. 2- Create an MO with 1 operation in that work center, expected time > 0. 3- Create and set a project on the MO. 4- Make sure that project has an analytic account. 5- Mark the operation as done from the status widget. (click on it and choose done, don't use the start button) 6- Go to the analytic account of the project and check the gross margin. = No cost of the workorder was added. Now, this PR takes into account the duration of the WO first when marking it as done directly from the status widget. Task-5156286
Customers can no longer cancel a self-order once it has been sent to the kitchen display. This avoids situations where the order is removed in the backend but the kitchen team is not informed, helping prevent confusion and preparation mistakes.
Original PR description
Currently, it is possible to cancel orders that have been sent to the kitchen display. However when doing so, the kitchen displayd does not receive any information about the cancellation. Steps to reproduce: ------------------- - Modify restaurant and enable self ordering - Open self an place an order (not paid but sent to kitchen) - Go back to "My orders" and cancel it > Order is cancelled in backend but not in the kitchen display Why the fix: ------------ When an order is sent to the kitchen the only way to cancel it should be by going to the register. Therefore now, if an order is present on the kitchen display we will not show the cancel button. opw-5030223 Community: https://github.com/odoo/odoo/pull/229039 Forward-Port-Of: odoo/enterprise#98035 Forward-Port-Of: odoo/enterprise#95770
This change corrects a validation issue in Odoo’s testing tools when a method’s parameter and return types are specified both in the documentation and in the code. It prevents the checker from failing on matching types, making automated quality checks more reliable.
Original PR description
This commit fixes a bug in `TestDocstring` when a method has type hint specified both in the docstring and as a type hint.
Example:
```
def example(a: list[int]) -> int:
"""
:param list[int] a: a list
:rtype: int
"""
return len(a)
```
the `_test_docstring_params` method will break twice:
- the `rtype` check raises `AssertionError: <class 'int'> != 'int'`
- the `type` check raises `AssertionError: list[int] != 'list[int]'`
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update helps the system notice broken WebSocket connections much sooner when the network is slow or unstable. As a result, users are less likely to experience silent message delays or missed updates before the app reconnects.
Original PR description
When a TCP connection is not closed cleanly, it can take minutes to detect a closed WebSocket connection. During this time, no messages are received. This can happen in slow or unstable network conditions. Browsers do not expose WebSocket ping/pong mechanisms. To detect dead connections quickly, periodic application level messages are sent if no messages were either sent or received within a minute. This approach ensures quicker detection compared to relying on the OS TCP timeout, which is typically set to a high value. X-original-commit: d043e12 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#234311 Forward-Port-Of: odoo/odoo#234275
This fix avoids a server error when a credit or debit note is sent to DGI and its original document is not a valid electronic invoice. Instead of failing with a traceback, Odoo now shows a clear message so the user can correct the document before resubmitting.
Original PR description
### Description of the issue/feature this PR addresses: When informing a Credit or Debit Note to DGI we always need to inform the related original document, Before this change is the related document…
### Description of the issue/feature this PR addresses:
When informing a Credit or Debit Note to DGI we always need to inform the related original document, Before this change is the related document is not a real CFE then will raise a traceback error
### Steps to reproduce:
1. Create an e-invoice and confirm in Odoo (without sending to DGI)
2. Create an e-credit note from the e-invoice created in (1) and confirm
3. Try to send the credit note to DGI
The result is a traceback:
```
RPC_ERROR
Odoo Server Error
Occured on 18.core.odoo.localhost on model account.move.send.wizard on 2025-10-21 20:47:48 GMT
Traceback (most recent call last):
File "/home/odoo/custom/odoo/odoo/http.py", line 2144, in _transactioning
return service_model.retrying(func, env=self.env)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/service/model.py", line 156, in retrying
result = func()
^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 2111, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 2359, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/addons/base/models/ir_http.py", line 333, in _dispatch
result = endpoint(**request.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/http.py", line 754, in route_wrapper
result = endpoint(self, *args, **params_ok)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/web/controllers/dataset.py", line 42, in call_button
action = call_kw(request.env[model], method, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/odoo/api.py", line 535, in call_kw
result = getattr(recs, name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/account/wizard/account_move_send_wizard.py", line 294, in action_send_and_print
attachments = self._generate_and_send_invoices(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/odoo/addons/account/models/account_move_send.py", line 719, in _generate_and_send_invoices
self._generate_invoice_documents(moves_data, allow_fallback_pdf=allow_fallback_pdf)
File "/home/odoo/custom/odoo/addons/account/models/account_move_send.py", line 620, in _generate_invoice_documents
self._call_web_service_before_invoice_pdf_render(invoices_data_web_service)
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move_send.py", line 88, in _call_web_service_before_invoice_pdf_render
invoice._l10n_uy_edi_send()
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 813, in _l10n_uy_edi_send
request_data = move._l10n_uy_edi_prepare_req_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 787, in _l10n_uy_edi_prepare_req_data
xml_content = self._l10n_uy_edi_get_xml_content()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 773, in _l10n_uy_edi_get_xml_content
"referencia_lines": self._l10n_uy_edi_cfe_F_reference(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/account_move.py", line 381, in _l10n_uy_edi_cfe_F_reference
cfe_serie, cfe_number = self.l10n_uy_edi_document_id._get_doc_parts(related_cfe)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/custom/enterprise/l10n_uy_edi/models/l10n_uy_edi_document.py", line 215, in _get_doc_parts
return re.findall(r"([A-Z]{1,2})[-]*([0-9]{1,8})", record.l10n_latam_document_number)[-1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^
IndexError: list index out of range
The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
RPC_ERROR
at makeErrorFromResponse (http://18.core.odoo.localhost/web/assets/c15481d/web.assets_web.min.js:3162:163)
at XMLHttpRequest.<anonymous> (http://18.core.odoo.localhost/web/assets/c15481d/web.assets_web.min.js:3167:13)
```
### Desired behavior after PR is merged:
Now we ensure to show a proper message to the user to fix the problem: the original document should be a electronic one
<img width="1203" height="664" alt="after" src="https://github.com/user-attachments/assets/bb7b105e-12f0-4935-b6bc-37edb3bc3aca" />
References LATAM 1301 / ADHOC Task 54770
Forward-Port-Of: odoo/enterprise#90281This update corrects the invoice information sent to Chorus Pro so it matches French BIS3/Peppol requirements. It also removes an invalid attribute and renames one label to better match the wording used by Chorus Pro, reducing the risk of invoice rejection.
Original PR description
1. We didn't met one of the specific requirement of the BIS3 invoices to be sent through Chorus Pro. > The SIRET number for the final recipient, behind Chorus Pro should always be sent in the following tag: Invoice/cac:AccountingCustomerParty/PartyLegalEntity/CompanyID 2. One of the attributes of the CompanyID was set to schemeName which is not a valid attribute of the Peppol BIS3 specification. Fixed in 18.0+: https://github.com/odoo/odoo/commit/c3ae4b29c51c7b0cff11aac5f4bf4aab5fad16c9 task-none (possible opw-4972189, but might not be the only problem) Source: <img width="787" height="673" alt="image" src="https://github.com/user-attachments/assets/2a410fa8-572a-4738-aa5d-764e91271880" /> https://www.pagero.com/onboarding/aife/aife-en Forward-Port-Of: odoo/odoo#234139 Forward-Port-Of: odoo/odoo#229014
This change fixes an issue where the date picker could reopen after a user selected a date. It improves the experience when entering dates on forms such as customer invoices, especially when the system takes a moment to save the change.
Original PR description
Before this commit, the date picker would reopen after selecting a value. This was caused by `activeInput` being reset after the close, which took time when the `onChange` RPC was slow. As a result, `useEffect` was triggered before `activeInput` had been reset, causing the picker to reopen. To fix this, we've reduced the number of `useEffect` calls. It will no longer be triggered when the input value changes. Steps to reproduce: - Open Customer Invoice - Set the invoice date => the picker will stay instead of being closed. Note that this is a date field with an onChange 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
The edit icon for favorite filters no longer flickers when you hover over it. This makes the search filter menu feel smoother and more stable for users.
Original PR description
This PR fixes an issue related to the edit favourite filter icon. Prior to this PR, the edit favourite filter icon used `d-none` by default and `display: block` on hover. Since `display: none` removes the element from the layout, the parent popover resized on hover, causing a flickering effect. This did not occur for filters with short labels (which had enough room for the icon) or for long labels (where the label was truncated). To prevent the flickering, the icon now uses `visibility: hidden/visible`, which keeps its space in the layout and avoids layout shifts. https://github.com/user-attachments/assets/5308c11e-8706-403c-80e3-fc05ab37a61d task-5237493 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234383
22 changes
Resolved issues and error corrections
This update fixes an issue in the yearly calendar where some end dates could disappear from view when the screen was zoomed and the user scrolled to the bottom. The calendar now reacts properly to window size changes, so dates remain visible and easier to read.
Original PR description
Before this commit, when zooming on the screen in the yearly calendar and scrolling down to the bottom, some end dates are not visible. By merging this commit, resolved dates will be visible on screen when scrolling down to the bottom by responding to window size changes in the DOM. task-4809668 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
This update fixes several spelling mistakes in the Surveys app, including menu labels, breadcrumbs, dashboard text, and a column heading. It improves the clarity and professionalism of the user interface, but does not change how the feature works.
Original PR description
**Surveys app misspellings on main menu item, dashboard name, breadcrumbs, and column label** Impacted versions: - 16.0+ (confirmed on Runbot, however the PR target is 18.0+ to only be applied on the latest stable release) Steps to reproduce: 1. Open any Community Runbot (or deploy Odoo locally) 2. Navigate to the **Surveys** app to view misspelling across multiple app views. Current behavior --> Expected behavior - "Participations" is not a word --> It should be "Participants" - "Quizz" is misspelled --> It should be "Quiz" Proposed changes highlighted in green [here on the screenshots](https://imgur.com/a/0vM48R0). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix corrects a problem in the editor where selecting table cells from right to left or bottom to top in Firefox could drop the first cell from the selection. It improves the reliability of table editing for users working in Firefox.
Original PR description
Steps to Reproduce: 1. Create a table in the editor (Firefox). 2. Select table cells backward (right → left or bottom → top). Description of the issue this PR addresses: - The first selected cell does not remain selected in Firefox when extending the selection backward. task-5094832 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change stops users from canceling a manufacturing order that has already been completed. Instead of canceling related stock movements by mistake, the system now shows a clear error message so the finished order remains protected.
Original PR description
Steps to reproduce:
- Enable multi-step routes.
- Go to Warehouse:
- Manufacturing Operations - Enable 3 steps.
- Create a storable product P1.
- Create a MO to produce one unit of P1.
- Validate the MO.
- Go to the MO list view.
- Select the MO.
- Try to cancel it.
Issue:
The MO is not canceled, but the picking from production to stock is canceled instead.
A done MO should not be cancelable, a UserError should be raised.
opw-5216220**Steps to reproduce** - With Studio, create a many2one field in relation to the Employee model. - Have a user with no "Employees" rights. - With this user and in mobile view, click on the field to select an employee. -> No records found. Note: the many2one_avatar_employee widget used in HR apps avoid this problem. **Cause** Issue since https://github.com/odoo/odoo/commit/e962860c6f0d8ec9e50bb376e1faab5c7bc69374 The `web_search_read` on the private employee model returns no record
Original PR description
**Steps to reproduce** - With Studio, create a many2one field in relation to the Employee model. - Have a user with no "Employees" rights. - With this user and in mobile view, click on the field to…
**Steps to reproduce** - With Studio, create a many2one field in relation to the Employee model. - Have a user with no "Employees" rights. - With this user and in mobile view, click on the field to select an employee. -> No records found. Note: the many2one_avatar_employee widget used in HR apps avoid this problem. **Cause** Issue since https://github.com/odoo/odoo/commit/e962860c6f0d8ec9e50bb376e1faab5c7bc69374 The `web_search_read` on the private employee model returns no records when an `image_*` or `avatar_*` field is part of the requested fields. This is because we try to fetch these fields https://github.com/odoo/odoo/blob/188a3fe45fb41463ff86d1fa5e930ab43fb70d0e/addons/hr/models/hr_employee.py#L240 but they are not stored on the public employee model, and will not be put in cache. When performing a read after that, these fields are missing from cache. We try to fetch them from the db https://github.com/odoo/odoo/blob/e962860c6f0d8ec9e50bb376e1faab5c7bc69374/odoo/models.py#L3185 but this fetch is again done using the public employee. This results in missing values and is interpreted as an access error, no data is returned in `web_search_read`. **Solution** Read the problematic fields to make them present in cache when the cache of the public employee is copied to the one of the private employee. opw-4297115 Forward-Port-Of: odoo/odoo#197575
This change fixes an issue where partner details used for Peppol verification could briefly become inconsistent when multiple updates were applied separately. As a result, validations are now more reliable and less likely to fail with mismatched endpoint information.
Original PR description
In some cases, when doing two consequent writes instead of one batch, the ORM will trigger the dependencies needlessly, and it can end up to discrepancies like: EAS=0208, endpoint=BE... which lead to a validation error. opw-5228670 opw-5225590 opw-5228716 opw-5229057 opw-5232276 Forward-Port-Of: odoo/odoo#234290
This fix stops users from canceling a manufacturing order that has already been completed. Instead of canceling a related stock transfer by mistake, the system now shows an error and keeps the completed order unchanged.
Original PR description
Steps to reproduce:
- Enable multi-step routes.
- Go to Warehouse:
- Manufacturing Operations - Enable 3 steps.
- Create a storable product P1.
- Create a MO to produce one unit of P1.
- Validate the MO.
- Go to the MO list view.
- Select the MO.
- Try to cancel it.
Issue:
The MO is not canceled, but the picking from production to stock is canceled instead.
A done MO should not be cancelable, a UserError should be raised.
opw-5216220This change updates the dropshipping test so it includes the accounting setup needed to create purchase invoices. It prevents the test from failing when demo data is not installed, improving reliability in automated checks.
Original PR description
The test `test_dropship_return_backorders_bill_on_order` failed when running without demo data because no chart of accounts was installed, so no Purchase journal existed. As a result, `purchase_order.action_create_invoice()` raised: UserError: No journal could be found in company ... for any of those types: purchase This change inherits from `AccountTestInvoicingCommon` to have the necessary charts. [runbot-231285](https://runbot.odoo.com/odoo/error/231285) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224775
This change prevents Argentine invoice reports from failing when the Spanish (Argentina) language is not available. The report now checks for that language before using it, so invoices continue to render instead of crashing.
Original PR description
**Description of the issue/feature this PR addresses:** Rendering the Argentine invoice report fails with: UserError: Invalid language code: es_AR when the language 'es_AR' is not active in res.lang. **Current behavior before PR:** The report template (l10n_ar.report_invoice_document) always forces lang='es_AR' when calling amount_to_text, causing a crash if that language is not available. **Desired behavior after PR is merged:** The template now checks dynamically if 'es_AR' exists in res.lang before using it. If not, it safely skips rendering to avoid breaking the report. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects the Australian TPAR report so country names are exported properly and no longer cause line length errors. It also fixes PDF generation for the report, allowing downloads to complete without errors.
Original PR description
Behavior before: Exporting the TPAR report using the TPAR option failed with a line length error because the SQL query returned the full JSON object for country names (e.g., {'en_US': 'Australia'})…
Behavior before:
Exporting the TPAR report using the TPAR option failed with a line length error because the SQL query returned the full JSON object for country names (e.g., {'en_US': 'Australia'}) instead of plain text, resulting in incorrect line lengths. Additionally, PDF export failed with a KeyError for the missing 'level' key, as dynamically generated report lines did not include a level field, which the QWeb template requires.
Behavior after:
SQL query uses the JSONB text extraction operator (->>) to retrieve only the country name string (e.g., 'Australia'), ensuring correct line lengths during export. All dynamic report lines are assigned 'level': 1 so that PDF export works correctly without errors.
Root cause:
Country names are stored as translatable JSONB fields, and the previous query did not extract the localized text, returning the full JSON structure. Dynamic report lines for partners did not include a level key by default, causing the PDF template rendering to fail.
Ticket [link](https://www.odoo.com/odoo/project.task/5148697)
opw-5148697
Forward-Port-Of: odoo/enterprise#97990This change fixes a pricing bug in Point of Sale where extra charges for product options could be counted twice. As a result, configurable products now display and charge the correct total price at checkout.
Original PR description
Before this commit, if a product had dynamic attributes with extra prices, those extra prices were computed twice, resulting in incorrect total prices. opw-5187405 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The mobile search panel popover now uses a background color that matches both light and dark themes. This improves readability and visual consistency for users on mobile devices, without changing the feature itself.
Original PR description
This commit adjusts the search_panel background color so it adapts correctly to both light and dark modes on mobile. It only affects the "popover" use case. task-5121027 Requires: - https://github.com/odoo/enterprise/pull/98248 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects how downpayment invoices are prepared for ECPay so the payment data is valid. It prevents negative quantities from being sent and helps ensure invoice values are reported accurately.
Original PR description
When an invoice is created from a sale order with a downpayment, the invoice line for the downpayment typically has a negative quantity and a positive unit price. However, ECPay does not accept negative quantities, and this also leads to incorrect price values being sent in the JSON payload. To address this, when an invoice line has a negative quantity, it is inverted to ensure the data sent to ECPay is valid and consistent. **task**-5211264
This update fixes an issue where changing the delivery information on an invoice could be lost when the invoice was confirmed. It helps ensure the delivery date stays correct in anglo-saxon accounting flows, avoiding unexpected changes in customer and accounting records.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Enable anglo-saxon accounting; 2. have a product category with automated AVCO; 3. assign category to a deliverable product; 4. set product to invoice on…
Versions
--------
- 17.0+
Steps
-----
1. Enable anglo-saxon accounting;
2. have a product category with automated AVCO;
3. assign category to a deliverable product;
4. set product to invoice on delivery;
5. add product to a sales order;
6. confirm order & delivery;
7. create invoice;
8. change the delivery on the invoice;
7. confirm the invoice.
Issue
-----
The delivery date gets reset.
Cause
-----
Commit 818cf04f05767 added `delivery_date` as a permanently protected field when modifying moves or move lines, protecting the records on `write`. With anglo-saxon accounting however, new move lines are created when confirming an invoice, which in turn recalculate the delivery date, as `_get_protected_vals` isn't used for their move on `create`.
Solution
--------
Add `self.env['account.move'].protecting(_get_protected_vals({}, moves))` when creating new lines for a move, to avoid recomputing fields that should always be protected.
opw-4965036
Forward-Port-Of: odoo/odoo#231186The VAT summary report for Argentinian accounting now shows the correct total when an invoice includes a price-included VAT tax alongside multiple IIBB taxes. This prevents the VAT amount from being counted more than once, so the report matches the amounts shown in the accounting form.
Original PR description
**Issue** When using a VAT tax marked as price included, together with multiple IIBB taxes on the same invoice, the VAT summary report displays an incorrect total. Specifically, the VAT amount is…
**Issue** When using a VAT tax marked as price included, together with multiple IIBB taxes on the same invoice, the VAT summary report displays an incorrect total. Specifically, the VAT amount is counted multiple times, once for each IIBB tax, leading to an inflated total. **Steps to Reproduce** 1. Install the Accounting app and the Argentinian localization (l10n_ar) 2. Set the 21% VAT Purchase tax as Included in Price 3. Create a vendor bill applying the 21% VAT tax and at least two IIBB taxes 4. Open the VAT summary report for that bill Expected Behaviour: The total in the VAT summary should match the total shown in the accounting form view, with each tax counted only once. **Root Cause** The VAT summary report in the Argentinian localization relies on an SQL query to aggregate tax information for each `account.move`. The query joins `account_move_line` with `account_tax`, `account_tax_group`, and the many-to-many relation table `account_move_line_account_tax_rel`. Each `account_move_line` related to a VAT tax line (via `tax_line_id`) is joined with the `account_move_line_account_tax_rel` table. If that base line is related to multiple IIBB taxes, the join multiplies the VAT line once per IIBB tax since multiple matching rows exist. **Fix** The solution separates the logic for computing tax lines and base lines into two distinct subqueries. Each is aggregated independently to prevent duplication caused by one-to-many and many-to-many joins. The results are then joined using the unique `account_move_line.id`, ensuring each tax amount is counted exactly once in the final totals. opw-4776861 Forward-Port-Of: odoo/enterprise#96315 Forward-Port-Of: odoo/enterprise#85873
The appointment booking flow no longer uses a hard-coded maximum capacity of 12. Administrators can now set a global limit for the highest resource capacity that can be selected on the website, which makes the system work correctly for larger resources.
Original PR description
**Steps to reproduce:** - Install Appointment and Website apps - Create a resource with capacity above 12 - Create an appointment_type on `Resources` - Check `Manage Capacities` - Set its assignment method to `Select Time then auto-assign` - Go to the website and select the new resource - The maximum capacity you can book in the drop-down list is stuck to 12 **Issue:** Arbitrary maximum value (12) seemed to be used in the appointment website and controllers, for the resource capacity which can be booked by someone. **Fix:** Added `resource_max_capacity_allowed` setting to configure the maximum allowed value globally. related: https://github.com/odoo/enterprise/commit/2e855b910173b56e8501d0ebe9ee6f83ac5845bc related: https://github.com/odoo/enterprise/commit/db36b59c80b45c6df1da3ac9dc876e79121e5e5e opw-5059177
The mobile search panel now uses colors that fit dark mode better. This makes the interface easier to read and more consistent for users who work on phones or tablets at night or in low-light settings.
Original PR description
This commit adapts colors of search_panel for mobile in dark mode. | Before | After | |--------|--------| | <img width="904" height="1022" alt="image" src="https://github.com/user-attachments/assets/9136de22-3ce1-40e3-bb79-8f87c8ee2bf8" /> | <img width="372" height="653" alt="Capture d’écran 2025-10-29 à 08 37 39" src="https://github.com/user-attachments/assets/6aff402b-6dc8-46ce-8e2a-d55887374f51" /> | Requires: - https://github.com/odoo/odoo/pull/234361 task-5121027
Users can now search for messages and jump directly to them inside mailboxes. This removes a previous limitation that prevented message navigation in certain mailbox views, making it easier to find and review conversations.
Original PR description
Before this commit, we could not jump to messages in mailboxes. This happens because the `useMessageHighlight()` hook prevented jumping to messages in thread that were not their origin thread. This commit fixes the issue by removing this limitation specifically for mailboxes. opw-4948798 opw-5087102
The shared project Kanban view no longer allows users to edit stages, which prevents an error from appearing when they try to browse for more projects. This makes the shared project experience more stable and avoids unexpected interruptions for invited users.
Original PR description
Steps to reproduce: - 1. Install the Project module. 2. Create a new project and share it with a user. 3. Log in as that user. 4. Open the shared project Kanban view and try to edit a stage. 5. Try to search for more projects. Issue: - A traceback occurs when clicking on 'Search More'. Fix: - Prevent stage editing in shared project Kanban view. task-5176630
This change corrects the automated tests for the tax reporting feature after a previous update caused them to fail. It helps ensure the tax report continues to behave as expected and reduces the risk of regressions in future updates.
Original PR description
See https://github.com/odoo/enterprise/commit/5291d0249ba925182fb9e670f9b46b9e57bda00c
Miscellaneous changes
task-5184489 Related: https://github.com/odoo/enterprise/pull/98193
Original PR description
task-5184489 Related: https://github.com/odoo/enterprise/pull/98193
task-5184489 Related: https://github.com/odoo/odoo/pull/233275
Original PR description
task-5184489 Related: https://github.com/odoo/odoo/pull/233275
11 changes
Enhancements to existing features
For Swiss companies, payment and direct debit files now automatically use the latest legally required Pain version. If an older version is detected, users are guided to update it so payments continue to work correctly and stay compliant with local banking rules.
Original PR description
This commit enforce forces new Pain version for CH companies. A RedirectWarning is raised for users on old version in Credit Transfer and Direct Debits. The users are redirected to the bank journal to update the Pain versions. The new versions were already implemented but now they are enforced in CH companies due to legal requirements. task-5149417
Resolved issues and error corrections
This change prevents duplicate withholding tax records from being created when the Argentina withholding demo data is installed. It helps keep the tax configuration clean and avoids confusion for users reviewing accounting setup.
Original PR description
**Description of the issue/feature this PR addresses**: This pr is to avoid duplicated taxes when the demo data is installed. **Steps to reproduce**: 1. Install l10n_ar_withholding module with demo…
**Description of the issue/feature this PR addresses**: This pr is to avoid duplicated taxes when the demo data is installed. **Steps to reproduce**: 1. Install l10n_ar_withholding module with demo data. 2. Take position in "(AR) Responsable Inscripto" company. 3. Check the taxes created on "Invoicing > Configuration > Accounting > Taxes". 4. Delete the filter "Sale or Purchase". 5. Add custom filter: Argentina Withholding Payment Tax type (l10n_ar_withholding_payment_type) is in ["supplier", "customer"]. 6. You will see that there are duplicated taxes (duplicated names) with suffix (Copy). **Current behavior before PR**: Duplicated taxes are created when demo data is installed. <img width="1583" height="784" alt="image" src="https://github.com/user-attachments/assets/49c9f4d4-b599-427b-a786-51191685b3fd" /> **Desired behavior after PR is merged**: No duplicated taxes are created when demo data is installed. _Task latam side_: 1360. _Task Adhoc side_: 57627. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users can no longer create private Knowledge articles when they do not have the proper create permission. The interface also hides the create buttons in those cases, which prevents confusion and keeps what users see aligned with what they are allowed to do.
Original PR description
How to Reproduce : 1. Remove 'Create' access on the 'Knowledge Article' model for Portal and Internal users. 2. Now log in as a Portal. 3. Try to create a new private article. 4. Log in as an…
How to Reproduce : 1. Remove 'Create' access on the 'Knowledge Article' model for Portal and Internal users. 2. Now log in as a Portal. 3. Try to create a new private article. 4. Log in as an Internal user. 5. Try to create a new private article. Both Internal and Portal users can still create private articles even after 'Create access' is removed. Article creation logic in `knowledge.article` was bypassing the usual access rights because of `sudo` (mainly to add the creator as a member, since creation rights on the member model are not granted). This allowed users to create private articles even without create access. This commit introduces: 1. Model-level access check in `create`. Sudo the creation of articles only when the user has create rights. 2. UI imp to hide the '+' button in the sidebar and the `New` button in the topbar when the user doesn't have create access. 3. New test cases to verify that model-level access rights are respected when creating an article. task-4916280
This change prevents draft sales orders from being removed when an invoice or delivery address is deleted from a customer record. It restores the expected behavior so business users do not lose orders by accident while maintaining normal address management.
Original PR description
Versions -------- - 17.0 Steps ----- 1. Create a new partner; 2. add an invoice and/or delivery address; 3. create a draft sales order for the partner; 4. unlink the invoice or delivery address. Issue ----- The draft order was magically deleted. Cause ----- An `unlink` override deletes any draft/cancelled orders linked to the address. This behavior was removed for version 18.0+ via 7ad89d892f36, but is still present in 17.0. Solution -------- Backport 7ad89d892f36 opw-5220488
Users can now click through search results to jump directly to messages in mailboxes. This removes a previous limitation that blocked navigation for messages outside their original thread, making message search more reliable and efficient.
Original PR description
Before this commit, we could not jump to messages in mailboxes. This happens because the `useMessageHighlight()` hook prevented jumping to messages in thread that were not their origin thread. This commit fixes the issue by removing this limitation specifically for mailboxes. opw-4948798 opw-5087102
This change disables tokenization for Boleto payments so the same payment method is not treated as reusable. It helps avoid inconsistent behavior across payment providers and reduces payment issues caused by Boleto being an offline, one-time-use method.
Original PR description
## Versions 17.0+ ## Issue Boleto is an offline, one-time-use payment method and cannot be tokenized with most payment providers (e.g., Adyen: https://docs.adyen.com/payment-methods/boleto-bancario/, Nuvei: https://www.nuvei.com/apm/boleto). ## Exception Stripe allows a form of tokenization by storing the customer's billing information and regenerating a new Boleto for each payment (cf. https://docs.stripe.com/payments/boleto). Technically, the Boleto itself is not reusable — Stripe simulates tokenization by associating customer info with new Boleto transactions. ## Fix To maintain consistent behavior and avoid provider-specific edge cases, tokenization is disabled for Boleto payments globally. opw-5156718
This update corrects how the system measures text during fuzzy search, so searches work properly even when certain language marks are removed during processing. It helps prevent incorrect matches and potential search errors for users working with languages such as Thai.
Original PR description
The fuzzy search mechanism (specifically the _match utility) calculates the length of the string before normalizing it (e.g., with `unaccent`). However, `unaccent` can remove non-spacing marks (like Thai tone marks or vowels), which changes the length of the string. This mismatch caused the search loop to iterate past the end of the normalized string, leading to incorrect behavior or potential errors. This commit moves the length calculation to after the string has been unaccented, ensuring the loop has the correct bounds. opw-5189276 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The debug info popover in account reports now uses a readable text color in dark mode. This makes the formula details easier to read without changing how the reports work.
Original PR description
When using the dark mode, the popover available only in debug mode on the account reports (when pressing the info button on the right of each line) used to display the formula with a dark color, making it hard to read.
Users who do not have the right permissions can no longer click the Log Note button and then hit an access error. This makes the interface consistent with Send Message and avoids confusing failed actions for project users.
Original PR description
Before this fix, users without sufficient read/write access could still click the "Log Note" button, unlike the "Send Message" button. Attempting to log a note would raise an access error, leading to a poor user experience. This issue has already been fixed in later versions (see odoo/odoo@fc1bb984ff373f54375072a5a3cbc8585c7dfc58). This commit applies the same fix here and adds a test. **Steps to reproduce:** - Log as a user with User access to projects - Open Projects - Open the dropdown on a Project and click view - The Send Message button should be disabled, but not the Log Note button. opw-5090572 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Miscellaneous changes
In order to put the localization translations on Weblate, we did some cleanup of the POT and PO files for them: - Re-exported all POT files - Removed POT files for countries that don't need other languages than English - Removed all `i18n_extra` folders and moved any existing translations over to the `i18n` folder - Updated PO file names by removing superfluous country codes, or simply correcting wrong ones - Removed PO files for irrelevant languages in a localization - Updated the PO file
Original PR description
In order to put the localization translations on Weblate, we did some cleanup of the POT and PO files for them: - Re-exported all POT files - Removed POT files for countries that don't need other languages than English - Removed all `i18n_extra` folders and moved any existing translations over to the `i18n` folder - Updated PO file names by removing superfluous country codes, or simply correcting wrong ones - Removed PO files for irrelevant languages in a localization - Updated the PO files according to the POT files using `msgmerge` - Added new PO files for missing languages We also updated the `.weblate.json` file to add all the localizations in a separate Weblate project, limited to the languages they support. task-5169642 Related: https://github.com/odoo/enterprise/pull/98321 18.0: https://github.com/odoo/odoo/pull/234342
In order to put the localization translations on Weblate, we did some cleanup of the POT and PO files for them: - Re-exported all POT files - Removed POT files for countries that don't need other languages than English - Removed all `i18n_extra` folders and moved any existing translations over to the `i18n` folder - Updated PO file names by removing superfluous country codes, or simply correcting wrong ones - Removed PO files for irrelevant languages in a localization - Updated the PO file
Original PR description
In order to put the localization translations on Weblate, we did some cleanup of the POT and PO files for them: - Re-exported all POT files - Removed POT files for countries that don't need other languages than English - Removed all `i18n_extra` folders and moved any existing translations over to the `i18n` folder - Updated PO file names by removing superfluous country codes, or simply correcting wrong ones - Removed PO files for irrelevant languages in a localization - Updated the PO files according to the POT files using `msgmerge` - Added new PO files for missing languages We also updated the `.weblate.json` file to add all the localizations in a separate Weblate project, limited to the languages they support. task-5169642 Related: https://github.com/odoo/odoo/pull/233521 18.0: https://github.com/odoo/enterprise/pull/98781