Daily updates from Odoo
Thursday, October 23, 2025
205 changes
27 changes
New functionality added to Odoo
Users can now upload e-Receipt XML files exported from the Nilvera Portal directly from the Receipts list. Odoo creates draft receipts from the uploaded files and opens the resulting records, reducing manual data entry for Turkish e-dispatch workflows.
Original PR description
This PR introduces a new option to import e-Receipt XML files exported from the Nilvera Portal. - An "Upload e-Receipt (XML)" button is now added in the list view of Receipts (stock picking). - Upon upload, draft receipts are created based on the XML data. - After successful import, the user is redirected to a new view displaying the generated receipts. TaskID:4452521 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231845 Forward-Port-Of: odoo/odoo#217530
Enhancements to existing features
This update improves performance when Odoo connects sales orders with related projects. It helps avoid slow database scans in cases with many projects, making affected sales order pages or processes respond more efficiently.
Original PR description
This commit adds an index on `project.project. reinvoiced_sale_order_id`, because the search in `sale.order. _compute_project_ids` might not be selective enough based on `sale_order_id`, which is a related field using `sale_line_id`. Since it's related, there is only a where clause on `sale_line_id IS NOT NULL`, which might not be selective enough and leads to a Seq. Scan of the `project_project` table. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232623
The web development tooling now includes VoIP-related modules in its linting checks. This helps catch code quality issues earlier for those areas, reducing maintenance risk without changing user-facing behavior.
Original PR description
Forward-Port-Of: odoo/odoo#232559 Forward-Port-Of: odoo/odoo#232484
Resolved issues and error corrections
When an applicant is refused and a refusal email is sent, the email is now also recorded in the application's chatter. This gives recruiters a clearer communication history and helps teams confirm what was sent to candidates.
Original PR description
To reproduce: ============= refuse an application with `send_email` checked, the email is sent but not logged in the chatter Solution: ========= Add a `message_post` in the `_prepare_send_refusal_mails` method opw-5137342 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Vendor credit note DTE files in Chilean localization now import as credit notes instead of being incorrectly treated as invoices. This prevents import errors and helps accounting teams process supplier credit notes through drag-and-drop as expected.
Original PR description
### Steps to reproduce Go to Accounting -> Vendor Bills Attempt to import a valid vendor credit note by dragging-dropping the DTE file in the list view. Notice how the vendor credit note gets created with an error: ``` Error importing attachment 'DTE.xml' (type=l10n_cl.dte): This specific error occurred during the import: You can not use a credit_note document type with a invoice ``` ### Analysis `_l10n_cl_import_dte` should set the move type to credit note when the document type code is '61', but does not. This was broken by 42744fcecdbd36e See https://github.com/odoo/enterprise/commit/42744fcecdbd36ea0101070c68299227a9f204a6#diff-044bc1ef3ea4878783a064258b4436b44b3064c5196c22d0d104daee8fde4501L294 ### Solution Correctly set move_type to `in_refund` if the document type code is '61' Linked issue https://github.com/odoo/odoo/issues/232348 task-none
Accounting users can now create SEPA Direct Debit mandates without encountering an access error. This ensures authorized invoicing and banking staff can complete direct debit setup without needing administrator rights.
Original PR description
Have the Payment Provider Sepa Direct Debit module installed. Connect with a user with access right for Accounting: Invoicing & Banks. Create a Direct Debit Mandate => Get an access error. Reason: the compute does a read_group with a value on payment.provider, which non System Admin have no access to. Solution: Add a sudo for these _read_group Forward-Port-Of: odoo/enterprise#97127
Public website customers could get stuck after paying for an online order when accounting journal restrictions were enabled. The fix ensures payment confirmation can complete correctly without triggering an internal access error, improving checkout reliability.
Original PR description
Error in backend while public user payment confirmation Steps: - Install `website_sale` - Activate `restrict_mode_hash_table` on sale journal - From an incognito window, Make an order in ecommerce and pay it -> we get stucked on 'Your payment has been successfully processed' page because of an acces error in the backend This is because when posting a new move, we either to access or modify moves we get from `chain['moves']`, however these moves are returned with `sudo(False)` by `AccountMove._get_chain_info()`. opw-5128189 Forward-Port-Of: odoo/odoo#232143
Event registration pages now translate the date selection labels when visitors use another language. This improves the multilingual registration experience by showing consistent localized wording for event slots.
Original PR description
Scenario: - adds slots to an event - register to that event with another language Result: "Selected Date" or "Select a Date" is not translated or translatable. Fix: wrap those JS strings with _t function. opw-5167911 Forward-Port-Of: odoo/odoo#231729
Manufacturing users can now open the work-in-progress accounting wizard even when a work order is still running. The fix prevents an error caused by unfinished work orders that do not yet have an end time, reducing disruption during production cost tracking.
Original PR description
#### Issue: - Traceback when calculating the cost of a workorder #### Step to reproduce: - with apps: mrp, accountant - create a MO for a product - add a WO - confirm - start the WO - Action > "Post…
#### Issue: - Traceback when calculating the cost of a workorder #### Step to reproduce: - with apps: mrp, accountant - create a MO for a product - add a WO - confirm - start the WO - Action > "Post WIP Accounting entry" #### Current Behavior: - get a traceback #### Expected behaviour - open the WIP wizard #### Cause of the issue: - to calculate the cost of production, wizard use all WO including the one still running. However as it is still running its end date is registered as `False`. It raises a traceback when it compares the end of the WO with a limit date because `bool` and `datetime.datetime` are not compatible for '<'. #### Solution: - check if the end date of the WO is defined In module mrp_workorder an override of [button_start](https://github.com/odoo/enterprise/blob/18.0/mrp_workorder/models/mrp_workorder.py#L284-L295) change how work order are launched. Therefore, the test should be launched on an Enterprise run. opw-4961873 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221938
This fix prevents an error when posting work-in-progress accounting entries for a manufacturing work order that is still in progress. Users can now open the WIP wizard as expected, reducing disruption during manufacturing and accounting workflows.
Original PR description
Issue: - Traceback when calculating the cost of a workorder Step to reproduce: - with apps: mrp, accountant - create a MO for a product - add a WO - confirm - start the WO - Action > "Post WIP Accounting entry" Current Behavior: - get a traceback Expected behaviour - open the WIP wizard Cause of the issue: - to calculate the cost of production, wizard use all WO including the one still running. However as it is still running its end date is registered as `False`. It raises a traceback when it compares the end of the WO with a limit date because `bool` and `datetime.datetime` are not compatible for '<'. Solution: - check if the end date of the WO is defined Test: - in module mrp_workorder an override of button_start change how work order are launched. Therefore, the test should be launched on an Enterprise run. opw-4961873 Forward-Port-Of: odoo/enterprise#97558 Forward-Port-Of: odoo/enterprise#93812
Large PNG images uploaded to Odoo are now resized without being converted to a lower-quality web palette. This prevents visible image degradation on website content and removes the need for users to manually resize images before upload.
Original PR description
When uploading a png image ir_attachment, the image is not modified if its resolution is under the maximum 1920x1920. However, if the resolution is bigger, it both gets resized and is converted to a WEB palette, which visibly degrades the quality of the image. A workaround for this is to resize the image locally to be max 1920 on either dimensions and then upload it, which effectively bypasses this special treatment. Steps to reproduce: - Go to the website app - Add a Text - Image snippet - Double click the image - Upload a .png image of a resolution strictly greater than 1920 in either width or height Old behavior: the png is visibly degraded New behavior: the png is not visibly degraded opw-3935533 Forward-Port-Of: odoo/odoo#173508
The fix restores the speed slider for animated background shapes in the website editor. Users can now adjust animation speed as expected, improving editing accuracy for page designs.
Original PR description
Steps to reproduce: - Drop a snippet - Add a background shape (e.g. Rainy 05) - Use the slider to change the speed - Nothing happens This commit is adapting `CSS_ANIMATION_RULE_REGEX` as it was too restrictive, the space after the colon is now optional. task-5170549 Forward-Port-Of: odoo/odoo#231747
This fixes a missing hours field when planning service work from a sales order. Users can now enter allocated hours in the planning dialog when the usual start time field is hidden, helping schedules capture the required effort correctly.
Original PR description
Steps to reproduce: - Create a Sales order with planning services. - Click on To Plan stat button. - Click on empty cell Issue: - Plan dialog is opened but has missing allocated_hours field. Reason: - In this commit https://github.com/odoo/enterprise/commit/d21bd4b694ec63ba83bea077714a8fe928d6e014 allocated hours was merged with start_datetime using a widget and thus removed from view. - But in planning list view we hide start_datetime when we schedule shifts from sales order. Fix: - Add back allocated_hours conditionally to be visible when we schedule shifts as in other cases start_datetime is present. task-5117776 Forward-Port-Of: odoo/enterprise#96391
Website form editors can no longer delete the final option from a multiple-checkbox field. This prevents forms from getting stuck in a state where users cannot add options back, improving reliability when configuring website forms.
Original PR description
Since `html_builder`, the last element of a multiple checkboxes form field can be removed, but it leads to a situation where no element can be added anymore to the field. To avoid this, this commit restores the former behavior which did forbid the removal of the last element. Steps to reproduce: - Drop a form snippet - Add a field - Set the field type to "Multiple checkboxes" - Remove all options => It was possible to remove the last option. task-4367641
The website donation form now waits for required currency information before processing a donation click. This prevents rare crashes or failed submissions on slow networks and reduces accidental double-click issues by showing a loading state.
Original PR description
This fixes a very rare race condition in the `test_01_donation` tour... but it is actually surprising it is not more frequent than it is. Steps to reproduce: - Simulate a slow network (e.g. using…
This fixes a very rare race condition in the `test_01_donation` tour... but it is actually surprising it is not more frequent than it is. Steps to reproduce: - Simulate a slow network (e.g. using Chrome DevTools) - Load a page with a donation snippet - Quickly fill in the donation form and click the submit button => You'll sometimes get a crash. Or a more precise one: - Add a 1 minute delay to the `/website/get_current_currency` route - Load a page with a donation snippet - Fill in the donation form and click the submit button once the page is fully loaded. => You'll definitely get a crash. This commit makes that button's handler async-protected, meaning it will now properly wait for what is needed (the currency) before proceeding, but it will also display a loading effect for the duration and prevent double clicking. Once the form is submitted, the loading effect is removed for stability safety. In master it can probably be improved. runbot-220885 Forward-Port-Of: odoo/odoo#232585 Forward-Port-Of: odoo/odoo#232408
Website pages in right-to-left languages now load dynamically requested styling using the visitor's website language instead of the session language. This prevents excessive horizontal whitespace on portal pages with chatter, improving usability for Arabic and other RTL-language users.
Original PR description
Scenario to reproduce from 18.0: - install right-to-left (eg. arabic) language on website - open a portal record with chatter (eg. /my/invoices/1) - switch to right-to-left language - scroll…
Scenario to reproduce from 18.0: - install right-to-left (eg. arabic) language on website - open a portal record with chatter (eg. /my/invoices/1) - switch to right-to-left language - scroll horizontally to the left Result: there is a huge amount of whitespace scrollable to the left. Cause: In 18.0, the chatter has an hidden textarea .o-mail-Composer-fake with position "left: -10000px; top: -10000px;". But the chatter assets (portal.assets_chatter_style) are called dynamically with getBundle which is using the session lang instead of the website lang. So the bundle is gotten with the wrong lang and the CSS is not rtlcss'ed and this create big whitespace to the left of the page. Fix: set the website request language when getting bundle for the frontend. Note: this PR also create a TestLangUrlCommon to prevent TestLangUrl tests of being run a second time in TestControllerRedirect. opw-5013485 Forward-Port-Of: odoo/odoo#232671 Forward-Port-Of: odoo/odoo#223575
This fix corrects how VoIP contact search combines phone keypad-style search terms with other filters. Users should see more accurate contact results instead of searches returning few or no matches.
Original PR description
t9_search should be ORed to the subdomain, which in turn should be ANDed to the domain. Currently, both the subdomain and the t9_search are ANDed to the domain, resulting in a "subdomain AND t9_search" condition, which is not correct and unlikely to match anything. Forward-Port-Of: odoo/enterprise#97731
Helpdesk users can now add the SLA status grouping back in the SLA reporting view after removing it. This avoids needing to reload the report and makes SLA analysis smoother and less disruptive.
Original PR description
Currently, when the user opens the sla reporting view, if he removes the default grouping of sla_status, he has no way to get it back unless he reloads the view completly. This commit fixes this issue by adding the sla_status field to the group_by options. task-5076401 Forward-Port-Of: odoo/enterprise#95261
The offer signature shortcut now works correctly when an employee has signed the same offer more than once. HR users are shown all related signature requests instead of being blocked or taken to an incorrect single request, making follow-up smoother.
Original PR description
Steps to reproduce: - Go to an employee and create an offer - Sign the offer with the employee twice - Log as the HR responsible and use the "Requested signature" smartbutton on the offer This has been fixed by opening a kanban view of all sign requests, if multiple. task-5053624
Subscription orders using external tax calculators now keep the correct recurring total instead of being recalculated with standard tax rules. This prevents customers and staff from seeing incorrect recurring amounts when taxes are supplied by an external service.
Original PR description
sale_subscription now uses `account.tax` to recalculate the tax amounts [1], thus bypassing amounts set by external calculators. For externally calculated orders, we override the recurring_total calculation to restore the previous behavior of calculating the amount using `price_subtotal` on the lines. This field will contain the amount returned by the external calculator. [1] https://github.com/odoo/enterprise/commit/70376f94e9f26e631890312edc0857d9ff37dc7b opw-4964610 Forward-Port-Of: odoo/enterprise#93567 Forward-Port-Of: odoo/enterprise#93054
The table selection popup in POS self-order now lists tables consistently by floor and table number. This makes it easier for customers or staff to find the right table and reduces confusion during ordering.
Original PR description
Task [#4991803](https://www.odoo.com/odoo/my-tasks/4991803) Runbot: https://runbot.odoo.com/runbot/bundle/18-0-incremental-order-table-pop-pos-self-order-ltra-391429 --- When selecting a table in the POS self-order, we sort the tables by `floor_id` and then by `table_number` in ascending order. This ensures a consistent and user-friendly experience when choosing a table. Forward-Port-Of: odoo/odoo#222811 Forward-Port-Of: odoo/odoo#222421
Invoices grouped by Sent or Not Sent now show only the matching records instead of duplicating all invoices in both groups. This makes invoice lists more reliable for accounting teams when tracking whether customer invoices have been sent.
Original PR description
### Issue: The groups "Sent" and "Not Sent" display all the invoices. ### Steps to reproduce: - Go in Accounting > Customer > Invoices - Create a custom GroupBy with "Sent" - Unfold the groups: all invoices appear in each group ### Cause: `web_read_group` returns the groups with their length and the domain corresponding. When unfolding `web_search_read` uses the given domain to get the records to display. Here the issue comes from the domain returned, it contains `['move_sent_values', '=', 'sent']`, but `move_sent_values` is a computed field that doesn't have a `_search` method so the domain doesn't filter on this field. ### Solution: Add the method `_search_move_sent_values` to search on `is_move_sent`. opw-5164650 Forward-Port-Of: odoo/odoo#232400
The scheduled check for Mexican electronic invoice status now rotates through records instead of repeatedly checking the same first batch. This helps ensure all imported posted invoices are monitored for possible SAT cancellations or status changes.
Original PR description
Currently one of the domains returned by the method `_get_update_sat_status_domains` is `[('state', '=', 'invoice_received'), ('move_id.state', '=', 'posted')]`. This domain is used to always return…
Currently one of the domains returned by the method `_get_update_sat_status_domains` is `[('state', '=', 'invoice_received'), ('move_id.state', '=', 'posted')]`. This domain is used to always return l10n_mx_edi_documents that have been imported from somewhere and whose invoice has been posted. This is because Odoo needs to always checked the value of the originator of an EDI document, in case it has been cancelled from the SAT Portal for instance.
Both `state = 'invoice_received'` and `'move_id.state = 'posted'` are mostly fixed value. The state needs to stay `invoice_received` as Odoo needs to always check the originator document's value. And once an invoice is posted, it's stays as so except in the case of cancellation.
This leads to an issue when the database contains more than 100 documents that are both `invoice_received` and `move_id.state = 'posted'`. In this case, the cron `_fetch_and_update_sat_status` will always process the same 100 documents. Once the limit of 100 is reached, the cron retriggers itself before terminating. Then on the next execution, the search call with the domain coming from `_get_update_sat_status_domain` will return the same 100 documents again.
This commit fixes this issue by ordering the documents in the cron method by `write_date asc`. Even if the SAT value of the documents does not change, the `write_date` should be updated as their is still a write that is triggered via `_update_document_sat_state`. This prevents the cron from always processing the same documents over and over again.
Forward-Port-Of: odoo/enterprise#93205Website form fields that are still in use can no longer be deleted accidentally. This prevents crashes when editing forms and guides users to remove the field from the form before deleting it.
Original PR description
The system crashes when a user tries to edit a website form field and that field has already been deleted from the model. **Steps to produce:-** - Install the `website` module. - Create a `new custom…
The system crashes when a user tries to edit a website form field and that field has already been deleted from the model. **Steps to produce:-** - Install the `website` module. - Create a `new custom field` on a model(for example, a field on the `mail.mail` model). - Website > edit > `add Form` widget to a page, and configure it to use the `mail.mail` model. - Add the newly created custom field to the form and save the page. - Now, `delete` the custom field which is created previously. - Return to the website page > edit > mark the deleted field as required, and attempt to save the changes. **Error:-** `ValueError: Unable to whitelist field(s) [''] for model 'mail.mail'.` **Root cause:-** - At [1], we can see that in the current version, it `only logs an error` using the logger, but in later versions, it `raises a ValueError` instead. **Solution:-** - This fix prevents a field from being deleted if it is actively used in any website form. - It adds a validation check that blocks the deletion and raises an error, forcing the user to remove the field from the form first. [1]: https://github.com/odoo/odoo/blob/d4f424d731fa93ccd232d0def0a7612997345ef7/addons/website/models/website_form.py#L123-L126 **sentry-5689731444** I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232415 Forward-Port-Of: odoo/odoo#219590
This fixes an issue where only one shipping label printed when several label files were attached to a delivery record. Businesses using connected delivery printers can now print all expected labels at once, reducing manual reprints and shipping delays.
Original PR description
Before this commit, only 1 label get printed even if multiple files are in the chatter After this commit we handle the cases with multiple files + revert suppression of public method for API opw-5181209 Forward-Port-Of: odoo/enterprise#97843 Forward-Port-Of: odoo/enterprise#97805
This fix prevents crashes when users rapidly drag and drop cards in large grouped Kanban views, especially while the page is still updating. It makes the experience more reliable for teams working with many records and columns by safely cancelling actions when the view and data are temporarily out of sync.
Original PR description
On a grouped kanban view displaying a lot of records (i.e. with a lot of columns and a lot of records by column), drag and drop several records from the same column quick multiple times. Before this…
On a grouped kanban view displaying a lot of records (i.e. with a lot of columns and a lot of records by column), drag and drop several records from the same column quick multiple times. Before this commit, different crashes could occur. The first category of crashes concern the sortable hook. It called the onDrop callback even if the dragged element was no longer in the DOM (which occurs if there's a re-rendering while the user is dragging). This has been fixed in the hook, and tested. Another crash could arise in kanban (in the model). If the user dropped the card while there was a scheduled/ongoing re-rendering, i.e. at a specific moment where the model isn't synchronized with the DOM, the dropped card was still in the DOM, but it's associated datapoint was no longer referenced in hte model. In that case, we can do nothing but cancel the d&d. Note that this couldn't be tested, as reproducing the exact behavior (typically having a slow rendering due to the number of cards to render) isn't possible in a unit test, where user interactions are done programmatically. Task~5167650 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#231886
Products assigned to allowed subcategories now appear correctly in mobile self-order sessions. This prevents customers from missing available items when businesses organize menus with nested product categories, aligning mobile behavior with PoS and kiosk ordering.
Original PR description
**Steps to reproduce:** - Make a sub category, such as Soda for Drinks in PoS product categories - Make a product and assign this sub category to it - Allow the category in the PoS configuration for…
**Steps to reproduce:** - Make a sub category, such as Soda for Drinks in PoS product categories - Make a product and assign this sub category to it - Allow the category in the PoS configuration for a Mobile order Session - Open the Session, the product will not be displayed **Problem:** When a product has a subcategory, it is not displayed in the mobile interface, even if said category is allowed in the settings. This problem does not occur in the Kiosk, only on the mobile sessions. **Why the fix:** The products should be displayed if their category has been added to the available categories in the settings. It now works as it does in the PoS and the Kiosk, meaning it is displayed as long as the sub category is mentioned in the Restrict Categories section of the configuration. Also, in case you have categories A -> A/B -> A/B/C and you don't have products associated to A but you have some in C, they won't show up in the self. Currently, products from child categories can be shown in the self when all their parent categories had products associated to them. When computing the available categories, we would only return categories which had products directly related to them, regardless if their nth child had some. Thus in the setting mentioned previously, only the category C was returned. However this logic is not correct with the fact that the self, not in kiosk mode, only shows the top categories, meaning only the categories without parents. https://github.com/odoo/odoo/blob/434e8cf53a039cc2efc3cb531608028182928ad9/addons/pos_self_order/static/src/app/pages/product_list_page/product_list_page.js#L146-L151 The self was not showing the products from C as C had a parent category. In order for the product from C to be shown, the category A had to be included in the list of available categories. opw-4934728 Forward-Port-Of: odoo/odoo#221740
13 changes
Enhancements to existing features
The update includes VoIP-related modules in the project’s automated code quality checks. This helps maintain consistent standards and reduces the risk of issues in future VoIP updates, with no direct change for end users.
Original PR description
Forward-Port-Of: odoo/odoo#232559 Forward-Port-Of: odoo/odoo#232484
Resolved issues and error corrections
This fixes a display issue where portal pages in right-to-left website languages could show excessive blank horizontal space. Dynamic website styling now uses the active website language, so pages render correctly for users browsing in languages such as Arabic.
Original PR description
Scenario to reproduce from 18.0: - install right-to-left (eg. arabic) language on website - open a portal record with chatter (eg. /my/invoices/1) - switch to right-to-left language - scroll…
Scenario to reproduce from 18.0: - install right-to-left (eg. arabic) language on website - open a portal record with chatter (eg. /my/invoices/1) - switch to right-to-left language - scroll horizontally to the left Result: there is a huge amount of whitespace scrollable to the left. Cause: In 18.0, the chatter has an hidden textarea .o-mail-Composer-fake with position "left: -10000px; top: -10000px;". But the chatter assets (portal.assets_chatter_style) are called dynamically with getBundle which is using the session lang instead of the website lang. So the bundle is gotten with the wrong lang and the CSS is not rtlcss'ed and this create big whitespace to the left of the page. Fix: set the website request language when getting bundle for the frontend. Note: this PR also create a TestLangUrlCommon to prevent TestLangUrl tests of being run a second time in TestControllerRedirect. opw-5013485 Forward-Port-Of: odoo/odoo#232671 Forward-Port-Of: odoo/odoo#223575
Large PNG images uploaded to Odoo are now resized without being converted to a limited web color palette. This prevents visible image quality loss on websites and other areas using uploaded attachments, so users no longer need to resize images manually before uploading.
Original PR description
When uploading a png image ir_attachment, the image is not modified if its resolution is under the maximum 1920x1920. However, if the resolution is bigger, it both gets resized and is converted to a WEB palette, which visibly degrades the quality of the image. A workaround for this is to resize the image locally to be max 1920 on either dimensions and then upload it, which effectively bypasses this special treatment. Steps to reproduce: - Go to the website app - Add a Text - Image snippet - Double click the image - Upload a .png image of a resolution strictly greater than 1920 in either width or height Old behavior: the png is visibly degraded New behavior: the png is not visibly degraded opw-3935533 Forward-Port-Of: odoo/odoo#173508
This fixes a missing field when planning service work from a sales order. Users can once again see and set allocated hours in the planning dialog when the usual scheduling time field is hidden, helping avoid incomplete shift planning.
Original PR description
Steps to reproduce: - Create a Sales order with planning services. - Click on To Plan stat button. - Click on empty cell Issue: - Plan dialog is opened but has missing allocated_hours field. Reason: - In this commit https://github.com/odoo/enterprise/commit/d21bd4b694ec63ba83bea077714a8fe928d6e014 allocated hours was merged with start_datetime using a widget and thus removed from view. - But in planning list view we hide start_datetime when we schedule shifts from sales order. Fix: - Add back allocated_hours conditionally to be visible when we schedule shifts as in other cases start_datetime is present. task-5117776 Forward-Port-Of: odoo/enterprise#96391
Donation forms now wait until the page has loaded the current currency before processing a click. This prevents rare crashes or failed submissions on slow connections and shows a loading state to avoid duplicate clicks.
Original PR description
This fixes a very rare race condition in the `test_01_donation` tour... but it is actually surprising it is not more frequent than it is. Steps to reproduce: - Simulate a slow network (e.g. using…
This fixes a very rare race condition in the `test_01_donation` tour... but it is actually surprising it is not more frequent than it is. Steps to reproduce: - Simulate a slow network (e.g. using Chrome DevTools) - Load a page with a donation snippet - Quickly fill in the donation form and click the submit button => You'll sometimes get a crash. Or a more precise one: - Add a 1 minute delay to the `/website/get_current_currency` route - Load a page with a donation snippet - Fill in the donation form and click the submit button once the page is fully loaded. => You'll definitely get a crash. This commit makes that button's handler async-protected, meaning it will now properly wait for what is needed (the currency) before proceeding, but it will also display a loading effect for the duration and prevent double clicking. Once the form is submitted, the loading effect is removed for stability safety. In master it can probably be improved. runbot-220885 Forward-Port-Of: odoo/odoo#232585 Forward-Port-Of: odoo/odoo#232408
The Helpdesk SLA report now lets users add the SLA status grouping back after removing it. This avoids needing to reload the reporting view and makes SLA analysis smoother for support teams.
Original PR description
Currently, when the user opens the sla reporting view, if he removes the default grouping of sla_status, he has no way to get it back unless he reloads the view completly. This commit fixes this issue by adding the sla_status field to the group_by options. task-5076401 Forward-Port-Of: odoo/enterprise#95261
This fixes invoice grouping by Sent status so each group now shows only the invoices that belong there. Accounting users can more reliably review which customer invoices have or have not been sent, avoiding confusing duplicate results.
Original PR description
### Issue: The groups "Sent" and "Not Sent" display all the invoices. ### Steps to reproduce: - Go in Accounting > Customer > Invoices - Create a custom GroupBy with "Sent" - Unfold the groups: all invoices appear in each group ### Cause: `web_read_group` returns the groups with their length and the domain corresponding. When unfolding `web_search_read` uses the given domain to get the records to display. Here the issue comes from the domain returned, it contains `['move_sent_values', '=', 'sent']`, but `move_sent_values` is a computed field that doesn't have a `_search` method so the domain doesn't filter on this field. ### Solution: Add the method `_search_move_sent_values` to search on `is_move_sent`. opw-5164650 Forward-Port-Of: odoo/odoo#232400
The scheduled check for Mexican electronic invoice status will no longer get stuck reviewing the same first batch of documents repeatedly. This helps ensure all eligible received invoices are checked with the SAT over time, improving reliability for compliance monitoring.
Original PR description
Currently one of the domains returned by the method `_get_update_sat_status_domains` is `[('state', '=', 'invoice_received'), ('move_id.state', '=', 'posted')]`. This domain is used to always return…
Currently one of the domains returned by the method `_get_update_sat_status_domains` is `[('state', '=', 'invoice_received'), ('move_id.state', '=', 'posted')]`. This domain is used to always return l10n_mx_edi_documents that have been imported from somewhere and whose invoice has been posted. This is because Odoo needs to always checked the value of the originator of an EDI document, in case it has been cancelled from the SAT Portal for instance.
Both `state = 'invoice_received'` and `'move_id.state = 'posted'` are mostly fixed value. The state needs to stay `invoice_received` as Odoo needs to always check the originator document's value. And once an invoice is posted, it's stays as so except in the case of cancellation.
This leads to an issue when the database contains more than 100 documents that are both `invoice_received` and `move_id.state = 'posted'`. In this case, the cron `_fetch_and_update_sat_status` will always process the same 100 documents. Once the limit of 100 is reached, the cron retriggers itself before terminating. Then on the next execution, the search call with the domain coming from `_get_update_sat_status_domain` will return the same 100 documents again.
This commit fixes this issue by ordering the documents in the cron method by `write_date asc`. Even if the SAT value of the documents does not change, the `write_date` should be updated as their is still a write that is triggered via `_update_document_sat_state`. This prevents the cron from always processing the same documents over and over again.
Forward-Port-Of: odoo/enterprise#93205This fix ensures Spanish Facturae e-invoicing tax classifications are loaded correctly for mainland Spain and the Canary Islands. It also prevents unrelated taxes from receiving an incorrect default value, reducing the risk of inaccurate electronic invoice tax reporting.
Original PR description
Currently the tax data defined in l10n_es_edi_facturae is incomplete and never loaded. This commit makes sure that the l10n_es_edi_facturae_tax_type is loaded correctly and adds the appropriate templates for es_common_mainland and es_canary_common. The default is also removed on the field l10n_es_edi_facturae_tax_type to avoid the value being assigned for unrelated taxes. task-4981325 Forward-Port-Of: odoo/odoo#231277
Point of Sale orders now keep the same receipt number format whether they are created online or while temporarily offline. This removes confusing extra wording on offline orders, making backend order records easier to compare and reconcile.
Original PR description
**Steps to reproduce:** - Go to PoS, make an order and pay for it - Before clicking next order close your connection with the server - Make a purchase like this - Go back online and check the orders…
**Steps to reproduce:** - Go to PoS, make an order and pay for it - Before clicking next order close your connection with the server - Make a purchase like this - Go back online and check the orders in the backend The order made online only has the receipt number, but the order made offline has *Order* in front of it. **Why the fix:** The receipt number on a PoS order should be consistand and should not be changed depending on if the purchase was made online or offline. With this commit, every order will have only it's receipt number without the *Order* in front of it even if it was made offline. It is still possible to see if an order was made online or offline with the **F** variable, which is the first number of the last part of the receipt number. If it is 1, the order was made offline, if it is 0, it was made online. The *refPrefix* parameter from the *getNextOrderRefsLocal* function is not used anymore, so it has been replaced by an empty string in the function call in stable and could be deleted when in master. opw-4965095 Forward-Port-Of: odoo/odoo#224416
The VoIP call transfer screen now starts with an empty search field instead of showing the last contact search. This prevents confusion for users transferring calls and makes it easier to choose the correct recipient.
Original PR description
**Purpose:** Previously, when a contact was searched and made a call. During a call, clicking "Transfer" showed the old search term. **Specification:** Now, the search box is explicitly emptied when transferring the call by resetting this.softphone.addressBook.searchInputValue. **Task-** 5087938
This update prevents crashes that could occur when users quickly drag and drop multiple cards in large grouped Kanban views. It makes the interface safer during heavy screen refreshes, reducing interruptions for users working with many records.
Original PR description
On a grouped kanban view displaying a lot of records (i.e. with a lot of columns and a lot of records by column), drag and drop several records from the same column quick multiple times. Before this…
On a grouped kanban view displaying a lot of records (i.e. with a lot of columns and a lot of records by column), drag and drop several records from the same column quick multiple times. Before this commit, different crashes could occur. The first category of crashes concern the sortable hook. It called the onDrop callback even if the dragged element was no longer in the DOM (which occurs if there's a re-rendering while the user is dragging). This has been fixed in the hook, and tested. Another crash could arise in kanban (in the model). If the user dropped the card while there was a scheduled/ongoing re-rendering, i.e. at a specific moment where the model isn't synchronized with the DOM, the dropped card was still in the DOM, but it's associated datapoint was no longer referenced in hte model. In that case, we can do nothing but cancel the d&d. Note that this couldn't be tested, as reproducing the exact behavior (typically having a slow rendering due to the number of cards to render) isn't possible in a unit test, where user interactions are done programmatically. Task~5167650 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#231886
This fixes a logging issue in the Peppol partner verification process. Verification status changes are now recorded correctly even when multiple electronic address schemes are checked, improving traceability for support and operations.
Original PR description
Failed fw-port in https://github.com/odoo/odoo/pull/231142. The logging won't happen if a value is found for the second tested EAS. task-none
3 changes
Resolved issues and error corrections
Fixed an issue where tapping an order line in the Point of Sale product screen no longer selected it when the certified EU IoT scale module was installed. This restores normal cashier workflow while keeping the long-press configurator behavior available.
Original PR description
Task: [5163235](https://www.odoo.com/odoo/project/1737/tasks/5163235) --- In the product screen, pressing an orderline was supposed to select this line and a long press was supposed to open the Configurator popup. However, since the feature of the long press, if we install the module `l10n_eu_iot_scale_cert`, pressing an orderline does not select it anymore. This was due to the fact that a `t-ref` was added in the orderline template and that in the `l10n_eu_iot_scale_cert` module, we were overriding this template completely.
Helpdesk users can now reapply the SLA status grouping in the SLA reporting view after removing it. This avoids needing to reload the page and makes report exploration smoother.
Original PR description
Currently, when the user opens the sla reporting view, if he removes the default grouping of sla_status, he has no way to get it back unless he reloads the view completly. This commit fixes this issue by adding the sla_status field to the group_by options. task-5076401 Forward-Port-Of: odoo/enterprise#95261
The scheduled SAT status check now rotates through older updated Mexican e-invoice documents instead of repeatedly checking the same first batch. This helps ensure posted supplier invoices imported into Odoo continue to be monitored for possible cancellation or status changes on the SAT portal.
Original PR description
Currently one of the domains returned by the method `_get_update_sat_status_domains` is `[('state', '=', 'invoice_received'), ('move_id.state', '=', 'posted')]`. This domain is used to always return…
Currently one of the domains returned by the method `_get_update_sat_status_domains` is `[('state', '=', 'invoice_received'), ('move_id.state', '=', 'posted')]`. This domain is used to always return l10n_mx_edi_documents that have been imported from somewhere and whose invoice has been posted. This is because Odoo needs to always checked the value of the originator of an EDI document, in case it has been cancelled from the SAT Portal for instance.
Both `state = 'invoice_received'` and `'move_id.state = 'posted'` are mostly fixed value. The state needs to stay `invoice_received` as Odoo needs to always check the originator document's value. And once an invoice is posted, it's stays as so except in the case of cancellation.
This leads to an issue when the database contains more than 100 documents that are both `invoice_received` and `move_id.state = 'posted'`. In this case, the cron `_fetch_and_update_sat_status` will always process the same 100 documents. Once the limit of 100 is reached, the cron retriggers itself before terminating. Then on the next execution, the search call with the domain coming from `_get_update_sat_status_domain` will return the same 100 documents again.
This commit fixes this issue by ordering the documents in the cron method by `write_date asc`. Even if the SAT value of the documents does not change, the `write_date` should be updated as their is still a write that is triggered via `_update_document_sat_state`. This prevents the cron from always processing the same documents over and over again.
Forward-Port-Of: odoo/enterprise#9320533 changes
New functionality added to Odoo
This update adds automated checks for how the Point of Sale handles linked sales orders, quotations, order lines, and down payments. It helps prevent regressions in sales workflows by making sure these scenarios continue to work as expected in future changes.
Original PR description
Task: [#4945627](https://www.odoo.com/odoo/my-tasks/4945627)
Community PR: [#221920](https://github.com/odoo/odoo/pull/221920)
Runbot: https://runbot.odoo.com/runbot/bundle/saas-18-3-hoot-pos-sale-ltra-390474
---
This commit adds Hoot tests for the `pos_sale` module:
- components
- control_buttons
- onClickQuotation (1)
- orderline (1)
- models
- pos_order_line
- getSaleOrder (3)
- saleDetails (2)
- setQuantityFromSOL (2)
- pos_order
- _getIgnoredProductIdsTotalDiscount (1)
- services
- pos_store
- onClickSaleOrder (4)
Also add a product used for down payments and create a sample sale order with two lines to support the tests.
Forward-Port-Of: odoo/odoo#230851
Forward-Port-Of: odoo/odoo#221920Enhancements to existing features
The point of sale experience has been refined with clearer button labels, better guidance, and fewer unnecessary warnings. These changes help cashiers and restaurant staff move through orders, payments, notes, and preparation steps more smoothly and with less confusion.
Original PR description
pos*: point_of_sale, pos_restaurant This commit introduces several UX enhancements in the standard POS flow: - Removed unintended onboarding step tip. - Updated note input dialog title to include the…
pos*: point_of_sale, pos_restaurant This commit introduces several UX enhancements in the standard POS flow: - Removed unintended onboarding step tip. - Updated note input dialog title to include the selected product name (e.g., “Pizza: Add Customer Note”). - Fixed issue where the Payment button incorrectly became primary when only the order-level note was updated. - Renamed "Order" to "Send" when only a note or message needs to be sent for preparation. - Added "New Order" button on the Ticket screen when no orders are available. - Improved placeholder text for floating order name input. - Added a back button on the Floor screen in table-finding mode for direct sale. - Moved preset filters next to order state filters (Active, Paid, etc.). - Made the Customer button primary when a customer is required for the order. - Removed unnecessary toaster warning for “Pay Later” payment method selection. - Shifted order preparation warning from the Validation button to the Payment button on the Product screen. - Added toaster notification when an order is sent for preparation summary. Task-5116688 Related-https://github.com/odoo/enterprise/pull/97458
The option to create batch payments is now available to users working in Invoicing. This makes it easier for the right finance users to access batch payment workflows without needing broader accounting permissions.
Original PR description
This commit will change the security group of the create batch payment action, to be available in invoicing. task-5187435
This update improves automated checks around the warning shown when discarding an order during restaurant preparation. It helps ensure the point of sale flow behaves correctly on the Product screen, reducing the risk of staff encountering inconsistent warnings during service.
Original PR description
*: pos_restaurant_preparation_display, l10n_de_pos_res_cert This commit improves the preparation flow by updating the `discardOrderWarningDialog` tour step to validate its behavior on the Product screen. Task-5116688 Related- https://github.com/odoo/odoo/pull/229915
This update refreshes localization files and translation configuration, mainly for the 3-way matching accounting area. It helps keep multilingual text and translation workflows aligned for users working in different languages.
Users can now download invoices in a single ZIP file containing all supported formats, such as PDF and XML. This makes it easier for businesses using Odoo to share sales and purchase invoices with accountants who may use different tools.
Original PR description
With PEPPOL, many clients use Odoo for invoicing while their accountant uses another tool. To easily send invoices to the accountant, it’s important to export invoices for both sales and purchase. Adding a `Export ZIP` option to download invoices in all supported extensions (pdf, xml, ..etc) in the same zip. task-4946367 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219245
The web tooling configuration now includes VOIP-related modules in automated code quality checks. This helps maintain consistent standards and catch issues earlier, with no direct impact on end users.
Original PR description
Forward-Port-Of: odoo/odoo#232559 Forward-Port-Of: odoo/odoo#232484
Belgian partners are now checked against the two most commonly used Peppol identifiers, making it more reliable to find whether they exist on the Peppol network. The update also removes outdated recommendation warnings because the required identifier is now handled automatically during registration.
Original PR description
1. For belgian partner, we now check for 0208 and 9925 which are the two most used EAS when looking for partner existence on the Peppol network. 2. Remove the warnings about the recommended EAS: 0208 is now the mandatory EAS, this will be handled directly on IAP where the Peppol Access Point will try to register 0208 in all cases with an alias system. Note that we have always computed 0208 as recommended value in registration process. task-4852903 Forward-Port-Of: odoo/odoo#231142 Forward-Port-Of: odoo/odoo#227431
Resolved issues and error corrections
Large PNG images uploaded to the website are now resized without the visible quality loss caused by palette conversion. This removes the need for users to manually resize images before uploading and helps website content look sharper.
Original PR description
When uploading a png image ir_attachment, the image is not modified if its resolution is under the maximum 1920x1920. However, if the resolution is bigger, it both gets resized and is converted to a WEB palette, which visibly degrades the quality of the image. A workaround for this is to resize the image locally to be max 1920 on either dimensions and then upload it, which effectively bypasses this special treatment. Steps to reproduce: - Go to the website app - Add a Text - Image snippet - Double click the image - Upload a .png image of a resolution strictly greater than 1920 in either width or height Old behavior: the png is visibly degraded New behavior: the png is not visibly degraded opw-3935533 Forward-Port-Of: odoo/odoo#173508
The Last Appraisal button is available again for employees after it was unintentionally removed. This helps managers and HR users quickly access an employee's most recent appraisal from the employee record.
Original PR description
The action on res.users to see the last appraisal has been removed by this PR https://github.com/odoo/enterprise/pull/88518. This commit reintroduces the action in hr.employee.public. task-5166704
This fixes the planning dialog opened from a sales order so users can see and set allocated hours when creating a shift. It prevents missing scheduling information for sales-related planning services, making shift planning from sales orders work as expected.
Original PR description
Steps to reproduce: - Create a Sales order with planning services. - Click on To Plan stat button. - Click on empty cell Issue: - Plan dialog is opened but has missing allocated_hours field. Reason: - In this commit https://github.com/odoo/enterprise/commit/d21bd4b694ec63ba83bea077714a8fe928d6e014 allocated hours was merged with start_datetime using a widget and thus removed from view. - But in planning list view we hide start_datetime when we schedule shifts from sales order. Fix: - Add back allocated_hours conditionally to be visible when we schedule shifts as in other cases start_datetime is present. task-5117776 Forward-Port-Of: odoo/enterprise#96391
This update fixes several business-facing issues across accounting, payroll, localization reports, and translations. It improves tax accuracy in bank reconciliation and trial balance reports, allows authorized payroll administrators to cancel payslips, corrects Indian and Peruvian tax reporting data, and refreshes many translations.
This update fixes the layout of the ePos test widget and Epson printer IP field in Point of Sale settings. The fields are now better aligned and spaced, making the configuration screen clearer and easier to use.
Original PR description
- Adjust the display of the ePos test widget and Epson printer IP field in the Point of Sale configuration and settings views for better alignment and spacing. | View | Before | After | | :--- | :----: | ---: | | pos_config_view.xml | <img width="406" height="151" alt="image" src="https://github.com/user-attachments/assets/e2b6f619-62e7-44d8-928b-53ce5401d9a7" /> | <img width="403" height="184" alt="image" src="https://github.com/user-attachments/assets/96a0137d-cc56-4b2e-a322-811e5ad4b130" /> | | res_config_settings_views | <img width="535" height="249" alt="image" src="https://github.com/user-attachments/assets/679a1fce-45f3-4378-96bb-077d8cdef2e1" /> | <img width="535" height="218" alt="image" src="https://github.com/user-attachments/assets/efd62f18-a3fc-45f2-9ca2-4132a6b1a1df" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Helpdesk SLA reporting view now lets users add the SLA status grouping back after removing it. This avoids needing to reload the report and makes analysis smoother for support teams.
Original PR description
Currently, when the user opens the sla reporting view, if he removes the default grouping of sla_status, he has no way to get it back unless he reloads the view completly. This commit fixes this issue by adding the sla_status field to the group_by options. task-5076401 Forward-Port-Of: odoo/enterprise#95261
This update fixes several issues when launching AI chat from the systray, including missing message recipients, missing record details, and crashes on some forms. It also makes system AI agents visible for easier configuration and improves handling of prompt-based chats.
Original PR description
Currently: - when using the "Send as Message" button in a chat with an agent (opened from the systray), the default recipients are not added in the composer - creating a default prompt for "get help…
Currently: - when using the "Send as Message" button in a chat with an agent (opened from the systray), the default recipients are not added in the composer - creating a default prompt for "get help on a record" on a model that does not inherit from `mail.trhead` does not work: it's the default "ask ai" chat that is opened when clicking on the "ai" button in the systray from this record's form view ( the "prompt buttons" created are not shown and the record info is not added in the prompt) - clicking on this ai button in the systray from the res.users form view results in a crash (one tries to fetch a thread because the model has a "message_ids" field, but it's a related field and the model does not have a thread) - "system agents" are not shown in the agent views, making it difficult to edit them (while one user could want to change the model used by a system agent if that user does not have an api key for the provider of the default model) With this PR: - adds the default recipients (and creates their related partner if needed, as it would be done when opening the full composer from the chatter) - the info about the current record is always added to the context when using the ai systray button from a form view, even if there's no chatter - the "send as message" and "log note" are added from the launch chat service, only if the model inherits from `mail.thread` (instead of relying on the field `message_ids`) - moved the call to open the ai chat back to the form controller to avoid sending 2 events on the bus (currently systray sends an event to the form controller which in turn sends an event with the model info to the systray), and to make it easier to reuse this "open chat with agent" (shouldn't need to always go through the systray for that) - the "system agents" are now shown in the agents views. Their name/description have therefore been reworked. The website page generator and call summarizer agents are now archived by default, as they are only used in very specific contexts Task-5109721
This fix prevents active website live chat conversations from being canceled when a customer starts another chat. It helps customers keep ongoing conversations open across devices or sessions while still clearing only requests that are truly pending.
Original PR description
The website livechat module allows agents to start conversations with customers, but conversations are only displayed on the next navigation. Previously, pending chat requests were canceled whenever a customer opened a new live chat. The search condition for pending chats was too broad: it did not consider who started the conversation or whether it was already ongoing. As a result, ongoing chats could be unintentionally canceled. Customers could have multiple conversations (e.g. on different devices). This change ensures that only pending chat requests are canceled, leaving ongoing chats intact. task-5186567 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#232704 Forward-Port-Of: odoo/odoo#232624
Fixed an Accounting issue where grouping customer invoices by sent status showed every invoice in both Sent and Not Sent groups. Users can now rely on this grouping to review invoice communication status accurately.
Original PR description
### Issue: The groups "Sent" and "Not Sent" display all the invoices. ### Steps to reproduce: - Go in Accounting > Customer > Invoices - Create a custom GroupBy with "Sent" - Unfold the groups: all invoices appear in each group ### Cause: `web_read_group` returns the groups with their length and the domain corresponding. When unfolding `web_search_read` uses the given domain to get the records to display. Here the issue comes from the domain returned, it contains `['move_sent_values', '=', 'sent']`, but `move_sent_values` is a computed field that doesn't have a `_search` method so the domain doesn't filter on this field. ### Solution: Add the method `_search_move_sent_values` to search on `is_move_sent`. opw-5164650 Forward-Port-Of: odoo/odoo#232400
HTML-based automatic values in signing documents are now converted to readable plain text instead of showing raw HTML. The signing flow also no longer crashes when constant multiline fields are used, making document completion more reliable.
Original PR description
Before this task, when a html field is used to populate auto value, the html is kept, making it unusable. Moreover, JS error prevent to use constant multi line fields. task-5104647
The spreadsheet component was updated to a newer version with fixes for chart behavior and duplicate chart identifiers. This should make spreadsheet reports and dashboards more reliable, while also improving calculation performance for larger sheets.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/1c1d1eca68 [REL] 19.0.7 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/1c1d1eca68 [REL] 19.0.7 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/d6535bdab4 [FIX] charts: fix smart chart engine [Task: 5079093](https://www.odoo.com/odoo/2328/tasks/5079093) https://github.com/odoo/o-spreadsheet/commit/3011482818 [PERF] evaluation: zonify evaluation [Task: 4936229](https://www.odoo.com/odoo/2328/tasks/4936229) https://github.com/odoo/o-spreadsheet/commit/cb66cfd145 [FIX] model: ensure chart ID unicity [Task: 5153264](https://www.odoo.com/odoo/2328/tasks/5153264) Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya <rmbh@odoo.com> Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
This fixes a display issue where checkbox borders in the website link editing popover blended into the background when dark mode was enabled. Users editing links can now clearly see and use the advanced options checkbox, improving usability for dark mode users.
Original PR description
In dark mode the checkbox in the link popover wasn't visible due to the same popover background and checkbox border colors. Steps to see the issue: - Set dark mode as the preferred theme - Open Website and start editing - Click on any link - Click on the "Edit Link" pen icon - Click on the "Advanced Mode" gear icon => The checkbox borders aren't visible task-5155669
Full-day leave requests using time off types measured in hours now display correctly as full days instead of being shown as half days. This prevents confusion for employees and managers reviewing time off calendars.
Original PR description
Steps to reproduce: - Go to Time Off - Create a time off type that can be taken in hours - Take a full day of leave using this type of time off - The time off will be displayed as half a day, even though it is a full day Reason: The check to display the time off as half a day did not check that the time off starts in the afternoon, which caused the issue. How it was fixed: The condition now checks if the time off starts in the afternoon so that the display is correct. Task ID: 5072255
The table selection popup in POS self-ordering now lists tables consistently by floor and table number. This makes it easier for customers or staff to find the correct table and reduces confusion during ordering.
Original PR description
Task [#4991803](https://www.odoo.com/odoo/my-tasks/4991803) Runbot: https://runbot.odoo.com/runbot/bundle/18-0-incremental-order-table-pop-pos-self-order-ltra-391429 --- When selecting a table in the POS self-order, we sort the tables by `floor_id` and then by `table_number` in ascending order. This ensures a consistent and user-friendly experience when choosing a table. Forward-Port-Of: odoo/odoo#222811 Forward-Port-Of: odoo/odoo#222421
Fixes an issue where changing the speed of animated background shapes in the website editor had no effect. Users can now adjust shape animation speed as expected when designing pages, improving editing reliability.
Original PR description
Steps to reproduce: - Drop a snippet - Add a background shape (e.g. Rainy 05) - Use the slider to change the speed - Nothing happens This commit is adapting `CSS_ANIMATION_RULE_REGEX` as it was too restrictive, the space after the colon is now optional. task-5170549 Forward-Port-Of: odoo/odoo#231747
A flaky automated test around browser tab notifications in the Discuss app was fixed. This improves reliability of Odoo's test suite and helps avoid false build failures without changing end-user behavior.
Original PR description
Before this commit, the following test could fail non- determinstically: ``` [HOOT] Test "@mail/discuss_app/discuss/out-of-focus notif takes new inbox messages into account" failed: 3. [toBe]…
Before this commit, the following test could fail non- determinstically: ``` [HOOT] Test "@mail/discuss_app/discuss/out-of-focus notif takes new inbox messages into account" failed: 3. [toBe] expected values to be strictly equal > Expected: "(1) Inbox" > Received: "(1) Odoo" ``` This happens because the test is opening discuss and simulating posting of message from an external user, in order to assert the tab shows "(1) Inbox", where (1) is the number of unread messages and "Inbox" comes from the active thread of discuss app. The test can have "Odoo" because this is the default tab title and posting of message happened so fast that discuss app client action did not have time to notify of inbox being the active conversation, even when awaiting the showing of counter on discuss sidebar. - The notifying of active conversation name in discuss app is a side-effect of rendering of discuss app. - The showing of badge next in discuss sidebar item and the (1) both come from "mail.message/inbox" bus notification. When `mail.message/inbox` is faster than side-effect rendering, then we get this "(1) Odoo" instead of "(1) Inbox". It happens a very short time, as it eventually turns into "(1) Inbox", but the test just awaits badge rendering and then assert synchronously the value in tab title. This commit fixes the issue by awaiting asynchronously the expected document.title in HOOT test. Note that document.title is not in DOM because HOOT has the document.title mocked, so we patch it to have awaiting of step. Fixes runbot-error-233459
This fix prevents an error when users try to post WIP accounting entries for a manufacturing work order that is still in progress. The system now handles unfinished work orders correctly, allowing the WIP wizard to open instead of blocking the process with a traceback.
Original PR description
Issue: - Traceback when calculating the cost of a workorder Step to reproduce: - with apps: mrp, accountant - create a MO for a product - add a WO - confirm - start the WO - Action > "Post WIP Accounting entry" Current Behavior: - get a traceback Expected behaviour - open the WIP wizard Cause of the issue: - to calculate the cost of production, wizard use all WO including the one still running. However as it is still running its end date is registered as `False`. It raises a traceback when it compares the end of the WO with a limit date because `bool` and `datetime.datetime` are not compatible for '<'. Solution: - check if the end date of the WO is defined Test: - in module mrp_workorder an override of button_start change how work order are launched. Therefore, the test should be launched on an Enterprise run. opw-4961873 Forward-Port-Of: odoo/enterprise#97912 Forward-Port-Of: odoo/enterprise#93812
Valid Chilean vendor credit note files are now imported as credit notes instead of being incorrectly treated as invoices. This prevents import errors and helps accounting teams process supplier credit notes without manual workarounds.
Original PR description
### Steps to reproduce Go to Accounting -> Vendor Bills Attempt to import a valid vendor credit note by dragging-dropping the DTE file in the list view. Notice how the vendor credit note gets created with an error: ``` Error importing attachment 'DTE.xml' (type=l10n_cl.dte): This specific error occurred during the import: You can not use a credit_note document type with a invoice ``` ### Analysis `_l10n_cl_import_dte` should set the move type to credit note when the document type code is '61', but does not. This was broken by 42744fcecdbd36e See https://github.com/odoo/enterprise/commit/42744fcecdbd36ea0101070c68299227a9f204a6#diff-044bc1ef3ea4878783a064258b4436b44b3064c5196c22d0d104daee8fde4501L294 ### Solution Correctly set move_type to `in_refund` if the document type code is '61' Linked issue https://github.com/odoo/odoo/issues/232348 task-none Forward-Port-Of: odoo/enterprise#97694
This fix prevents an error when users try to post work-in-progress accounting entries for a manufacturing order with a work order still in progress. The system now handles unfinished work orders correctly, allowing the WIP wizard to open instead of interrupting the user with a crash.
Original PR description
#### Issue: - Traceback when calculating the cost of a workorder #### Step to reproduce: - with apps: mrp, accountant - create a MO for a product - add a WO - confirm - start the WO - Action > "Post…
#### Issue: - Traceback when calculating the cost of a workorder #### Step to reproduce: - with apps: mrp, accountant - create a MO for a product - add a WO - confirm - start the WO - Action > "Post WIP Accounting entry" #### Current Behavior: - get a traceback #### Expected behaviour - open the WIP wizard #### Cause of the issue: - to calculate the cost of production, wizard use all WO including the one still running. However as it is still running its end date is registered as `False`. It raises a traceback when it compares the end of the WO with a limit date because `bool` and `datetime.datetime` are not compatible for '<'. #### Solution: - check if the end date of the WO is defined In module mrp_workorder an override of [button_start](https://github.com/odoo/enterprise/blob/18.0/mrp_workorder/models/mrp_workorder.py#L284-L295) change how work order are launched. Therefore, the test should be launched on an Enterprise run. opw-4961873 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232758 Forward-Port-Of: odoo/odoo#221938
This fixes how VoIP contact searches combine phone keypad search terms with other contact filters. Users should see more accurate contact results when searching from the VoIP interface, reducing cases where valid contacts were not found.
Original PR description
t9_search should be ORed to the subdomain, which in turn should be ANDed to the domain. Currently, both the subdomain and the t9_search are ANDed to the domain, resulting in a "subdomain AND t9_search" condition, which is not correct and unlikely to match anything. Forward-Port-Of: odoo/enterprise#97811 Forward-Port-Of: odoo/enterprise#97731
Products assigned to allowed subcategories now appear correctly in mobile self-order sessions. This ensures customers can see and order all configured items, matching the behavior already available in PoS and kiosk modes.
Original PR description
**Steps to reproduce:** - Make a sub category, such as Soda for Drinks in PoS product categories - Make a product and assign this sub category to it - Allow the category in the PoS configuration for…
**Steps to reproduce:** - Make a sub category, such as Soda for Drinks in PoS product categories - Make a product and assign this sub category to it - Allow the category in the PoS configuration for a Mobile order Session - Open the Session, the product will not be displayed **Problem:** When a product has a subcategory, it is not displayed in the mobile interface, even if said category is allowed in the settings. This problem does not occur in the Kiosk, only on the mobile sessions. **Why the fix:** The products should be displayed if their category has been added to the available categories in the settings. It now works as it does in the PoS and the Kiosk, meaning it is displayed as long as the sub category is mentioned in the Restrict Categories section of the configuration. Also, in case you have categories A -> A/B -> A/B/C and you don't have products associated to A but you have some in C, they won't show up in the self. Currently, products from child categories can be shown in the self when all their parent categories had products associated to them. When computing the available categories, we would only return categories which had products directly related to them, regardless if their nth child had some. Thus in the setting mentioned previously, only the category C was returned. However this logic is not correct with the fact that the self, not in kiosk mode, only shows the top categories, meaning only the categories without parents. https://github.com/odoo/odoo/blob/434e8cf53a039cc2efc3cb531608028182928ad9/addons/pos_self_order/static/src/app/pages/product_list_page/product_list_page.js#L146-L151 The self was not showing the products from C as C had a parent category. In order for the product from C to be shown, the category A had to be included in the list of available categories. opw-4934728 Forward-Port-Of: odoo/odoo#221740
This fix ensures newly created vendor bills correctly show their commercial status and prevents the commercial event process from getting stuck when an event is resent. It also corrects the issuer acceptance event so submissions are accepted properly by Colombia's DIAN tax authority.
Original PR description
this commit solves following issues: - the commercial status was missing on newly created vendor bills - the flow got stuck when an event had already been sent and we tried to send it again - The accept by issuer event generated errors on DIAN's side task: 5064534
This update prevents an error message from appearing when users open a spreadsheet dashboard dropdown in the search bar. It restores missing functionality in the Community edition so spreadsheet dashboards work more reliably.
Original PR description
…in community edition Description of the issue/feature this PR addresses: To move the missing code from enterprise edition Current behavior before PR: Open a spreadsheet dashboard dropdown in search bar in 19.0 community edition, the traceback message box appeared: AttributeError: The method 'ir.model.has_searchable_parent_relation' does not exist Desired behavior after PR is merged: No traceback --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents errors when printing PDF documents through IoT in manufacturing work orders. It ensures the document list is handled correctly, so users can print quality-related documents without encountering a traceback.
Original PR description
Due to `active_ids` being provided with a `list[list]` instead of just `list`, pdf document rendering was returning a traceback. This commit fixes the issue by flattening the list passed to the context of the client action. (e.g. `res_ids` was provided `[[21, 22], [21, 22]] instead of [21, 22, 21, 22]`). opw-5190570
This fixes a layout problem on right-to-left website pages where portal pages with chatter could show excessive blank horizontal space. Dynamic website styling now uses the page's selected language, ensuring the layout direction matches what visitors see.
Original PR description
Scenario to reproduce from 18.0: - install right-to-left (eg. arabic) language on website - open a portal record with chatter (eg. /my/invoices/1) - switch to right-to-left language - scroll…
Scenario to reproduce from 18.0: - install right-to-left (eg. arabic) language on website - open a portal record with chatter (eg. /my/invoices/1) - switch to right-to-left language - scroll horizontally to the left Result: there is a huge amount of whitespace scrollable to the left. Cause: In 18.0, the chatter has an hidden textarea .o-mail-Composer-fake with position "left: -10000px; top: -10000px;". But the chatter assets (portal.assets_chatter_style) are called dynamically with getBundle which is using the session lang instead of the website lang. So the bundle is gotten with the wrong lang and the CSS is not rtlcss'ed and this create big whitespace to the left of the page. Fix: set the website request language when getting bundle for the frontend. Note: this PR also create a TestLangUrlCommon to prevent TestLangUrl tests of being run a second time in TestControllerRedirect. opw-5013485 Forward-Port-Of: odoo/odoo#232759 Forward-Port-Of: odoo/odoo#223575
12 changes
Resolved issues and error corrections
Submenu items in the website navigation now keep the same font styling as the main navbar. This prevents submenu text from unexpectedly changing when a user updates the paragraph font, keeping website menus visually consistent.
Original PR description
To reproduce: ============= 1- Go to website 2- Add a submenu to any menu item. 3- Choose a font for the navbar. 4- Change paragraph font. → Observe that the added submenu in the navbar also changes…
To reproduce: ============= 1- Go to website 2- Add a submenu to any menu item. 3- Choose a font for the navbar. 4- Change paragraph font. → Observe that the added submenu in the navbar also changes its font. Problem: ========= When creating submenu the class nav-link which contains the navbar font was removed by theses lines: https://github.com/odoo/odoo/blob/6f5682b1cab3c2e043e1f1d4316093bab2752521/addons/website/static/src/js/content/auto_hide_menu.js#L173-L179 cause this one was false https://github.com/odoo/odoo/blob/6f5682b1cab3c2e043e1f1d4316093bab2752521/addons/website/static/src/js/content/auto_hide_menu.js#L39-L39 but in the default template the navbar has another class name https://github.com/odoo/odoo/blob/6f5682b1cab3c2e043e1f1d4316093bab2752521/addons/website/views/website_templates.xml#L498-L498 Undesired Behavior: =================== When you set a navbar font, the navbar and submenu both initially use it. But if you change the paragraph font afterward, the submenu text incorrectly switches to the paragraph font, while the navbar still uses the correct navbar font. Desired Behavior: ================== Once a navbar font is set, it should be consistently applied to both the navbar and submenu text, regardless of changes to the paragraph font afterward. Solution: ========= If we are in the navbar we will keep the nav-link class. Link for bug: https://drive.google.com/file/d/1OyWUUEvvtHw5MKITew5F_KOP_m6zgi9B/view opw-4943240 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes a Point of Sale issue where a session could lose or show the wrong user when another employee opened it in a separate browser tab. It helps ensure payments through Six terminals use the correct employee context, reducing checkout errors.
Original PR description
This commit fixes an undefined `user_id` on the pos session when trying to start a payment with a Six terminal from another user than the one that started the session. Before this commit: - open a pos session with Mitchell Admin, - check the value of `pos.session.user_id` (it will be `2`), - open another tab and connect as Marc Demo, - check the value of `pos.session.user_id` again: it should be `6`, but instead is `undefined`. After this commit: `pos.session.user_id` is set to the right `user_id` while loading pos data. opw-5055977
The web test runner now handles cases where someone clicks Run before all test assets have finished loading. This prevents an early-click crash in manual testing and makes the test workflow more reliable.
Original PR description
Before this commit, in manual mode, "Run" could be clicked before the assets finished loading (and so, before the test runner was properly "ready"). This caused a crash because it tried to resolve a promise that did not exist yet. Steps to reproduce: - Go to test URL (manual) - Click "Run" as soon as the button is visible (probably via a script to make sure the click is fast enough) This commit fixes that by adding failsafes around that promise, effecitvely allowing to click "Run" early on. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Benefits form now prevents users from creating related employee, cost, or mandatory benefit records from the selection fields. This keeps benefit setup cleaner and reduces accidental duplicate or incomplete records.
Original PR description
This commit prevents creating new employee, cost or mandatory benefits records directly from the Benefits form by setting these fields' `'no_create'` to `True`. task-5156844
Splitting a delivery now correctly updates the status of the original stock movement, not just the newly created one. This prevents warehouse users from seeing misleading availability information after part of a delivery is split off.
Original PR description
Steps to reproduce: - Create a storable product “P1” - Update its quantity to 10 - Create a delivery picking with 10 units of P1 - Confirm → The picking is in “Ready” state and the move is “Available” - Update the “Quantity” of P1 to 6 units in the picking → The move state is recomputed to “Partially Available”, since the demanded quantity exceeds the quantity done. https://github.com/odoo/odoo/blob/18.0/addons/stock/models/stock_move.py#L2207-L2208 - Split the picking Problem: A new picking is created with 4 units in quantity and its move is “Available”, but the original move with 6 units does not have its state recomputed. opw-5173374
Fixes an issue where pages containing videos added by an administrator could become uneditable for restricted website editors. Videos are now stored in a sanitizer-friendly way and rebuilt for visitors, allowing non-admin editors to keep updating website content safely.
Original PR description
Steps to reproduce the current behaviour: - Update the DEMO user to be a website "restricted editor" and sales "admin" who cannot bypass HTML field sanitization. - As ADMIN, add a YouTube video to a…
Steps to reproduce the current behaviour: - Update the DEMO user to be a website "restricted editor" and sales "admin" who cannot bypass HTML field sanitization. - As ADMIN, add a YouTube video to a product page > Save. - As DEMO, try to update the content on the product page > You cannot (a dialog informs you that you cannot edit the content because an admin edited it previously). Explanation: Starting from [1], an HTML field can be flagged as `sanitize_overridable` which allowed users with the `base.group_sanitize_override` group to skip the HTML field sanitize process. If such users added some content that is not considered "sanitize friendly" (e.g. YouTube iframe), a restricted user won't be allowed to add content in the fields, since the sanitizer will remove the original content from the DOM. For this case, the code from [2] added an implementation to consider the field as none editable and warn the user once he tries to update it. Implementation: The goal of this commit it to fix the current limitation for video upload that currently prevents non admin users to edit a website record once an admin adds a video on it... The idea of the fix is the following: - We already have a technical fallback when uploading a video to save the iframe `src` to an attribute: `data-oe-expression`. - The public widget is now destroying the video iframes so they are never saved in the DOM. - A non-lazy code will build the iframes immediately on page load. - The public widget can always create the iframes if they are not already created (for compatibility). [1]: https://github.com/odoo/odoo/commit/cf844e34dd0ce4830eb99fd0fa5b6b9cb58c867c [2]: https://github.com/odoo/odoo/commit/cb80c15d3db49ede3c93171abcaa9064b88822c6 task-3757205 Forward-Port-Of: odoo/odoo#175717
Manufacturing shop floor backorders now show the quantity needed for the specific operation instead of the total remaining manufacturing order quantity. This prevents operators from recording too many units on partially completed steps and helps keep production progress accurate.
Original PR description
**PROBLEM** When creating a backorder, the quantity to produce during an operation is correctly displayed on the shop floor step. But when clicking to modify it, the pop over display the total…
**PROBLEM** When creating a backorder, the quantity to produce during an operation is correctly displayed on the shop floor step. But when clicking to modify it, the pop over display the total quantity to produce, and not the quantity to produce in that specific operation. **STEP TO REPRODUCE** 1. create a BoM of product with 3 or more operations 2. Create a Manufacturing order for i.e. 10 unit 3. Open shop floor 4. Register the production in shopfloor: - Op1 – 10 units registered - Op2 – 7 units registered - Op3 – 5 units registered 5. At the end, a backorder is created for 5 units. 6. When we open the wizard to register the production on the Op2, the quantity to produce that is displayed is 5, which is wrong because we only need to produce 3 unit for that step. **CAUSE** When creating the confirmation dialog, we pass the wrong value `qty_remaining` which is the quantity of product we will end after finishing the Manufacturing Order. **FIX** We should pass `qty_production` instead which is the quantity to produce for the specific step. opw-5011739 Forward-Port-Of: odoo/enterprise#93599
Large PNG images uploaded to Odoo are now resized without being converted to a lower-quality color palette. This prevents visible image degradation on website content and removes the need for users to resize images manually before uploading.
Original PR description
When uploading a png image ir_attachment, the image is not modified if its resolution is under the maximum 1920x1920. However, if the resolution is bigger, it both gets resized and is converted to a WEB palette, which visibly degrades the quality of the image. A workaround for this is to resize the image locally to be max 1920 on either dimensions and then upload it, which effectively bypasses this special treatment. Steps to reproduce: - Go to the website app - Add a Text - Image snippet - Double click the image - Upload a .png image of a resolution strictly greater than 1920 in either width or height Old behavior: the png is visibly degraded New behavior: the png is not visibly degraded opw-3935533 Forward-Port-Of: odoo/odoo#173508
Helpdesk SLA reports now include the SLA status as an available grouping option. This lets users remove and reapply the grouping without having to reload the report, making analysis smoother and less frustrating.
Original PR description
Currently, when the user opens the sla reporting view, if he removes the default grouping of sla_status, he has no way to get it back unless he reloads the view completly. This commit fixes this issue by adding the sla_status field to the group_by options. task-5076401 Forward-Port-Of: odoo/enterprise#95261
After a successful test import, Odoo now resets the starting point before running the real import. This prevents users from accidentally importing only the final batch of records when using batch limits, making contact imports more reliable.
Original PR description
Steps to reproduce ================== - Go to contacts - Click on the cog menu > Import records - Upload a csv file - Limit the batch limit to a value lower than the total number of records in the csv file - Click on the test button - Click on the Import button => Only the last batch is imported Cause of the issue ================== The start line is not reset after the test import, which can be confusing Solution ======== When the test import fully succeeds, we reset the start line opw-4916102
Odoo now sends lightweight checks on inactive live connections so broken WebSocket sessions are detected sooner. This helps users on slow or unstable networks resume receiving real-time updates more quickly instead of waiting for long system timeouts.
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. 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#232352
This fix stops accounting records from being deleted when they are still used by journal entries in another company. It helps protect shared multi-company accounting data from accidental loss or inconsistency.
Original PR description
In a multi-company environment, accounts can be shared. A Python constraint prevents deleting an account if it has journal items in the current company. However, this check was missing when an account only contained journal items belonging to other shared companies. This commit fixes the issue by: 1. Updating the `ondelete` attribute of the `account_id` field on `account.move.line` to cascade the restriction at the database level. 2. Updating the existing Python constraint on `account.account` to enforce this logic in stable versions without a module update (this will be removed in the master branch). task-5158966 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
12 changes
Enhancements to existing features
Stock synchronization logs for Amazon sales now include the related account ID. This gives support teams clearer context when investigating customer stock sync issues, helping them resolve cases more efficiently.
Original PR description
Based on feedback from the support team, additional information has been added to the stock sync logging messages. This enhancement includes the account ID for better traceability and to help the team understand customer issues more effectively.
Odoo now routes Peppol partner lookup checks through its IAP service so it can support the Peppol network’s upcoming DNS change. This helps keep electronic invoicing partner discovery working after the switch from CNAME to NAPTR records, without requiring unsupported package changes in stable versions.
Original PR description
Starting from 1st November, the Peppol SML will start to use NAPTR records instead of CNAME. This mainly allow them to enforce a specify a scheme (https). To be able to retrieve this specific type of records and follow the replacement record we need `pythondns` package which is not available in stable versions. We therefore will now use IAP to serves as a bridge to query the Peppol network when retrieving a partner services/existence on Peppol. This solution is also good to handle future changes by moving most of the logic into IAP where stable policy is easier to handle. Related: https://github.com/odoo/iap-apps/pull/1203 Documentation: https://docs.peppol.eu/edelivery/changelog/2025-04/Peppol%20CNAME%20to%20NAPTR%20Migration%20Process%20v1.0.0%202025-04-17.pdf task-5059508
Electronic invoices can now use a fallback payment code when no bank account is configured, avoiding validation errors in BIS3 exports. This makes initial setup smoother for businesses that have not added bank details yet.
Original PR description
Backport of commit 026743fb2627edeada5ae2a517b64bf05ae921ae . To generate a valid BIS3 format, if we put 30 - credit transfer as payment means, we need to have a bank account set. If it's not the case, it will raise an error. We improve the usability by changing that code to ZZZ - mutually defined if no bank account is provided to the invoice. This should improve the onboarding flow when no bank account is set yet. task-None Forward-Port-Of: odoo/odoo#232795
Resolved issues and error corrections
This fix ensures the point of sale cash drawer can still be opened through an ePOS printer even when a configured IoT box is unreachable. It prevents store staff from being blocked at payment by an unrelated disconnected device.
Original PR description
Steps to reproduce: 1. Configure a POS to use an ePOS printer with the cashdrawer enabled. 2. Also configure the POS to use an IoT box with a dummy device, e.g. '[Shop] Scale'. The important thing is that the IoT box is not reachable when the POS opens, so the dummy devices work well for this. 3. Open the POS, make an order and go to payment, then click 'Open cashbox'. Expected behaviour: The cashdrawer opens Actual behaviour: Nothing happens task-5059502 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix makes a website-related automated test independent from optional demo data. It helps ensure test results are more consistent, reducing false failures in development and release validation.
Original PR description
runbot-162894
Italian electronic bill imports now avoid applying the same discount twice when the XML contains both a discount section and a separate negative line. This helps keep vendor bill totals accurate and prevents extra manual correction after import.
Original PR description
When importing a bill in an IT company the system will automatically parse the xml and populate the record. In case of discount, an element <ScontoMaggiorazione> will be present, either for the whole document or for a single line. However, an extra negative line may be present in the xml representation of the bill, creating a double discount **Steps to reproduce** - With an IT Company setup - Import an xml bill having <ScontoMaggiorazione> element and a negative line representing the same discount **Issue** Double discount line will be created in the bill **Analysis** This occurs because, when parsing the bill, the system will import also negative lines, even if a discount has been already applied opw-4913335 [Ticket link](https://www.odoo.com/odoo/project/49/tasks/4913335)
Large email campaigns can now retry failed sends in smaller batches, avoiding memory failures when hundreds of thousands of emails are involved. This helps larger organizations recover from temporary mail server outages without manual cleanup or lost campaign progress.
Original PR description
Steps to reproduce the issue: 1. Have 100s of thousands of recipients on a campaign 2. Disconnect your outgoing server and send 3. Reconnect the mailing server and retry sending. Current behavior before PR: A `MemoryError` is raised due to the large number of emails processed to `unlink()` Desired behavior after PR is merged: Larger-scale clients would be able to resend 100s of thousands of emails if they fail opw-5091567
Responsible HR users can now sign offers without errors when employees request extra time off and automatic allocation is enabled. This helps keep salary package and holiday workflows moving smoothly without manual intervention.
Original PR description
- When the employee requested extra time off, and the automatic allocation setting was turned on, signing the offer as the responsible HR caused an error. Task-5022631 Forward-Port-Of: odoo/enterprise#92663
Peppol document routing now uses Odoo's IAP service to handle the required DNS lookup changes before older CNAME-based lookups are discontinued. This keeps electronic invoicing connectivity working as Peppol infrastructure requirements change and centralizes future lookup updates.
Original PR description
From November 1st, CNAME DNS will be deprecated for Peppol lookups. From February 1st CNAME lookups will no longer be supported. The replacement are NAPTR DNS records. Multiple solutions were available, such as using DoH (e.g. with cloudflare DNS), but we ended up choosing to proxy DNS requests through IAP to centralize the lookups and make such specs upgrades easier to handle in the future. IAP is now responsible of doing the DNS lookup and fetching the service groups of the found SMP. IAP-side: https://github.com/odoo/iap-apps/pull/1227 task-5179969
This fixes an error that could interrupt Ingenico card payments in Point of Sale. The system now avoids unnecessary repeated status updates and only contacts the database when payment activity or driver status changes, improving payment reliability for store operations.
Original PR description
Currently when paying with ingenco there is an error: "Uncaught (in promise) TypeError: can't access property "payment_method", line is undefined." This is due to the fact that Ingenco sends requests to the database every second even when the status of the driver didn't change since the last payment. This PR fixes the issue by only sending requests to the database if a) THe driver status has changed b) A payment is being processed It also fixes the deprecation warning for isSet() replaced by is_set(). opw-5166439 opw-5181429 opw-5164612 opw-5170658
This fixes an issue where users could add tax tags to journal items dated before the tax lock date, potentially changing already locked tax reports. The system now checks tax lock rules before and after edits so protected tax reporting periods remain unchanged.
Original PR description
Despite the tax lock date, users are able to modify the tax report by adding tags.
**Steps to reproduce:**
Ensure the tax lock date is set
1. Journal Items list view
2. Edit one/many lines that
- have a date before the tax lock date,
- don't have a tax,
- nor tax tags,
- and is not a tax line.
3. Add a new tax tag
**Issue:**
The tax tags are added and might impact a tax report, when you should have received a user error.
**Cause:**
The `write` function calls the `_check_tax_lock_date` which in turn only checks the existing line instead of the values given in the `write` parameters. Since the line has no existing tax tags the check does not fail.
**Solution:**
Call the tax lock check both before and after writing the move line.
Task-5169152Landscape reports printed through a Virtual IoT Box will now keep their intended orientation instead of being cropped as portrait pages. This prevents wasted paper and ensures printed business documents match the on-screen report layout.
Original PR description
When printing a landscape report using a Virtual IoT Box, we end up printing a portrait page cropped. This commit adds the "pdf fit page" argument to ensure the page printed follows the report orientation. opw-5051809 Task: 5149706