Thursday, November 20, 2025
10 changes · 18.0
Enhancements to existing features
This change makes the system find delivery information for product lots much faster by reworking how the lookup is done behind the scenes. It reduces the number of database reads and removes repeated processing, which can significantly speed up stock operations for larger batches.
Original PR description
### Description: This refactoring replaces the recursive calculation in `_find_delivery_ids_by_lot` with an iterative process. This change significantly reduces the amount of database queries by prefetching and batching all required lines in a single pass, and it also eliminates the overhead caused by repeated recursive function calls. ### Benchmark: | Total Lots | Before | After | |------------|--------|--------| | 69 | 1 sec | 106 ms | | 1152 | 1 min | 5 sec | ### Reference: opw-5096599 Forward-Port-Of: odoo/odoo#233478
The customer portal now reads subscription billing periods from the system configuration instead of relying on a fixed list. This prevents errors when businesses use custom periods such as daily subscriptions, and makes the portal more adaptable to future changes.
Original PR description
Problem -------- In v18.0, the day billing period was removed from the sale.subscription.plan model. For our use case, we require daily subscriptions, so we added this value back to the…
Problem -------- In v18.0, the day billing period was removed from the sale.subscription.plan model. For our use case, we require daily subscriptions, so we added this value back to the billing_period_unit selection field via inheritance. However, this customization causes an error (a KeyError) when accessing the customer portal at /my/subscriptions/<int:order_id>. This is because the controller logic relies on a hardcoded list of periods and does not account for the new custom "day" value. - Screenshot Order with plan Daily: <img width="1246" height="483" alt="image" src="https://github.com/user-attachments/assets/5dc5ca0d-a2f2-434d-8183-15a0424d9f34" /> - Screenshot when trying to get in order on the website: <img width="1250" height="776" alt="image" src="https://github.com/user-attachments/assets/5b10504e-71e2-4c13-8611-39e8a41e05d1" /> Proposed Solution -------- This PR improves the subscription portal by dynamically retrieving billing periods instead of using a hardcoded list. The portal now reads the available options directly from the billing_period_unit field's selection (i.e., self.env['sale.subscription.plan']._fields['billing_period_unit'].selection). This improves maintainability, as future changes to the field's selection will be automatically reflected without requiring code modifications. This makes the portal robust and automatically compatible with any custom periods added via inheritance. - <img width="1331" height="752" alt="image" src="https://github.com/user-attachments/assets/4f7be6c3-d96b-4525-8e23-6e1323adabde" />
The tax closing process now warns users if they try to close a later period while an earlier one is still open. This helps prevent gaps that could break carryover calculations, especially for reports that depend on a continuous closing order.
Original PR description
For instance with a monthly periodicity and the last closed period is January: When we try to close March, it will show a warning telling us a period in between is not yet closed. This only applies to report with carryover as it can break the carryover chain if we don't do it in the order task-4252735
Resolved issues and error corrections
This change prevents errors when connecting to certain Swedish blackbox devices that only support an older protocol version. The system now checks the device version first and only sends commands it can understand, improving receipt registration reliability.
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#99008
This fixes a calculation issue when importing Italian EDI vendor bills or credit notes that contain a Maggiorazione discount. The line total now keeps the correct sign and amount, preventing incorrect totals on imported documents.
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
This change updates the version information used for LinkedIn connections so the integration continues to work with the current API. It was needed because the previous version has been retired by LinkedIn, which could otherwise disrupt social posting and account syncing.
Original PR description
This commit updates the linkedin version header so that we can use the version of the API. Our actual version was recently sunset, needing the change of version to be done. task-5271712 Forward-Port-Of: odoo/enterprise#99759
When users create a contact from suggested recipients in the full message composer, Odoo now correctly keeps the suggested name and email details. This prevents missing or incorrect partner information, especially in CRM, where lead data could previously be transferred incorrectly.
Original PR description
When a partner is created from suggested recipients for the composer, values suggested for its creation are not used. Whereas they should be used, just like is the case when sending a message from the small composer. We just need to normalize the emails from the "additional values" dict on the server. As was done in [1] for the post route (small composer). Additionally the suggested recipient for leads is updated to use the contact name if available, to match suggested recipient values which defaults to assuming we are creating an individual (not a company) task-5241064 [1]: https://github.com/odoo/odoo/commit/67c5a61b09e199430a48aa15a899ac05c761ad6a
When a subscription delivery is returned, the system now properly updates the sold quantity on the order line. This keeps subscription invoicing and delivery figures aligned after returns, preventing incorrect quantities from being reported.
Original PR description
**Steps to reproduce** - Create a new subscription using a subscription product. Confirm it. - Run the "Sale Subscription: generate recurring invoices and payments" scheduled action to generate the delivery. Validate the delivery. - Return the delivery and validate the return. - Issue: the delivered quantity of the sale order line is not updated. **Cause** Currently, we consider a move as related to a subscription period based on the `date_deadline` field (see _get_outgoing_incoming_moves). Since `_prepare_procurement_values` is not called when creating a return, the `date_deadline` is not set on the return moves. **Change** The returns linked to a move in a subcription period will be conisdered for the computation of the delivered quantities. opw-5136406 Forward-Port-Of: odoo/enterprise#98690
This fix stops users from accidentally changing values that should be read-only when they drag and drop items in Gantt planning views. It helps avoid unintended updates to planned work, such as changing the wrong product or work center during scheduling.
Original PR description
Issue ----- Gantt view's drag & drop allows the user to change the value of readonly fields if they are stored. E.G. in the Planning view of MRP, grouped by Work Center > Product, dragging & dropping…
Issue ----- Gantt view's drag & drop allows the user to change the value of readonly fields if they are stored. E.G. in the Planning view of MRP, grouped by Work Center > Product, dragging & dropping can change the product of the WO if the user is not careful and drops the WO on top of another product's WO. Steps to reproduce ----- - Have 2 products - Create a MO for product 1 with a WO at work center 1, plan it - Create a MO for product 2 with a WO at work center 2, plan it - Got to Manufacturing, Planning, Planning by Work Center - Add a custom group (by product) - Drag the WO of WC2 and drop it on top of the other WO > Both the WC and the product of the second WO change Cause ----- The example problem is only for versions 17.0 & 18.0 where the `product_id` field of `mrp.workorder` is both readonly and stored. https://github.com/odoo/odoo/blob/31e46a841b38de0f99beb1844f985bc670621486/addons/mrp/models/mrp_workorder.py#L34 While the user cannot change the field value manually, automatic actions such as a gantt view drag & drop can change its' value by passing it to `write` since the field is stored. This does not pose any problem for related fields that are not stored. More broadly, gantt views should not ignore the `readonly` attribute of fields. Solution ----- Add a new `o_gantt_readonly` class to all cells of rows grouped by a readonly field - and their "child" rows. For example, if the grouping is done by "Work Center > Product > Quality Check" and "Product" is readonly, rows grouped by either "Product" or "Quality Check" will be marked as readonly. When the user drags a pill, dynamically remove the class from cells of the same "child group". The class will then be added back upon pill drop. ----- Ticket: opw-4875366 Forward-Port-Of: odoo/enterprise#94166
The stock forecast now uses the actual received quantity for completed stock moves instead of the originally planned amount. This fixes incorrect future/past forecast numbers when a receipt is validated for less or more than expected, helping users trust the inventory forecast shown on product pages.
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