Daily updates from Odoo
Friday, November 21, 2025
25 changes · saas-18.4
New functionality added to Odoo
This change adds support for carrying customer and checkout details from the online store into Taiwan e-invoices. It helps ensure invoices are created with the right information automatically, reducing manual entry and the risk of errors.
Original PR description
This module adds extra functions on the website sale for l10n_tw_edi_ecpay, passing values from e-commerce to invoice for creating Taiwan E-invoice task-5122489 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236548 Forward-Port-Of: odoo/odoo#228989
Enhancements to existing features
This change makes Odoo’s automatic database column conversion more conservative and predictable. It avoids unnecessary background recomputation during upgrades, which helps reduce upgrade time and limits the automatic handling to simpler cases that are less likely to cause issues.
Original PR description
The auto column conversion should be limited to simple and intuitive use cases. It shouldn't trigger the slow ORM recomputation if the field is computed. We always expect an upgrade script to handle…
The auto column conversion should be limited to simple and intuitive use cases. It shouldn't trigger the slow ORM recomputation if the field is computed. We always expect an upgrade script to handle more complex use cases.
This commit introduces two changes:
### 1. Removal of `drop_not_null` during auto column conversion
Before https://github.com/odoo/odoo/commit/50767ef90eadeca2ed05b9400238af8bdbe77fb3 We dropped the not_null constraint because the original column would be renamed. After that commit, we actually don't need to drop the not_null constraint since the `convert_column` will neither convert a not-null value to `null` nor convert 'null' to a not-null value. Keeping the not_null constraint shouldn't block the column convert.
### 2. Removal of `column.clear()`
When a computed/related Float field is changed from `digits=None` to `digits='xxx'`, the `column.clear()` will trigger ORM recomputation during upgrade which is useless since `double precision` to `numeric` is lossless. The recomputation in ORM is slow and should be avoided. If the rerounding is really needed, a sql script is required for upgrade or installation.
The `column.clear()` was originally introduced to avoid `Missing not-null constraint` warnings in specific scenarios:
Case 1 (Upgrade Warning): from saas-18.4 to 19.0
old database: Selection field `l10n_be.export.sdworx.leaves.wizard.reference_year` upgrade: pre-migrate `util.rename_model(cr, "l10n_be.export.sdworx.leaves.wizard", "l10n.be.hr.payroll.export.sdworx")` new database: Integer field `l10n.be.hr.payroll.export.sdworx.reference_year` The column value which was a required stringified integer is auto-converted to an integer.
Case 2 (Installation Warning):
In pos_urban_piper, the required field `pos.config.name` is overridden from `translate=False` to `translate=True`. The column value which was a required text is auto-converted to `'{"en_US": "text"}'::jsonb`
The not_null constraint was previously lost by the `sql.drop_not_null` in `update_db_column` and is not restored by `update_db_notnull` because of the inconsistency between the variable `column['is_nullable']` and the actual not_null constraint in the database.
Thanks to change 1, we will no longer lose the not_null constraint in `update_db_column`. The constraint can be kept even without `column.clear()`.
By removing the `column.clear()`, we also revert the meaning of the `column` variable, which is the column's configuration (dict) before `update_db` if it exists, or `None`
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#236299This update clears existing product menu connections in UrbanPiper and runs a fresh synchronization. It helps ensure the menu shown to customers matches the latest Odoo data and reduces issues caused by outdated links.
Original PR description
Following this commit: - Flush out all existing UrbanPiper product menu linkages and performs a fresh menu sync. task-5231247 Forward-Port-Of: odoo/enterprise#98994
The IoT Box homepage now waits longer between data refreshes when a tab stays open. This reduces unnecessary background requests, helping the device stay responsive while still updating the page periodically.
Original PR description
In order to avoid spamming the IoT Box with requests to update the homepage when a tab is kept open, we now progressively delay the `/data` fetch during the first 30min to end up fetching only once every 30min. Forward-Port-Of: odoo/odoo#236664
Resolved issues and error corrections
This fix corrects a configuration error in the Uruguayan e-invoicing stock flow that was causing a build failure. It helps ensure stock-related electronic document processing works as expected and avoids interruptions during deployment and validation.
Original PR description
runbot build error id: 234034 Forward-Port-Of: odoo/enterprise#99920
This fix prevents Odoo from showing an error traceback when the Egyptian e-invoice service rejects a request and returns a response that cannot be read as JSON. Instead, the error is now handled properly, giving users a smoother and more reliable invoicing experience.
Original PR description
Before this commit: Steps 1) When clients try to download e-invoice for ETA 2) If ETA rejects the request, Odoo fails to parse to JSON 3) a JSONDecodeError exception is raised 4) Odoo doesn't catch it and a traceback is raised => A JSONDecodeError is raised but actually it's not json.decoder.JSONDecodeError, it's actually requests.exceptions.JSONDecodeError as mentioned here https://requests.readthedocs.io/en/latest/api/#requests.JSONDecodeError After this commit: If the request is rejected and Odoo failed to parse the response to JSON the exception is catched properly. opw-5241411 opw-5272195 Forward-Port-Of: odoo/odoo#236672
This update removes duplicate methods in several HR-related components. It helps keep the codebase cleaner and reduces the risk of inconsistent behavior or maintenance issues in these areas.
Original PR description
found by pylint 4 Forward-Port-Of: odoo/enterprise#99927 Forward-Port-Of: odoo/enterprise#99809
This update adjusts Odoo’s internal code checks so they continue to run correctly with the latest pylint and astroid versions. It also fixes a couple of test-related warnings and removes a few false alerts, helping maintainers keep quality checks reliable without affecting normal business use.
Original PR description
- astroid 4 deprecates toplevel exports of nodes, thankfully that was never actually necessary so we can just import that unconditionally - remove support for pre-jammy pylint / astroid, specifically `astroid.nodes` was added in astroid 2.7.0 and `astroid.node_classes` deprecated then and removed in 3.0, this can affect Bullseye users as it shipped with astroid 2.5 - Astroid 4 changes `spec.Finder.find_module` in order to cache it (pylint-dev/astroid#2509), we can just make our method static for all versions as we don't need `self` anyway. - The mail test triggers `function-redefined` (E0102), fix it. - Skip the escpos script thing which triggers a bunch of `undefined-variable` (E0602) false positives. Forward-Port-Of: odoo/odoo#236530 Forward-Port-Of: odoo/odoo#236258
This change improves compatibility with Swedish cash register blackboxes by checking which protocol version they support during setup. As a result, receipts can be registered without triggering an "unknown message type" error on devices that only support the older protocol version.
Original PR description
The serial protocol used with the Swedish blackbox has 2 versions, with v2 adding some more commands. Before this commit, we assumed that the blackbox was compatible with v2, causing an 'unknown message type' error if it only supported v1. After this commit, we check the protocol version of the blackbox when we initialise the driver, so that we only send compatible commands when we register a receipt. opw-5077448 Forward-Port-Of: odoo/enterprise#99930 Forward-Port-Of: odoo/enterprise#99008
This update prevents the restaurant point of sale from creating a new order too early after a payment when preview skipping is enabled. It avoids errors on the floor plan and makes the checkout flow more reliable when using printers and preset selections.
Original PR description
**Steps to reproduce:** - In the config, click the ePos Printer checkbox - Also check Automatic Receipt Printing and Skip Preview Screen - Put a default preset with Name as it's identification - Go…
**Steps to reproduce:** - In the config, click the ePos Printer checkbox - Also check Automatic Receipt Printing and Skip Preview Screen - Put a default preset with Name as it's identification - Go in the restaurant and make a sale, pay for it - When going back to the floor plan, a traceback appears **Why the fix:** This current problem arises because we are trying to access the current order, but we are on the floor plan, so there is no current order yet. The order is undefined, so we try to access *undefined.floating_order_name* and a traceback appears. But the root issue is deeper than this. In the restaurant, the order is initialized when clicking a table, or when we create a floating order. But when the Skip Preview Screen option is enabled, we try to initialize the order right after the last order has been validated, like we do it in the normal PoS. Doing this, we will try to handle the preset selection way too early, as the order is not fully initialized yet, and we will try to access data that have not been set yet. The current error is not the only one we have with this setup, as other errors also arise if we bypass this specific error. To fix this, we are now only initilizing the new order when we click on a table that has no order or when making a floating order. We do not create a new order after the validation of the last one, even if the Skip Preview Screen option is enabled. This is only true in the restaurant, as we keep on initializing a new order after the validation in the regular PoS. Before this commit, we also tried to create a new order when opening the restaurant from the frontend (see image below), which resulted in a traceback. We now only create a new order if the default screen is different from the Floor Screen. <img width="375" height="249" alt="image" src="https://github.com/user-attachments/assets/e38520f6-81e2-471e-a987-98d9426a6493" /> Starting in version 19.0, there is another waiting screen after paying and before going back to the floor plan, which handles things, so the bug is not present anymore. But the traceback we get when opening the register from the frontend is still present in future versions. opw-5131309
This fix stops users from creating the same RFQ more than once when several tabs or users are working on the same approval. It helps avoid duplicate purchase quantities and prevents accidental over-ordering.
Original PR description
**Problem:** It's possible to click the "Create RFQ's" button more than once, as the user may have multiple tabs open or multiple users are viewing the same record. When this happens, the approval will create or add to an RFQ even if it already did, and this causes double the intended product quantities. **Solution:** The "Create RFQ's" button becomes hidden when purchase_order_count > 0 (i.e. there are linked POs) so we can perform this check within the button's method `action_create_purchase_orders` to prevent RFQ generation (or modification). opw-5227493 Forward-Port-Of: odoo/enterprise#99817 Forward-Port-Of: odoo/enterprise#99706
This update corrects how Italian EDI imports handle “Maggiorazione” discounts on vendor bills and credit notes. It prevents the line total from flipping sign or calculating incorrectly, so imported documents show the right amounts.
Original PR description
Since commit #206238, discounts of type "MG" (Maggiorazione) caused the line total amount sign to flip, leading to incorrect calculations of the total amount. **Steps to reproduce:** - Import a vendor bill/credit note XML (Italian EDI). - Include a line with a Maggiorazione discount. - The line total amount currently appears with the wrong sign and/or amount. Ticket [link](https://www.odoo.com/odoo/project.task/5220218) opw-5220218 Forward-Port-Of: odoo/odoo#236300
This update corrects the invoiced quantity on sales orders when a POS order is refunded from the backend. It ensures the sales order stays accurate after refunds, which helps avoid billing and reporting mismatches.
Original PR description
When doing a refund of a POS order linked to a SO in the backend, the qty_invoiced on the SO line is not updated correctly. Steps to reproduce: ------------------- * Create a SO with 1 quantity of any product * Settle the SO in the PoS * Refund the PoS order from the backend not from the PoS interface * Check the qty_invoiced on the SO line > Observation: The qty_invoiced is still 1 Why the fix: ------------ The method _compute_qty_invoiced was not triggered when the refunding order was paid. So we need to add a new dependency on the function. Note: ----------- In the test we need to flush all before doing the payment of the refund, because if we do not do it, the _compute_qty_invoiced method would be called during the payment. But that is not the case outside of the test. This is just to ensure that the test fails correctly without the fix. opw-4991405 Forward-Port-Of: odoo/odoo#236379 Forward-Port-Of: odoo/odoo#231840
This update corrects how product forecast quantities are calculated after stock moves are completed. Forecasts will now reflect the actual quantity received or delivered, instead of incorrectly using the original requested amount, which could show misleading negative or positive values in the past.
Original PR description
### Steps to reproduce: - Create a storable product - Create a receipt for 100 units of that product - Mark as to do, set the quantity to 50 and validate without backorder - Go to your product form >…
### Steps to reproduce: - Create a storable product - Create a receipt for 100 units of that product - Mark as to do, set the quantity to 50 and validate without backorder - Go to your product form > Forecast #### > The forecast displays a quantity of -50 for every date in the past ### Cause of the issue: The part of the report query relying on done moves is based on the `prodcut_uom_qty` of the move and hence on its demand. However, when the move is 'done' only its quantity should be relevant. #### Note: The same issue happen if you receive more than the demand. That is: - Mark as to do, set the quantity to 150 and validate without backorder - Go to your product form > Forecast #### > The forecast displays a quantity of 50 for every date in the past The issue did not happen prior to 17.0 because validating a move for a quantity that differs from the demand would: - in case quantity < product_uom_qty: split the move in 2: one done move where the demand matches the quantity and one cancelled move with the remaining demand. - in case quantity > product_uom_qty: the demand of the move was updated to match the quantity of the move. This has been changed in f9867a5fa572a15fb89c49c61e569427d6388cbc now, validating a move for a quantity that differs from the demand will keep the demand intact. opw-5152570 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234576
This fix ensures that additional fields added to pay run forms by localizations are kept when the record is saved. It prevents user-entered values from being lost, which helps maintain accurate payroll data.
Original PR description
In some localizations, extra fields are added in the form view of payruns, these field values are lost due to the way we buildRawRecord
This change removes a fragile step from the point of sale localization test where the system tried to close the PoS at the end. That closing action was often failing because it could take too long on setups with many installed add-ons, so removing it makes the test more reliable and quicker to run.
Original PR description
backport of : https://github.com/odoo/odoo/pull/231884 Remove the closing of the PoS in the tour as it is really unstable and fail a lot. It's mostly due to the fact that the PoS take a long time to close with a lost of modules installed. This will also make the tour faster. runbot-233183 Forward-Port-Of: odoo/odoo#236372 Forward-Port-Of: odoo/odoo#234310
Fixed anchor links so that when the “Open in New Window” option is enabled, they now open in a new tab as expected. This restores the intended behavior for website links and avoids sending users to the same page instead of the linked section.
Original PR description
Steps to Reproduce: 1. Create an anchor link for any dropped snippet. 2. Insert the link through the link popover. 3. Enable the "Open in New Window" option. 4. Click on Save. 5. Click on the link. Issue: Even though the "Open in New Window" option is enabled, the page scrolls in the same tab instead of opening in a new window and scrolling to the targeted view. Reason: When an anchor link has target="_blank", `ev.preventDefault()` was still being called, which prevented the browser from performing its default behavior of opening the link in a new tab. Fix: Removed `ev.preventDefault()` for such links, as the expected behavior is to open them in a new tab whenever target="_blank" is set. Additionally, the offcanvas mobile-specific logic has been removed, as it is no longer necessary now that `ev.preventDefault()` is no longer used. task-5104027 Forward-Port-Of: odoo/odoo#236783 Forward-Port-Of: odoo/odoo#228787
This fix removes an incorrect block when creating a reordering rule for a product in a different company. Previously, kit bills of materials from another company could prevent setup even though they should not apply there.
Original PR description
Steps to reproduce: - Create a storable product "P1" - Add a kit BoM restricted to Company A - Switch to Company B - Try to create an orderpoint for "P1" in Company B Issue: A validation error is raised: "A product with a kit-type bill of materials cannot have a reordering rule." Cause: The check did not consider the company of the BoM, so kit BoMs defined in other companies incorrectly blocked orderpoint creation. Solution: Add the company condition in the BoM search domain to ensure that only BoMs belonging to the same company (or global ones) are considered. opw-5158491 Forward-Port-Of: odoo/odoo#232685
When users press Alt+A from the public website, the editor now opens in a usable translation state whenever the page supports translations. This fixes a confusing case where the editor opened but could not actually translate the page, improving the experience for multilingual websites.
Original PR description
__Before this commit:__ 1. Add a 2nd language to your site 2. Show the website homepage in the 2nd language and be outside the admin backend (no admin navbar at the top of the page) 3. Press Alt+A…
__Before this commit:__ 1. Add a 2nd language to your site 2. Show the website homepage in the 2nd language and be outside the admin backend (no admin navbar at the top of the page) 3. Press Alt+A (the shortcut to open the builder) => The builder opens, but it is unusable. The builder options are the translation options, but the iframe is not in a translatable state. __Cause:__ Pressing Alt+A outside the admin backend just [adds `enable_editor=1` in the URL][1]. When the page is displayed in the 2nd language `data-translatable` is included in the metadata so the translation mode opens. However the iframe relies on the `edit_translations` search param being set to include the translation branding (i.e. `data-oe-translation-source-sha`) which is not the case after pressing Alt+A. __The fix:__ Add `edit_translations` when pressing Alt+A in any case. If the page is translatable, the translation mode will correclty open, otherwise it will be ignored and the edit mode will open instead. NB: By doing this, we bypass the checks in [`attemptStartTranslate`][2] therefore a user who doesn't have the proper access rights will still be able to open the translation mode but they will not be able to do anything. Using those checks would add too much complexity to the code in regards to how niche the feature is anyway. [1]: https://github.com/odoo/odoo/blob/d985ec2e9b61b5e6c36a278654d526aaa5b512e2/addons/website/static/src/js/content/redirect.js#L33 [2]: https://github.com/odoo/odoo/blob/d985ec2e9b61b5e6c36a278654d526aaa5b512e2/addons/website/static/src/client_actions/website_preview/edit_website_systray_item.js#L54 task-5125700
Refunds in Point of Sale now handle serial-numbered products more accurately. When only part of a quantity is refunded, staff can choose which serial numbers to return, and the system preselects the right number by default to make refunds faster and less error-prone.
Original PR description
When refunding an order that contains a product tracked by serial number if you refund less than the total quantity of the product in the order all the serial numbers of the original order would be set anyway. Also you were not able to select the serial numbers to refund. Steps to reproduce: ------------------- * Create product P1, storable, tracked by serial number * Create 2 Serial Numbers SN1, SN2 for P1 * Create a POS order with 2x P1 (SN1, SN2) * Pay and validate the order * Refund the order, set quantity of P1 to 1 * Validate the refund > Observation: The refund order contains P1 with SN1 and SN2, and you cannot edit the serial numbers. Why the fix: ------------ We now allow to select the serial numbers when doing a refund and only show the serial numbers that were in the original order. We also select by default the same number of serial numbers as the quantity to refund. opw-4965171 Forward-Port-Of: odoo/odoo#235514 Forward-Port-Of: odoo/odoo#230778
This change fixes a test issue in the point-of-sale localization flow, helping automated checks run reliably again. It does not change the business behavior of the product, but it prevents false failures during validation and delivery.
Original PR description
Fix runbot issue runbot-233183 Forward-Port-Of: odoo/enterprise#99832 Forward-Port-Of: odoo/enterprise#99370
This fix makes planning analysis reports count time only when a shift actually falls within working hours. It prevents hours from being incorrectly assigned to the wrong month when a shift crosses midnight outside an employee’s schedule.
Original PR description
### Steps to reproduce: - Create an employee with fixed working schedule from 8 to 5 - Create a Planning shift for this employee that starts in a month and ends in the first day of the next month outside of working hours (e.g. Sept30th 8AM -> Oct1st 2AM) - Navigate to Timesheets / Planning analysis reports - Notice October has been taken into consideration in the report's planned hours ### Cause: The query we are using for the timesheets/planning report doesn't take working hours into consideration it only cares about the date. So if the shift ends in October 1st we are taking it into account whether it is inside working hours or not. ### Fix: Add a condition to the where clause to check the working hours and if the record lays in this period or not. opw-5089052 Forward-Port-Of: odoo/enterprise#96846
This fix makes the vendor on-time rate shown in the smart button match the graph and the actual purchase order quantities. It prevents duplicated receipts from inflating totals and gives users a reliable delivery performance view.
Original PR description
**Steps to reproduce:** 1- Install the purchase_stock module. 2- Create a new PO with a new vendor. 3- Add new one product in the purchase order line with quantity > 1. 4- Confirm the PO and go to…
**Steps to reproduce:** 1- Install the purchase_stock module. 2- Create a new PO with a new vendor. 3- Add new one product in the purchase order line with quantity > 1. 4- Confirm the PO and go to the generated receipt. 5- Validate the receipt with less than the ordered quantity, by choosing no backorder. 6- Duplicate the receipt for the remaining quantity and validate it. 7- In vendor form view, the On-time Rate value shown in the smart button differs from the value in the graph. **Issue:** https://github.com/odoo/odoo/blob/e7da32fe67cfe78bc6da8bf5d36a7c584763e3bb/addons/purchase_stock/report/vendor_delay_report.py#L26-L42 - The On-time Rate shown in the smart button does not match the graph. **Example:** - PO Line ordered qty: 10 - First receipt validated: 6 (no backorder) - Duplicated receipt validated: 4 - In vendor form view inside On-time Rate Smart button - Total quantity coming: 14 (incorrect) - Expected total qty for calculation: 10 (from PO line) - On-time delivery rate calculated: **71.43%** - Expected On-time delivery rate: **100%** **Cause:** - The report uses `product_qty` from the stock move. - When a receipt is duplicated and the demand quantity is manually set, `product_qty` is recomputed from this demand value. This leads to a mismatch between the PO line quantity and the aggregated stock move quantities. **NOTE:** In `test_02_vendor_delay_report_partially_cancelled_purchase_order`, added the line:: `purchase_order.order_line.flush_recordset()` - Because we were taking the `partner_id` from the `Purchase Order line` is a stored related field. - The computed value first lives in Odoo’s cache. - It is not written to the database until a flush occurs. - If we immediately call something like _read_group() (which queries the database directly), it won’t see the cached value — only what is persisted in the DB. **Solution:** - Use the purchase order line quantity instead of the stock move’s `product_qty` to ensure consistent and accurate On-time Rate calculation. opw-4991367 Forward-Port-Of: odoo/odoo#236779 Forward-Port-Of: odoo/odoo#225529
Documentation and clarification updates
This change updates the corporate CLA documentation for Moduon. It is an administrative/legal update and does not affect product behavior or customer workflows.
Original PR description
@moduon MT-12696 Forward-Port-Of: odoo/odoo#236642
This change updates the Adhoc Contributor License Agreement documentation to include additional members. It keeps the agreement records current so contributions can continue to be processed smoothly.
Original PR description
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#227891