Thursday, July 10, 2025
20 changes · 18.0
New functionality added to Odoo
Adds a new financial summary tool that helps users generate and review financial summary information from within Odoo. This supports sales-related requirements by making key financial details easier to access and organize for business decision-making.
Original PR description
Description of the issue/feature this PR addresses: requerimientos de ventas 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
Enhancements to existing features
Expense receipt scanning now captures the actual merchant or place name, such as a restaurant or fuel station, instead of a broad category like food or gasoline. This makes automatically created expense records clearer and easier for employees and approvers to understand.
Original PR description
The detection of the description has been improved in the latest version of the expense OCR API. It now actually detects a description (restaurant name, fuel station name, etc) instead of predicting a category ('food', 'parking', 'gasoline', etc).
Task [link](https://www.odoo.com/odoo/project/2068/tasks/4623180)
task-4623180
Forward-Port-Of: odoo/enterprise#89448Odoo now better supports the updated mobile-first finance connection flow by handling bank accounts created directly inside the embedded iframe. This helps users continue setup when their searched institution is not already available in Odoo Finance, reducing friction during bank synchronization.
Original PR description
The aim of this commit is making sure that the odoo database code is handling properly the new feature introduced with the iframe revamp in mobile-first. This feature allows user to create a bank account from the iframe directly if Odoo Finance doesn't have the searched institution. task-4481880 Forward-Port-Of: odoo/enterprise#81894
Resolved issues and error corrections
This fixes how Mexican DIOT tax report columns are calculated so they use the correct tax tags and tax values. Businesses should see more accurate DIOT reporting for paid VAT and import-related tax categories, reducing confusion from previously misleading column definitions.
Original PR description
Description of the issue/feature this PR addresses: The language used in the DIOT documentation was confusing and even though we had the exact same description for two columns it turns out they were different, so we need to change the logic of a few columns to make it work as needed. Current behavior before PR: In the DIOT, the columns Paid 8% N, Paid 8% s, Paid 16%, Importation 16% and Intangible imports 16% are sums of taxes paid with this type of tax. Desired behavior after PR is merged: Taxes now have a correction in their tags so that the columns in the DIOT report are calculated correctly. Likewise, the way of computing the columns Paid 8% N, Paid 8% s, Paid 16%, Importation 16% and Intangible imports 16% has been simplified. Now it no longer adds up different types of taxes, but only one type. opw-4920577 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217441
Windows printer handling now sends documents to the printer one at a time when multiple jobs arrive simultaneously. This prevents print jobs from failing during busy periods and improves reliability for businesses using Odoo IoT printing on Windows.
Original PR description
Before this commit, if multiple documents were sent to print at exactly the same time, some of them could end up erroring because the Windows printing API requires us to send one document at a time. After this commit, we use a lock similar to the Linux driver, to ensure that only one document is sent to the printer at once. opw-4829908 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218300
Turkish Nilvera e-invoice XML notes now include the remaining invoice amount written out in uppercase text. For invoices in a foreign currency, the note includes both the Turkish Lira amount and the foreign currency amount, helping recipients and compliance checks read the payable amount clearly.
Original PR description
This commit will add the amount residual in text in the note of the xml we sent to nilvera. If the invoice is in another currency than Turkish Lira, we have to add two notes one for the amount in turkish lira and one in the other currency task-4518269 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#195938
Odoo now shows a plus sign when a list selection may include more records than the displayed count, such as "10,000+". This helps users understand the true scope of bulk actions and reduces the risk of applying actions to more records than expected.
Original PR description
Previously, when selection was made in domain mode, the system used the global `web.active_ids_limit` config parameter instead of the actual number of records selected (based on session limit). This caused unintended behavior. For example: - Open a list view of a model with 25,000 records. - The pager limit is initially set to 10,000. - When selecting all 10,000 visible records and performing an action (e.g., archive), the system would incorrectly apply the action to 20,000 records (based on the default value of `web.active_ids_limit`), not the selected 10,000.
Automatic check-out now uses the employee schedule's local date instead of UTC when calculating expected and previous working hours. This prevents employees in time zones ahead of UTC from being checked out too early when they clock in before UTC midnight.
Original PR description
**Issue** The auto check out cron was using the check in time in UTC to determine the excepted working hours and the previous attendances. For example: - have an employee with a working schedule using a UTC+8 timezone. - check-in on a monday before 8am (0:00 UTC) in the employee's tz. - the auto check-out cron closes the attendance immediately because there are no working hours for the attendance's check in day in UTC (Sunday). **Change** Use the date of the check-in localized in the tz of the calendar used by the attendance's employee to determine the previous worked hours for that day and the expected worked hours. opw-4654847
This fix prevents an error when a cancelled sales order containing a kit is returned to quotation and confirmed again. It ensures cancelled delivery moves are ignored so users can proceed with the sales workflow normally, even when a kit uses the same component more than once.
Original PR description
Bug introduced in: https://github.com/odoo/odoo/pull/207955
Steps to reproduce the bug:
- Create a kit product:
- BoM:
- Components:
- 1 unit of C1
- 1 unit of C1 (same product)
- Create a SO with one unit of kit
- Confirm the SO
- The delivery is created
- Cancel the SO → the delivery is canceled.
- Set the SO back to quotation and confirm again
Problem:
A traceback is triggered:
raise ValueError("Expected singleton: %s" % record)
ValueError: Expected singleton: mrp.bom.line(24, 25)
When a kit's BoM contains the same product multiple times, multiple bom_line_ids match a given move. Assigning them causes an error. Additionally, cancelled moves were incorrectly considered.
Solution:
Filter out cancelled stock moves before accessing the bom_line_id to ensure only active moves are considered.
opw-4919875Cash-rounded invoices now export and import correctly in UBL electronic invoice formats. This prevents validation failures and helps ensure totals, taxes, and payable amounts remain consistent when invoices are exchanged with customers or authorities.
Original PR description
Currently these problems can appear when an invoice is cash rounded. 1. In case we use the "Modify tax amount" (`biggest_tax`) cash rounding strategy: The rounding amount is added to the taxes in…
Currently these problems can appear when an invoice is cash rounded.
1. In case we use the "Modify tax amount" (`biggest_tax`) cash rounding strategy:
The rounding amount is added to the taxes in Odoo but not in the UBL XML
- This affects everything that uses `_prepare_invoice_aggregated_taxes`
(and not just UBL XML)
2. The generated UBL XML is invalid (for any rounding strategy).
See below for details.
3. The import of the exported UBL XML does not yield back the same invoice
(even after fixing the export / the previous 2 problems).
Also there are some problems with the correction of tax values
of imported UBL XML (`correct_invoice_tax_amount`).
(They probably do not cause issues in practice but would after this
fix. We adapt the correction as part of the fix for (3).)
#### Runbot: How to generate problematic XML
1. Select BE Company CoA
2. Enable Cash Rounding in the settings
3. Create a cash rounding method
(in the settings where cash rounding can be enabled):
- precision `1.00`
- strategy: any
- profit / loss account: any
4. Create an invoice
- Set a Belgian partner (e.g. "BE Company CoA" is okay)
- Set the the cash rounding method from step 2
- Single Line with price=70.00€ and a 21% tax
5. The total should be 85.00 € (84.70 € w/o the rounding)
In the journal items there should be the following
non payment term items:
- 70.00€ base
- 14.70€ tax
- 0.30€ rounding (depending on the cash rounding strategy the tax is set or not)
6. Confirm & Send (with BIS Billing 3.0)
7. Look at the UBL BIS 3 XML in the `Invoice` element
- `TaxTotal/TaxAmount`: 14.70€
- `TaxTotal/TaxSubtotal/TaxableAmount`: 70.00€
- `TaxTotal/TaxSubtotal/TaxAmount`: 14.70€
- `LegalMonetaryTotal/TaxExclusiveAmount`: 70.00€
- `LegalMonetaryTotal/TaxInclusiveAmount`: 85.00€
- `LegalMonetaryTotal/PayableAmount`: 85.00€
8. This fails validation `BR-CO-15`:
```
Invoice total amount with VAT (BT-112)
= Invoice total amount without VAT (BT-109) + Invoice total VAT amount (BT-110).
```
(`LegalMonetaryTotal/TaxInclusiveAmount` = `LegalMonetaryTotal/TaxExclusiveAmount` + `TaxTotal/TaxAmount`)
Since the cash rounding is included in `LegalMonetaryTotal/TaxInclusiveAmount` but not in
`TaxTotal/TaxAmount` (or `LegalMonetaryTotal/TaxExclusiveAmount`)
#### Tax value correction details (with examples)
Currently we try to fix the tax amounts after importing an invoice.
The function we use for that (`_correct_invoice_tax_amount`) has the following issues:
- We look for `TaxTotal/TaxSubtotal` elements anywhere.
But i.e. such elements can also exist inside `InvoiceLine` elements.
Example:
- module `l10n_dk_oioubl` file `test_xml_oioubl_dk.py`
- function `test_oioubl_import_exemple_file_4` / XML file 'external/BASPRO_01_01_00_Invoice_v2p1.xml'
- The tax total parsed from the document may need to be inverted.
E.g. credit notes can be given as an invoice with negative amounts.
See function `_get_import_document_amount_sign`.
Example:
- module `l10n_account_edi_ubl_cii` file `test_xml_ubl_be.py`
- function `test_import_invoice_xml_open_peppol_examples` / XML file 'bis3_invoice_negative_amounts.xml'
- We compare the tax total from the document only with a single line of that tax.
But there can be multiple lines for a single tax. We have to use the sum of all those lines for the comparison.
Example:
- module `l10n_account_edi_ubl_cii` file `test_xml_ubl_au.py`
- function `test_export_import_invoice` / XML file 'from_odoo/a_nz_out_invoice.xml'
#### The fix
This commit does the following to fix that
1. We include cash rounding lines belonging to a tax in the tax computation for the UBL XML export
(or rather everything any tax computation done with `_prepare_invoice_aggregated_taxes`).
2. After fixing (1) we only have to fix the "Add a rounding line" (`add_invoice_line`) strategy.
This is as follows
- Subtract the cash rounding from the `LegalMonetaryTotal/TaxInclusiveAmount`
- Add node `LegalMonetaryTotal/PayableRoundingAmount` with the value of the cash rounding
3. Cases
- `add_invoice_line`: We create a dedicated invoice line with the amount found in node
`LegalMonetaryTotal/PayableRoundingAmount` (if it is present).
- `biggest_tax`: We update the amount on the tax line to match the value found in the XML.
(Currently we only do this if the difference is not greater than '0.05')
The fixes for the tax value correction on import are also needed for 3./`biggest_tax`.
#### Runbot: example XML after the fix
The export in the example then looks like this for the different cash rounding strategies
- `add_invoice_line`
- `TaxTotal/TaxAmount`: 14.70€
- `TaxTotal/TaxSubtotal/TaxableAmount`: 70.00€
- `TaxTotal/TaxSubtotal/TaxAmount`: 14.70€
- `LegalMonetaryTotal/TaxExclusiveAmount`: 70.00€
- `LegalMonetaryTotal/TaxInclusiveAmount`: 84.70€
- `LegalMonetaryTotal/PayableRoundingAmount`: 0.30€
- `LegalMonetaryTotal/PayableAmount`: 85.00€
The validation for the `LegalMonetaryTotal/PayableAmount` is still
okay since (in the example) it is just `LegalMonetaryTotal/TaxInclusiveAmount` + `LegalMonetaryTotal/PayableRoundingAmount`.
- `biggest_tax`
- `TaxTotal/TaxAmount`: 15.00€
- `TaxTotal/TaxSubtotal/TaxableAmount`: 70.00€
- `TaxTotal/TaxSubtotal/TaxAmount`: 15.00€
- `LegalMonetaryTotal/TaxExclusiveAmount`: 70.00€
- `LegalMonetaryTotal/TaxInclusiveAmount`: 85.00€
- `LegalMonetaryTotal/PayableRoundingAmount`: (not exported)
- `LegalMonetaryTotal/PayableAmount`: 85.00€
#### References
Also see
- https://docs.peppol.eu/poacc/billing/3.0/bis/#_rounding
- https://docs.peppol.eu/poacc/billing/3.0/bis/#_calculation_of_totals
task-4854592
Forward-Port-Of: odoo/odoo#213378This fixes an issue where newly created, automatically validated attendance records could show zero extra hours even when an employee worked overtime. The correction ensures overtime is calculated immediately when the record is saved, improving accuracy for attendance and payroll-related reviews.
Original PR description
Introduced by cc81bb59f87540cf4dd8da65510417d8023ef65b **Steps to reproduce** 1. Create a new automatically validated attendance. 2. Set the employee, check in and check fields before saving the form. Issue: the "Extra hours" field is not computed. e.g.: if the employee has worked 1 hour more than expected, "Worked Extra Hours" equals 1:00 (ok), but "Extra hours" appears as 0:00. **Cause** The previous fix intended to avoid recomputation of the `validated_overtime_hours` field. No better way was found than to exclude records where the `overtime_hours` was different than the `validated_overtime_hours` (meaning it had been manually modified by the user). The problem comes from the fact that at creation, `validated_overtime_hours` was sent in the `vals_list` to the create with a value of 0. **Solution** Force the computation of the field at creation.
Manufacturing users can now create a new workcenter directly from the operations form even when no Bill of Materials has been selected. This removes an unnecessary company setting that caused an error and interrupted setup workflows.
Original PR description
**Current behavior:** Can't create a workcenter from the operations (workorder) form view without having a BoM filled in (due to company check issue). **Expected behavior:** Can **Steps to reproduce:** Open `Manufacturing / Configuration / Operations` -> create new -> type in a new workcenter name -> hit create -> error **Cause of the issue:** in `mrp_routing_workcenter_form_view` we get some context for a `default_company_id`- it's not only unnecessary because `Mrp.Workcenter` will get a default company just fine via its its `resource.mixin` inheritance. The currently provided company comes from the BoM, thus the issue happens when the BoM has not yet been filled in on the view. **Fix:** Remove the context in the view. opw-4836904
When a purchase order linked to a sales delivery is cancelled, Odoo now allows the delivery to use available inventory instead of continuing to wait for the cancelled purchase. This helps orders move forward when stock is later added or already available, reducing unnecessary delivery delays.
Original PR description
Steps to reproduce the bug:
- Unarchive the MTO route
- Create a product P1:
- Type: Storable
- Route: MTO
- Supplier: Vendor A
- Create a sales order for 1 unit of P1
- Confirm the SO
→ A purchase order is created for Vendor A with 1 unit of P1
- Cancel the PO
- Update the quantity on hand of P1 to 1
- Go to the delivery picking of the SO
- Check availability
Problem:
The quantity on hand is not taken into account, and the picking remains
in the "Waiting Availability" state.
When the purchase order is cancelled, the stock move should switch to
MTS instead of remaining in MTO.
opw-[4876611](https://www.odoo.com/web#id=4876611&view_type=form&model=project.task)
opw-[4874199](https://www.odoo.com/web#id=4874199&view_type=form&model=project.task)Attendance reports now respect the employee’s weekly contracted hours when calculating expected hours for flexible schedules. This prevents reports from overstating expected time when an employee works more days than their contract allows.
Original PR description
### Issue: - When the attendance is flexible, the weekly expected hours shown in reports are incorrect. - This happens because the calculation is based only on the hours worked per day and doesn't…
### Issue:
- When the attendance is flexible, the weekly expected hours shown in reports are incorrect.
- This happens because the calculation is based only on the hours worked per day and doesn't
take into account the total hours worked during the week.
It ignores the weekly limit defined in the employee's working schedule.
- As a result, if an employee works more days than expected, the report may show more than the allowed weekly hours.
Example:
- An employee has a 32h/week contract and 8h/day.
- If they work 5 days, the system still counts 8h as expected for each day — totaling 40h instead of 32h.
### Steps To reporduce:
- Set up a flexible contract with 32 hours/week (8 hours/day) for an employee.
- Log 5 attendances in one week with 8 worked hours each.
- Go to report and filter by employee by week, notice the current behavior yields 5 x 8 = 40 hours in expected_hours.
### Solution:
- Check the weekly hours cap defined in `resource_calendar_id.full_time_required_hours`.
- If total `expected_hours` from earlier attendances this week exceeds that limit, set expected_hours = 0 for any excess.
OPW-4583064
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis change corrects how monthly payroll summaries are aggregated for Swiss ELM transmissions. It helps ensure payroll reporting totals are calculated accurately, reducing the risk of incorrect submissions or follow-up corrections.
Original PR description
Forward-Port-Of: odoo/enterprise#89839
Fixes Colombian electronic invoicing so cash rounding lines are included correctly in tax calculations and UBL invoice output. This helps ensure legally required invoice files match rounded invoice totals, reducing validation errors when submitting invoices.
Original PR description
#### [FIX] l10n_co_dian: UBL related cash rounding issues In the community PR the UBL XML generation was adjusted to support cash rounding. (See there for more details) This commit adjusts the code in `l10n_co_dian` to be compatible. #### [FIX] l10_co_edi: tax_amls include rounding lines Currently rounding lines (with taxes) are not included in the tax lines. This is fixed in this commit. See the community PR / commits for motivation. #### info task-4854592
The Spanish tax report now avoids adding rectification lines for bills and credit notes that fully cancel each other within the same reporting period. This prevents incorrect BOE 349 declarations while preserving expected rectifications for documents from previous periods.
Original PR description
# How to reproduce the issue On a **l10n_es** fiscal position: - Create a bill for the current period and then create a credit note for this bill. - In the tax report, under model 349, download the BOE report. Since the bill has been fully canceled within the same period, no rectification line should appear in the BOE report (correct behavior). - Create a bill from a previous period. - Create a credit note for this bill in the current period. - Download the BOE report from model 349. A rectification line appears for the previous period bill, which is expected. However, a rectification line also appears for the current period bill, which is incorrect, as the bill was canceled within the same period. This commit prevents moves from the current period from being included as rectification lines in the BOE report. opw-4895636 Forward-Port-Of: odoo/enterprise#89624 Forward-Port-Of: odoo/enterprise#89382
Fixed an issue where returning to a receipt in the Barcode app could incorrectly increase the requested quantity for lot-tracked products. This keeps warehouse receipts accurate when users partially process and later complete grouped barcode lines.
Original PR description
### Steps to reproduce: - Create a storable product tracked by lot - Create and confirm a receipt for 10 units of that product - Go to the barcode app and regiter 1 unit - Exit the picking - Go back…
### Steps to reproduce: - Create a storable product tracked by lot - Create and confirm a receipt for 10 units of that product - Go to the barcode app and regiter 1 unit - Exit the picking - Go back to the picking register the 9 remaining units - Exit the picking and comeback #### > The demand of the receipt has been updated from 10 to 19. ### Cause of the issue: Exiting the picking will launch a call of the `post_barcode_process` in order to keep track of the changes you made without changing the initial demand: https://github.com/odoo/enterprise/blob/c26c21cec14a234021bb13bbc2684334bc64b70b/stock_barcode/models/stock_move.py#L50-L53 THe first time you enter the picking you have a single move with a quantity of 10. The first time you exit, since you have set a qty_done of 1 (and hence have updated the quantity of the associated move to 1), the `split_uncompleted_moves` will then create a move for a quantity of 9 in order to keep 10 units assigned. The second time you enter the picking both moves are grouped in a single line since the product is tracked by lot, however, when you update the qty_done of that grouped line you will actually only update the quantity of the first move line and its related move. Since the `_truncate_overreserved_moves` was not designed to handle these grouped lines, it does not notice that the combined reservation overcomes the actual demand. opw-4731803
The Belgian POS blackbox integration now acknowledges status messages properly, preventing repeated or misplaced responses. This reduces failed communications with the device and helps ensure sales certification requests receive the expected replies.
Original PR description
We did not send an `ACK` after asking for blackbox status, leading in BlackBox sending it again. This lead to situations where we sent requests to the BlackBox, and received the status instead of the actual response. In addition, the repeated status responses were missing the leading `ACK`, resulting in our log: `sent 1 NACKS without receiving response, giving up.` More, if we sent a command too soon to the BlackBox (before it finished instanciating), we were receiving its `certified ref` instead of the actual response, due to the `_push_status` method called from the `run` method of the BlackBox Driver parent class. This `run` method is now overridden by the BlackBox driver Task: 4750435 Backport of https://github.com/odoo/enterprise/pull/87659
Work permit fields have been restored in the Swiss payroll employee view. This helps Swiss payroll users access and maintain important employee permit information directly where they need it.
Original PR description
In this PR we reintroduce the work permit fields for the swiss localization, which is heavily used. Forward-Port-Of: odoo/enterprise#89864