Daily updates from Odoo
Monday, October 13, 2025
32 changes · saas-18.4
Resolved issues and error corrections
This fix prevents failures when creating Indian GST return records for tax units with multiple companies. The system can now find a valid purchase journal from any company in the tax unit instead of only checking the main company.
Original PR description
Before this PR: - The system searched for a purchase journal only in `company_id`. - In a tax unit with multiple companies, if the main company had no purchase journal configured, record creation failed with a 'NOT NULL constraint violated' error. After this PR: - The journal search now checks all companies in `company_ids` (or falls back to `company_id`), - allowing the system to find a valid purchase journal across the tax unit. OPW: 5159518 Forward-Port-Of: odoo/enterprise#96919 Forward-Port-Of: odoo/enterprise#96838
This update adds safeguards so Danish Nemhandel connections are moved to test/demo mode when a database is neutralized. It helps prevent accidental registration or document sending through production services in copied or test environments.
Original PR description
To avoid sending/registering on production, add a neutralize script. The existing proxy client are put in demo mode. The new connections will be registered on the test server. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229934
The Indian localization test setup was adjusted so it no longer depends on US accounting data when demo data is unavailable. This makes automated checks more reliable and avoids false failures during development or release validation, without changing customer-facing functionality.
Original PR description
Standalone `l10n_in` tests were failing when running without demo data because outside-India companies (e.g., US) were defaulting to their country-based chart of accounts. This required the `l10n_us_account` module, causing errors when the module was not installed. <img width="518" height="28" alt="image" src="https://github.com/user-attachments/assets/748663a0-f329-459c-b0e8-0c3de7019258" /> This commit adapts the test cases to run without l10n_us_account dependency. task- 5116352 Forward-Port-Of: odoo/odoo#230041
Changing a coupon reward on a confirmed sales order now updates the coupon's remaining points correctly. This prevents customers from losing or retaining the wrong number of points when a discount reward is switched after order confirmation.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10…
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10 points; 5. use coupon code on a confirmed order; 6. select 10% discount reward; 7. change to a 50% discount reward; 8. check coupon point total. Issue ----- Even though the 5 point reward was used, only 4 out of 10 points remain. Cause ----- When updating the reward line of a confirmed order, it keeps track of point cost changes before & after a write. Its purpose is to restore back the point difference on the coupon record. The issue is that while point changes are stored, coupon changes are not. When updating reward lines, `_reset_loyalty` is used, which removes the `coupon_id` from the lines. As a consequence, attempting to restore the point difference on `line.coupon_id` after an update, it writes to an empty record. Solution -------- Store both coupons & their used points before write. After write, restore the previous points to the previous coupon, and subtract the current point cost from the current coupon. This way, any combination of coupon/point changes should have the points updated as expected. opw-4910922 Forward-Port-Of: odoo/odoo#230907 Forward-Port-Of: odoo/odoo#222054
Fixes an issue where confirming a batch transfer could lose barcode scanning settings, causing location barcodes such as WH-Stock to be read incorrectly. This helps warehouse users scan batch deliveries reliably after confirmation without manual workarounds.
Original PR description
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and…
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and confirm - Scan WH-Stock #### > The scan fails considering you scanned each letter independently. ### Cause of the issue: When the barcode is scanned a call of the split barcode will be launched to split the barcode in multiple barcodes according to the `barcode_separator_regex` present in the config: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_model.js#L613-L632 The issue lies in the fact that even thought the is `barcode_separator_regex` was conrrectly populated at the onWillStart of the mainComponent: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L97 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_picking_model.js#L36-L38 It was reset by the batch confirmation here: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L123-L135 because this part of the config is not meant to be returned by the private method `_get_barcode_data` but rather by public complete version `get_barcode_data`: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L91-L98 Now, since no `barcode_separator_regex` was provided to our new config, each character will be considered to be considered as an independent barcodes and the `WH-Stock` barcode will not match any location. opw-5062331 Forward-Port-Of: odoo/enterprise#95295 Forward-Port-Of: odoo/enterprise#94056
This fixes a Sales issue where automated checks could fail if a customized sales order line view showed another field before the product field. It helps keep Sales customizations more reliable and reduces false test failures during deployments.
Original PR description
To reproduce: 1. Manually modify the SO view `view_order_form` notebook SO lines list view to make visible any column before `product_id` For example:…
To reproduce:
1. Manually modify the SO view `view_order_form` notebook SO lines list view to make visible any column before `product_id` For example:
https://github.com/odoo/odoo/blob/18.0/addons/sale/views/sale_order_views.xml#L521 making the field `display_type` visible
2. Run the tests of `sale` module
=> `sale` module tests will fail on test `test_sale_combo_configurator_preconfigure_unconfigurable_ptals`
```
FAILED: [18/22] Tour sale_combo_configurator_preconfigure_unconfigurable_ptals → Step Verify that configurable ptals are now configured (trigger:
.sale-combo-configurator-dialog
.combo-item-grid
.product-card:has(.card-title:contains("Test product"))
:contains("Attribute B: B")).
Element (
.sale-combo-configurator-dialog
.combo-item-grid
.product-card:has(.card-title:contains("Test product"))
:contains("Attribute B: B")) has not been found.
TIMEOUT step failed to complete within 10000 ms.
```
see runbot build fail at:
https://runbot.odoo.com/runbot/build/89552334
The issue happen as - for some dark magic JS/XML reason - adding the field before product_id make fail the step to click the checkbox using the span.
Fix was suggested by PIPU to solve/workaround the issue
In practice, this issue was discovered accidentally with a customisation which was willing to add a custom field at the start of the list
opw-5068699
Forward-Port-Of: odoo/odoo#228029Maintenance equipment pages now open even when customized workflows leave repair or request dates empty. This prevents a data entry edge case from blocking users from viewing equipment records while still keeping the maintenance request in related calculations.
Original PR description
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them…
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them from opening equipment views that displayed fields that depended on it. Steps to reproduce: - Create new maintenance request for an equipment - Put maintenance request into a `maintenance.stage` where `done=True` (e.g. "Repaired") - Force `close_date` to not be `readonly` in form view + set it to `False` - Try to open the assigned equipment's form view Expected result: Form view opens without issue Actual result: `unsupported operand type(s) for -: 'bool' and 'datetime.date'` Issue was due to `mttr` calculation in `_compute_maintenance_request` not expecting `close_date` to be `False`. Since we want the request to still be considered for the rest of the compute, we count its "Time to Repair" as 0 in this case since we cannot use infinity in this case. Additionally, we also gracefully fail in the same way in case `request_date` is also forced to be `False` since it is not a mandatory field and can cause the same issue. 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#230942 Forward-Port-Of: odoo/odoo#230821
Appointment video call links now use the correct website domain tied to the appointment type. This prevents customers from receiving links with the wrong company or website address in multi-company, multi-website setups.
Original PR description
**Steps to reproduce:** - Create 2 companies - Create a website for each company - Set a custom website domain on the second one - Create appointement type for each website - Create an appointement on both websites - The link created for the video call has the wrong base for one of them **Issue:** Appointment `get_base_url` finds its base_url without considering the current website. **Fix:** Compute the base_url according to the appointement type to ensure the current website is taken into account. opw-4880715 Forward-Port-Of: odoo/enterprise#96826 Forward-Port-Of: odoo/enterprise#92734
Fixed an issue where lunch orders could be incorrectly archived after repeated Receive actions or when similar orders already existed. This keeps orders visible and ensures quantities are only merged when the target order can actually be updated.
Original PR description
**Issue** The lunch order merge logic was causing orders to be unexpectedly archived when they shouldn't be. Users would see their orders disappear from the list view after certain operations like…
**Issue** The lunch order merge logic was causing orders to be unexpectedly archived when they shouldn't be. Users would see their orders disappear from the list view after certain operations like clicking "Receive" multiple times or when trying to merge orders with existing ones in immutable states. **Steps to Reproduce** 1st problem - Create a lunch order - From the order list view, select the order and click the "Receive" button - Select and click the "Receive" button again on the same order - The order gets archived and disappears from the view 2nd problem - Create a lunch order - From the order list view, select the order and click the "Receive" button - Place another order for the same product as before - From the order list view, once the second order is set to received, it gets archived and the update quantity logic not triggered **Root Cause and Solution** 1st problem: When searching for matching orders to merge, the current order being processed could match itself, leading to self-deactivation. Fixed by adding matching_lines = matching_lines - line to exclude the current record from potential merge targets. 2nd problem: The merge logic was trying to combine new orders with existing "sent" and "confirmed" orders, but the update_quantity method correctly excludes these states since they shouldn't be modified once sent/received. This created a mismatch where orders would be archived but quantities wouldn't update. Fixed by excluding "sent" and "confirmed" states from merge target searches entirely. Task ID: 5123211 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229084
The Point of Sale scan button now opens the camera even when an order is selected on the ticket screen. This helps cashiers scan QR codes without needing to change screens or clear their current selection.
Original PR description
Before this commit: = - The scan button did not function when an order was selected. After this commit: = - The scan button now opens the camera to scan a QR code even when an order is selected. Task: 4778136 Forward-Port-Of: odoo/odoo#211875
The event form now correctly shows the Community menu option when the Track Quiz feature is installed on its own. This prevents users from missing a relevant event website setting unless another event feature happens to be installed.
Original PR description
In the event form the "community" button is supposed to be shown when "track quiz" is installed. However when this was done in [1] there a mistake was made and only the label was removed, as well as the wrong field added after it. That field was removed in [2] but it was again not noticed that only the label was made visible. It may not appear easily because installing website_event_meet also unhides both the label and the field. Hence you only ge this issue when installing track quiz without it. However in 18.3 [3] removed website_event_meet which means the issue is not corrected anymore. task-5159806 [1]: https://github.com/odoo/odoo/commit/147cf5f328f5a55882a62a4279d1d92511628320 [2]: https://github.com/odoo/odoo/commit/c0f0f9f47573b74ca6b1fcdc3383e43f28f7a2e1 [3]: https://github.com/odoo/odoo/commit/9cab4f8f77f71e405971c184544765e8f252a012 Forward-Port-Of: odoo/odoo#231020
Mexican DIOT reports now identify United Kingdom records with the correct country code instead of grouping them under “Other country.” This helps businesses produce more accurate tax reporting for UK-related transactions.
Original PR description
The DIOT country adaptation map lacked the ISO 3-letter code for the UK, causing records with country 'GB' to be reported as 'ZZZ' ("Other country").
Added mapping 'GB' → 'GBR' to ensure correct DIOT country code generation.

Forward-Port-Of: odoo/enterprise#96771This fixes an issue where follow-up report tests could fail if they started before midnight and continued after midnight. The change keeps test results consistent over time, helping maintain confidence in accounting report quality without changing customer-facing behavior.
Original PR description
Tests https://runbot.odoo.com/odoo/runbot.build.error/159772 where failing when setUpClass run before midnight and the test itself run at/after midnight because `today` was not the same. As follow-up report divides the lines per partner to due/overdue utilizing `today` in comparison, This resuls in different lines than expected. Forward-Port-Of: odoo/enterprise#96486
Employee contracts in Swiss payroll now only show insurance options that belong to the relevant company. This prevents users in multi-company environments from accidentally selecting another company's insurance records, improving data accuracy and compliance.
Original PR description
Currently, in a multi-company setup, you are able to select insurances from other companies on the employee contract task-5157106 Forward-Port-Of: odoo/enterprise#96821
Invoices now link to the payment that is actually reconciled and confirmed, rather than an older draft payment created during duplicate or reset workflows. This helps users open the right payment from the invoice and avoids confusion in payment follow-up.
Original PR description
[FIX] account: set correct links between invoices and payments The problematic found case was the following: - Create an invoice and register a payment for it, using the wizard, with a journal having…
[FIX] account: set correct links between invoices and payments The problematic found case was the following: - Create an invoice and register a payment for it, using the wizard, with a journal having an outstanding account set - Use the smart button on the invoice form view to open the payment and reset it back to draft - Duplicate the payment, confirm the new one and reconcile it with the invoice => If we go back to the invoice form, the smart button linking payments is now redirecting to the 1st payment, that's in draft state, instead of the second confirmed one. This is because there can be 2 types of links between payments and invoices: - When there's no journal entry for payment, the link is done via the Many2many table 'account_move__account_payment'. - When there's a journal entry, the link is done via the table 'account.partial.reconcile'. Before this commit, the button on the invoice form view was based on account_move__account_payment and wasn't looking at all at account.partial.reconcile as one would expect. To solve that, we now look at reconciled_payment_ids that is computed as the union of account_move__account_payment and account.partial.reconcile. Task-4613193 Runbot: https://runbot.odoo.com/runbot/bundle/18-0-outstanding-double-link-roto-354130 Forward-Port-Of: odoo/enterprise#96926 Forward-Port-Of: odoo/enterprise#89089
Selecting an events-focused website setup will no longer automatically install ecommerce features. This keeps the website configuration aligned with the user's chosen purpose and avoids adding unnecessary sales tools.
Original PR description
Steps to reproduce: 1. Install website module 2. Select events in configurator 3. Build website. => Ecommerce is installed, which should not as it does not make sense with only the events. After this commit: - Ecommerce will no longer be installed when the events is configured. task-4922600 Forward-Port-Of: odoo/odoo#221527
Fixed an accounting issue where an invoice could link users to an old draft payment instead of the confirmed payment that actually settled it. This helps finance teams avoid confusion when reviewing paid invoices and their related payments.
Original PR description
[FIX] account: set correct links between invoices and payments The problematic found case was the following: - Create an invoice and register a payment for it, using the wizard, with a journal having…
[FIX] account: set correct links between invoices and payments The problematic found case was the following: - Create an invoice and register a payment for it, using the wizard, with a journal having an outstanding account set - Use the smart button on the invoice form view to open the payment and reset it back to draft - Duplicate the payment, confirm the new one and reconcile it with the invoice => If we go back to the invoice form, the smart button linking payments is now redirecting to the 1st payment, that's in draft state, instead of the second confirmed one. This is because there can be 2 types of links between payments and invoices: - When there's no journal entry for payment, the link is done via the Many2many table 'account_move__account_payment'. - When there's a journal entry, the link is done via the table 'account.partial.reconcile'. Before this commit, the button on the invoice form view was based on account_move__account_payment and wasn't looking at all at account.partial.reconcile as one would expect. To solve that, we now look at reconciled_payment_ids that is computed as the union of account_move__account_payment and account.partial.reconcile. Task-4613193 Runbot: https://runbot.odoo.com/runbot/bundle/18-0-outstanding-double-link-roto-354130 Forward-Port-Of: odoo/odoo#231140 Forward-Port-Of: odoo/odoo#202076
The online shop category sidebar now handles long category names correctly, including nested categories. This prevents layout distortion and keeps the product browsing experience visually consistent for shoppers.
Original PR description
__Issue:__ In the product categories sidebar (`#products_grid_before`), nested `<li>` elements could become wider than their parent `<ul>` when the category names were long (e.g., "Untersuchungshandschuhe"). This caused the parent <ul> to expand in height before the child and broke the visual layout. __Fix:__ Force `<li>` elements inside the `#categories_recursive` list to respect their parent width by applying `width: 100%` This keeps the sidebar layout consistent even with long category names. - opw-5075226 Forward-Port-Of: odoo/odoo#228343
When a user types a full URL and it is automatically converted into a link, the link popover now correctly shows the prompt to replace the URL with the page title. This makes the editing experience clearer and restores the intended option for newly created links.
Original PR description
**Current behaviour before PR:** Steps to reproduce: - Type a full valid URL e.g. `https://odoo.com` - Press space to create link. - Open popover by clicking on link. There is no banner at the bottom of popover showing "Replace URL with its title?" when a newly link is created. After merging this commit [1], When the link popover is opened for the first time, replace title option should be visible in the popover. **Desired behaviour after PR:** Now, replace title banner is shown at the bottom of popover if link is created by transformation. [1]: https://github.com/odoo/odoo/commit/7da241d6fd3a3fa1e6d617b436d397b5b28320cf task-5085975 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The website editor now only shows the Countries Filter option on the Customers page where it actually applies. This avoids confusing editors on the Partners page with a setting that has no effect.
Original PR description
Scenario: - install website_customer and website_crm_partner_assign - go to /partners - in edit mode, disable the option "Countries Filter" Result: nothing happen Cause: there is no filter options on /partners page, but the options of /customers page are targetting class o_wcrm_filters_top that is common to both page, so they are shown on /partners incorrectly. Fix in stable: change the selector to only show options on /customers. Fix in master: in website_customer, change the o_wcrm_filters_top class to o_wc_filters_top class. opw-5102381 Forward-Port-Of: odoo/odoo#228575
Users could encounter an error when hiding an HTML field that contained newly added images before saving the record. The update makes the editor preserve the field content safely while images finish saving, preventing the crash and improving form reliability.
Original PR description
**PROBLEM** When hiding a HtmlField field from a view with pending images in it, there is a traceback. **STEP TO REPRODUCE** 1. Using studio, create a HtmlField on the view of your choice. 2. Add a…
**PROBLEM** When hiding a HtmlField field from a view with pending images in it, there is a traceback. **STEP TO REPRODUCE** 1. Using studio, create a HtmlField on the view of your choice. 2. Add a checkbox next to it, and link the HtmlField visibility to the button. 3. Add a image to the HtmlField (don't save the record !) 4. Hide the HtmlField using the checkbox, there should be a traceback. (if not, try with a bigger image). **CAUSE** commitChanges() will try to retrieve the field value to commit by looking at the related element in the DOM. Before retrieving this value, we call savePendingImages() to save the new images added to the HtmlField. https://github.com/odoo/odoo/blob/1416aad902a97ce56aaecc2aadc4dd9f7814ee53/addons/html_editor/static/src/fields/html_field.js#L159-L162 This introduces a delay, during which the DOM element could be destroyed. **FIX** We don't call commitChanges() in OnBlur(). Instead, we cache the new value in a property of HtmlField called `newValue` when `OnChanges()` is called. Inside OnBlur(), we save the pending images by directly calling `savePendingImages()` and we commit the new value by calling `updateValue(this.newValue)` opw-5061820 Forward-Port-Of: odoo/odoo#227482
Selected tags on website blog and eLearning pages are now preserved when users open the website editor, refresh through navigation, or use the search bar. This prevents visitors and editors from unexpectedly losing active filters, making browsing and content management more reliable.
Original PR description
Before the change in the blog/slides pages of a website every tag but one disappears when opening the editor or when the search bar is used. Steps to reproduce: - Log in Odoo with a user that can access the website editor Open the Website - Install the blog app if it is not already present - Open the blog app - Click on two or more tags to add them to the filter Open the Website editor or use the search bar - Every tag but one will be removed After the change all the tags will be kept when opening the editor or using the searchbar. task-4216129 Fixes #164577 Forward-Port-Of: odoo/odoo#226898
SEPA payments will now use high priority only for Belgian companies. This helps companies in other countries avoid potential extra bank fees caused by unnecessary high-priority payment processing.
Original PR description
Having priority set as HIGH for SEPA payments can induce extra fees (ex. in CH). This commit only sets the priority to HIGH for BE companies. task-4874217 Forward-Port-Of: odoo/enterprise#96869 Forward-Port-Of: odoo/enterprise#95420
Fixes an issue where Colombian online shoppers could get stuck during checkout when selecting certain tax obligation options. Addresses with double-digit obligation option IDs now save correctly and customers can continue to delivery.
Original PR description
Problem: When there is an obligation type code with id greater than 9, and it is selected in the dropdown of the website sale address form for obligation type, the screen keeps loading forever and…
Problem: When there is an obligation type code with id greater than 9, and it is selected in the dropdown of the website sale address form for obligation type, the screen keeps loading forever and there is an “expected singleton” traceback in the logs. This is because in the method `_parse_form_data` in `l10n_co_website_sale`, the obligation type field on `form_data` is set to be a list of “type ids” which leads to an error when `convert_to_cache` is called as the browse function in this attempts to convert the list to a tuple of single characters. For example, if the list is ["10"], it gets converted to ("1","0") hence leading to the expected singleton traceback.
Purpose: Instead of passing a form list to form_data,we pass the record set which will correctly set the values in the address, much like how `default_obligations_ids` is also currently set. After this correction, the website address screen will save the address properly and redirect to the delivery screen for further actions.
Steps to Reproduce on Runbot:
1. Create a Colombian company, make sure l10n_co is installed
2. Set the company on the website to this company
3. Ensure that there is a record in the table `l10n_co_edi_obligation_type_ids` with id > 9. Create one if it does not exist.
4. Open the /shop page in incognito mode as a public user.
5. Add a product, go to the checkout page, proceed to the address page.
6. Enter all the information including the Identification Number (e.g. 623.456.789-1). Choose “NIT” in identification type and select the type code from step 3 in the dropdown for obligation type. Choose country “Colombia” along with a state and city
7. Click on "Continue checkout". The page gets stuck in a loading state
forever.
opw-4776301
Forward-Port-Of: odoo/enterprise#90862This fixes a collision issue in sales commission reporting where some commission adjustment logs could generate the same internal report record ID. The change helps ensure commission achievements remain distinct and accurately represented after transfers or adjustments.
Original PR description
This commit 5b6fdda126e4cfa5ebf92f7b96d1805f6c4b992b introduce an entropy date to avoid having two separate achievment.report record with the same ID. Entropy date for log where based on the write_date, this commit 03d1ee3495a4936fbff0d21743bb784c85b50b12 add the sign of the amount. Unfortunatly this is not enough, the adjustment after the transfer can be positive as well and thus two achievment ends-up with the same ID anyway. This commit use the id of the log to add more entropy to the entropy_date, since log are created in the same transaction, they are likely to have id just seperate by one or only few number, id % 10 seems enough, therefore two log on the same order, with the same create_date will have different entropy date and end up with a different id. Forward-Port-Of: odoo/enterprise#96622
This change updates internal test data so products are treated as properly configured for manufacturing instead of as incomplete purchase items. It prevents test failures caused by artificially extended lead times, helping keep planning and rental workflows reliable in validation.
Original PR description
This PR addresses the issue where tests were failing due to unconfigured products (no vendor/ no BoM). Now unconfigured products' lead_time is incremented by 365 due to this PR: https://github.com/odoo/odoo/pull/216293 Before this fix: Products have `buy` route by default and no vendor, so they are considered unconfigured products and lead time is incremented by 365, and tests fail as any lead time refers to a date earlier than today would only affect the first period in the MPS which is not intended in the tests. After this fix: Products have `manufacture` route and there is BoM, so they are considered configured products and lead time is calculated normally from BoM which is 0. Task-4779057 Forward-Port-Of: odoo/enterprise#88766
The sales commission achievement report now uses the latest end date from relevant commission plans when setting its default date range. This prevents reports from ending too early and helps users see the full expected commission period.
Original PR description
When there is active_plan_ids in the context the date_to are the max of plans' date_to when not it's the min, this is wrong it should be the maw as well Forward-Port-Of: odoo/enterprise#96526
This fixes incorrect Maltese fiscal position mappings that could assign sales taxes where purchase taxes should apply, and vice versa. Businesses using the Malta localization will get more accurate tax handling for EU and non-EU partner transactions.
Original PR description
### Steps to reproduce: - Install "l10n_mt" and switch to a Maltese company - Check the fiscal position "EU Partner", it maps Sales taxes to Purchase ones - "Partner outside the EU" maps Purchase taxes to Sales ones ### Solution: Fix the CSV. We map the taxes respecting Sales/Purchase and with the same percentage. opw-5065298 Forward-Port-Of: odoo/odoo#230638 Forward-Port-Of: odoo/odoo#227423
Products that are missing key setup, such as a bill of materials or vendor, will now appear on the replenishment report much earlier instead of only on the delivery date. This gives teams advance warning to complete product configuration and avoid last-minute delivery or production issues.
Original PR description
Before this commit, RR for unconfigured products (no BoM/ no vendor), was not created until the same day of the delivery date (lead_time=0). Now, RR for unconfigured products is created considering the lead_time is incremented by 365 days. Note that this commit reverts the effect of the commit: https://github.com/odoo/odoo/commit/40d0bc0df0dc09f5138aa747cbbc715ae77f104c It's functionally decided to make the total lead_days for products with no bom to be 365 days without adding the security_lead_days. It's meant just to warn the user on the RR dashboard that the product needing replenishment is not configured, no matter to the security_lead_days in this case. Task-4779057 Forward-Port-Of: odoo/odoo#216293
This fix prevents a module uninstall process from failing when worksheet-related database fields have already been removed. It helps keep uninstall and reinstall operations consistent, avoiding broken data structures that could affect later setup.
Original PR description
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks…
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks when uninstalling module `worksheet`:
```
ir.model.data._module_data_uninstall():
... records are deleted ...
ir.model.fields.unlink():
drop column of corresponding fields
delete ir.model.field records
ir.model.unlink():
drop table of corresponding models
ir.model._unlink_if_uninstalling():
self.env['worksheet.template'].search([('model_id', ...)]).unlink()
delete ir.model records
```
The call to `ir.model.unlink()` crashes when searching for worksheet templates, since column `model_id` has been dropped already. This makes the transaction fail, and it is rolled back to a savepoint just before the call to `ir.model.unlink()`. In other words, the uninstallation manages to drop most of the columns that must go, but fails to drop all the tables that must go. And the uninstallation proceeds anyway...
Now consider uninstalling module `resource`. That module defines model `resource.calendar` with required field `name`, and also defines a record in that model (a default calendar). When the module is uninstalled, module `worksheet` is also uninstalled (because it depends on `resource`), and so the situation above happens. Consequently, most of the columns of table `resource_calendar` are dropped, but the table is not. If we reinstall module `resource` after that, the ORM re-creates column `name` (which is `NULL` on the default calendar at least), but fails to add the `NOT NULL` constraint on that column.
The fix consists in avoiding the `search()` above in the ondelete method if the column `model_id` does not exist anymore.
Forward-Port-Of: odoo/enterprise#96845Analytic grid reports now keep all months visible when weekends are hidden in the yearly view. This prevents missing month columns and makes year-level reporting easier to read and rely on.
Original PR description
To reproduce: ============= 1- Go to Analytic Reporting. 2- From the year dropdown, uncheck "Show weekends". → Some months disappear unexpectedly. Problem: ========= Weekend filtering was applied even in year range. In year view, each column is already a full month, so filtering out weekends is incorrect. Fix: ==== Adjust the condition to skip filtering when range is not "month". Weekend logic now only applies to month range grid. community-pr: https://github.com/odoo/odoo/pull/226975 opw-5078200 Forward-Port-Of: odoo/enterprise#96171 Forward-Port-Of: odoo/enterprise#94593
This fixes an issue where some translated error messages displayed byte-string content as a list of numbers instead of readable text. Users may now see clearer server or connection error details in their selected language.
Original PR description
Improvements introduced by https://github.com/odoo/odoo/pull/197702 streamlined the auto formating of iterables to lists when passed as an argument to translatable strings in Odoo. While doing so,…
Improvements introduced by https://github.com/odoo/odoo/pull/197702 streamlined the auto formating of iterables to lists when passed as an argument to translatable strings in Odoo.
While doing so, strings were ignored (to prevent formating them as a list of the individual characters), but they failed to account for the fact that **byte strings** might also be passed as arguments in certain parts of the code.
An example can be found here:
https://github.com/odoo/odoo/blob/f037c39ad4d33384f81a418cb63fcdd6a5085d56/odoo/addons/base/models/ir_mail_server.py#L265-L278
`repl` in this context will be a byte string object returned by the SMTP connection.
## BUG:
Before the fix, if you would pass a byte string as an argument to a translatable string using keyword templating, the output would be the raw representation of the bytes as a list instead of the human readable content.
For example if we use in a french localisation:
`raise UserError(_('The server refused the test connection with error %(repl)s', repl=b'TEST byte string'))`
Before the fix we could get:
`Le serveur a refusé la connexion de test avec l'erreur 84, 69, 83, 84, 32, 98, 121, 116, 101, 32, 115, 116, 114, 105, 110 et 103`
And after the fix:
`Le serveur a refusé la connexion de test avec l'erreur b'TEST byte string'`
## Proposed fix:
In the same way that we ignore `str` arguments before auto applying the `format_list` method, we will also ignore them if the type is `bytes`
OPW-5107313
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#231179