Friday, December 5, 2025
12 changes · saas-18.3
Enhancements to existing features
This update enhances the handling of Chilean electronic invoices by ensuring document folio numbers align with available CAF files. A key change requires a valid owner document (subject_serial_number) for certificates, improving data integrity and compliance with SII regulations. This resolves an issue where expired CAF folio numbers caused errors and ensures accurate invoice processing.
Original PR description
This pull request introduces improvements to the handling of Chilean electronic document sequences, enforces stricter validation for certificate data, and modernizes string formatting throughout the…
This pull request introduces improvements to the handling of Chilean electronic document sequences, enforces stricter validation for certificate data, and modernizes string formatting throughout the codebase. The most significant changes focus on ensuring that document folio numbers are correctly managed in accordance with available CAFs, making the certificate model more robust, and updating code style for clarity and consistency. This improvement is mostly made because CAFs have expiration dates and fixed folio numbers. If the expiration date is reached but the folios were not fully consumed, the system will try to generate a document with following number in the sequence but an error will be raised because that number belongs to an expired CAF, althought the user had already uploaded a new CAF. To fix this, whenever the system looks for the highest number to set to a document, it previously check if that number is between the folio numbers of a valid CAF file. ### Chilean electronic document sequence management * Added `_get_last_sequence` method to `account_move.py` to ensure that the folio number used for Chilean electronic documents (DTE) is valid and corresponds to an available CAF. If no CAF is available for the current folio, the sequence is reset using the document type's prefix and starting number. ### Certificate model validation * Made `subject_serial_number` a required field in the `Certificate` model, enforcing that every certificate has a valid owner document and improving data integrity. We made this change to prevent the field being empty after loading the certificate in Odoo, since it is required by the SII to validate invoices. Forward-Port-Of: odoo/enterprise#92208
Resolved issues and error corrections
This update fixes an issue where debit notes created in the Uruguay localization were incorrectly assigned as e-invoices (type 111). The fix ensures debit notes automatically use the correct document type (113), streamlining invoice processing for Uruguayan customers. This improves data accuracy and compliance.
Original PR description
**Steps to reproduce:** * Install and activate the **Uruguayan Localization** for the company. * Create a contact located in Uruguay. * Create an invoice for this customer and set **Document Type =…
**Steps to reproduce:** * Install and activate the **Uruguayan Localization** for the company. * Create a contact located in Uruguay. * Create an invoice for this customer and set **Document Type = 111 (e-Invoice)**. * From the invoice's gear icon, create a **Debit Note**. **Observed behavior:** * The debit note is automatically assigned **Document Type 111 (e-Invoice)**, even though it should use **113 (e-Invoice Debit Note)**. * Attempting to change the document type manually only shows 113 as an option, confirming the debit note should not have been set to 111. **Cause:** * `_compute_l10n_latam_document_type()` applies a rule that assigns Document Type **111** to all Uruguay electronic invoices with RUT identification. * This logic does **not** check whether the move is a **debit note** (`m.debit_origin_id`), and therefore incorrectly overrides the expected debit note document type. * The override prevents the correct selection (internal_type == *debit_note*) from being applied. **Fix:** * Add a condition in the automatic e-Invoice assignment logic. * Debit notes now bypass the e-Invoice assignment and fall through to the parent method, which correctly assigns **Document Type 113**. opw-5154599 Forward-Port-Of: odoo/enterprise#100938
This update enhances the Point of Sale experience by adding a 'Reload Data' button to error dialogs. Previously, users were left without clear guidance on how to resolve data-related issues, often requiring support assistance. Now, users can easily retry data loading directly from the error dialog, streamlining the process.
Original PR description
Before this commit: --------- - Users could only click "Ok" or close error dialogs. - No clear guidance to resolve blocking issues. After this commit: ----------------- - ErrorDialog shows a "Reload Data" button alongside "Ok". Task-5353590 Related PR-https://github.com/odoo/odoo/pull/238112
This update resolves a previous error that prevented users from creating consolidated invoices for multiple POS orders linked to the same customer. The fix ensures accurate invoice generation when multiple orders are combined, improving the POS invoicing process. This change ensures consistent and reliable invoice creation for SA company users.
Original PR description
Currently, an error occurs when trying to create a consolidated invoice for multiple POS orders associated with the same customer. **Steps to reproduce:** - Install the `l10n_sa_pos` module and…
Currently, an error occurs when trying to create a consolidated invoice for multiple POS orders associated with the same customer. **Steps to reproduce:** - Install the `l10n_sa_pos` module and switch to the `SA company`. - Create two POS orders for the `same customer` without invoicing at checkout. - Close the POS session and go to `Point of Sale` > `Orders`. - Select both orders > click `Create Invoice` > `confirm` the action. (Make sure `Consolidated Billing` is enabled) **Error:** `ValueError: Expected singleton: pos.order(8, 7)` **Root cause:** At [1], the code accesses `self.date_order`, but when `consolidated billing` is enabled, self contains multiple POS orders, causing an `error`. **Fix:** This commit prevents the error by ensuring that the `current datetime` is assigned when creating a `consolidated invoice`, same as [2]. [1]: https://github.com/odoo/odoo/blob/583bacdc8ad2b87b99b11d1e12dacf6e42edf22b/addons/l10n_sa_pos/models/pos_order.py#L13 [2]: https://github.com/odoo/odoo/blob/583bacdc8ad2b87b99b11d1e12dacf6e42edf22b/addons/point_of_sale/models/pos_order.py#L828-L832 opw-5266908 Forward-Port-Of: odoo/odoo#237677
This update corrects a bug in the aged receivable report that prevented it from displaying accurate data when invoices lacked a due date. The fix ensures the report correctly filters and displays outstanding invoices, resolving a discrepancy between the report's data source and its display.
Original PR description
step to reproduce: - create a invoice and confirm it - remove due date from it and save it - ensure the confirmed invoice do not payment term or due date - open aged receivable report - open this…
step to reproduce: - create a invoice and confirm it - remove due date from it and save it - ensure the confirmed invoice do not payment term or due date - open aged receivable report - open this entry <img width="1599" height="238" alt="image" src="https://github.com/user-attachments/assets/010f97f4-0d50-4e5a-9366-ae67d17e2bb7" /> Observation: - on clicking the entry, when redirected to list view, there are `0` records. Issue: - The query which is used to display data on report uses `COALESCE(account_move_line.date_maturity, account_move_line.date)` https://github.com/odoo/enterprise/blob/ffc329e4ff2bd6512164ecd4206210fd5c9264b9/account_reports/models/account_aged_partner_balance.py#L222-L226 - while the method `_build_domain_from_period` uses only `date_maturity` in domain redirecting to list view - This creates inconsistencies between two. https://github.com/odoo/enterprise/blob/ffc329e4ff2bd6512164ecd4206210fd5c9264b9/account_reports/models/account_aged_partner_balance.py#L383-L394 opw-5237298 Forward-Port-Of: odoo/enterprise#99883
This fix resolves an issue where stock valuations were incorrectly calculated after splitting a purchase order into a batch and validating the batch. The problem stemmed from how the system handled quantity updates during batch validation, leading to inaccurate valuation amounts. This update ensures correct stock valuations are generated when using batch billing.
Original PR description
…n batch billed on ordered qty **Problem:** When the picking of a purchase order (of a product billed on ordered quantity) is split into different moves and put in a batch, at batch validation, svls…
…n batch billed on ordered qty
**Problem:**
When the picking of a purchase order (of a product billed on ordered quantity) is split into different
moves and put in a batch, at batch validation, svls are created with the wrong values.
**Steps to reproduce:**
- enable "Batch, Wave & Cluster Transfers" settings
- create a storable product with a standard price of 1
- set the category as avco
- in the Purchase tab select the control policy as
"on ordered quantities"
- create and confirm a purchase order for 50 of this product
- on the Receipt, change the quantity to 20 and split the
picking
- go back the the PO and create and confirm a bill for
the full amount
- click on the receipt smart button
- select the two pickings and then the 'Action' button
- select add to batch
- check 'new batch transfer' and confirm
- open the batch and validate it
- open stock valuation
**Current behavior:**
the newly created svls have total values of
50 and 50.10
**Expected behavior:**
it should be 20 and 30
**Cause of the issue:**
When the batch is validated, _action_done is called
on the two stock moves.
https://github.com/odoo/odoo/blob/dc57ea4d306f8745d37f2c5d2c3d3fa4bcaf7253/addons/stock/models/stock_picking.py#L1258
In the stock_account override:
- first the super method is called
As a consequence the state of the two moves becomes 'done'
and the qty_received of the linked purchase order line becomes 50.
- then product_price_update_before_done is called before creating
the svls.
Inside product_price_update_before_done we call _get_price_unit.
In the purchase_stock override of _get_price_unit :
- because the super method of action_done was already called,
qty_received of the purchase order line is 50, so _get_qty_received_without_self
will return 30.
https://github.com/odoo/odoo/blob/dc57ea4d306f8745d37f2c5d2c3d3fa4bcaf7253/addons/purchase_stock/models/stock_move.py#L50
So received_qty is 30 and later remaining_qty will be 20
https://github.com/odoo/odoo/blob/dc57ea4d306f8745d37f2c5d2c3d3fa4bcaf7253/addons/purchase_stock/models/stock_move.py#L86
- but because no svl was created yet receipt_value will stay 0 and later
remaining_value will be 50
https://github.com/odoo/odoo/blob/dc57ea4d306f8745d37f2c5d2c3d3fa4bcaf7253/addons/purchase_stock/models/stock_move.py#L55-L63
Therefore price_unit will be 2.5 (50/20) instead of 1
**fix**
We do not take into account the move(s) of the
same batch in the remaining value (because svls are not created yet)
so we should not take them into account in the remaining quantity.
opw-5179581
Forward-Port-Of: odoo/odoo#238222
Forward-Port-Of: odoo/odoo#235601This update fixes an issue where Express Checkout wasn't automatically applying the correct tax based on the customer's address. Now, the system correctly identifies and uses the appropriate fiscal position, eliminating the need for a page reload to see accurate pricing and taxes for users utilizing Stripe Express Checkout.
Original PR description
## Issue: When a fiscal position should apply based on the address provided during Express Checkout, it was not applied automatically The correct fiscal position only appeared after reloading the…
## Issue: When a fiscal position should apply based on the address provided during Express Checkout, it was not applied automatically The correct fiscal position only appeared after reloading the checkout page This issue affects public users using the eCommerce with Stripe Express Checkout ## Cause: The fiscal position was correctly determined during the `availableCarriers` computation, but it was not propagated to the payment request itself As a result, prices and taxes were only updated after a full page reload ## Steps to reproduce: - Configure Stripe with Express Checkout (e.g., Google Pay) - Create a fiscal position with automatic detection (Country = US, Tax mapping: 15% → 0%) - Create a product using the 15% tax - Go to the website shop and add the product to the cart - Use Express Checkout with a US address - Observe that the fiscal position is not applied unless the page is reloaded opw-5018238 Forward-Port-Of: odoo/odoo#238690 Forward-Port-Of: odoo/odoo#236832
This update resolves an error that occurred when creating time off allocations using hours, particularly when each attendance had a defined start and end date. The fix prevents a division-by-zero error, ensuring time off allocations are created correctly. This addresses a symptom of a deeper issue with how attendance dates are handled, but doesn't fully resolve the underlying problem.
Original PR description
_ ## Short functional explanation of the error When creating a time off allocation with a time off type expressed in hours, and having start/end dates for every attendance in the corresponding…
_ ## Short functional explanation of the error When creating a time off allocation with a time off type expressed in hours, and having start/end dates for every attendance in the corresponding calendar, an error is raised. ## Reproduction Steps 1. Go to Employees and click on the Configuration tab > Working Schedules. 2. Click on a schedule and click on the button next to Work Entry Type to show the Starting date. 3. Set a starting date for each entry. 4. Go to Time Off. Click on the Configuration tab > Time Off Types. 5. Click on a time off and next to the Take Time Off in, select Hours. 6. Click on the Management tab > Allocations. Click on New. 7. Select an employee that has the schedule you updated earlier. ## Expected behavior The allocation is created. ## Unexpected Behavior A traceback occurs: ``` ZeroDivisionError: float division by zero ``` ## Origin of the issue When setting a start or/and an end date to an attendance, this attendance won't be taken into account for global attendances anymore. This leads to an erroneous computation of hours_per_day, leading to a few issues; one of them is related to time off allocation: When setting a time off with a time off type expressed in hours, if every single attendance in the calendar has a start/end date, there will be no global attendance hours left, leading to a division by 0: https://github.com/odoo/odoo/blob/8097b674a23858ed7692a0b30ca74419b8f890f7/addons/hr_holidays/models/hr_leave_allocation.py#L262 After discussion, we decided that this fix would only fix a symptom, and not the problem itself. _ opw-5340056 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#237782
This update resolves an issue where the timesheet grid incorrectly displayed unavailable days when flexible hours were enabled for a company. The fix ensures that all days are treated as working days when flexible hours are in use, providing accurate timesheet availability. This improves the usability of the timesheet feature for companies utilizing flexible work schedules.
Original PR description
**Description** When a company's working schedule has flexible hours enabled, the timesheet grid was incorrectly displaying random weekdays as non-working days (greyed out cells). The affected days…
**Description** When a company's working schedule has flexible hours enabled, the timesheet grid was incorrectly displaying random weekdays as non-working days (greyed out cells). The affected days varied by month because the unavailability calculation was time-dependent. **Steps to reproduce** 1. Enable flexible hours on company's working schedule 2. Go to Timesheets > All timesheets 3. Switch to Grid view and filter by month 4. Observe that random weekdays (e.g., Wed/Thu or Mon/Tue) are greyed out **Fix** The grid_unavailability method now checks if the company calendar has flexible_hours enabled. When true, it returns an empty list of unavailable days, treating all days as potential working days. This fix adds the flexible_hours check in two locations within the grid_unavailability method to cover all code paths: 1. get_company_unavailable_dates() helper function - prevents unnecessary calculation when called as fallback 2. company_unavailable_days assignment from calendar_work_intervals - handles the direct path when company calendar is found This follows the same pattern as the gantt view fix #100385 opw-5215646 Forward-Port-Of: odoo/enterprise#100881
This update resolves issues preventing video options from being correctly saved and applied when embedding videos via various methods (Powerbox, URL editing, and Dailymotion). It ensures that video settings, including loop and autoplay, are accurately captured and applied, enhancing the user experience for embedding videos.
Original PR description
Issues: 1. Resetting options when dialog is closed without modification: When the media dialog is closed without changing any options and "Add" is clicked, the videoSelector component is reset,…
Issues:
1. Resetting options when dialog is closed without modification:
When the media dialog is closed without changing any options
and "Add" is clicked, the videoSelector component is reset, causing
previously selected parameters to be lost.
- Steps to reproduce:
- Drop a Video snippet.
- Double-click the snippet and toggle a few options (e.g., "Loop").
- Save the video configuration.
- Double-click the snippet again to open the video configurator.
- Save without making any changes.
- The options will be reset.
2. Embedding videos via Powerbox does not capture URL query parameters:
When embedding a video via Powerbox, option values from the URL
query parameters (like loop or autoplay) are not correctly applied.
- Steps to reproduce:
- Add any Text snippet.
- Paste a YouTube video URL with query parameters (e.g., ?loop=1&autoplay=1).
- Choose to embed the YouTube video from the Powerbox popup.
- The Video snippet is added without options enabled for the pasted URL.
3. Manual URL editing does not synchronize options:
Editing the video URL manually does not update the toggle states
of corresponding options.
- Steps to reproduce:
- Drop a Video snippet.
- Double-click the snippet and append query parameters to the URL.
- The option buttons should toggle according to the parameters, but they do not.
4. Dailymotion preview fails for protocol-independent URLs:
Previewing Dailymotion videos fails for URLs like //[www.dailymotion.com/](http://www.dailymotion.com/)....
- Fixes implemented:
- Preserve selected options when saving the Video snippet without any changes.
- Retrieve all query parameters from the URL and include them in the RPC request.
- Synchronize option toggles with the URL input when the user manually edits it.
- Fixed the Dailymotion regular expression to support protocol-independent
URLs (e.g., //[www.dailymotion.com/](http://www.dailymotion.com/)...).
task-4529118
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#238441
Forward-Port-Of: odoo/odoo#210596This update fixes an issue where tax returns were incorrectly generated due to an incorrect ordering of companies during searches. The change ensures parent companies are prioritized, resolving a problem where branch companies were being used as the primary company for tax calculations. This improves the accuracy of tax return generation.
Original PR description
The ordering of companies returned by searches is important when computing the `company_ids` field used in tax return generation. Previously, companies were ordered by (sequence, name). In cases where the parent company has no sequence value it appears after branch companies in the search results. This causes the branch company to be treated as the primary one, leading to incorrect tax return computation and tax returns are created with branch companies even though main company is the active This fix adds order='parent_path' to ensure parent company are first in search. opw-5344905
This update fixes an issue where nested BoM kits were incorrectly valued, leading to inflated costs. The fix ensures accurate cost sharing within complex BoM structures, particularly when using AVCO (Average Cost). It also addresses a separate issue with BoM valuation ignoring variant-specific lines and zero quantities.
Original PR description
### [FIX] purchase_mrp, mrp: correct BoM Kit valuation with nested kits #### Issue: When purchasing a BoM Kit (50/50) containing others BoM Kits (50/50), cost share was applied at each level (50%…
### [FIX] purchase_mrp, mrp: correct BoM Kit valuation with nested kits
#### Issue:
When purchasing a BoM Kit (50/50) containing others BoM Kits (50/50), cost share was applied at each level (50% instead of 25%), leading to overvaluation (e.g., 200% total instead of 100%)
#### Cause:
`cost_share` was always applied fully during BoM explosion and as a portion of the full price on `_get_unit_price()`
#### Other bug fixed:
Fix `_get_cost_share()` to correctly return 0 when BoM total cost_share already equals 100%
#### Requirement:
AVCO (Average Cost) must be enabled on all components/BoMs
#### Steps to reproduce:
1. Recreate that hierarchy with AVCO Products
- A kit "Testing Kit Complete" containing:
-- "Component01", cost share 50%
-- A kit "Testing Kit 1", cost share 50%:
--- "Component02", cost share 50%
--- "Component03", cost share 50%
2. Create and validate a Purchase Order for "Testing Kit Complete" (unit price: 1000)
3. Receive the products
4. Go in Inventory > Reporting > Valuation and search for Component
5. All 3 components are set to 500, instead of Component01: 500 / Component02: 250/ Component03: 250
opw-4806023
### [FIX] purchase_mrp: correct BoM valuation with product variants or optional lines
#### Issue:
BoM valuation ignores variant-specific lines and does not skip lines with quantity 0
#### Cause:
The code only checks that the BoM adds up to 100%
But this can cause issues with variants that do not include all products or with optional lines
As a result, the total valuation may be incorrect
#### Steps to reproduce:
1. Recreate a kit hierarchy with AVCO products:
- Kit "Variant Kit" (Variant Color: White and Wood) containing:
-- "Component01", cost share 0%, only for variant White
-- "Component02", cost share 0%
2. Create and confirm a Purchase Order for "Variant Kit" (variant: Wood, unit price: 1000)
3. Receive the products
4. Go to Inventory > Reporting > Valuation and search for the components
5. Only Component02 appears with 500$, so only half of the total value is shown
opw-4806023
opw-5085457