Daily updates from Odoo
Thursday, July 24, 2025
48 changes · saas-18.4
Resolved issues and error corrections
When users generate an electronic invoice XML from the Send & Print wizard using download-only options, Odoo now creates the related document record as expected. This keeps accounting documents complete even when the invoice attachment is not sent by email.
Original PR description
Event with the document integration correctly setup, e-invoice xml generated in the send&print wizard will not create an associated document unless the attachment is actually sent via mail Steps to reproduce: - Have a EU Company setup - Enable and configure Peppol Electronic Invoicing - Enable documents integration with accounting - Create an invoice to a Peppol enabled customer, confirm - Open send&print wizard, enable only 'Download' and 'BIS Billing 3.0' Issue: Document related to the xml attachment is not created. This will work as expected when the message is sent to the customer opw-4720588 Enterprise PR https://github.com/odoo/enterprise/pull/88746 Forward-Port-Of: odoo/odoo#219161 Forward-Port-Of: odoo/odoo#216243
This change updates an internal purchase inventory test so it has the right access to product unit information. It prevents avoidable test failures and helps keep future purchase and replenishment updates reliable.
Original PR description
The `product_uom_id` field was causing test failures in `test_reordering_rule.py` because it was not present in the `product.supplierinfo` form view . This commit adds the group permission `uom.group_uom` to the user who is running the test, to ensure that the `product_uom_id` field is available and preventing the test failure. build_error-111983 Forward-Port-Of: odoo/odoo#218830 Forward-Port-Of: odoo/odoo#206688
Electronic invoice exports now include product barcode information in the standard item identification field, matching what the system already reads during imports. This helps trading partners and integrations receive more complete product data and reduces mismatches between imported and exported e-invoices.
Original PR description
[FIX] account_edi_ubl_cii: export product barcode too Currently we use the `Item/StandardItemIdentification` as the barcode when importing a product. But we do not export the same information. In 18.0+ the `Item/StandardItemIdentification` was added to the UBL XML (for exporting) in commit 72e312815f372de88388c47c612bb5f44b4d8b4e. But there it is only used in `l10n_co_dian`. After this commit we export and fill the tag "by default". task-4941855 Forward-Port-Of: odoo/odoo#219391 Forward-Port-Of: odoo/odoo#218779
The website editor now stops showing an endless saving state when a page save fails, such as after entering an invalid blog date. This lets users see the error, correct the issue, and continue editing without having to refresh or reopen the builder.
Original PR description
With the initial website builder refactor, if there is an error during save, the editor stays in the "saving state". Steps to reproduce: - On `/blog`, open website builder - Change a date to an invalid value - Save - Close the error dialog about the invalid date - Bug: the save button is still spining Website refactor: 9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2 task-4367641
The Point of Sale now prioritizes favorite products when only a limited set of products is loaded. This helps ensure frequently used items are available to cashiers sooner, improving checkout efficiency.
Original PR description
- Make sure `is_favorite` products are prioritized to be loaded inside POS when using `pos_limited_loading`. - Added `NULLS LAST` to `ORDER BY is_favorite` to avoid getting `NULLS` records before `TRUE` ones. task-id: 4920408 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217952
This fix ensures membership levels and pricelists are shared from a parent partner to its child contacts when the parent buys a membership. It also prevents a child contact's membership purchase from incorrectly changing the parent, making membership access and pricing more accurate for related contacts.
Original PR description
Description of the issue/feature this PR addresses: Correct the behaviour of the member level assignment in membership when childs partners are concerned. Current behavior before PR: When buying a membership with a child partner apply the Level and the Pricelist to the Parent but those are not forwarded to the child. Desired behavior after PR is merged: A partner buying a membership should forward the membership level and Pricelist to its children. A child buying a membership should get that membership without forwarding it to its parent. TASK-4801759 Forward-Port-Of: odoo/odoo#211883
This fixes an issue where payment differences entered when closing a Point of Sale session could make the recorded payment amount incorrect. Businesses get more accurate accounting entries for POS sessions, especially when reconciling bank payments with small differences.
Original PR description
When a payment difference was created in the PoS, it was introducing errors in the accounting entries. Steps to reproduce: ------------------- * Make sure bank payment method has an outstanding account * Open PoS and make a sale paid by bank for 100$ * Close the session and introduce a payment difference of -10$ * Check the accounting entries created for the PoS session > Observation: The difference is correctly recorded but the payment appears as a payment of 80$ instead of 90$. Why the fix: ------------ We revert this fix (https://github.com/odoo/odoo/pull/196253) that was wrongly modifying the payment amount to fix the session report. opw-4723227 Forward-Port-Of: odoo/odoo#219684 Forward-Port-Of: odoo/odoo#211914
Deleting a customer or address no longer automatically removes related draft or cancelled sales orders. This prevents users from losing orders unexpectedly when removing an invoicing or shipping address and lets them decide how to handle linked orders.
Original PR description
On partner deletion, draft & cancelled orders were automatically deleted as well (to ease the deletion of 'unused' partners). Nevertheless, since both the main customer and the shipping and invoicing addresses were considered, the deletion of a partner might lead to the unexpected deletion of an order where the deleted partner was only the invoicing or shipping address. The user might not even be aware of it if they didn't enable the shipping/invoicing addresses setting. We believe it's better to drop this magical deletion and let the user be aware that there are orders related to the customer, so that they can handle it the way they want to, without the program deciding for them. opw-4866778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219609
Tasks linked to milestone-based sales now keep the sales order item that matches the selected milestone. This prevents billing or project tracking confusion when users manually change a task's milestone, including on subtasks.
Original PR description
**Step to reprocduce :** 1. Install sale_project module 2. Create a product - type: Service - Invoice policy: based on the milestones - Create on order: Project & Task. 3. Create a sale order with…
**Step to reprocduce :**
1. Install sale_project module
2. Create a product
- type: Service
- Invoice policy: based on the milestones
- Create on order: Project & Task.
3. Create a sale order with that product and add two SO lines with different descriptions.
4. Confirm the sale order.
5. Click on the Tasks smart button in the sale order to open the generated tasks.
6. From one of the tasks (e.g., m1)
7. Manually remove the existing milestone and sales order item from the task.
8. Then assign a different milestone (e.g., m2) to the task.
9. The sale order item set different (e.g., m1) instead of the newly set milestone.
**Issue:**
When a task has its `milestone_id` and `sale_line_id` manually cleared, and a new milestone
is later assigned, the task does not get the correct Sales Order Item.
**Cause:**
In the `_compute_sale_line` method, the logic priority the parent task and project when
computing the `sale_line_id`, and only uses the `milestone_id.sale_line_id` as a fallback.
https://github.com/odoo/odoo/blob/259f7eafb15882807640a00cf6939129f27c8fbb/addons/sale_project/models/project_task.py#L109-L113
**Solution :**
To fix this `_compute_sale_line` method to priority the milestone's `sale_line_id`
when a milestone is explicitly set. This ensures that if the task’s milestone
changes, its sale line reflects the one from the milestone, even for subtasks.
opw-4701106
Forward-Port-Of: odoo/odoo#215213This fix stops content history records from being written to directly and avoids copying history data during duplication. This helps prevent errors when records are copied and keeps editor history managed only through the intended process.
Original PR description
This commit prevent direct write to history, also, removes it from copy_data as it would fail anyway when trying to write the history Forward-Port-Of: odoo/odoo#219182 Forward-Port-Of: odoo/odoo#217167
Reloading pages after opening embedded actions such as Planning or Timesheets now rebuilds the navigation trail more accurately. This prevents an unrelated task record from appearing in the breadcrumb, although the tasks list may no longer appear there and remains accessible from the top menu.
Original PR description
- Open the Project app. The URL is `/odoo/project`; - Open a project. For example, the project with ID 5. The URL is `/odoo/project/5/tasks`; - Click on an embedded action. For example, 'Planning'.…
- Open the Project app. The URL is `/odoo/project`; - Open a project. For example, the project with ID 5. The URL is `/odoo/project/5/tasks`; - Click on an embedded action. For example, 'Planning'. The URL is `/odoo/project/5/tasks/5/action1574`; - Switch to another embedded action. For exemple, `Timesheet`. The URL is `/odoo/project/5/tasks/5/project-timesheets`. Note that in this case, the last action of the URL has changed. Reload the browser (F5). When reloading the router and the action service will use the URL to reconstruct the breadcrumb. It will decompose the URL as follows: - `/odoo/project` : The list of projects; - `/odoo/project/5` : The form view of the project '5', this is a known limitation; this step was not included the initial flow; - `/odoo/project/5/tasks`: The list of tasks of the project 5; - `/odoo/project/5/tasks/5` : The form view of the task 5. This line is an error, the task 5 should not be included in the breadcrumb. - `/odoo/project/5/tasks/5/project-timesheets` : The `Timesheet` embedded action. The issue occurs because the 'active_id' of the 'Timesheet' embedded action is taken as a 'resId' for the action tasks, which add an error on the breadcrumb. This commit, changes the behaviour to allways replace the last action with the embedded action. This behaviour is already done when changing of embedded action, but not for the first one. If we take our example again : - `/odoo/project`; - `/odoo/project/5/tasks`; - Click on an embedded action: `/odoo/project/5/action1574`; - Switch to another embedded action: `/odoo/project/5/project-timesheets` After reloading, the breadcrumb will be: - `/odoo/project` : The list of projects; - `/odoo/project/5` : The form view of the project '5'; - `/odoo/project/5/project-timesheets` : The `Timesheet` embedded action. However, this commit causes a side effect. The list of tasks will no longer appear in the breadcrumb. Users can still access it via the Top Menu. opw-4889557 Forward-Port-Of: odoo/odoo#219504 Forward-Port-Of: odoo/odoo#219404
Website text highlights now update and clean themselves up more reliably when content is edited, split, previewed, or saved. This prevents misplaced highlight effects, especially after editing highlighted text and switching to mobile preview, improving the visual consistency of website pages.
The IoT Box homepage now points to the correct settings page for configuring remote debugging. This restores the ability to set up ngrok-based remote access from the homepage, avoiding a broken setup path for support and troubleshooting.
Original PR description
During the forward port, the URLs for ngrok in the homepage were not changed from `hw_posbox_homepage` to `iot_drivers`, meaning remote debug could not be configured from the IoT box homepage. This commit fixes the URLs. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where Cloudflare Turnstile verification data could be saved into sales order notes when customers completed the optional extra checkout step. The checkout experience remains the same, but internal order notes stay clean and free of unnecessary captcha data.
Original PR description
Scenario:
- enable extra step in website ecommerce
- enable turnstile
- do the checkout process until after "extra step" step
- go check the sale order
Result: there is a big "turnstile_captcha: {1000 character hash}" that is
logged each time the customer filled the "extra step" step.
Cause:
turnstile if enabled is activated for all website_form and will add a
turnstile_captcha parameter.
For other website.form, the captcha is removed from the params when
calling:
request.env['ir.http']._verify_request_recaptcha_token('website_form')
but the custom route /website/form/shop.sale.order doesn't do that so
the captcha is logged in note.
Fix:
Recaptcha is already disabled on the extra_step with the class:
s_website_form_no_recaptcha, so it makes sense to just have the
same behavior for turnstile.
opw-4934132
Forward-Port-Of: odoo/odoo#219558
Forward-Port-Of: odoo/odoo#219269IoT boxes will now notify Odoo when their own connection details change, not only when new devices are discovered. This helps keep the database up to date with current IP address, hostname, MAC address, domain, and version information, including more reliable IP detection on Windows.
Original PR description
Currently we notify the database of any iot changes only if the iot box discovered new devices. However if its ip address/hostname/mac address/domain/version change the db is never notified. This PR adds this change + fixes the get_ip() method which was using netifaces which is unreliable on Windows to now use socket to get the iot box ip address Forward-Port-Of: odoo/odoo#219184 Forward-Port-Of: odoo/odoo#218109
Fixed an issue where express checkout customer details were not updated when the website was viewed in languages such as Spanish. This helps shoppers complete delivery orders reliably regardless of the selected website language.
Original PR description
[FIX] website_sale: handle translated express checkout partners Versions -------- - 17.0+ Steps ----- 1. Change website language to Spanish 2. add a deliverable order to cart; 3. go via express checkout. Issue ----- The express checkout partner doesn't get updated as expected. Cause ----- Before this commit, it checks whether the express checkout partner's name ends with the order reference, as is the case in English. In Spanish however, the order reference gets used in the middle of the name. As a consequence, the `_create_or_edit_partner` method does not get called. Solution -------- Check whether the order reference is part of the partner name. opw-4894059 Forward-Port-Of: odoo/odoo#218660 Forward-Port-Of: odoo/odoo#217528
This update fixes inconsistencies in how Spanish taxes are linked to fiscal positions. It helps ensure the correct tax behavior is applied for Spanish localization scenarios, reducing accounting configuration errors.
Original PR description
In this [commit](https://github.com/odoo/odoo/commit/8b539c1f303f1b49916c29190c11dcf2cab57d2c) taxes were mapped with fiscal positions but some taxes had inconsistencies. This PR aims to fix that mapping inconsistencies for ES. TaskID:4951601 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219578
This fix ensures Odoo completes all pending automatic field updates, including updates triggered while new records are being created. It also prevents access-related crashes during property field recalculations, improving reliability for affected business workflows.
Original PR description
The existing implementation was incomplete when some recomputation creates a new record that has fields to recompute. The latter fields were not taken into account when recomputing "all fields". We also adapt the flushing loop in the same way. This fix revealed a related issue. Properties fields have a compute method, which is a technical artifact to update their default values when the many2one to their definition record is modified. For some weird reason, this method re-triggers its computation on the record. And in some of those cases (when the record becomes inaccessible) the second recomputation crashes (`AccessError`). The fix consists in computing the field in sudo mode. Forward-Port-Of: odoo/odoo#220111 Forward-Port-Of: odoo/odoo#219395
The Contacts test setup now assigns a default country so automated nightly checks run reliably when only the Contacts app is installed. This prevents false test failures and helps keep release validation stable.
Original PR description
**PROBLEM** `test_vat_label_string` fail on nightly test **CAUSE** `self.env.user.company_id.country_id` is empty because: - we don't load demo data by default starting from 18.3 - we installed only one app, so the module that sets the default company country (there must be one since runbot non-nightly tests passed) isn't installed. **FIX** set the country to US in the test, so we have a country to work with. see https://runbot.odoo.com/odoo/error/229770 Forward-Port-Of: odoo/odoo#218351
This fixes a mobile usability issue where users could not scroll properly while editing a contact record, such as changing the country field. The update removes conflicting scroll behavior so forms and pop-ups are easier to use on small screens.
Original PR description
Steps to reproduce ================== - Use a mobile viewport - Go to contact - Open a record - Edit the contry - Try to scroll => Nothing happens Cause of the issue ================== Both the `.o_content` and the `.modal-body` are scrollable, so we need to scroll twice to go to the bottom. Solution ======== We revert https://github.com/odoo/odoo/commit/7d7aedc6149a170db2c73b1f62872bd35786c5ca opw-4851373 Forward-Port-Of: odoo/odoo#219423
This fixes an issue where Odoo could show an additional error while recording a failed company image download in the mail plugin. The original download may still fail, but the system now logs it properly without causing a traceback.
Original PR description
When logging a failed image download for a new company,
A traceback will appear.
[1]- https://github.com/odoo/odoo/blob/2317fec604907280aa89c52cfcaeb9adc30e5d04/addons/mail_plugin/controllers/mail_plugin.py#L360
https://github.com/odoo/odoo/blob/2317fec604907280aa89c52cfcaeb9adc30e5d04/addons/mail_plugin/controllers/mail_plugin.py#L342-L344
here, ``new_company_info`` is dictionary, but at [1] the code incorrectly accesses
``name`` as an attribute.
So, it will lead to the below traceback.
Traceback:
```
File "/home/odoo/src/odoo/addons/mail_plugin/controllers/mail_plugin.py", line 359, in _create_company_from_iap
_logger.warning('Download of image for new company %s failed, error %s', new_company_info.name, e)
AttributeError: 'dict' object has no attribute 'name'
```
sentry-6554480256
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#206771This update fixes an internal test issue in the Point of Sale loyalty area so that a promotion tax test can be safely retried without failing for the wrong reason. It helps maintain confidence in automated checks and reduces noise from misleading test failures, with no direct change for end users.
Original PR description
Tests in this file are all sorts of fucked up in ways which break retrying, but this one is problematic because it *also* fails on the reg, with a misleading error as on retrying the `setUp` fails because it tries to update `product_b`, which this test overrode (so the record is rolled back, and trying to update it fails with a `MissingError`). The error is completely unforced as the test just wants to have two products in the DB with different taxes, we don't even need local variables. runbot-226343 Forward-Port-Of: odoo/odoo#220085
This fixes a timing issue where simultaneous system processes could overwrite each other's configuration changes. The update makes configuration changes more reliable, reducing the risk of lost settings during operations such as updates or checkouts.
Original PR description
In the following scenario, changes to the odoo.conf file could be lost: 1. A long-running process enters a `writable()` block (e.g. git checkout) 2. While it is still running, another process wants…
In the following scenario, changes to the odoo.conf file could be lost: 1. A long-running process enters a `writable()` block (e.g. git checkout) 2. While it is still running, another process wants to update the conf file but gets blocked waiting for `writable()`. However it has already loaded the entire `odoo.conf` file into memory ready to write it back. 3. The first long running process now makes a change to the `odoo.conf` file. In the case of the checkout process, it is changing the `server_wide_modules` key. 4. The first process finishes and releases the `writable()` lock. 5. The second process now writes to the conf file, however it is using the now-stale version it held in memory from step 2. 6. The original changes to the conf file are lost. The fundamental issue is that the `update_conf` function is loading the conf file into memory too early. To fix this, we aquire the `writable()` lock first, and then we can load the conf file knowing that it won't change until we are done. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220073 Forward-Port-Of: odoo/odoo#219928
Saving a blog post after removing all content now shows a clear validation message instead of triggering a backend error. This helps users understand that the content is empty and prevents noisy system errors during normal editing.
Original PR description
Currently an error occurs when we try to save a blog post with no content. Steps to replicate: - Install the `website_blog` module. - Navigate to the website, go to the Blogs section, and create a…
Currently an error occurs when we try to save a blog post with no content. Steps to replicate: - Install the `website_blog` module. - Navigate to the website, go to the Blogs section, and create a new blog. - Click to open the newly created blog. - Remove any existing content (e.g., placeholder text like 'Start Typing...'). - Type `/column` and click on the 2-column option. - Click on the columns that appear — you’ll see a delete icon. - Delete all the columns, click Save and check the terminal. Error: `ParserError: Document is empty` The error occurs when all content in the blog is deleted, resulting in empty HTML content. During saving, `html.fromstring(lang_value)` [1] is called with `lang_value` being effectively empty, which leads to a `ParserError`. [1] - https://github.com/odoo/odoo/blob/28c3b9cf10488536dce5a4927fdbe8fcd6e5a839/addons/web_editor/models/ir_ui_view.py#L126 This commit fixes the problem by catching the `ParserError` and raising a `ValidationError` when the HTML content is empty. sentry-5081806749 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#216790
Vietnam localization can now generate VietQR codes when the city field is empty but a valid state such as Ha Noi or Hai Phong is provided. This prevents unnecessary payment QR errors for businesses using Vietnamese bank details.
Original PR description
* Problem: Using Vietnam localisation, leave city empty and just input state_id as Hà Nội or Hải Phòng, try to use vietqr code -> Raise error missing city * Solution: Just like https://github.com/odoo/odoo/pull/218984 we should check for state too although according to VietQR document, merchant city is not required see (https://vietqr.net/portal-service/download/documents/QR_Format_T&C_v1.0_VN_092021.pdf and search for term 'Merchant City') 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#219873 Forward-Port-Of: odoo/odoo#219566
This fixes missing partner information on journal items created by the withholding tax on payment process. It helps accounting teams keep payment-related tax entries complete and easier to reconcile or audit.
Original PR description
Fixes an issue where the partner is missing from the journal items generated by the withholding tax on payment system. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218268
Fixed an issue where electronic invoice XML files generated from the send and print flow were not saved into Documents unless they were also sent by email. Businesses using Peppol and accounting document integration will now get the expected document record even when users only download the XML file.
Original PR description
Event with the document integration correctly setup, e-invoice xml generated in the send&print wizard will not create an associated document unless the attachment is actually sent via mail Steps to reproduce: - Have a EU Company setup - Enable and configure Peppol Electronic Invoicing - Enable documents integration with accounting - Create an invoice to a Peppol enabled customer, confirm - Open send&print wizard, enable only 'Download' and 'BIS Billing 3.0' Issue: Document related to the xml attachment is not created. This will work as expected when the message is sent to the customer It occurs because, in case of xml attachment, we don't create an associated document until some attachment have been registered on the move, effectively delaying document creation until the mail attachments are created opw-4720588 Forward-Port-Of: odoo/enterprise#90289 Forward-Port-Of: odoo/enterprise#88746
This fix ensures employee attendances that cross midnight are split into separate daily work entries. It prevents conflicting work entries when payroll or attendance records include overnight shifts, improving reliability for companies with night work schedules.
Original PR description
Steps to reproduce the issue: 0. Set work_entry_source to "attendance" on the running contract of the employee. 1. Create an attendance for yesterday 23:00:00 UTC to today 06:00:00 UTC. 2. Create an…
Steps to reproduce the issue: 0. Set work_entry_source to "attendance" on the running contract of the employee. 1. Create an attendance for yesterday 23:00:00 UTC to today 06:00:00 UTC. 2. Create an attendance today from 08:00:00 UTC to 16:00:00 UTC. Current behavior before PR: Odoo will create a conflicting work entry with the one created in step 1, because the logic recreates all work entries in a timeframe between the start date at 00:00:00 and end date at 23:59:59. The first entry started before this timeframe, so the recreated work entry does not align with the existing one, causing a conflict. Desired behavior after PR is merged: The work entries now span a single day at a time. If an attendance starts at night and ends the next morning, two entries will be created: one from the start time to end of day, and another from the start of the next day to the end time. opw-4869604 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#90588
This fix prevents an upsell order containing a non-recurring product from accidentally increasing the quantity on the original subscription. It helps keep subscription records and billing quantities accurate when customers modify upsell orders.
Original PR description
**Steps to reproduce:** - Install `sale_subscription` - Create a recurring product (P1) and a non-recurring product (P2) - Create a Sale Order (S1) with P1 (quantity > 0) and confirm it - Create an…
**Steps to reproduce:** - Install `sale_subscription` - Create a recurring product (P1) and a non-recurring product (P2) - Create a Sale Order (S1) with P1 (quantity > 0) and confirm it - Create an upsell of S1 (new child order S2) - In S2, edit the P1 line, and select P2 - Set quantity > 0 for P2 - Confirm S2 **Issue:** After confirming the upsell order (S2), the quantity of P1 on the original subscription (S1) is incorrectly increased by the quantity of P2 from S2. The _compute_parent_line_id method did not reset the parent_line_id when the product was not a subscription Product, which caused it to incorrectly update the subscription This issue is present in all three versions: **16.0, 17.0, and 18.0**. **Solution:** Reset parent_line_id to False if the product is not a subscription product to prevent incorrect subscription updates. [opw-4638955](https://www.odoo.com/odoo/project.task/project.task/4638955) Forward-Port-Of: odoo/enterprise#90848 Forward-Port-Of: odoo/enterprise#88282
Self-order kiosks can print receipts again through connected IoT devices. The fix adds the missing dependency and adjusts the connection method so kiosk orders work even without a standard user session.
Original PR description
The kiosk was updated to use iot http service to print receipt, but the dependancy was missing. This commit fixes the issue. We now override the iot http service to avoid using the orm as there is no session using self order, and use rpc calls instead.
AI prompt placeholders for fields and records now insert with cleaner formatting, making them easier to delete and edit around. The prompt widget also avoids unnecessary updates when content has not changed, improving reliability and reducing needless processing.
Original PR description
Purpose: -------- Currently records and fields inserted in AI prompts are badly formatted, making it sometimes impossible to delete an inserted field or to place the cursor after a field or a record. This commit fixes their format: For standalone fields, we do not insert divs inside a span anymore For grouped fields, the container is now a div instead of a t (which was set as inlined by the qweb plugin while the group shouldn't) For records, the container is now a span instead of a div, since we want the records to be inlined. Also, ai prompt widget now only calls onChange when the prompt content changed (to not make useless calls to it) Task-4780975 Forward-Port-Of: odoo/enterprise#90774
Fixed an issue in the Barcode app where scanning a destination package after picking products could incorrectly change the recorded source location of earlier product lines. This keeps warehouse transfer records accurate when products from multiple locations are packed into the same package.
Original PR description
Issue ===== When a package is scanned as the destination package, if a source location was previously scanned, the source location will be updated for every product who will be packed. How to…
Issue ===== When a package is scanned as the destination package, if a source location was previously scanned, the source location will be updated for every product who will be packed. How to reproduce ================ - Enable multi-locations and package; - Create an empty package, two locations and two products; - Create a delivery in the Barcode app; - Scan the first location then the first product; - Scan the second location then the second product; - Scan the empty package -> The package is rightly assigned as the result package for both lines, but the source location of the first product was update for the last scanned source location. Cause of the issue ================== When a source location was previously scanned, when a line is updated (`updateLine`), we update the line's source location. Usually, that's the wanted behavior but in this case, we don't want to the source location of already processed lines when we scan a destination package. Solution ======== When calling `updateLine` from `_assignEmptyPackage`, give a key in the parameters to not update the source location. [opw-4859851](https://www.odoo.com/odoo/project.task/4859851) Forward-Port-Of: odoo/enterprise#90280 Forward-Port-Of: odoo/enterprise#89142
This fixes a display issue where subscription product prices could appear twice on the shop page. Customers now see a cleaner, more accurate product listing, reducing confusion during browsing.
Original PR description
This PR fixes an issue where the product price was displayed twice on the `/shop` page of a product with a subscription type. task-4954676 Issue: <img width="618" height="271" alt="image" src="https://github.com/user-attachments/assets/e00adabf-ecfb-4424-8c2a-3b7413cbeee3" />
Odoo Sign now safely handles signature requests that are not in the shared state by leaving their sharing link empty. This prevents error messages when users inspect request data or when integrations retrieve signature requests.
Original PR description
### Issue Commit [58425a0](https://github.com/odoo/enterprise/commit/58425a0022c79f2c45f23fdd5a5476d8c20a887e) introduced a new field `share_link` in `sign.request` that gets computed for requests…
### Issue Commit [58425a0](https://github.com/odoo/enterprise/commit/58425a0022c79f2c45f23fdd5a5476d8c20a887e) introduced a new field `share_link` in `sign.request` that gets computed for requests that are in the 'shared' state. However this compute method fails for requests not in the 'shared' state leading to a traceback error. This commit fixes it by setting the default as False for the sign.request records that do not have state='shared' so the traceback error is handled. This can be reproduced in v17 and above by: 1. Open any sign.request record that isn't in the shared state 2. Enable Developer Mode 3. Using the debug icon, click on view record data The traceback will be visible here which mentions that the compute method failed to assign It can also be re-produced by using an xml-rpc / json-rpc ORM call to search_read the sign.request records that does not have state = 'shared' ### Before https://github.com/user-attachments/assets/24c07f2a-2398-44b4-8969-30abb576876a ### After https://github.com/user-attachments/assets/e92b1212-5405-4b98-ba41-c81b2ac547d7 [opw-4864159](https://www.odoo.com/odoo/project/49/tasks/4864159) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#90576
Ecuador electronic invoice processing now handles empty responses from the tax authority without crashing. This helps businesses continue processing invoices more reliably when the external service returns an unexpected or blank reply.
Original PR description
The system will crash when we receive nothing in `response` and also tryig to retrieve values from response. **Error:-** `TypeError: 'NoneType' object is not subscriptable` **Root Cause:-** - While…
The system will crash when we receive nothing in `response` and also tryig to retrieve values from response. **Error:-** `TypeError: 'NoneType' object is not subscriptable` **Root Cause:-** - While we are in `EC Company`. - When we click `Process Now` on the invoice. It will call `button_process_edi_web_services` method. And while in execution when at [1], `move.company_id._l10n_ec_is_demo_environment()` is `False`, then it calls `_l10n_ec_send_document` method. - While submitting electronic invoices to SRI, the method `_l10n_ec_get_client_service_response_new()` sometimes returns `None` . - It may also lack expected keys like 'estado' or 'comprobantes', depending on SRI’s behavior. [1] https://github.com/odoo/enterprise/blob/ce9eed675db4de3bcd1b283688c5c44d2e1ecf12/l10n_ec_edi/models/account_edi_format.py#L425-L428 **Solution:-** - Wrapped the access to response and its keys inside a `try...except` block that catches:- - `TypeError`: for cases where the response is `None`. **Sentry - 6708486009, 6728767866** Forward-Port-Of: odoo/enterprise#88611
Membership purchases now apply the correct member level, pricelist, and commission benefits across parent and child partner records. This prevents child contacts from incorrectly keeping benefits after a parent loses membership, while ensuring parent purchases still extend the right benefits to children.
Original PR description
Corrects the behaviour of the member level assignment in membership when childs partners are concerned. A partner buying a membership should forward the membership level and Pricelist to its children. A child buying a membership should get that membership without forwarding it to its parent. When removed, children should not keep the membership if the parent lose it. TASK-4801759 Forward-Port-Of: odoo/enterprise#86776
AI-related action buttons now appear only on AI-generated messages, not on a user's own messages. This prevents confusion in chat workflows and also fixes related display issues, including copy button placement and unnecessary out-of-office alerts in AI conversations.
Original PR description
Before this commit, ai actions like "insert", "send message" and "log note" were appearing on both the messages sent by the AI and the user's own messages. Of course, the actions shouldn't appear in the user's messages. To fix this, we changed one element in the conditions for these actions. Prior we were fetching the user_id from the author of the message and comparing it with the current user. Recent changes make it impossible to fetch the user_id like so. Now we use the function isSelfAuthored which would return false for AI messages and true for the user's own messages.
Fixed an issue where loans could fail when being cancelled, reset to draft, and confirmed again while Accounting Audit Trail was enabled. This helps users manage loan lifecycles reliably even when historical posted entries must be preserved for compliance.
Original PR description
Steps: - Activate Audit Trail in Accounting configuration - Create and confirm a loan, having some moves posted in the past - Cancel it, reset it to draft the re-confirm it again -> ValueError: Expected singleton This is because posted moves can not be unlinked when canceling/closing the loan if audit trail is activated. Therefore we try to access the `state` field from a recordset instead of a singleton. With this commit, we filter the generated move to get the newly created one. opw-4834361 Forward-Port-Of: odoo/enterprise#90578 Forward-Port-Of: odoo/enterprise#88286
This fix prevents access errors when users open AI-related views that display tools. It matters because non-system users can use the relevant screens without being blocked by unnecessary permission checks.
Original PR description
The changes are proposed because only systems users have read access to the ai.tool model. Runbot error: 182051
This update fixes an automated test for Mexican point-of-sale invoicing so it matches the expected invoice XML structure. It ignores a variable identifier that is not important to the business scenario, helping prevent false build failures.
Original PR description
Fix the test file for pos order then invoice request to match the expected XML structure, by ignoring the `UUID` attribute in the `TimbreFiscalDigital` element because it is not relevant for the test and can cause issues with the test validation. build_error https://runbot.odoo.com/runbot/build/83409879 Forward-Port-Of: odoo/enterprise#88756
Point of Sale users are now prevented from validating a customer deposit with a zero amount. Instead of an error screen, the system displays a clear warning, helping cashiers avoid disruption during checkout.
Original PR description
Steps to reproduce: =================== - From the POS UI, select a customer - Select Deposit Money - Try to deposit `0` amount by clicking Validate button Issue: ====== A traceback is raised when attempting to validate a deposit with zero amount. Cause: ====== The system does not check for zero-amount orders when creating a deposit payment line. Fix: ==== Add a dialog warning when the deposit amount is zero to prevent further processing. Task: 4862811 Forward-Port-Of: odoo/enterprise#90739 Forward-Port-Of: odoo/enterprise#87709
Employees without expense management rights can now submit expenses created from OCR uploads without running into an access rights error. This keeps receipt-to-expense processing working smoothly for standard users and avoids failed submissions caused by an internal status update order.
Original PR description
How to reproduce the issue: - Upload a pdf via the OCR with a user without expense right. On submitting the expense, an access rights error on the write is thrown. When the expense is created by OCR, on submit, we pass through the action_submit method in hr_expense_extract, which performs validate_ocr, and writes on the expense's extract_state field after the super().action_submit call, which changes the state of the expense from draft to submitted. However, the rule ir_rule_hr_expense_employee_not_draft forbids modifying the expense if it is not in draft state. opw-4855000 Forward-Port-Of: odoo/enterprise#90616
Internal users can now create or update Colombian contacts with a NIT tax ID without seeing an access denied message. The system can perform the required DIAN certificate check in the background, reducing disruption for everyday contact management.
Original PR description
When entering a Colombian Tax ID (NIT), the onchange checks `company.l10n_co_dian_certificate_ids`, which reads `certificate.certificate` records , resulting in an “Access Denied” popup. This changes Wrap the certificate lookup in `company.sudo()` so that the NIT VAT‐onchange can fetch the DIAN certificate records. Steps to Reproduce: 1. Install the l10n_co_dian module and switch to CO company 2. Create a user with only the “Internal User” (base.group_user) group—do not grant Administration/Settings. 3. Log in as that non-admin user. 4. Go to Contacts -> Create. 5. Set Country = Colombia and Identification Type = NIT. 6. Enter any VAT (NIT) number and leave the field. 7. “Access Denied” error for certificate.certificate. opw-4936604 Forward-Port-Of: odoo/enterprise#90176
Sharing a folder shortcut from the breadcrumb menu no longer causes a server error. This keeps document sharing reliable for users working with shortcut folders.
Original PR description
Reproduce: 1/ Create a shortcut of a folder 2/ Select it in the search panel 3/ Opening "Share" via the breadcrumb's cog menu triggers a server error. In d3e6a8df, we incorrectly changed this one2many reference from `[0]` to `.id`. Task-4762955
The Swedish SIE4 import now reads files using UTF-8 encoding instead of ISO-8859-1. This helps customer accounting files import correctly when they contain Swedish characters, reducing manual corrections and failed imports.
Original PR description
The aim of this commit is using UTF8 instead of ISO-8859-1 for the file decoding. We received feedback from customers that the previous decoding wasn't handle correctly swedish characters. The documentation tends to say that we should follow CP437. As UTF8 is a superset of CP437, we are now using it. opw-4868415 Forward-Port-Of: odoo/enterprise#90498
Batch payments can now correctly handle exchange rate differences when reconciling bank statement lines. This prevents incorrect suspense entries with zero foreign-currency amounts, improving accounting accuracy for multi-currency payments.
Original PR description
This commit will add the possibility to have exchange diff on batch payment. That was a problem that cause the move of the bank statement line to have a suspense with an amount currency at zero. task-4921741 Forward-Port-Of: odoo/enterprise#89717
The Czech VAT Control Statement XML export now uses the official field name for B2 transaction dates. This prevents the Czech tax portal from treating the date as blank when businesses upload the report.
Original PR description
**Steps to reproduce**: 1. Install `l10n_cz` and `l10n_cz_reports_2025`. 2. Create a vendor bill with a vendor whose place of supply is in-country, set the bill amount to more than 10,000, and…
**Steps to reproduce**: 1. Install `l10n_cz` and `l10n_cz_reports_2025`. 2. Create a vendor bill with a vendor whose place of supply is in-country, set the bill amount to more than 10,000, and confirm the bill. 3. Go to Reporting → Tax Return → VAT Control Statement (CZ). 4. You will see the bill listed under section B2. Now export the XML. 5. In the exported XML, the field `dan_dppd` is present. **Observations**: When exporting XML from the VAT Control Statement report, the date field in the B2 section is incorrectly named `dan_dppd`. According to the official CZ VAT Control Report documentation ([link](https://adisspr.mfcr.cz/dpr/adis/idpr_pub/epo2_info/popis_struktury_detail.faces?zkratka=DPHKH1#110009830_dppd)), As a result, when importing the generated XML into the CZ portal, the field appears blank because it is not recognized. **Issue**: The export template uses the incorrect tag `dan_dppd` instead of the correct `dppd` for the B2 section. **Solution**: The export template was updated to use `dppd` instead of `dan_dppd` in the B2 section, as per the official documentation. opw-4868515 Forward-Port-Of: odoo/enterprise#90394
Manual discounts now carry over when optional products are added to subscription order lines. This prevents user-entered pricing adjustments from being unintentionally replaced by automatic pricelist calculations.
Original PR description
**Current Behavior:** Manual discounts are not retained when adding optional products to the order. **Steps to Reproduce:** 1) Install the sale_subscription module. 2) Create a subscription with a…
**Current Behavior:** Manual discounts are not retained when adding optional products to the order. **Steps to Reproduce:** 1) Install the sale_subscription module. 2) Create a subscription with a recurring plan. 3) Add a product to the Optional Products section. 4) Manually set a discount on the optional product. 5) Click on the Add to Order Lines (cart) button. 6) A new SOL is created. **Issue:** The newly created SOL does not retain the manually set discount. **Cause:** - When the user clicks the Add to Order Lines button, the `add_option_to_order` method is triggered. This method creates a new sale order line (SOL) using values from `_get_values_to_add_to_order`. - In the current implementation, this method is overridden for subscription orders to exclude the discount value from the returned data. https://github.com/odoo/enterprise/blob/42d829ea6e6a98f251cfffc8fb67b5320a5ada12/sale_subscription/models/sale_order_option.py#L17-L21 - This forces a recomputation of the discount based on pricelist rules, which unintentionally removes any manually set discount. **Solution:** - Only remove the discount value from the returned data and trigger recomputation if there is no manual discount. - This ensures that any user-defined discount is preserved when creating the order line. opw-4840735 Forward-Port-Of: odoo/enterprise#90423 Forward-Port-Of: odoo/enterprise#89381