Wednesday, February 11, 2026
35 changes · 19.0
Resolved issues and error corrections
The Spanish accounting localization no longer separates sales accounts by Spain, intra-community, and export sales when the official requirements do not call for that distinction. This simplifies the chart of accounts and reduces unnecessary accounting complexity for Spanish companies.
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
Month names shown in reports and HR-related workflows now use the language set in the Odoo user environment instead of the server or system locale. This helps multilingual businesses present dates consistently in the expected language across employee, digest, point-of-sale, and localization documents.
Original PR description
Month name is using the locale language instead of the env language Get month name in the env language Enterprise PR: odoo/enterprise#106175 Task [link](https://www.odoo.com/odoo/project.task/5902364) task-5902364 Forward-Port-Of: odoo/odoo#247794 Forward-Port-Of: odoo/odoo#246790
Invoices created from point of sale orders paid through a customer account now correctly include payments made through a later settlement order. This prevents invoices from incorrectly appearing unpaid after the customer has already settled the balance.
Original PR description
If you made a PoS order paid with the customer account payment method, and then you created a settle due order to settle the previous one. If you then create the invoice for the original order, the invoice would appear as unpaid, because the payments of the settle due order were not taken into account. Steps to reproduce: ------------------- * Create a PoS order and pay with the customer account payment method * Settle the order that you just created with a settle due order * Close the session * Go on the original order and create the invoice > Observation: The invoice appears as unpaid when it should be paid. Why the fix: ------------ When creating the invoice we gather all the payments of the order to create the corresponding journal entries. But the payment of the settle due order were not included. So the order was considered as unpaid. opw-5268042
The stock forecast report now avoids including archived product variants when checking related stock movements. This prevents a crash when users view forecasts for products that have archived variants with pending operations, keeping inventory planning accessible and reliable.
Original PR description
Currently, accessing the Forecast report on a Product Template causes a crash if the template contains an archived variant that still has active stock moves (e.g., a pending delivery). ## **Steps to…
Currently, accessing the Forecast report on a Product Template causes a crash if the template contains an archived variant that still has active stock moves (e.g., a pending delivery).
## **Steps to Reproduce:**
1) Install `stock` with demo data.
2) Create a Delivery orders(stock picking) for product `conference chair(E-COM12)`
with demand of 40 qty, click on `Mark as todo`.
3) Navigate to `stock>products>products` and open `conference chair` product form
view.
4) From the variant smart button archive `E-COM12` variant.
5) Navigate back to product form view and click on `forecast` smart button.
## **Error:**
`TypeError: Cannot read properties of undefined (reading 'free_qty')`
## **Root Cause:**
`this.props.docs.product[line]` at [1] is undefined because the server did not
include an entry for that product id in the report header.
### **Complete Flow:**
On clicking the Forecast button an ORM call is made to [_get_report_values](https://github.com/odoo/odoo/blob/0dd40ede75f68b18192738f0d20aadaac9f348c7/addons/stock/report/stock_forecasted.py#L512-L519),
which calls [_get_report_data](https://github.com/odoo/odoo/blob/0dd40ede75f68b18192738f0d20aadaac9f348c7/addons/stock/report/stock_forecasted.py#L156-L172) to build the report data.
#### **Header Part:**
- [_get_report_header](https://github.com/odoo/odoo/blob/0dd40ede75f68b18192738f0d20aadaac9f348c7/addons/stock/report/stock_forecasted.py#L112-L144) returns metadata only for active variants because,
[_get_product_quantity](https://github.com/odoo/odoo/blob/0dd40ede75f68b18192738f0d20aadaac9f348c7/addons/stock/report/stock_forecasted.py#L69-L72) is called which calls _get_products(see[2]), and _get_products only
returns active variants for the product template.
#### **Lines Part:**
- [_get_product_lines](https://github.com/odoo/odoo/blob/82fe034509a6b401e86c345a82aa7b8948294e52/addons/stock/report/stock_forecasted.py#L239) iterates over products coming from the move search
and it includes both archived and unarchived variants.
[_move_confirmed_domain](https://github.com/odoo/odoo/blob/82fe034509a6b401e86c345a82aa7b8948294e52/addons/stock/report/stock_forecasted.py#L55-L56) calls _move_domain(see[3]), which searches stock.move using
product_tmpl_id when given a template id and therefore returns moves for
every variant of the template (archived or not).
#### **Why the mismatch happens:**
- `_get_products` fetches variants using `browse()` which by default excludes archived variants.
`_product_domain`(see[3]) uses product_tmpl_id when given product_template_ids,
which matches moves for all variants of the template. As a result, moves can reference
archived variant ids that the header never listed.
[1]- https://github.com/odoo/odoo/blob/0dd40ede75f68b18192738f0d20aadaac9f348c7/addons/stock/static/src/stock_forecasted/forecasted_details.js#L188
[2]- https://github.com/odoo/odoo/blob/82fe034509a6b401e86c345a82aa7b8948294e52/addons/stock/report/stock_forecasted.py#L61-L67
[3]- https://github.com/odoo/odoo/blob/82fe034509a6b401e86c345a82aa7b8948294e52/addons/stock/report/stock_forecasted.py#L25-L31
## **Fix:**
- This commit ensures that archived product variants are excluded directly
at move search level by appending `('product_id.active', '=', True)` to
the product domain used by the forecast report. This ensures that only
active product variants are considered when fetching stock moves.
### **opw-5440872**Fixes a subcontracting issue where changing a purchase receipt quantity after the bill of materials was updated could show the wrong received quantity on detailed lines. This helps keep receiving records accurate and avoids confusion in subcontracted manufacturing purchases.
Original PR description
**Issue** In subcontracting, if a BOM is modified after the creation of a PO, then modifying the move quantity of the associated receipt can lead to inconsistency between move and move line…
**Issue** In subcontracting, if a BOM is modified after the creation of a PO, then modifying the move quantity of the associated receipt can lead to inconsistency between move and move line quantities. **Steps to reproduce** - Create a subcontracting BOM of a final product using 1 component product - Create a PO of the final product for a quantity of 10 and confirm it - Modify the BOM to use 2 component products instead - Go to the receipt of the PO and modify the quantity to 2 and validate it - Click on the move line of the receipt -> The displayed quantity is 10 instead of 2 **Cause** Setting the quantity triggers this line: https://github.com/odoo/odoo/blob/c496235b9520b2a33040174974de7d37e74b0580/addons/mrp_subcontracting/models/stock_move.py#L78-L78 which calls: https://github.com/odoo/odoo/blob/c496235b9520b2a33040174974de7d37e74b0580/addons/mrp_subcontracting/models/stock_move.py#L107 Since the BOM has been modified, a `consumption_issues` is detected and `_update_finished_move()` won't be called: https://github.com/odoo/odoo/blob/c496235b9520b2a33040174974de7d37e74b0580/addons/mrp_subcontracting/models/mrp_production.py#L86-L89 And since the returned action is not used when calling `subcontracting_record_component`, `_update_finished_move()` won't be called later neither, which is the method responsible for updating the move line quantities: https://github.com/odoo/odoo/blob/c496235b9520b2a33040174974de7d37e74b0580/addons/mrp_subcontracting/models/mrp_production.py#L142-L146 **Solution** Since the consumption issue actions are ignored in this case, just skipped it and avoid inconsistencies. opw-5493577 Forward-Port-Of: odoo/odoo#246433 Forward-Port-Of: odoo/odoo#245065
This fixes the Spanish Mod 390 VAT report so specific tax box balances are included in the correct annual totals. Businesses using the Spanish localization get more accurate VAT reporting and reduce the risk of incorrect filings.
Original PR description
In this commit: Fixing 390 computation: - Add balance from 27, 29, 649 and 31 to casilla 33. - Add balance from 28, 30, 650 and 32 to casilla 34. Related PR : https://github.com/odoo/enterprise/pull/105597 task-5732679 Forward-Port-Of: odoo/odoo#247823 Forward-Port-Of: odoo/odoo#245828
The attendance menu now avoids getting stuck when location lookup is slow or unavailable by timing out after 10 seconds and continuing without location data. It also blocks repeated clicks while an attendance action is pending, reducing duplicate records and incorrect check-in or check-out times.
Original PR description
when using signInOut with geolocation, slow or temporarily unavailable network connections could cause getCurrentPosition to hang indefinitely (default timeout is infinite). This led to: - Frontend…
when using signInOut with geolocation, slow or temporarily unavailable network connections could cause getCurrentPosition to hang indefinitely (default timeout is infinite). This led to: - Frontend not updating, allowing multiple clicks and creating duplicate attendance entries - Incorrect check-in/check-out data __Steps to reproduce:__ 1. check in while online and server reachable 2. disconnect network or make server unreachable 3. check out Currently, getCurrentPosition would hang indefinitely. till the network is restored. then it will trigger the rpc call much later than the action time. in the meantime, the user could click multiple times, creating multiple attendance records. With this fix, getCurrentPosition will timeout after 10 seconds, then it will proceed without position. and if the server is unreachable, it will show an error notification without allowing multiple clicks. __FIX__ - Adds a timeout to getCurrentPosition - Uses a `_attendanceInProgress` flag to prevent multiple clicks - Ensures only the first callback (success or error) triggers the RPC opw-5414044 Forward-Port-Of: odoo/odoo#247140 Forward-Port-Of: odoo/odoo#244477
Vendor bills can now find matching purchase orders from related companies during payment matching, consistent with existing bill matching behavior. This helps multi-company businesses reconcile bills and purchases correctly when orders are created in a child company and billed in a parent company.
Original PR description
On bills, the `purchase_vendor_bill_id` field already allows matching with cross-company purchase orders. This commit extends this behavior to payment matching. Steps to reproduce: - Create a child company from a parent company. - Create a purchase order in the child company. - Create a bill in the parent company. - In the bill’s payment matching, the child company’s purchase order should be available. opw-5416947 Forward-Port-Of: odoo/odoo#244973
Point of Sale now calculates refund quantities for each item inside a combo instead of applying the combo quantity to every line. This lets businesses refund the correct number of included items, such as all burgers in multi-menu orders, reducing refund errors at checkout.
Original PR description
When refunding a combo item, the 'To Refund' text would always show the same quantity for all the orerlines as for the combo. But combos could have orderlines with a higher quantity than the combo itself (i.e. 3 menus with 2 burgers each - 6 burgers in total. Now the POS would only let us refund up to the limit qty of the combo, so 3 instead of all 6 burgers) After the fix, we check the quantity of each line in the combo and we refund the full quantity (i.e. if you have a 3 menus with 2 burgers each - 6 burgers in total. The burgers will be divided per combo, so each menu refund will automatically refund 2 burgers.) Task-[5503962](https://www.odoo.com/odoo/project/1737/tasks/5503962) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale now correctly shows availability for event tickets marked as unlimited, even when the overall event has a seat limit. This prevents staff from seeing sellable tickets as sold out and helps avoid missed ticket sales.
Original PR description
We had a bug when selling event tickets in POS where tickets with seats_max set to 0 (which should mean unlimited) appeared as sold out when the event had seats_limited enabled. Steps to reproduce:…
We had a bug when selling event tickets in POS where tickets with seats_max set to 0 (which should mean unlimited) appeared as sold out when the event had seats_limited enabled. Steps to reproduce: ------------------- * Create an event with seats_limited=True and seats_max > 0 * Create a ticket for that event with seats_max=0 (unlimited) * Open POS and view the event product > Observation: Ticket appears as "Sold out" instead of showing available seats Why the fix: ------------ The frontend logic only treated tickets with seats_max=0 as unlimited when the event itself was not limited (!event.seats_limited). However, according to the backend logic, seats_max=0 means the ticket is unlimited regardless of the event's limitation status. When the event is limited, unlimited tickets should still respect the event's seats_available limit, not show as sold out. We now check for seats_max=0 independently of event limitation. If the event is not limited, tickets with seats_max=0 are fully unlimited. If the event is limited, we use the event's seats_available value (since the ticket doesn't constrain availability but the event does), ensuring correct display of availability status. opw-5475803
This fix prevents manufacturing orders from failing when large quantities of serial-tracked products are split across linked production steps. It improves reliability for businesses handling high-volume manufacturing with traceable items.
Original PR description
**Issue** When producing a large number of serial-tracked products, a RecursionError can occur. **Steps to reproduce** - Create three products tracked by serial number (ensure MTO and Manufacture…
**Issue** When producing a large number of serial-tracked products, a RecursionError can occur. **Steps to reproduce** - Create three products tracked by serial number (ensure MTO and Manufacture routes are enabled). - Create a BoM for product A containing product B. - Create a BoM for product B containing product C. - Create a BoM for product C containing another product. - Create a manufacturing order of 100 units for product A and confirm it. - Go to the MO C and split into 100 mo - Go to the MO B and split into 100 mo -> RecursionError: maximum recursion depth exceeded. **Cause** While splitting, this method is called: https://github.com/odoo/odoo/blob/cda011dc8590773f6c3a26f4ae9d5242a3147024/addons/mrp/models/mrp_production.py#L2031 which ultimately calls: https://github.com/odoo/odoo/blob/cda011dc8590773f6c3a26f4ae9d5242a3147024/addons/stock/models/stock_move.py#L658-L661 This retriggers `_compute_packaging_uom_id` for all moves in `move_orig_ids` or `move_dest_ids`, and accessing the full recordsets causes recursive recomputation leading to a RecursionError. opw-5265424
Deleting content blocks in the website editor could leave behind invisible empty content, causing a "Document is empty" error when saving product descriptions. This fix cleans up those empty structures after removal so users can save edited pages normally.
Original PR description
Steps to reproduce: =================== 1- Go to Website > eCommerce > Products 2- Open any product and click "Edit website" 3- Add a lot of content blocks (contact form etc..) & save 4- In the…
Steps to reproduce: =================== 1- Go to Website > eCommerce > Products 2- Open any product and click "Edit website" 3- Add a lot of content blocks (contact form etc..) & save 4- In the product description, delete all content blocks and keep the last one 5- Click Save ->"Document is empty" validation error appears Cause: ====== When saving an HTML field after deleting all content, whitespace text nodes (like newlines) may remain in the DOM element. The _copy_custom_snippet_translations lang_value might have this whitespace as the content, which will cause "Document is empty" error when the content is parsed by fromstring(). This didn't occur before the migration because the previous implementation called _onSnippetRemoved after a content block was deleted, and that handler removed any empty elements. https://github.com/odoo/odoo/blob/8d66c79ecf74900af1c5b003723363be3d52cbc8/addons/website/static/src/components/wysiwyg_adapter/wysiwyg_adapter.js#L1370 Solution: ========= After removing the content block, we should also do a cleanup. opw-5263743 Forward-Port-Of: odoo/odoo#241291
Copying content from locked Knowledge clipboard blocks now preserves full table formatting instead of copying only the text. This makes copied content behave consistently between editable and locked views and avoids manual rebuilding of table layouts after pasting.
Original PR description
Problem: In Knowledge, when adding a clipboard block and inserting a table inside it, clicking on the copy button only copies the text inside the table instead of the full table structure. Cause: In `html_viewer`, the copy logic clones only the deepest selected node. In contrast, `html_editor` (via `clipboard_plugin`) copies the entire selection range. This difference causes inconsistent behavior between editable and locked content. Solution: Align the behavior by copying the full selection in `html_viewer`, ensuring tables and other complex structures are copied entirely and consistently. Steps to reproduce: - Open Knowledge. - Add a clipboard block. - Insert a table inside the block. - Lock the content. - Click the copy button. - Paste into any editable field. - Observe that only the text (not the table) is pasted. opw-5476320 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes a checkout issue where shoppers who changed a product quantity in the add-to-cart window could still see the old quantity in their cart. The cart now keeps the shopper’s intended quantity, reducing order mistakes and checkout frustration.
Original PR description
**Steps to produce:** - Install `website_sale` with demo data. - Go to the shop page. - Select product `Customizable Desk` > click `Add to cart`. - In the wizard, change the quantity to 100 and…
**Steps to produce:** - Install `website_sale` with demo data. - Go to the shop page. - Select product `Customizable Desk` > click `Add to cart`. - In the wizard, change the quantity to 100 and directly click `Checkout`. **Issue:** - The cart shows the product with quantity = 1 instead of the edited value. Root cause: - When the user clicks Checkout, both `setQuantity` and `onConfirm` are triggered almost simultaneously. - At [1], the `_setQuantity` method is called, but due to the await before the quantity update is completed, the update may not finish in time. As a result, the previous quantity is sometimes used during checkout instead of the newly selected one. Solution: - we can update the quantity immediately before awaiting `_updateCombination`, ensuring that the correct quantity is already set when onConfirm runs. [1]: https://github.com/odoo/odoo/blob/f4eabe47a602301013afa63da6bdf87809903d29/addons/sale/static/src/js/product_configurator_dialog/product_configurator_dialog.js#L225 opw-5435672 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#247866 Forward-Port-Of: odoo/odoo#241424
Sales orders imported into Point of Sale and paid through an online payment method now move out of quotation status as expected. This prevents paid orders from appearing unfinished in the Sales app and keeps payment and order status aligned.
Original PR description
When a Sale Order was imported in PoS and paid using online payment method, the SO's state stayed in Quotation. Steps to reproduce: ------------------- * Create a new Sale Order with a product available in POS * Add Online Payment in the Payment Methods * Import and settle the Order in POS * Pay the order with the Online Payment > Observation: In Sale app, the Sale Order is still in Quotation state. Why the fix: ------------ Online payments call `action_pos_order_paid()` directly, which only sets the POS order state to paid and never confirms the linked sale.order. Other payment methods do it in `sync_from_ui()`. Extended `action_pos_order_paid()` in pos_sale will now confirm linked quotations after POS marks the order as paid. opw-5022526 Forward-Port-Of: odoo/odoo#247998 Forward-Port-Of: odoo/odoo#230112
This fix stops Inventory users from accidentally creating duplicate lot or serial numbers when GS1 barcode rules are enabled. It helps preserve traceability accuracy and reduces the risk of stock records being mixed up or duplicated.
Original PR description
## Issue When using the *Default GS1 Nomenclature*, it is possible to create multiple lots/serial numbers with a same name if that name matches a barcode rule pattern. ## Steps to reproduce 1.…
## Issue
When using the *Default GS1 Nomenclature*, it is possible to create multiple lots/serial numbers with a same name if that name matches a barcode rule pattern.
## Steps to reproduce
1. Install *Inventory* (`stock`)
2. In Settings, enable *Lots & Serial Numbers* and set *Barcode Nomenclature* to *"Default GS1 Nomenclature"*
3. Create a product tracked *By Unique Serial Number* or *By Lots*
4. In Inventory > Products > Lots / Serial Numbers, create a lot/serial number named *"101"* and set the product to the one created in the previous step
- The name *"101"* matches the pattern of the rule *"Batch or lot number"* (`(10)([!"%-/0-9:-?A-Z_a-z]{0,20})`)
5. Create a second lot/serial number with the same name and the same product
6. **The second lot/serial number is succesfully created**
## Cause
When comparing a (new) `stock_lot.name` to existing `stock_lot`s, the potential rules at the start of the name are removed by the `gs1_decompose_extended` method [here](https://github.com/odoo-dev/odoo/blob/e06282df3a7482cc327d3124e6c2b1c8bc55c2f0/addons/barcodes_gs1_nomenclature/models/barcode_nomenclature.py#L116-L125). This results in comparing **the end** of the new lot/serial number with **the entire** name of existings serials.
## Solution
Commit https://github.com/odoo/odoo/commit/3513b189a225ca52fc9fae94693f00f43ded71aa introduced the `skip_preprocess_gs1` context flag. This flag allows to skip the step that removes the start of the new lot/serial number before comparing it to existing serials.
## Test
The test for this commit is added in `stock_barcode` by [this PR](https://github.com/odoo/enterprise/pull/104720)
opw-5477003This fix ensures that when products are grouped by category in Point of Sale, every relevant product appears in the list. It prevents missing items during sales, helping cashiers find and sell products reliably.
Original PR description
Before this commit when activating the "Group by category" option in the POS, some products were missing from the product list. Now we use the `getAllBy` generic model method to group products by category, which ensures that all products are correctly grouped and displayed in the POS.
Posting invoices for kit products with multiple tracked components no longer fails when using average cost or FIFO valuation. This helps businesses invoice delivered kits reliably while keeping cost of goods calculations accurate.
Original PR description
**Issue**: The computation of cogs value, in AVCO (or FIFO) setup with kit of several component leads to traceback **Steps to reproduce**: - Create a kit product with 2 components: - Inventory…
**Issue**:
The computation of cogs value, in AVCO (or FIFO) setup with kit of several component leads to traceback
**Steps to reproduce**:
- Create a kit product with 2 components:
- Inventory tracking enabled
- Use a category configured with AVCO and Perpetual (at invoicing) valuation
- Create a SO for the kit product and confirm it
- Go to the associated delivery and validate it
- Create and post the invoice on the so -> A traceback occurs
**Cause**:
In `_get_cogs_price_unit`, the code accesses `self.product_id.cost_method` assuming a singleton: https://github.com/odoo/odoo/blob/5d2e4b0f3fa8cdf2a977db05c7c2565b06ca2513/addons/stock_account/models/stock_move.py#L245 but `self.product_id` can be a multi-recordset when the sale line corresponds to a kit with multiple components https://github.com/odoo/odoo/blob/5d2e4b0f3fa8cdf2a977db05c7c2565b06ca2513/addons/stock_account/models/account_move_line.py#L67-L68 https://github.com/odoo/odoo/blob/5d2e4b0f3fa8cdf2a977db05c7c2565b06ca2513/addons/sale_stock/models/account_move.py#L155-L156
which causes the traceback.
**solution**
The solution has been inspired by this:
https://github.com/odoo/odoo/blob/008e69e8215fecc1f3fe45a36189592577cdc593/addons/stock_account/models/stock_move.py#L225-L228
opw-5880383This fixes an issue where users navigating with a keyboard could become trapped in the search bar filters and be unable to move forward through the page. Keyboard navigation now continues past the search bar as expected, improving accessibility and day-to-day usability.
Original PR description
When navigating any view using keyboard navigation, the focus gets stuck on the search bar filter and cannot move forward. After this commit keyboard navigation will move forward from the search bar filter. Issue introduced by https://github.com/odoo/odoo/pull/208862 Task-5421313 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Bill of Materials report now keeps the selected product variant aligned between the server and the screen. This prevents users from being blocked from switching to another valid variant when product variant ordering differs from internal IDs.
Original PR description
Steps to reproduce on runbot ------------------ Select a product with several variants and a Bill of Materials (e.g. Stool). Change the variants order so that their ids are not ordered, this can be…
Steps to reproduce on runbot ------------------ Select a product with several variants and a Bill of Materials (e.g. Stool). Change the variants order so that their ids are not ordered, this can be done by modifying the default_code for example (e.g. Internal Reference for variant "Color: Green" set to "A"). When accessing the BoM report, you won’t be able to switch to one of the possible variants (in the example the Dark Blue variant). Why it is happening ------------------ The default variant to be displayed when opening the report is selected in the backend using the product_variant_id field. This field is computed as the first element in product_variant_ids as they are ordered in the model. We then send this variant’s information to the frontend and a dictionary containing every variant (key= id and value = display_name). In the serialization process, the object is reordered based on the keys. Thus, if the variants were not ordered based on their ids in python, the order will change. The displayed variant is correct as it has been passed directly but the frontend also computes the currentVariant attribute. This is computed as the first element in the dictionary but in this case, it is not the one that has been selected in the backend, as the order changed. As a result, you see the report for a variant A but the frontend considers you are on the report for variant B so you cannot switch to variant B as you are supposed to be already on it. The fix ------------------ I propose to use the explicitly passed id as the currentVariantId. opw-5409493 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#248009 Forward-Port-Of: odoo/odoo#241603
This update fixes how mail activities check access permissions when linked to business documents. It helps ensure users get the correct access behavior while adding tests to prevent regressions and monitor batch performance.
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#247997 Forward-Port-Of: odoo/odoo#245744
A bug in Point of Sale product data handling was fixed to stop repeated lookups when certain product fields were empty or false. This prevents potential freezes or crashes when accessing affected product information, improving reliability for users at checkout.
Original PR description
Before this commit, if a getter was defined in both product.product and product.template models, and the getter returned a falsy value (like false or an empty string), it could lead to infinite recursion when accessing the property. This was due to the way the models fell back to each other to retrieve the property value. opw-5886320 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale refund orders are now reported with negative amounts instead of positive ones. This prevents refunds from inflating reported sales and improves the accuracy of business reporting.
Original PR description
Before this commit, the refund orders had positive amount in the report, which is not correct. opw-5821547 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where invoicing a point of sale order paid through a customer account could leave duplicate outstanding credits after the session was closed. The reversal is now matched against the original customer account entry, so only the invoice remains open for follow-up.
Original PR description
If you made a PoS order paid with the customer account payment method, then close the session. Then invoice the order, a reversal entry would be created but it would not be reconciled at all. As no payment was made a this point it should be reconciled with the original Customer Account entry from the pos session, this way only the invoice remains open. Steps to reproduce: ------------------- * Create a PoS order and pay with the customer account payment method * Close the session * Go on the order and create the invoice > Observation: The reversal move is not reconciled and the customer has two outstanding credits. Why the fix: ------------ When creating the invoice we reconcile the reversal entry with the original customer account entry from the pos session. This way only the invoice remains open. opw-5268042
This fix stops timeout errors from appearing when website builder actions legitimately wait for a user to choose something in a dialog. It improves the editing experience for website and online store pages by avoiding misleading technical error messages during normal use.
Original PR description
In [0] was added a timeout on operations, as an heuristic to detect when an operation is stuck. Unfortunately, when an action opens a dialog, waiting for the user to choose may go over the timeout limit, thus triggering the timeout. The timeout should be deactivated for those type of actions. This commit sets `canTimeout = false` on actions that open a dialog and wait for user choice in the `apply` method. Steps to reproduce: - Open website builder - Drop `s_sidegrid` snippet - Click on "Add Elements" option: Image - Wait 10sec - Bug: It show the error message "A technical issue occurred..." [0]: https://github.com/odoo/odoo/commit/6df83abb35c95ab42e55d9a08cf6c411efa64b3e
This fix prevents errors when editing a payment whose journal entry has been split across multiple bank or cash lines. Businesses can adjust and repost these payments more reliably, reducing interruptions in accounting workflows.
Original PR description
This PR improves payment move synchronization and fixes an error that is caused while changing amount of a Payment that has multiple liquidity lines. Steps to reproduce: 1. Create payment with x…
This PR improves payment move synchronization and fixes an error that is caused while changing amount of a Payment that has multiple liquidity lines. Steps to reproduce: 1. Create payment with x amount and validate it. 2. Open the payment journal entry. 3. Reset to draft and update the liquidity line amount from x to (x - y) 4. Create another liquidity line with amount y to balance entry and post it. 5. Draft the payment and try to update the amount. A traceback will appear. `ValueError: Expected singleton` Cause: The lines for payment JE are prepared for the case assuming that there will be only 1 liquidity line, but since we have more than 1, we get a Singleton error. Description of changes made: While preparing values for move in `synchronize_to_moves()` check for multiple liquidity lines and append all values to write. Further, the `_prepare_move_line_default_vals()` is also improved in order to manage different type of move lines individually. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#246675
This update ensures invoices for Point of Sale orders are correctly marked as paid when a settle due order is used to complete the payment. Previously, the system didn't account for payments from settle due orders, leading to invoices appearing unpaid. This fix ensures accurate invoice status and payment tracking.
Original PR description
If you made a PoS order paid with the customer account payment method, and then you created a settle due order to settle the previous one. If you then create the invoice for the original order, the invoice would appear as unpaid, because the payments of the settle due order were not taken into account. Steps to reproduce: ------------------- * Create a PoS order and pay with the customer account payment method * Settle the order that you just created with a settle due order * Close the session * Go on the original order and create the invoice > Observation: The invoice appears as unpaid when it should be paid. Why the fix: ------------ When creating the invoice we gather all the payments of the order to create the corresponding journal entries. But the payment of the settle due order were not included. So the order was considered as unpaid. opw-5268042
This update resolves an issue where invoice exports were failing when invoices included a section or note line as the first entry. The fix filters out these lines during currency rate calculations, preventing a division-by-zero error and ensuring invoices can be correctly sent and downloaded. This improves the reliability of invoice export processes.
Original PR description
Before this commit: Steps 1) Create an invoice with a section or note line as the first line 2) Try to send or download the invoice => A traceback error is raised with the message: File "/home/odoo/src/enterprise/17.0/l10n_cl_edi_exports/models/account_move.py", line 68, in _get_inverse_currency_rate return float_round(abs(self.line_ids[0].balance / self.line_ids[0].amount_currency), 2) ZeroDivisionError: float division by zero This occurs because the `_get_inverse_currency_rate()` method is dividing over self.line_ids[0].amount_currency which is always equal to 0 in case of section or note line is added as a first line in the invoice. After this commit: Filtering out section and note lines in _get_inverse_currency_rate() to correctly calculation the inverse currency rate opw-5488417 Forward-Port-Of: odoo/enterprise#105774
This update fixes an issue where reports related to Spanish withholding taxes were incorrectly including a specific tax type (347). The change ensures that these reports accurately reflect withholding tax moves by clearing the `type for 347` field, improving the accuracy of financial reporting. This resolves a potential discrepancy in tax calculations.
Original PR description
- Moves that use withholding taxes should have the `type for 347` unselected and left blank. Related PR : https://github.com/odoo/odoo/pull/245828 task-5732679 Forward-Port-Of: odoo/enterprise#106889 Forward-Port-Of: odoo/enterprise#105597
This update resolves a bug that caused a RecursionError when producing large quantities of serial-tracked products. The fix prevents excessive recomputation during manufacturing order splitting, ensuring stability and preventing errors with high-volume production runs. This improves the reliability of the MRP module.
Original PR description
**Issue** When producing a large number of serial-tracked products, a RecursionError can occur. **Steps to reproduce** - Create three products tracked by serial number (ensure MTO and Manufacture…
**Issue** When producing a large number of serial-tracked products, a RecursionError can occur. **Steps to reproduce** - Create three products tracked by serial number (ensure MTO and Manufacture routes are enabled). - Create a BoM for product A containing product B. - Create a BoM for product B containing product C. - Create a BoM for product C containing another product. - Create a manufacturing order of 100 units for product A and confirm it. - Go to the MO C and split into 100 mo - Go to the MO B and split into 100 mo -> RecursionError: maximum recursion depth exceeded. **Cause** While splitting, this method is called: https://github.com/odoo/odoo/blob/cda011dc8590773f6c3a26f4ae9d5242a3147024/addons/mrp/models/mrp_production.py#L2031 which ultimately calls: https://github.com/odoo/odoo/blob/cda011dc8590773f6c3a26f4ae9d5242a3147024/addons/stock/models/stock_move.py#L658-L661 This retriggers `_compute_packaging_uom_id` for all moves in `move_orig_ids` or `move_dest_ids`, and accessing the full recordsets causes recursive recomputation leading to a RecursionError. opw-5265424
This update resolves an issue where duplicate GS1 serial/lot numbers could cause incorrect stock lot queries. The fix ensures that lot names are correctly processed, preventing errors when creating multiple lots with similar names, regardless of whether the 'stock_barcode' app is installed.
Original PR description
## Issue When using the *Default GS1 Nomenclature*, it is possible to create multiple lot/serial numbers with a same name if the name matches a barcode rule pattern. ## Fix The fix related to this…
## Issue When using the *Default GS1 Nomenclature*, it is possible to create multiple lot/serial numbers with a same name if the name matches a barcode rule pattern. ## Fix The fix related to this commit is introduced by [this PR](https://github.com/odoo/odoo/pull/244427). ## Problematic flow The problematic flow starts in the `StockLot._check_unique_lot` method when calling `self._read_group`. At that point, the domain is still correct: it contains the product_id and the (correct) name for the lot we try to create. https://github.com/odoo/odoo/blob/b51c80a4368b99e55073856061113244b16b23f9/addons/stock/models/stock_lot.py#L104-L111 In the `BaseModel._read_group` method, the query is defined by the `self._search` method. At that point, the domain is the same as in the previous step, so it is still correct. https://github.com/odoo/odoo/blob/b51c80a4368b99e55073856061113244b16b23f9/odoo/orm/models.py#L1902-L1904 Now the flow differs depending on whether the `stock_barcode` app is installed or not. If it is, the `stock_barcode/StockLot._search` method is called: https://github.com/odoo/enterprise/blob/24fea3814b95144953fb809d10bf6a62906c06fd/stock_barcode/models/stock_lot.py#L11-L15 This is the method that calls the `BarcodeNomenclature._preprocess_gs1_search_args` which uses the `skip_preprocess_gs1` context flag: https://github.com/odoo/odoo/blob/b51c80a4368b99e55073856061113244b16b23f9/addons/barcodes_gs1_nomenclature/models/barcode_nomenclature.py#L149-L151 **This flow makes the query returned by `self._search(domain)` erroneous, as the start of the name of the lot is removed further down the execution of the `preprocess_gs1_search_args` method.** ### If stock_barcode is not installed The `self._search` method called in the BaseModel will not call `stock_barcode/StockLot._search`, but instead it calls `BaseModel._search`. This totally skips the problematic gs1 flow. opw-5477003
This update fixes several issues related to rental scheduling conflicts, preventing users from overlapping bookings for the same resources. Specifically, it now validates date changes to rental shifts, preventing conflicts and ensuring resources are available for multiple bookings. The changes also ensure error messages are displayed correctly and that buttons are appropriately disabled when conflicts exist.
Original PR description
## [FIX] sale_renting_planning: prevent user to do a conflict with rental shift Before this commit, the user could update the shift linked to a rental order and creating a conflict with another shift…
## [FIX] sale_renting_planning: prevent user to do a conflict with rental shift Before this commit, the user could update the shift linked to a rental order and creating a conflict with another shift for the same resource and so, it would be impossible for the resource to be in 2 spaces at the same time (or it is impossible to rent a room to 2 different customers). This commit returns an Validation Error if the user updates the planned dates of a rental shift and creates a conflict. ## [FIX] sale_renting_planning: add problematic shifts only if rental order Before this commit, the previous fix making sure the error, saying no resource is available during the generation of a shifts when the user confirms a sale order, is only displayed when the `Sync Shifts and Rental Orders` is enabled, could potentially never display the error when it should be expected because we only check if the last SOL of the batch to generate shifts has the feature enable or not. This commit makes sure the error is correctly displayed as expected. ## [FIX] sale_renting_planning: update condition of Rental buttons in shift Before this commit, the user could click on Create order button for an open shift is the role having the rental feature enabled. To problem is a resource is required to make sure the rental order can be delivered. About the other button shown, `Add to Last Order` one, this one could be clicked even if the shift is in conflict with another shift and so, it will display a warning saying no resource is available. This commit makes sure - `Create Order` button in shift form view is not visible when the shift is a open shift. - `Create Order` and `Add to Last Order` buttons in shift form view are not displayed when the shift is in conflict. task-5065930 Forward-Port-Of: odoo/enterprise#97024
This update resolves an issue where reports related to Peruvian sales (l10n_pe) were occasionally producing inconsistent results. The fix ensures that stock movements are consistently identified in reports by sorting purchase and sales order IDs, guaranteeing accurate reporting. This improves the reliability of financial data for Peruvian customers.
Original PR description
Occasionally the test_kardex_report test fails: ``` Traceback (most recent call last): File "/data/build/enterprise/l10n_pe_reports_stock/tests/test_ple_kardex_report.py", line 126, in…
Occasionally the test_kardex_report test fails:
```
Traceback (most recent call last):
File "/data/build/enterprise/l10n_pe_reports_stock/tests/test_ple_kardex_report.py", line 126, in test_kardex_report
self.assertSequenceEqual(
AssertionError: Sequences differ: ['M1|[18 chars]|1||02/01/2024|01|FBILL202401|0002|02|product_[313 chars], ''] != ['M1|[18 chars]|1||01/01/2024|01|FBILL202401|0001|02|product_[313 chars], '']
First differing element 0:
'M1|0[17 chars]|1||02/01/2024|01|FBILL202401|0002|02|product_[21 chars]0|1|'
'M1|0[17 chars]|1||01/01/2024|01|FBILL202401|0001|02|product_[21 chars]0|1|'
- ['M1|0000|1|99|FURN9999|1||02/01/2024|01|FBILL202401|0002|02|product_order_no|NIU|3.00|0.00|1|',
? ^ ^
+ ['M1|0000|1|99|FURN9999|1||01/01/2024|01|FBILL202401|0001|02|product_order_no|NIU|3.00|0.00|1|',
? ^ ^
```
The issue was reproducible locally by disabling nested loop joins: `self.env.cr.execute("SET LOCAL enable_nestloop = off")` to nudge Postgres to use a different join strategy.
The test creates a PO that is picked and invoiced in two steps (first quantity 3, then the remaining 2). As a result, the `stock.valuation.layer` ends up being linked to two `account.move.line`s because the join goes through the same `purchase_order_line`. So it will appear twice in the `_get_ple_reports_data()` query. A `DISTINCT
ON (stock_valuation_layer.id)` was already there with the goal of picking one of them. Which one depends on the order, but it's not deterministic: the valuation layer's `id`, `product_id`, and `create_date` will all be the same.
This commit makes the behavior deterministic by sorting on PO line and SO line ids.
runbot-error-238888
Forward-Port-Of: odoo/enterprise#107047This update resolves an issue where the ICP report generation process failed due to a missing link between return types. The change now correctly identifies VAT reports to ensure accurate XBRL filing for the ICP report. This improves the reliability of tax reporting for Dutch businesses.
Original PR description
Since no return type has a link to ICP report, the tax return check will fail each time. This commit changes this by looking for VAT report returns. opw-5491728
This update fixes an issue where the system wasn't creating enough quality checks when using the barcode scanning feature with lot tracking. The change ensures that quality checks are generated for each unique lot received, improving inventory accuracy and quality control processes. This impacts users relying on lot-based tracking for quality assurance.
Original PR description
**Steps to reproduce:** * Install the `stock_barcode`, `quality_control` modules. * Go to *Inventory > Configuration > Settings* and enable **Packages**. * Create a product with **By Lot** tracking…
**Steps to reproduce:** * Install the `stock_barcode`, `quality_control` modules. * Go to *Inventory > Configuration > Settings* and enable **Packages**. * Create a product with **By Lot** tracking enabled and set a barcode reference. * Create a quality control point for this product with following configuration: * Operation: *Receipts* * Control per: *Quantity* * Control Frequency: *All* * Product: the previously created lot-tracked product. * Create a receipt for this product with a quantity of 6 and `mark as todo`. * Open the *Barcode* app and process the receipt. * Scan the product barcode. * Scan some quantity of the product with lot *LOT01* and put those units into a package(Put-In-Pack). * Scan the remaining quantity with lot *LOT02* and put those units into a different package(Put-In-Pack). * Click on **Quality Checks**. **Observed behavior:** * Only one quality check is created, even though the receipt contains two different lots that should each generate a quality check. **Cause:** * In `_inverse_qty_done`, move lines are marked as *picked* when `qty_done` is equal to quantity(Demand). * During the `write` operation, quality checks are created only for move lines that are not picked, which prevents creating a quality check for each lot. * Relevant code: https://github.com/odoo/enterprise/blob/464dc0c65548f3f440b293b534616743ddd5e130/quality_control/models/stock_move_line.py#L39 https://github.com/odoo/enterprise/blob/464dc0c65548f3f440b293b534616743ddd5e130/stock_barcode/models/stock_move_line.py#L67-L71 **Fix:** * Ensure that quality check points are generated correctly when validating products through the Barcode app using the Put in Pack option. --- opw-5405221 Forward-Port-Of: odoo/enterprise#105863 Forward-Port-Of: odoo/enterprise#102714