Thursday, July 24, 2025
39 changes · saas-18.4
New functionality added to Odoo
Oman companies can now access the tax returns workflow from the Tax Report. This adds the missing setup needed to show the Returns button and generate the tax closing form.
Original PR description
#### Issue: This commit adds a missing account.return.type data in the Oman localization. This is related to the new Accounting Returns #81569 The l10n_om module did not include an…
#### Issue: This commit adds a missing account.return.type data in the Oman localization. This is related to the new Accounting Returns #81569 The l10n_om module did not include an account.return.type record, which prevents the "Returns" button (linked to the action_open_returns) from appearing in the Tax Report. As a result, users in Oman are unable to access the Tax Closing form. Also the l10n_om is a community module, because of that, we need to add a new enterprise module to add the related data for the tax returns. The visibility of the button is controlled by the following condition: [Code](https://github.com/odoo/enterprise/blob/f924f120cbd04002e21c78b081e1c8006b56a4b6/account_reports/models/account_report.py#L1776) #### Affected Versions: 18.3 and later #### Steps to reproduce: 1.Install the l10n_om module 2.Switch to the Oman company 3.Go to Accounting > Reporting > Tax Report 4.The "Returns" button is not visible #### Expected behavior The "Returns" button should be visible, allowing the user to generate the closing tax form. #### Current behavior The button is hidden due to missing account.return.type data in the Oman localization. OPW-4943024 Forward-Port-Of: odoo/enterprise#90814
Enhancements to existing features
The IoT homepage now shows how long the Odoo service has been running, and on supported systems it also shows the operating system uptime. This makes it easier for support teams and users to assess device stability without needing remote command-line access.
Original PR description
Before this commit, the only way to check how long the IoT box had been running was to SSH into it and run a command. After this commit, the uptime of both the Odoo service and the OS is available in the homepage. On Windows only the Odoo service time is shown. task-4954737 <img width="651" height="600" alt="image" src="https://github.com/user-attachments/assets/f3144545-0696-4dd9-937b-0e82e196def3" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
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 update helps Turkish e-invoices meet GİB requirements by using the customer reference field as the registered tax office name in Nilvera submissions. Users are warned, and then blocked where required, if an e-invoice customer is missing this information before sending an invoice.
Original PR description
### Description of the issue/feature this PR addresses This PR adds a validation to ensure that E-Invoice partners in Turkey have the `reference` field filled with their registered tax office name,…
### Description of the issue/feature this PR addresses This PR adds a validation to ensure that E-Invoice partners in Turkey have the `reference` field filled with their registered tax office name, as required by GİB regulations. ### Current behavior before PR Partners marked as E-Invoice customers can be used in invoicing without a value in the `reference` field, which may lead to non-compliant UBL documents. ### Desired behavior after PR is merged Once the reference field is filled, it is sent via the UBL, as it is passed to tax_scheme_vals. The account move send wizard issues a critical warning for partners that should have the tax office name in the reference field. If this warning is ignored and the customer on the invoice has a TR e-invoicing status of Nilvera, a validation error is raised, prompting the user to complete the required reference field on the customer. Task-4886128 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217582 Forward-Port-Of: odoo/odoo#215772
Employee record access has been clarified so regular users see public employee information, HR officers can view employee records without payroll details, and HR administrators keep access to payroll and configuration options. This helps ensure sensitive payroll information is only available to the appropriate HR administrators.
Original PR description
Employee : No right : You see employee public Officer : You see hr.employee for everyone but no payroll tab Admin : You see hr.employee for everyone + payroll tab + configuration menu Task: 4900703 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Peppol document retrieval now handles large invoice volumes in smaller batches to avoid scheduled jobs timing out. This improves reliability for businesses with high transaction volumes by ensuring document processing can continue automatically when more work remains.
Original PR description
For database with big invoice volume, it is necessary to be able to retrieve documents in smaller batches otherwise crons will timeout due to the 15 minutes limit. Add a retrigger mechanic to the possibly heavy crons. opw-4925532 Forward-Port-Of: odoo/odoo#220001 Forward-Port-Of: odoo/odoo#218383
This update improves how the color picker and related popovers behave in the Odoo editor. It should make choosing and applying colors more reliable for users building or customizing pages.
This update makes the IoT Box image easier to troubleshoot and recover by improving access to system logs and restoring default Raspberry Pi sudo behavior. It also fixes startup update commands and increases default logging detail so issues are easier to diagnose.
Original PR description
This commit contains the following small changes: - No longer require a sudo password for pi user (reverting to default Raspberry Pi OS behaviour). This is because if Odoo couldn't start there was no way to fix it if you didn't have the current password. - Expose /var/log/ folder instead of just /var/log/odoo via nginx. This is useful because then we can see e.g. the nginx access logs. - Fix rc.local git checkout on reboot. This wasn't working because the commands were not being run as the odoo user. - Use INFO log level by default instead of WARNING. task-4954737 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220164
The Oman localization now separates supplier invoice base amounts from customs VAT for import taxes. This helps businesses record import VAT more accurately and align tax reporting with Oman VAT treatment.
Original PR description
To align with Omanian VAT treatment of imports, split the 5% EX tax into two: - "5% EX ONLY B" captures supplier invoice base (0% tax, affects base only). - New "5% EX ONLY" captures customs VAT (100% tax incl., with VAT Input account). Also removed VAT Input account & tax grids "+6b_T" from "5% EX ONLY B". task-id: 4909498 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217193
Payroll access rules were adjusted so employees without payroll rights no longer see the Payroll app, payroll officers can access employee payroll information, and payroll administrators can manage payroll configuration. This clarifies responsibilities and helps ensure sensitive payroll areas are shown only to the appropriate roles.
Original PR description
Payroll No right : You don't see payroll app Officer : Employee officer + payroll tab Admin : Employee admin + payroll app config. Task: 4900703
Website administrators can now open the website generator directly from the website settings. This makes importing or generating a website available as a standard settings action, instead of only during onboarding.
Original PR description
Added a button in the website settings that redirects to the website generator configurator. The goal is to have a standard way to import a website without necessarily it being part of the onboarding flow. closes odoo/enterprise#88334
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#215213Reloading 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.
IoT 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 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
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 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
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
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
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
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