Daily updates from Odoo
Wednesday, October 29, 2025
33 changes · saas-18.3
Resolved issues and error corrections
A test for timesheets involving time off and public holidays now uses the correct user context instead of an employee record. This helps keep automated checks accurate and reduces the risk of regressions in timesheet and holiday handling.
Original PR description
In the 'test_timesheet_time_off_including_public_holiday' test case, 'employee' was mistakenly passed to 'with_user'. This commit replaces 'employee' with 'user' for consistency. task-4809916 Forward-Port-Of: odoo/odoo#233366
Third-party checks now use the actual most recent operation to determine whether they are still on hand. This prevents checks that have already been both received and used for payment from incorrectly appearing as available.
Original PR description
**Steps to reproduce:** 1. Install the modules: `accounting`, `l10n_ar`, and `l10n_latam_check`. 2. Create a third-party check journal: * Add payment methods: *New Third Party Checks* (inbound) and…
**Steps to reproduce:** 1. Install the modules: `accounting`, `l10n_ar`, and `l10n_latam_check`. 2. Create a third-party check journal: * Add payment methods: *New Third Party Checks* (inbound) and *Existing Third Party Checks* (outbound). * Configure outstanding accounts for both methods. 3. Create a vendor payment: * Use the third-party check journal. * Select the *Existing Third Party Checks* method. * Leave the check list empty. * Keep the payment in *Draft*. 4. Create a customer payment: * Use the same journal and select the *New Third Party Checks* method. * Add a new check under the *Checks* tab. * Post the payment. 5. Return to the draft vendor payment created in step 3: * Add the newly created check to it (via *Add a line*). * Post the payment. 6. Go to **Customers → Third Party Checks**. **Observed behavior:** - The check still shows a `current_journal_id` even though it has both inbound and outbound operations. - As a result, the check incorrectly appears in the 'On Hand' filter. **Root cause:** - `_get_last_operation` was sorting operations by `date`. - In some scenarios or flows where multiple operations share the same `date`, the wrong operation could be selected as the "last one", leading `_compute_current_journal` to assign a journal incorrectly. **Solution:** - Sort operations by `write_date` to always pick the true last operation. - This ensures `_compute_current_journal` correctly clears `current_journal_id` whenever both inbound and outbound operations exist. opw-5012903 Forward-Port-Of: odoo/odoo#225556
Updating a customer statement email template no longer fails when all recipients have been removed. This prevents an unexpected error and lets users continue editing the email before choosing recipients.
Original PR description
Currently, an error occurs if the recipients of the statement report are removed and the user tries to update the email template. **Steps to Reproduce:** 1. Install Accounting. 2. Customers (list view) > select any record > Actions > Customer Statement > Send. 3. Remove recipients and try to update the email template. **Error:** `KeyError - False` **Cause:** The system tries to fetch mail field values from an empty recipient list, leading to a KeyError. **Fix:** This commit recomputes the recipient partners before updating the email subject and body from the template. sentry-6918345730 Forward-Port-Of: odoo/enterprise#96273
Cancelled restaurant POS orders are now removed from the Ticket Screen instead of appearing under paid orders. This keeps staff views accurate and reduces confusion when reviewing completed or cancelled sales.
Original PR description
pos*: point_of_sale, pos_restaurant Steps to reproduce: - Open the Restaurant POS and place an order. - Send it to the preparation screen by clicking Order. - Reopen the order and cancel it via the Action button. Issue: - The cancelled order still appears under the Paid section on the Ticket Screen. Fix: - Cancelled orders are now excluded from the Ticket Screen display. - Remove canceled orders from local records. Task: 4936636 Forward-Port-Of: odoo/odoo#231977 Forward-Port-Of: odoo/odoo#219402
This fix prevents Swedish payment batches using IBAN accounts from being incorrectly identified as local BBAN payments when account type details are missing. It helps avoid misclassification in payment processing and restores the expected behavior validated by automated tests.
Original PR description
The method `_is_se_bban` is supposed to flag if payments are bban or iban. But since 8d77c0442d7912880c5da5976c92b24d3f9885ca,
the method returns True for batch of iban payments when you don't provide the `partner_acc_type` params, because
`len({'bban_se', 'plusgiro', 'bankgiro', *(partner_acc_type or {})}) == 3`
is always True if `partner_acc_type` is None.
This commit fix that behaviour, by replacing the empty set by `{'iban'}`, meaning the second condition will always be
False when `partner_acc_type` is None.
This bug has been found by failing runbot tests (error: 233465)
no-task
Forward-Port-Of: odoo/enterprise#97876This fix restores the intended accounting setup for rounding differences in the French localization. It ensures those amounts are assigned to the correct type of account, helping keep financial records consistent and compliant.
Original PR description
These accounts were changed by mistake. Even more, they're of the wrong type. Re-add account to be consistent with 758 opw-5180702 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232902
This fixes an issue where testing a contact import with smaller batches could cause the final import to start from the wrong place and only import the last batch. After a successful test import, the import process now resets correctly so all records are included when the user proceeds.
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 Forward-Port-Of: odoo/odoo#232938 Forward-Port-Of: odoo/odoo#230805
This fixes an issue where adding a column in the report editor could update only some rows when report headers used conditional display rules. Business users editing delivery slips and similar reports should now see columns added consistently across the table.
Original PR description
The TableSizeComputer.compute() method can return cells with incorrect cell indexes. This can result in the _addColumn function only adding a column to some rows in the report editor.…
The TableSizeComputer.compute() method can return cells with incorrect cell indexes. This can result in the _addColumn function only adding a column to some rows in the report editor. TableSizeComputer.compute() does not handle cases where a conditional is used inside of a th element but the corresponding td element does not have a conditional. Steps to reproduce ----- 1. Open the Delivery Slip in the report editor. 2. Click the header to show the dropdown and select elif: o.move_line_ids and o.state=='done'. 3. Hover over the last th element to select the column button. 4. Click Insert right and see that only the header row has an additional column. Cause ----- TableSizeComputer.compute() calculates how many possible cells can be in a row which can be more than the total number of columns you have if you have th or td elements with a conditional inside of them. In the Delivery Slip report, a th element is present when using serial numbers and a different th element is present when not using serial numbers. The corresponding t-body has two different tr elements for these conditions. The compute method will have one less cell in these rows because the corresponding conditional is handled outside of the row. Solution ----- Only count mutually exclusive th or td elements once. This prevents the cellIndex from being larger than the total possible columns. opw-ticket 5173345 Forward-Port-Of: odoo/enterprise#98207
This fix ensures Peppol-related partner screens are built on the correct accounting e-invoicing views. It prevents upgrade or installation errors when the expected e-invoicing fields are not available in the base partner view.
Original PR description
Currently the following views inherit from `base.view_partner_tree`: - `res_partner_form_account_peppol` - `res_partner_view_tree` The views mentioned about contain xpath expressions based on the `ubl_cii_format` field. But the view in `base` does not include the field yet. It is added in module `account_edi_ubl_cii`. This commit changes the inheritance to be from the equivalent views in `account_edi_ubl_cii` instead. Otherwise there is an error in a test when upgrading from 16.0 to 17.0 with the backported `account_peppol` to 16.0. task-4925169 Forward-Port-Of: odoo/odoo#233461 Forward-Port-Of: odoo/odoo#231637
This fixes an issue where certain point-of-sale loyalty rewards could add one more product than the cashier intended, such as when changing quantities with the numpad. It also restores the intended reward calculation so eligible free items are applied correctly for configured promotions.
Original PR description
After commit https://github.com/odoo/odoo/commit/b86dd8f0674f02a14f4aaa10db39bd4a1e8270f1, an extra order line could be added unintentionally. For example, in a "Buy X Get Y" loyalty program, if you add the product and press 3x on the numpad, the system would incorrectly add 3x + 1 products to the order. Moreover, the fix introduced in the above commit was not correct according to the program logic. For instance, if the configuration is set to "Grant: 1 credit per order" with a minimum quantity of 2, and the reward is for one point, then when ordering 2 products, one of them should indeed be free. The previous fix changed this intended behavior, resulting in incorrect reward application. opw-5151979 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232192 Forward-Port-Of: odoo/odoo#231704
Website forms no longer crash when a field originally set to prefill contact details is changed into an attachment upload field. This keeps form editing and saving reliable for website managers making changes to contact forms.
Original PR description
Steps to reproduce: =================== 1- Add a Contact Us form. 2- Change the "Phone" field type to "Attachment" and save. → Traceback occurs. Cause: ====== After changing the field type, the field…
Steps to reproduce: =================== 1- Add a Contact Us form. 2- Change the "Phone" field type to "Attachment" and save. → Traceback occurs. Cause: ====== After changing the field type, the field still keeps its `fillWith` value. When saving or refreshing, the system tries to prefill it with a phone number. Since the type is now "file", it cannot be prefilled, causing a traceback. Why it didn't happen before: ============================ In older versions, fields were fetched using `serializeArray()`: https://github.com/odoo/odoo/blob/ad03751ef0a9e617c2b24a30b1c06aa4e25d48a1/addons/website/static/src/snippets/s_website_form/000.js#L167 That method automatically filtered out unsupported input types: https://github.com/odoo/odoo/blob/ad03751ef0a9e617c2b24a30b1c06aa4e25d48a1/addons/web/static/lib/jquery/jquery.js#L9001 Fix: ==== Exclude fields of file-like types from the prefill logic, similar to the behavior of `serializeArray()`. opw-5145855 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231185
This fixes an issue where customer information chosen after adding an online payment in Point of Sale was not saved correctly once the payment was completed. It helps ensure orders paid online are linked to the right customer for receipts, reporting, and follow-up.
Original PR description
Before this commit, if a partner was selected after adding an online payment line, the partner was not synced after completing the online payment. opw-5098127 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232547 Forward-Port-Of: odoo/odoo#232455
Fixes an issue where Safari users could not reliably apply, cancel, or choose link types when editing links in the HTML editor. This makes link editing in email templates and other rich text areas behave consistently across browsers.
Original PR description
## Issue: On Safari, the Apply and Dismiss buttons of the LinkPopover did not trigger their actions In some cases, it seemed to work only because a temporary link was not properly cleared The Link…
## Issue: On Safari, the Apply and Dismiss buttons of the LinkPopover did not trigger their actions In some cases, it seemed to work only because a temporary link was not properly cleared The Link Type Selection was also broken by the same bug ## Cause: Safari triggers a `pointerdown` event through the `LinkPopover`, which changes the `selection` and calls the `handleSelectionChange()` method https://github.com/odoo/odoo/blob/e43135e94bf22bc2f7a115c37e8a082f96871ed0/addons/html_editor/static/src/main/link/link_plugin.js#L672-L678 At that point, `documentSelection` is `null`, causing the overlay to close before the `onClickApply()` on the Apply button It's the same issue with the Dismiss button and the Link Type Selection ## Steps to reproduce: - Install mail to get access to an html_editor - Enable debug mode - Go in Email Templates and open one of them - Select a text and open link tools - Add Odoo.com and click on Apply - The link may seems to be created (if it's the case, there is no preview) - You can confirm that with the link type selector that closed the popover before the fix opw-5115887 Forward-Port-Of: odoo/odoo#233401 Forward-Port-Of: odoo/odoo#233241
The Swedish Point of Sale integration now correctly prevents receipts from being reprinted more than once, helping businesses stay compliant with local receipt-control requirements. It also improves blackbox error handling so disconnected devices and driver issues are reported more clearly instead of leaving the screen stuck loading.
Original PR description
Before this commit, the receipt reprint check logic (which only allows a receipt to be reprinted once) was not working. There were two issues preventing it from working: - The name of the function had changed but not been updated in this module, so the override was not applied. - The ID being used to check the order was incorrect. A few smaller issues were also fixed: - A logging issue in the IoT driver, which prevented the error severity from being printed. - An infinite loading UI if the blackbox was disconnected. - The blackbox error handler swallowing up some errors due to only expecting one specific format. Forward-Port-Of: odoo/enterprise#98271 Forward-Port-Of: odoo/enterprise#98076
Product packaging conversion lists now show a proper unit name instead of displaying “Undefined” when a unit has no related reference unit set. This prevents confusing packaging information for users setting up or reviewing product sales units.
Original PR description
### Steps to reproduce: - In the settings enable "Product Packaging" - Create a product and set its `uom_id` (next to sales price) to "pack of 6" - In the sales tab click on Packagings > This opens a list view of units with convertions #### > The "Units" is converted to "1 Undefined" ### Cause of the issue: The "Units" uom does not have any set `relative_uom_id` so that `record.relative_uom_id[1] ` is undefined: https://github.com/odoo/odoo/blob/e44ea4adbe56586349b78ae4796803777d8a782a/addons/uom/static/src/components/many2x_uom_tags/many2x_uom_tags.js#L74 opw-5189284 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233074
This fix prevents accounting updates from failing when analytic lines have no distribution information. Odoo now skips those empty entries safely, helping analytic accounting workflows continue without interruption.
Original PR description
Description of the issue/feature this PR addresses: This pull request addresses a bug in Odoo's analytic accounting module. Specifically, when updating analytic lines that have empty distributions,…
Description of the issue/feature this PR addresses: This pull request addresses a bug in Odoo's analytic accounting module. Specifically, when updating analytic lines that have empty distributions, the vals_list[0] ends up being empty. This situation causes an error in the write method, which prevents the system from properly updating analytic lines without distributions. Current behavior before PR: Before this fix, attempting to update analytic lines with empty distributions triggers an error in the write method. As a result, operations that involve updating such lines fail, potentially interrupting normal accounting workflows. Desired behavior after PR is merged: After merging this PR, the system will first check whether an analytic line has a valid distribution before attempting to update it. Lines with empty distributions will be safely skipped, preventing errors and allowing the rest of the analytic updates to proceed smoothly. This ensures more robust handling of analytic lines and avoids runtime exceptions during updates. Video: https://app.screencastify.com/watch/03zuCLh984kWun2Q71tK Odoo Task: https://www.odoo.com/es_ES/my/tasks/5181171 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232176
This fix prevents SAF-T general ledger reporting from failing when an accounting entry has no linked partner. It improves report reliability for businesses exporting compliance data.
Original PR description
### Issue: After #95804 , some of the code was improved but the consideration for partner_id being None was not expected. To fix this issue, we add partner_id on the domain. OPW-5177365 Forward-Port-Of: odoo/enterprise#98240
Repair order users can no longer enter a serial number on a new repair line before that line has been saved. This prevents the serial number from being lost during save and avoids confusion or rework when handling serialized products.
Original PR description
When creating a repair order, if you add a line and assign a serial number before saving the line, the serial number is removed when saving. Steps to reproduce: - Create a repair order and save it. - Add a repair line with a product tracked by serial number. - Without saving the repair order, add a serial number on the line. - Save the repair order. - You will notice that the serial number is no longer assigned to the repair line. This PR fixes the issue by making the serial number field read-only until the repair line is saved. opw-5156267 Forward-Port-Of: odoo/odoo#233264 Forward-Port-Of: odoo/odoo#232973
This fix prevents editor-specific list styling from unintentionally changing regular page content when the editor is loaded. It keeps website and backend content looking consistent by limiting the styling to the intended editor area.
Original PR description
Problem: The CSS selector `li *` was applied globally, affecting all list content on pages where the editor is loaded — including frontend content outside the editor. Cause: The selector was not scoped to the editor context, so its styling leaked into non-editor elements. Solution: Restrict the `li *` selector to apply only within headers inside the editor to prevent unwanted global styling. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232336
Default pallet dimensions for DHL deliveries have been corrected from millimeter-sized values to the centimeter values expected by DHL. This prevents delivery validation errors and allows shipping labels to be generated when using DHL pallets with default settings.
Original PR description
## Short functional explanation of the error When setting the 'DHLxw Package Type' of a DHL delivery method to 'DHL pallets' without changing default values, trying to validate an order delivery…
## Short functional explanation of the error When setting the 'DHLxw Package Type' of a DHL delivery method to 'DHL pallets' without changing default values, trying to validate an order delivery causes an error. ## Reproduction Steps 1. Type 'Delivery method' in the dashboard. Select DHL BE, set the region to Europe and the 'DHLxw Package Type' to 'DHL pallets'. Click on the arrow at the right of 'DHL pallets'. You should see the default values set to 1200, 1600 and 1200. These correspond to millimeters, while DHL expects centimeters. 2. Make sure you're using a company located in Belgium. 3. In the inventory settings, make sure that either 'multi-step route' is unchecked or that for your warehouse, the outgoing shipments are set to '1 step'. 3. Create a new quotation. Select a Customer with a Belgian address. Add a product for which there's at least 1 copy in stock. 4. Click on add shipping and select DHL BE. Then click add and ok. 5. Click on confirm. A smart button at the top of the page called "delivery" should appear. Click on it and set the scheduled date to a future day. Finally, click validate. ### Expected behavior New labels should generate without issue. ### Unexpected behavior An error occurs: ```Bad request Multiple problems found, see Additional Details 1001: The requested product(s) (N) not available based on your search criteria.(687662d08999745d3df3783068fcca24) 410107: The piece height exceeds max, N/- 410304: No products available ``` ## Origin of the issue The default values for DHL are set to 1200, 1600 and 1200, which correspond to millimeters. However, DHL expects centimeters, for which the default value is thus too high. Note: because the issue stems from default values, after implementing the fix, the module should be reinstalled. __ opw-4804639 Forward-Port-Of: odoo/enterprise#90272
Fixed an issue where course slide names containing a vertical bar could cause the browser title to show the wrong website name after switching slides. This keeps the page title consistent and avoids confusion for learners navigating course content.
Original PR description
How to reproduce: - Go to a course with a slide containing "|" in its name. (e.g. Basics of Gardening) - Change slide to this special named slide. - Change back to another slide. - The browser title contains the string part after the "|" instead of the website name. This commit now handles slides with name containing the "|" character. Task-5152858 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230489
Fixes an issue where deliveries linked to split manufacturing orders could show only the first produced quantity instead of the full ordered amount. This helps sales and warehouse teams see accurate delivery quantities when manufacturing backorders are completed.
Original PR description
Issue ----- After splitting a MO, the linked delivery's quantity only gets updated when the original MO is validated. Validating the backorder MOs doesn't affect the shown quantity. Steps to…
Issue ----- After splitting a MO, the linked delivery's quantity only gets updated when the original MO is validated. Validating the backorder MOs doesn't affect the shown quantity. Steps to reproduce ----- - Unarchive MTO route - Create a stored product - Routes MTO & Manufacturing - Empty BoM - Create a Sale Order for 3 units of the product & confirm it - Go to the linked MO and split it in 2 (quants of 1 and 2) - Confirm both MOs (and produce) - Go to the sale's delivery > The delivery's move only shows 1 unit of the product Why the move quantity is only 1 ----- After confirming the first of the 2 backorder productions, when we manufacture the product, we go through https://github.com/odoo/odoo/blob/e6b87a2a37b4550faf60a77981c533d19aa054d4/addons/mrp/models/mrp_production.py#L2054 Since the first backorder kept the existing move, it has the delivery move in `move_dest_ids` so we do https://github.com/odoo/odoo/blob/e6b87a2a37b4550faf60a77981c533d19aa054d4/addons/stock/models/stock_move.py#L2088-L2091 Which creates a SML for the delivery move when reserving it https://github.com/odoo/odoo/blob/e6b87a2a37b4550faf60a77981c533d19aa054d4/addons/stock/models/stock_move.py#L1853-L1858 https://github.com/odoo/odoo/blob/e6b87a2a37b4550faf60a77981c533d19aa054d4/addons/stock/models/stock_move.py#L1950-L1971 This in turn triggers the computation of the move's quantity since it depends on the move's lines https://github.com/odoo/odoo/blob/e6b87a2a37b4550faf60a77981c533d19aa054d4/addons/stock/models/stock_move.py#L382-L383 Our move ends up with a quantity of 1. When we proceed with the second MO, things are a little different since there is nothing in `moves_todo.move_dest_ids` when we do https://github.com/odoo/odoo/blob/e6b87a2a37b4550faf60a77981c533d19aa054d4/addons/stock/models/stock_move.py#L2088-L2091 This means we don't create a new SML for the delivery move, so the quantity stays at 1. Why there is no move_dest_id ----- When splitting the production, we go through https://github.com/odoo/odoo/blob/bc22cf5a225a4e7d58548a8d6dedbcd84d771acb/addons/mrp/models/mrp_production.py#L1815-L1829 We create new a MO and SM for the backorder. The SM is created here https://github.com/odoo/odoo/blob/bc22cf5a225a4e7d58548a8d6dedbcd84d771acb/addons/mrp/models/mrp_production.py#L1894-L1915 When preparing the values, we correctly copy the `move_dest_ids` of the original MO's SM, see https://github.com/odoo/odoo/blob/bc22cf5a225a4e7d58548a8d6dedbcd84d771acb/addons/mrp/models/stock_move.py#L646-L656 So when the backorder is created, its' SM has a correct `move_dest_ids`. The problem actually comes from what happens after `_split_productions` in `action_split` when we set the `date_start` https://github.com/odoo/odoo/blob/bc22cf5a225a4e7d58548a8d6dedbcd84d771acb/addons/mrp/wizard/mrp_production_split.py#L68-L78 In the write, we get to a line where we access the production's state https://github.com/odoo/odoo/blob/bc22cf5a225a4e7d58548a8d6dedbcd84d771acb/addons/mrp/models/mrp_production.py#L931 This triggers a recompute of the field. https://github.com/odoo/odoo/blob/bc22cf5a225a4e7d58548a8d6dedbcd84d771acb/addons/mrp/models/mrp_production.py#L539-L552 In the compute, we access `move_finished_ids`, which again triggers a recompute. In this compute, we call `_create_update_move_finished` https://github.com/odoo/odoo/blob/bc22cf5a225a4e7d58548a8d6dedbcd84d771acb/addons/mrp/models/mrp_production.py#L800 The problem is that the move we create gets its' `move_dest_ids` from the MO instead of using the one populated using `group_orders` (098af2f). https://github.com/odoo/odoo/blob/bc22cf5a225a4e7d58548a8d6dedbcd84d771acb/addons/mrp/models/mrp_production.py#L1142-L1167 ----- Ticket: opw-4865082 Forward-Port-Of: odoo/odoo#232712 Forward-Port-Of: odoo/odoo#223792
Assets created from vendor bills now calculate their original value using only the deductible portion of bill lines. This prevents overstating asset values when a bill includes non-deductible amounts, improving accounting accuracy.
Original PR description
We allow the user to create an asset from a bill with lines which are not fully deductible but the created asset's original value is the based on the entire balance of the journal item. It should be only the deductible part. task-5156256 Forward-Port-Of: odoo/enterprise#97505
This update makes the online shop wishlist test start from a clean wishlist before continuing. It helps prevent random test failures, improving confidence in the stability of future website shop updates.
Original PR description
Add a step to make sure the wishlist is empty before continuing the tour runbot-229616 Forward-Port-Of: odoo/odoo#233262
The Tasks shortcut on a sales order now preserves the user's current language and other settings when opening related tasks. This prevents menus from unexpectedly switching back to English for users working in another language.
Original PR description
Repro:
- Activate any language different than english
- Create a service product with create Project & Task
- Create a sales order with the product
- Navigate with smart buttons Project > Tasks > Activate Top Menu
- All good
- Now navigate directly to Tasks from the sales order
- Top Menu is in English
Issue:
- The issue here is the context language being lost due to context overriding in the code.
Fix:
- In this commit, I have updated the method from `with_context({'active_id': self.id})` to
`with_context(active_id=self.id)`. This fix ensures that the previous context is retained.
opw-5160373
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#233362Lithuanian payroll now avoids charging the pension accumulation contribution twice when it is enabled on an employee contract. This helps payslips reflect the expected employee social security contribution and prevents over-deducting payroll amounts.
Original PR description
**Issue**
When generating a payslip for an employee with the `l10n_lt_pension` setting enabled on the contract ("Participate to pension accumulation system"):
- the SSC is raised from 19.5% to 22.5%
- a 3% pension contribution ("Pension Scheme") is added This effectively doubles the expected contribution.
Various sources (e.g. https://taxsummaries.pwc.com/lithuania/individual/other-taxes) seem to show this is not correct.
opw-5067664
Forward-Port-Of: odoo/enterprise#98177
Forward-Port-Of: odoo/enterprise#95880This fix prevents the Point of Sale from crashing for Italian companies using the Italian fiscal printer setup when a cashier deletes a product line. It improves checkout reliability by safely handling zero-value lines during tax calculations.
Original PR description
Currently POS crashes with the Italian localization if they delete a product line. Steps to reproduce: ------------------- * Install l10n_it_pos and switch to the IT company * Create a pos and…
Currently POS crashes with the Italian localization if they delete a product line. Steps to reproduce: ------------------- * Install l10n_it_pos and switch to the IT company * Create a pos and configure Italian printer * Open shop * Add a product to cart * On the numpad try deleting the line > Observation, pos crashes Traceback: TypeError: Cannot read properties of undefined (reading 'tax_details') Why the fix: ------------ When first hitting the delete button we will put the price unit to 0. With that we have ``` const reduced_base_lines = Object.values(base_line_map).filter( (base_line) => !floatIsZero(base_line.price_unit, base_line.currency_id.decimal_places)); ``` returning an empty list. Utlimately making `reduce_base_lines_to_target_amount` return an empty list. `[][0]` returns `undefined` and we were passing `[undefined]` in parameters of `fix_base_lines_tax_details_on_manual_tax_amounts`, we enter the loop with undefined and try to access some variables. We also set `l10n_it_epson = False` in order to avoid recursively looping. opw-5184113
This update ensures Odoo can still be installed on newer Debian and Ubuntu versions after an older PDF-related system package was removed. It falls back to the replacement package, reducing installation failures for supported environments.
Original PR description
pypdf2 is not present anymore in debian/trixie Fallback on pypdf if pypdf2 is not available Note that it should mainly fix the deb_install but future fixes may be needed Forward-Port-Of: odoo/odoo#233598
This fix helps automated tests end cleanly by detecting processes that are still running after a test finishes. It also logs a warning when leftover processes are found during server shutdown, reducing the risk of stalled test runs and improving reliability for future releases.
Original PR description
In some case a process could remain aive at the end of a tests In addition to possible race condition, this can also cause a program to remain stuck at the end of the tests. This commit proposes to - catch all remaining processes at the end of a base case. - log a message if a process is found at the shutdown of the server. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231942
This fixes an internal manufacturing test that could pass or fail depending on tiny timing differences during work order processing. The change improves reliability of automated checks, reducing false failures without changing customer-facing manufacturing behavior.
Original PR description
### Issue: The test `test_mrp_backorder_operations` behaves non-deterministically. It may fail at this assertion:…
### Issue: The test `test_mrp_backorder_operations` behaves non-deterministically. It may fail at this assertion: https://github.com/odoo/odoo/blob/6e37542b53f9c9ec1baf8d58b1eeca376252186f/addons/mrp/tests/test_backorder.py#L986-L989 Because the `duration` of done workorder can vary. ### Cause: The delta time between `button_start()` and `button_finish()` https://github.com/odoo/odoo/blob/6e37542b53f9c9ec1baf8d58b1eeca376252186f/addons/mrp/tests/test_backorder.py#L983-L985 `button_finish()` triggers `Productivity._close()` https://github.com/odoo/odoo/blob/6e37542b53f9c9ec1baf8d58b1eeca376252186f/addons/mrp/models/mrp_workcenter.py#L572-L576 Which sets `Productivity.duration` to 0 if delta time is zero. Consequently, `workorder.duration` also becomes zero. When `bo_2.button_mark_done()` is called, the duration is set to `duration_expected` (240 in this test), which the assertion only can pass in that case. If delta time isn't zero, then duration will also be non-zero. So it will not set to `duration_expected`. As a result the assertion will fail. runbot-233247 Forward-Port-Of: odoo/odoo#231650
This change prevents French point-of-sale certification checks from treating orders without secure sequence numbers as valid previous orders. It avoids incorrect errors during database upgrades or recomputation, helping affected businesses complete maintenance smoothly.
Original PR description
## Description of the issue/feature this PR addresses: When obtaining the previous order for pos.order records, all orders with l10n_fr_secure_sequence_number == NULL will be recognised as the…
## Description of the issue/feature this PR addresses:
When obtaining the previous order for pos.order records, all orders with l10n_fr_secure_sequence_number == NULL will be recognised as the previous order for those where l10n_fr_secure_sequence_number == 1, as if their sequence value was zero.
## Current behavior before PR:
Since there can be more than one orders without sequence number, this behaviour will trigger an UserError exception, as the ORM will mistakenly deduce that there are multiple previous orders for a single one, which is not necessarily correct.
### Examples:
upg-3170341
```sql
lare_3170341=> SELECT count(id) FROM pos_order WHERE l10n_fr_secure_sequence_number IS NULL;
count
-------
67281
(1 row)
```
```python
# Debugging standard codebase with a Python debugger
...
match = prev_map.get(order.l10n_fr_secure_sequence_number - 1, []) # len(match) == 67281
if len(match) > 1:
raise UserError(_('An error occurred when computing the inalterability...'))
...
```
upg-3170341
```sql
lare_3167621=> SELECT count(id) FROM pos_order WHERE l10n_fr_secure_sequence_number IS NULL;
count
-------
294
(1 row)
```
```python
# Debugging standard codebase with a Python debugger
...
match = prev_map.get(order.l10n_fr_secure_sequence_number - 1, []) # len(match) == 294
if len(match) > 1:
raise UserError(_('An error occurred when computing the inalterability...'))
...
```
---
Traceback group: https://upgrade.odoo.com/odoo/tbg/1869
```
2025-09-30 07:48:30,945 329 INFO db_3167621 odoo.modules.loading: Loading module l10n_fr_pos_cert (110/131)
2025-09-30 07:48:31,375 329 INFO db_3167621 odoo.modules.registry: module l10n_fr_pos_cert: creating or updating database tables
2025-09-30 07:48:31,432 329 INFO db_3167621 odoo.models: Prepare computation of pos.order.previous_order_id
2025-09-30 07:48:31,597 329 WARNING db_3167621 odoo.modules.loading: Transient module states were reset
2025-09-30 07:48:31,597 329 ERROR db_3167621 odoo.modules.registry: Failed to load registry
2025-09-30 07:48:31,597 329 CRITICAL db_3167621 odoo.service.server: Failed to initialize database `db_3167621`.
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/service/server.py", line 1361, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-13>", line 2, in new
File "/home/odoo/src/odoo/18.0/odoo/tools/func.py", line 97, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 129, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 485, in load_modules
processed_modules += load_marked_modules(env, graph,
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 365, in load_marked_modules
loaded, processed = load_module_graph(
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 206, in load_module_graph
registry.init_models(env.cr, model_names, {'module': package.name}, new_install)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 618, in init_models
func()
File "/home/odoo/src/odoo/18.0/odoo/addons/base/models/ir_model.py", line 2007, in _reflect_relation
self.env.invalidate_all()
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 839, in invalidate_all
self.flush_all()
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 857, in flush_all
self._recompute_all()
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 850, in _recompute_all
self[field.model_name]._recompute_field(field)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 7359, in _recompute_field
field.recompute(records)
File "/home/odoo/src/odoo/18.0/odoo/fields.py", line 1463, in recompute
apply_except_missing(self.compute_value, recs)
File "/home/odoo/src/odoo/18.0/odoo/fields.py", line 1436, in apply_except_missing
func(records)
File "/home/odoo/src/odoo/18.0/odoo/fields.py", line 1485, in compute_value
records._compute_field_value(self)
File "/home/odoo/src/odoo/18.0/addons/mail/models/mail_thread.py", line 427, in _compute_field_value
return super()._compute_field_value(field)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5296, in _compute_field_value
fields.determine(field.compute, self)
File "/home/odoo/src/odoo/18.0/odoo/fields.py", line 110, in determine
return needle(*args)
File "/home/odoo/src/odoo/18.0/addons/l10n_fr_pos_cert/models/pos.py", line 79, in _compute_previous_order
raise UserError(_('An error occurred when computing the inalterability. Impossible to get the unique previous posted point of sale order.'))
odoo.exceptions.UserError: Une erreur s'est produite lors de la vérification de l'inaltérabilité. Impossible de récupérer la dernière commande de caisse unique et comptabilisée.
```
## Desired behavior after PR is merged:
The method `pos.order._compute_previous_order` already only checks orders with a sequence number != NULL, so to address this issue, we will use the same condition to retrieve only orders with a valid sequence. This will result in no more exceptions created by incorrect data.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#229585This fix prevents users from disabling required Peppol electronic invoicing services, reducing the risk of compliance problems. It also corrects small formatting inconsistencies in invoice e-invoice format labels so they display more consistently.
Original PR description
#### [FIX] account_peppol: disallow disabling services Currently it is possible to disallow any services in the configuration. This can lead to complicance issues; i.e. if someone disables "BIS Billing 3.0". 1. Ensure Peppol is activated (test mode or production; not demo) 2. Settings -> Accounting -> PEPPOL Electronic Invoicing -> Configure Peppol Services 3. Any service can be disabled. This commit hides the button to open the service wizard. (Also in the wizard it is now not possible to disable services anymore.) #### [FIX] account_edi_ubl_cii: missing parenthesis in invoice_edi_format Follow-up to commit 860c0974f9b541be63f4079ef52366f91c1994ce . There we improved the eInvoice format labels for clarity. But 2 label were formatted differently than the others. This commit fixes that. #### References task-4737164 Forward-Port-Of: odoo/odoo#233502 Forward-Port-Of: odoo/odoo#233382
Batch payment users now see a clear, non-blocking warning when SEPA Credit Transfer partners are missing required country or city details. This helps businesses correct partner records before generating payment files that could become invalid under upcoming SEPA rules.
Original PR description
Starting from November 15th, 2026, SEPA Credit Transfer (SCT) payments require both the partner's country and city to be defined when using structured addresses. If missing, the generated XML file will be invalid. This change adds a non-blocking red banner on the batch payment form to warn users and provide a link to review the affected partners. task-5156613 Forward-Port-Of: odoo/enterprise#97598