Daily updates from Odoo
Navigate
Branch
Tuesday, September 23, 2025
300 changes
4 changes
Resolved issues and error corrections
Fixed an issue in the Spanish SME balance sheet where some current payable accounts were counted twice, causing inflated totals. This improves the accuracy of financial reporting for Spanish companies using the affected balance sheet report.
Original PR description
In **`balance_pymes_line_32300`** (`CURRENT LIABILITIES > Current payables > Other current payables`), amounts are **doubled** because account **551** is included twice. * **Formula using…
In **`balance_pymes_line_32300`** (`CURRENT LIABILITIES > Current payables > Other current payables`), amounts are **doubled** because account **551** is included twice.
* **Formula using `account_codes`:**
```xml <field name="formula">-1034 - 1044 - 190 - 192 - 194 - 500 - 501 - 505 ...551 - 5566 - 5595 - 5598 - 560 - 561 - 569</field> ```
→ Explicitly includes account **551**.
* **Formula using `domain`:**
```xml <field name="formula" eval="['|', ('account_id.code','=like','550%'), '|', ('account_id.code','=like','551%'), '|', ('account_id.code','=like','554%'), ('account_id.code','=like','5525%')]"/> ```
→ Includes **all accounts starting with 551**, so **551** is also counted here.
This overlap causes the balance to be counted twice, inflating the reported value.
**steps to reproduce:**
1. With a Spanish company, go to **Accounting > Dashboard > Bank > Transaction > New**.
2. Select an account, search for **55100**, and add it.
3. Go to **Reporting > Balance Sheet > Other current payables**.
4. Notice that the reported amount is **double** the actual accounting data.
Overlapping formulas: specific account `551` and `5525` are counted in `account_codes`, while the `domain` formula already includes `551%`, leading to duplication.
**Fix**
Remove explicit account codes from `account_codes` if they are already covered by the `domain` prefixes to avoid double-counting. and also made sure to correct the same issue in the whole report.
opw-5075035
Forward-Port-Of: odoo/enterprise#94494Changing a linked to-do item between numbered and bulleted lists no longer causes an error. The editor now cleans hidden formatting characters before saving the text selection, making list formatting more reliable for users.
Original PR description
Steps to Reproduce: 1. Go to To-Do 2. Create a link 3. Select all using Ctrl + A 4. Switch to order list and then unordered list. 5. Traceback occurs Description of the issue: - This issue occurs because a feff (zero-width no-break space) character is present inside the link. When the link is inside a list and the list type is changed, the `removeFEFF` method is triggered. `removeFEFF` removes the feff characters, but the selection is preserved based on positions from when those feffs were still present inside the link. As a result, after the list type is changed, restoring the selection causes a traceback. Solution: - Triggered `clean_handlers` before preserving the selection. This ensures feff characters are removed from the link before the selection is preserved, preventing invalid selection offsets and avoiding the traceback. task-5095561 Forward-Port-Of: odoo/odoo#227680
This fix stops users from deleting the default barcode nomenclature that the barcode scanner setup depends on. It prevents crashes when enabling the barcode scanner in Inventory settings, keeping configuration changes reliable for users.
Original PR description
The system will crash with error when user tries to enable barcode scanner in settings. **Steps to produce: -** - Install `Inventory` module. - `Inventory > configuration > products > Barcode…
The system will crash with error when user tries to enable barcode scanner in settings.
**Steps to produce: -**
- Install `Inventory` module.
- `Inventory > configuration > products > Barcode Nomenclatures`.
- Delete the `Default Nomenclature` record.
- Go to settings uncheck `Barcode Scanner` and save settings.
- Now, again `enable` that and save.
Error: -
```py
ValueError: External ID not found in the system: barcodes.default_barcode_nomenclature
ParseError: while parsing /home/odoo/src/enterprise/saas-18.4/stock_barcode/data/data.xml:40, somewhere inside <record id='scale_up_alias_1' model='barcode.rule'>
<field name='name'>Scale Up Receipt</field>
<field name='type'>alias</field>
<field name='pattern'>WH-RECEIPTS</field>
<field name='alias'>WHIN</field>
<field name='barcode_nomenclature_id' ref='barcodes.default_barcode_nomenclature'/>
<field name='sequence'>0</field>
</record>
```
**Root cause: -**
- At [1], the records use the ref of `default_barcode_nomenclature` which is defined in barcode module. So, when the ref is deleted and we are trying to use it then it gives error.
**Solution: -**
- This commit resolves the error by prevent the deletion of `default nomenclature`.
[1]: https://github.com/odoo/enterprise/blob/400171c9cebc46ecdd907ada210c65f3bbd2dd66/stock_barcode/data/data.xml#L40-L71
**sentry-6823596992**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#226594Fixed an issue where changing a timesheet entry in list view and moving focus away could show the old time again. This helps users trust that their latest Time Spent edits are retained while entering or updating timesheets.
Original PR description
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation:…
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation: ----------------- The focus changes, but the Time Spent field reverts to its old value instead of keeping the newly entered one. Issue: ----------------- - For new records, the component retrieves the value only from the state, which is updated in the `onWillUpdateProps` lifecycle. This lifecycle triggers only on saving or editing, not when simply changing focus. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L123-L128 - The same behavior occurs when editing existing records, leading to incorrect value display. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L31-L33 Solution: ----------------- - For new records, since the default value is 0, the fix makes the component fall back to the updated record value if the state value is not yet available. - For existing records, if the timer is running, the timer’s value is displayed. otherwise, the component falls back to the updated record value. opw-4922847 Forward-Port-Of: odoo/enterprise#95141 Forward-Port-Of: odoo/enterprise#94729
6 changes
Resolved issues and error corrections
Fixed an issue in the HTML editor where changing a linked item between numbered and bulleted list styles could cause an error. Users can now edit list formatting in To-Do content more reliably without interruptions.
Original PR description
Steps to Reproduce: 1. Go to To-Do 2. Create a link 3. Select all using Ctrl + A 4. Switch to order list and then unordered list. 5. Traceback occurs Description of the issue: - This issue occurs because a feff (zero-width no-break space) character is present inside the link. When the link is inside a list and the list type is changed, the `removeFEFF` method is triggered. `removeFEFF` removes the feff characters, but the selection is preserved based on positions from when those feffs were still present inside the link. As a result, after the list type is changed, restoring the selection causes a traceback. Solution: - Triggered `clean_handlers` before preserving the selection. This ensures feff characters are removed from the link before the selection is preserved, preventing invalid selection offsets and avoiding the traceback. task-5095561 Forward-Port-Of: odoo/odoo#227680
Odoo now protects the default barcode setup record from being deleted. This prevents crashes when users disable and re-enable the Barcode Scanner setting, keeping inventory barcode configuration reliable.
Original PR description
The system will crash with error when user tries to enable barcode scanner in settings. **Steps to produce: -** - Install `Inventory` module. - `Inventory > configuration > products > Barcode…
The system will crash with error when user tries to enable barcode scanner in settings.
**Steps to produce: -**
- Install `Inventory` module.
- `Inventory > configuration > products > Barcode Nomenclatures`.
- Delete the `Default Nomenclature` record.
- Go to settings uncheck `Barcode Scanner` and save settings.
- Now, again `enable` that and save.
Error: -
```py
ValueError: External ID not found in the system: barcodes.default_barcode_nomenclature
ParseError: while parsing /home/odoo/src/enterprise/saas-18.4/stock_barcode/data/data.xml:40, somewhere inside <record id='scale_up_alias_1' model='barcode.rule'>
<field name='name'>Scale Up Receipt</field>
<field name='type'>alias</field>
<field name='pattern'>WH-RECEIPTS</field>
<field name='alias'>WHIN</field>
<field name='barcode_nomenclature_id' ref='barcodes.default_barcode_nomenclature'/>
<field name='sequence'>0</field>
</record>
```
**Root cause: -**
- At [1], the records use the ref of `default_barcode_nomenclature` which is defined in barcode module. So, when the ref is deleted and we are trying to use it then it gives error.
**Solution: -**
- This commit resolves the error by prevent the deletion of `default nomenclature`.
[1]: https://github.com/odoo/enterprise/blob/400171c9cebc46ecdd907ada210c65f3bbd2dd66/stock_barcode/data/data.xml#L40-L71
**sentry-6823596992**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#226594Timesheet users can now edit the Time Spent value in list view and move focus away without the field reverting to the previous value. This prevents confusion and helps ensure newly entered or adjusted time remains visible before saving.
Original PR description
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation:…
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation: ----------------- The focus changes, but the Time Spent field reverts to its old value instead of keeping the newly entered one. Issue: ----------------- - For new records, the component retrieves the value only from the state, which is updated in the `onWillUpdateProps` lifecycle. This lifecycle triggers only on saving or editing, not when simply changing focus. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L123-L128 - The same behavior occurs when editing existing records, leading to incorrect value display. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L31-L33 Solution: ----------------- - For new records, since the default value is 0, the fix makes the component fall back to the updated record value if the state value is not yet available. - For existing records, if the timer is running, the timer’s value is displayed. otherwise, the component falls back to the updated record value. opw-4922847 Forward-Port-Of: odoo/enterprise#95141 Forward-Port-Of: odoo/enterprise#94729
Credit notes for Mexico’s general public tax regime now keep the selected “Returns, discounts or bonuses” usage when allowed by current SAT rules. This prevents XML documents from being generated with the wrong usage value, helping businesses issue compliant credit notes without manual correction.
Original PR description
**Steps to reproduce:** 1. Install `l10n_mx` and `l10n_mx_edi`. 2. Create an invoice with: * Enable *CFDI to Public*. * Confirm, then send to SAT. 3. Create a credit note with: * *Usage* = `Returns,…
**Steps to reproduce:** 1. Install `l10n_mx` and `l10n_mx_edi`. 2. Create an invoice with: * Enable *CFDI to Public*. * Confirm, then send to SAT. 3. Create a credit note with: * *Usage* = `Returns, discounts or bonuses` (G02). 4. Download the generated XML for the credit note. **Observed behavior:** - The `<UsoCFDI>` tag in the XML shows `S01` (No fiscal effects). **Expected behavior:** - The `<UsoCFDI>` tag should show `G02` for credit notes under regime 616 when explicitly selected. **Root cause:** - For regime 616 (`Público en general`), the code always defaults to `S01`. - The condition only allowed `G02` when refunding a global invoice (`is_refund_gi`), not for normal credit notes. **Solution:** - Allow `G02` usage to be preserved for credit notes (tipo_de_comprobante = 'E') even when `CFDI to public` is active, as this is now permitted by SAT regulations for fiscal regime 616. **ref:** http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/catCFDI_V_4_20250820.xls opw-5012917 Forward-Port-Of: odoo/enterprise#93071
Field service sales orders with zero-priced service lines now correctly show as invoiced after the related invoice is created and posted. This prevents orders from remaining incorrectly marked as needing invoicing, reducing confusion during billing follow-up.
Original PR description
Steps: - Install sale and fsm module. - Enable anglo-saxon from the setting. - Create a service type product with fsm project as template. - Select that product on SO and set unit price to 0 on SOL. - Confirm that order and create and post invoice. Issue: - Sale order status still shows `To invoice` even though we create SOL related invoice. Cause: - In [PR] we made invoice status for anglo-saxon line `To Invoice` so it always say `To Invoice` even user create related invoice. Fix: - Make those lines `Invoiced` if there is related invoice by checking qty_invoiced is greater or equal to qty. [PR]: https://github.com/odoo/enterprise/pull/70132 opw-5055540 Forward-Port-Of: odoo/enterprise#94723
This change fixes an access problem in the self-ordering feature that could block public users from completing expected actions. It helps keep the customer ordering flow reliable without requiring unnecessary sign-in or extra permissions.
Original PR description
bypass Public user ACLs. build_error-231606
6 changes
Resolved issues and error corrections
Fixed an issue that blocked invoice creation when multiple Point of Sale orders for the same customer were selected in a Mexican company. This prevents an error during batch invoicing and helps staff complete sales administration without manual workarounds.
Original PR description
Currently, an error is raised when generating an invoice for multiple POS orders created for the same customer in a Mexican location. **Steps to reproduce:** - Install `l10n_mx_edi_pos` module. -…
Currently, an error is raised when generating an invoice for multiple POS orders created for the same customer in a Mexican location. **Steps to reproduce:** - Install `l10n_mx_edi_pos` module. - Switch the company to a **Mexican** company. - Create two POS orders for the same customer (ensure Invoice is disabled on the payment screen). - Without closing the POS session, go to the backend and navigate to Orders. - Select both orders and click **"Create Invoice"**. **Error:** `ValueError - Expected singleton: pos.order(5, 4)` **Cause:** The method `_prepare_invoice_vals()` accesses fields on `self`, assuming a single record. However, during batch invoicing, `self` can be multiple `pos.order` records. - [1] [1] - https://github.com/odoo/enterprise/blob/6e0396b078e7c6ffc98eef5a0d21a7df80651c19/l10n_mx_edi_pos/models/pos_order.py#L130-L135 **Fix:** Ensure the method only accesses fields on the first record, which prevents the singleton error during multi-record processing. sentry-6563854524
Sales orders for field service products with zero-priced lines now show the correct invoicing status after an invoice is created. This prevents orders from incorrectly appearing as still needing invoicing, reducing confusion for sales and accounting teams.
Original PR description
Steps: - Install sale and fsm module. - Enable anglo-saxon from the setting. - Create a service type product with fsm project as template. - Select that product on SO and set unit price to 0 on SOL. - Confirm that order and create and post invoice. Issue: - Sale order status still shows `To invoice` even though we create SOL related invoice. Cause: - In [PR] we made invoice status for anglo-saxon line `To Invoice` so it always say `To Invoice` even user create related invoice. Fix: - Make those lines `Invoiced` if there is related invoice by checking qty_invoiced is greater or equal to qty. [PR]: https://github.com/odoo/enterprise/pull/70132 opw-5055540 Forward-Port-Of: odoo/enterprise#94723
Credit notes for Mexico's public customer tax regime now keep the selected returns/discounts usage instead of being changed to no fiscal effects. This helps businesses generate compliant electronic invoice XML when issuing refunds or discounts under updated SAT rules.
Original PR description
**Steps to reproduce:** 1. Install `l10n_mx` and `l10n_mx_edi`. 2. Create an invoice with: * Enable *CFDI to Public*. * Confirm, then send to SAT. 3. Create a credit note with: * *Usage* = `Returns,…
**Steps to reproduce:** 1. Install `l10n_mx` and `l10n_mx_edi`. 2. Create an invoice with: * Enable *CFDI to Public*. * Confirm, then send to SAT. 3. Create a credit note with: * *Usage* = `Returns, discounts or bonuses` (G02). 4. Download the generated XML for the credit note. **Observed behavior:** - The `<UsoCFDI>` tag in the XML shows `S01` (No fiscal effects). **Expected behavior:** - The `<UsoCFDI>` tag should show `G02` for credit notes under regime 616 when explicitly selected. **Root cause:** - For regime 616 (`Público en general`), the code always defaults to `S01`. - The condition only allowed `G02` when refunding a global invoice (`is_refund_gi`), not for normal credit notes. **Solution:** - Allow `G02` usage to be preserved for credit notes (tipo_de_comprobante = 'E') even when `CFDI to public` is active, as this is now permitted by SAT regulations for fiscal regime 616. **ref:** http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/catCFDI_V_4_20250820.xls opw-5012917 Forward-Port-Of: odoo/enterprise#93071
Timesheet reports printed from a sales order now include the related helpdesk ticket name alongside the helpdesk team. This prevents incomplete report details and makes billed support time easier to understand for customers and internal teams.
Original PR description
to reproduce: ============= 1. make helpdesk team billable and records timesheets 2. create a helpdesk ticket and link it to a sale order 3. log timesheets on the ticket 4. print the timesheet report…
to reproduce: ============= 1. make helpdesk team billable and records timesheets 2. create a helpdesk ticket and link it to a sale order 3. log timesheets on the ticket 4. print the timesheet report **from the sale order** -> the task column will contain only the helpdesk team name, while it should contain "helpdesk team / ticket name" Problem: ======== in helpdesk_timesheet we inherit `hr_timesheet.timesheet_table` to adapt it to helpdesk tickets, but we use `show_ticket` to display the ticket name, which is only set in `hr_timesheet.report_timesheet` and `hr_timesheet.timesheet_project_task_page` but not in `sale_timesheet.timesheet_sale_page` which is the one used when printing the report from the sale order. Solution: ========= `show_ticket` should be set with value `bool(lines.helpdesk_ticket_id)` which is equivalent to `line.helpdesk_ticket_id` in the t-if condition. so we can directly use `line.helpdesk_ticket_id` and remove the `show_ticket` variable. opw-5002650 Forward-Port-Of: odoo/enterprise#95179
Brazilian service invoices with payment installments will now be sent to AvaTax without taxes included in the installment values. This prevents invoice rejection errors caused by mismatches between installment totals and line totals.
Original PR description
Service invoices require us to send installments without taxes. If we include taxes we get an error: **Errors**: Rejection: Total Installments doesn’t match Total Lines ∑ installments[m]grossValue - ∑ (lines[n].lineAmount-line[n].lineTaxedDiscount) <> 0 This **PR** clears taxes before tax calculation to ensure the installments we send are correct. **task**-4761630 Forward-Port-Of: odoo/enterprise#85108
Sendcloud delivery shipments can now use customs HS codes up to 12 characters, matching Sendcloud's API requirements. This helps avoid delays for international parcels, especially shipments to the US that may be held in customs when codes are incomplete.
Original PR description
**PROBLEM** We limit the `hs_code` length to 8 characters, but if we refer to the [sendcloud v2 api doc](https://api.sendcloud.dev/docs/sendcloud-public-api/branches/v2/parcels/schemas/parcel-item), we see that `hs_code` length can be up to 12 characters. Some clients have issue with parcels being held longer in custom when sending them to the US. [opw-5051585](https://www.odoo.com/odoo/project/49/tasks/5051585) Forward-Port-Of: odoo/enterprise#94894
1 change
Resolved issues and error corrections
Planning now blocks shift templates that span an excessive number of days before they can be used. This prevents employees from encountering an error when creating shifts from templates and gives users clearer feedback instead.
Original PR description
Currently, An error occurs when the employee adds a working 'Shift' in the resource calendar using a planning template that has too many span days. Step to produce: - Install the `planning` module. - Go to Planning / Configuration / Shift Templates, and Create a template that span day is more than 1000. - Create a 'Shift' in 'My Planning', Add an administrator as 'Resource,' and click on the 'Shift Templates'. `AttributeError: 'bool' object has no attribute 'replace'` The issue occurs because the system attempts to replace an hour and minute with end time at [1], But end time is False(boolean) as the 'plan_days' method returns a False value due to the excessive span days in the template. Link [1]: https://github.com/odoo/enterprise/blob/fd94c8bbe8f75540681f3b85ebf8d9767cf30f2a/planning/models/planning.py#L636 To resolve this, raise a validation error if the user tries to create a shift template with an excessive span days. Sentry-6190026432
1 change
Resolved issues and error corrections
This fix reduces excessive database checkpoints created during failed imports, preventing severe slowdowns or freezes in busy transactions. It also improves related accounting partner update processing and adds monitoring warnings before the risky database limit is reached.
Original PR description
Global Issue ----- Each time a save point is created inside a transaction, it creates a substransaction with its own subxid. As said in the documentation "The more subtransactions each transaction…
Global Issue
-----
Each time a save point is created inside a transaction, it creates a
substransaction with its own subxid. As said in the documentation
"The more subtransactions each transaction keeps open (not rolled back or released),
the greater the transaction management overhead. Up to 64 open subxids are cached in shared memory for each backend;
after that point, the storage I/O overhead increases significantly due to additional lookups of subxid entries in pg_subtrans."
https://www.postgresql.org/docs/current/subxacts.html
When the 64 is reach, it causes a huge I/O overhead (waiting for subtrans LRU) on every
transaction and lead to a complete freeze until the transaction that
create that many savepoints is killed.
Problem 1
---------
This amount of save point is reach during an import that eventually
failed. It retries with one savepoint per record. After 10 errors, the
import stops but if those error happen after few hundred correct line.
Hundreds of save point are created with their respective sub transaction
id.
Solution: We only create one savepoint when the import retries for
every record and rollback each time the import face an error.
As consequence, if record depends on previous one imported before the
rollback, some phantom error will appear and if some record sould be in
error due to previous record (unique constraint for ie.) some error can
be missed. Anyway the first error will remain correct.
In addition, in this PR we want to monitor the number of savepoint per
transaction and fire a warning with the stack info when the limit of 60 savepoint per
transaction is reached.
In order to monitor properly all the savepoint, we need to convert the
last cr.execute("SAVEPOINT") to the context manager
Problem 2
---------
Increase rank is call during _post once per partner.
Since https://github.com/odoo/odoo/commit/f12ce318020169b1355538066a8f81f78ecbf007
_do_action_change_account trigger the increase the rank of many partner
in one transaction.
By grouping the call of increase rank by count it reduce drastically the
amount of call to increase_rank and thus the number of savepoint35 changes
Enhancements to existing features
Businesses using international bpost shipping methods can now request bpack World Easy Retour return labels. This makes cross-border returns easier to manage and improves the customer return experience for international orders.
Original PR description
This ensures you can request 'bpack World Easy Retour' labels when using international bpost shipping methods. This PR is based on feedback from a PR I did on base 16.0 branch: https://github.com/odoo/enterprise/pull/58836.
A tooltip was added to explain the setting that prevents consecutive leave days for Belgian payroll time off types. This helps users understand the option during setup and reduces the chance of configuring leave rules incorrectly.
Original PR description
The field `No_Consecutive_Leaves_Allowed` was unclear to users when setting up time off types. Adding a tooltip clarifies its purpose and improves usability by reducing the risk of misconfiguration. task-5051915
The payslip other input report has been adjusted so users can no longer edit fields that should only be viewed. This helps protect payroll data accuracy and makes it easier for users to find the information they need through improved search behavior.
Original PR description
-In payslip other input report, some fields can be edited, which should not be allowed. -The view has been adjusted to prevent the edition on the report.
The employee list now includes each employee's yearly cost from salary contract information. This gives HR and management quicker visibility into workforce cost without opening individual employee records.
Original PR description
- added inherited list view in the hr_contract_salary to show the yearly cost in employee list view task id: https://www.odoo.com/odoo/project/1251/tasks/5030905
Indian payroll now includes account mappings for selected salary rules. This helps payroll-related accounting entries flow into the correct accounts, reducing manual setup and improving financial reporting consistency.
Original PR description
In this commit, Include chart of account for some of salary rules of Indian payroll. task-4929815
Payslips created through a payroll run now use the same naming format as off-cycle payslips. This makes payroll records easier to identify and keeps naming consistent across payroll workflows.
Original PR description
Computed the name of payslips generated through using a payrun, in order to follow the same naming convention as those created off-cycle Task-5075930 Forward-Port-Of: odoo/enterprise#95154
Document breadcrumbs now reflect the views users previously opened when moving into folders, making it easier to return to where they came from. The add link document wizard also no longer lets users open the folder directly, aligning it with the request document flow.
Original PR description
When navigating to a folder using the folder many2one widget, instead of using the folder parents hierarchy as breadcrumbs, using the previously opened views so that users can easily go back. Like for the "request document" wizard, removing the possibility to open the folder from the "add link" document wizard. Task-4298814
French accounting report and FEC import tests were updated to match recent underlying accounting data changes. This helps keep French localization checks reliable without changing business workflows for users.
Original PR description
Due to data changes in community. This commit aims to: 1. Force test_import_fec_file to run in FR company. 2. Rename account: "Inventory item purchases - Raw materials and supplies" used for test_import_fec_export. 3. Replace tax tva_normale_ttc that used in TestFrenchFiscalRounding (tax was deleted in community). task-4920071
Resolved issues and error corrections
Fixed an issue in the Spanish SME balance sheet where some payable accounts could be counted twice. This ensures the reported liabilities match the underlying accounting data and avoids overstated balances.
Original PR description
In **`balance_pymes_line_32300`** (`CURRENT LIABILITIES > Current payables > Other current payables`), amounts are **doubled** because account **551** is included twice. * **Formula using…
In **`balance_pymes_line_32300`** (`CURRENT LIABILITIES > Current payables > Other current payables`), amounts are **doubled** because account **551** is included twice.
* **Formula using `account_codes`:**
```xml <field name="formula">-1034 - 1044 - 190 - 192 - 194 - 500 - 501 - 505 ...551 - 5566 - 5595 - 5598 - 560 - 561 - 569</field> ```
→ Explicitly includes account **551**.
* **Formula using `domain`:**
```xml <field name="formula" eval="['|', ('account_id.code','=like','550%'), '|', ('account_id.code','=like','551%'), '|', ('account_id.code','=like','554%'), ('account_id.code','=like','5525%')]"/> ```
→ Includes **all accounts starting with 551**, so **551** is also counted here.
This overlap causes the balance to be counted twice, inflating the reported value.
**steps to reproduce:**
1. With a Spanish company, go to **Accounting > Dashboard > Bank > Transaction > New**.
2. Select an account, search for **55100**, and add it.
3. Go to **Reporting > Balance Sheet > Other current payables**.
4. Notice that the reported amount is **double** the actual accounting data.
Overlapping formulas: specific account `551` and `5525` are counted in `account_codes`, while the `domain` formula already includes `551%`, leading to duplication.
**Fix**
Remove explicit account codes from `account_codes` if they are already covered by the `domain` prefixes to avoid double-counting. and also made sure to correct the same issue in the whole report.
opw-5075035
Forward-Port-Of: odoo/enterprise#94494Field service sales orders with zero-priced service lines now show as invoiced once the related invoice has been created. This prevents completed invoicing from incorrectly appearing as still needing invoicing, improving clarity for users managing field service sales.
Original PR description
Steps: - Install sale and fsm module. - Enable anglo-saxon from the setting. - Create a service type product with fsm project as template. - Select that product on SO and set unit price to 0 on SOL. - Confirm that order and create and post invoice. Issue: - Sale order status still shows `To invoice` even though we create SOL related invoice. Cause: - In [PR] we made invoice status for anglo-saxon line `To Invoice` so it always say `To Invoice` even user create related invoice. Fix: - Make those lines `Invoiced` if there is related invoice by checking qty_invoiced is greater or equal to qty. [PR]: https://github.com/odoo/enterprise/pull/70132 opw-5055540 Forward-Port-Of: odoo/enterprise#94723
Tax return company data validation can now complete even when the logged-in user has no email address configured. The system still records the update in the activity log, preventing unnecessary interruptions for users.
Original PR description
Before Fix: When validating failed `company data` check in the Tax Return Kanban, the system attempted to log an update in the chatter. However, if the logged-in user did not have an email address configured, the action failed with the error: 'Unable to send message, please configure the sender's email address.' After Fix: The logging now runs in superuser mode. This ensures that updates are always posted in the chatter, regardless of whether the user has an email address set. Explanation: This change guarantees that important updates are consistently tracked in the chatter without interruption. Previously, users without an email address could not complete the validation, even though no actual email needed to be sent, the system only needed to record the change. By switching to superuser mode, we align with intended behavior: the system does not crash due to no email. task-5014717
Removed an unnecessary developer log from the spreadsheet chart configuration area. This keeps the browser console cleaner and avoids exposing irrelevant internal messages during normal use.
Original PR description
Task: 0 Forward-Port-Of: odoo/enterprise#95135
Searching from the Help page now waits for the needed background response before showing results. This prevents users from seeing an error screen and makes help content search work reliably.
Original PR description
Steps to reproduce: 1. Navigate to the Help menu. 2. Search for any term in the search bar. - A traceback occurs. Issue: The search method did not wait for the RPC call to complete and returned a promise prematurely, leading to an unhandled traceback. Fix: Ensure the method properly awaits the RPC call before returning the result. Forward-Port-Of: odoo/enterprise#94565
This fix prevents an error when the same Chilean electronic tax document is imported more than once. Instead of crashing, the system can now handle the duplicate import message correctly, improving reliability for Chilean localization users.
Original PR description
### Steps to reproduce: - Install 'l10n_cl_edi' and switch to a Chilean company - Import twice the same DTE XML file. ### Cause: This [commit](https://github.com/odoo/enterprise/commit/42744fcecdbd36ea0101070c68299227a9f204a6) forgot to add the `_()` method to format the message. As `append()` only needs one argument but two are given, there is a traceback. opw-5080094 Forward-Port-Of: odoo/enterprise#94929
Timesheet reports printed from sales orders now show the related helpdesk ticket alongside the helpdesk team. This makes billed support work easier to identify and avoids unclear report lines for customers and staff.
Original PR description
to reproduce: ============= 1. make helpdesk team billable and records timesheets 2. create a helpdesk ticket and link it to a sale order 3. log timesheets on the ticket 4. print the timesheet report…
to reproduce: ============= 1. make helpdesk team billable and records timesheets 2. create a helpdesk ticket and link it to a sale order 3. log timesheets on the ticket 4. print the timesheet report **from the sale order** -> the task column will contain only the helpdesk team name, while it should contain "helpdesk team / ticket name" Problem: ======== in helpdesk_timesheet we inherit `hr_timesheet.timesheet_table` to adapt it to helpdesk tickets, but we use `show_ticket` to display the ticket name, which is only set in `hr_timesheet.report_timesheet` and `hr_timesheet.timesheet_project_task_page` but not in `sale_timesheet.timesheet_sale_page` which is the one used when printing the report from the sale order. Solution: ========= `show_ticket` should be set with value `bool(lines.helpdesk_ticket_id)` which is equivalent to `line.helpdesk_ticket_id` in the t-if condition. so we can directly use `line.helpdesk_ticket_id` and remove the `show_ticket` variable. opw-5002650 Forward-Port-Of: odoo/enterprise#95179
Spanish translations for Peruvian electronic invoicing and stock documents were corrected where tariff fraction and withholding code labels were inaccurate or inconsistent. This helps users see the right wording on localization-related records and reduces confusion in compliant Peruvian reporting workflows.
Original PR description
## Issue: The latest `tariff_fraction` entries were not properly translated into Spanish There were also inconsistencies in the translation of some `withhold codes` ## Cause: The `.po` and `.pot` files were not correctly populated In addition, the translation of "Others" in `l10n_pe_withhold_code` conflicted with `l10n_pe_edi_reason_for_transfer__13`, because the `msgid` is the same but not the `msgstr` should be different opw-4741731 Forward-Port-Of: odoo/enterprise#95019 Forward-Port-Of: odoo/enterprise#92758
Restaurant POS orders no longer ask staff to send items to preparation when no preparation printer or display is configured. This prevents confusing checkout prompts and keeps payment flow smooth for configurations that do not use kitchen preparation routing.
Original PR description
Steps to reproduce: - Open a pos restaurant config that has no prep printer/display. - Add an orderline. - The order button appear and if you try to pay the popup ask for send to preparation is shown. Issue: If there is no preparationCategories for a config getOrderChanges consider that all the available categories are the preparationCategories. Fix: If there is no preparationCategories, set the orderline uiState hasChange to false. Note: When no preparation printer category is defined, no categories is to be return by default. For the preparation display, if no preparation categories is selected preparationCategories will return all the available categories. Task-5016231 Forward-Port-Of: odoo/enterprise#94672 Forward-Port-Of: odoo/enterprise#92541
Sendcloud deliveries can now send customs product codes up to 12 characters, matching Sendcloud's current requirements. This helps reduce the risk of parcels, especially shipments to the US, being delayed in customs due to truncated or incomplete codes.
Original PR description
**PROBLEM** We limit the `hs_code` length to 8 characters, but if we refer to the [sendcloud v2 api doc](https://api.sendcloud.dev/docs/sendcloud-public-api/branches/v2/parcels/schemas/parcel-item), we see that `hs_code` length can be up to 12 characters. Some clients have issue with parcels being held longer in custom when sending them to the US. [opw-5051585](https://www.odoo.com/odoo/project/49/tasks/5051585) Forward-Port-Of: odoo/enterprise#94894
A barcode workflow test was adjusted to wait for the correct step before continuing. This reduces false build failures caused by timing issues, helping keep validation of stock barcode processes more dependable.
Original PR description
The `test_put_packs_in_existing_pack` tour was using an erroneous trigger causing race condition. This commit replaces this trigger by another one to be sure previous step is completed before going forward. Runbot build error: [232638](https://runbot.odoo.com/odoo/runbot.build.error/232638) Forward-Port-Of: odoo/enterprise#95131
Field Service sales orders created from completed tasks now use the product’s currency when calculating line prices. This prevents incorrect pricing when the sales order and product use different currencies, helping invoices reflect the right converted amounts.
Original PR description
### Steps to reproduce: - Open Field Service module. - Create a new task. In the Customer field, select “Bloem GmbH”. - Open the task’s project. - In the Invoicing tab, create a new line for any…
### Steps to reproduce: - Open Field Service module. - Create a new task. In the Customer field, select “Bloem GmbH”. - Open the task’s project. - In the Invoicing tab, create a new line for any employee and any service. - Return to the task and in the Timesheets tab, add a new timesheet. - Click the Mark as done button. - Click the Sales order button. ### Cause: When creating the sale order out of the fsm task we use _get_tax_included_unit_price to get the price of the SO line but we are passing the order currency twice to this method so it doesn't convert the price as when it checks the currency and the product_currency it found they are the same so no need to convert https://github.com/odoo/odoo/blob/6653355b8bc063ceadf08af17fbf2c4a250553e6/addons/account/models/product.py#L239-L240 ### Fix: We pass the product currency instead of the order currency in order to be able to convert the price according to the currencies opw-5045071 Forward-Port-Of: odoo/enterprise#95134 Forward-Port-Of: odoo/enterprise#94947
Rental orders that are returned late now correctly include the extra delay fee. This prevents missed charges when rental delays are measured in hours, helping keep customer billing accurate.
Original PR description
In [^1], during a small refactor of the `sale.order.is_late` method to only account for logistic delays rather than rental delays, the rental extra delay margin computation was moved to the `sale.order.line._generate_delay_line` method. However, the computation used the utility class `relativedelta` instead of `timedelta`, which transformed the final rental duration into a `relativedelta` object. This object internally stores second durations differently than a `timedelta`. While `timedelta` stores durations as `days` and remaining `seconds`, `relativedelta` splits the information into `days`, `hours`, `minutes`, etc. Since rental orders only account for hours, the `seconds` field was null, resulting in no extra delay fee being added to the order upon return. This commit fixes the issue by using `timedelta` as expected. [^1]: https://github.com/odoo/enterprise/pull/88689 Forward-Port-Of: odoo/enterprise#95116
Salary offer pages now use the standard theme background color instead of a fixed color. This keeps the page readable and visually consistent when users work in dark mode.
Original PR description
With this commit the background-color is not hardcoded anymore; the background color is calculated with the bootstrap variable text-bg-secondary task-5089515 Forward-Port-Of: odoo/enterprise#94751
This update adds test coverage for Spain's Modelo 130 tax report to help ensure it continues to calculate and behave correctly. It reduces the risk of regressions in Spanish tax reporting without changing day-to-day user workflows.
Original PR description
opw-4933241 Forward-Port-Of: odoo/enterprise#94251 Forward-Port-Of: odoo/enterprise#90044
Unused AI-related code paths and an obsolete route were removed after the underlying methods had already been deleted. This reduces the chance of errors from outdated AI composer functionality and keeps the module easier to maintain.
Original PR description
Methods like **_ai_submit_to_model**, **_ai_add_message_to_context**, and **_ai_create_response** have been removed, along with the route **/ai/generate_w_composer**, from this [commit] [commit]: https://github.com/odoo/enterprise/commit/f8b9d475c0f19e5746ec47fe535c2030d117b534#diff-292213f329cde8a43c2882d1a0a972016a2fccb2f467fc79b196ebc2ae00f681L133-L191 In this commit, we are removing the method where the route and the referenced methods are called. sentry-6685514254 Forward-Port-Of: odoo/enterprise#95110
A test in the Indian payroll module is now allowed to run because the related salary contract app no longer causes it to fail. This improves confidence in payroll quality checks without changing day-to-day user workflows.
Original PR description
- Removed the test skip since the test is now working correctly task-5067701
This fixes an issue where edited time values in the Timesheet list view could revert when users moved focus with Shift + Tab. The entered time now stays visible for both new and existing timesheet lines, helping prevent confusion and inaccurate time entry.
Original PR description
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation:…
Steps to reproduce: ----------------- 1. Go to Timesheet → My Timesheet → List View → New OR Edit already filled time. 2. Change time in the Time Spent field. 3. Press Shift + Tab. Observation: ----------------- The focus changes, but the Time Spent field reverts to its old value instead of keeping the newly entered one. Issue: ----------------- - For new records, the component retrieves the value only from the state, which is updated in the `onWillUpdateProps` lifecycle. This lifecycle triggers only on saving or editing, not when simply changing focus. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L123-L128 - The same behavior occurs when editing existing records, leading to incorrect value display. https://github.com/odoo/enterprise/blob/e14b991927df14f41535e92dd01ea2ecac44a404/timesheet_grid/static/src/components/timesheet_display_timer/timesheet_display_timer.js#L31-L33 Solution: ----------------- - For new records, since the default value is 0, the fix makes the component fall back to the updated record value if the state value is not yet available. - For existing records, if the timer is running, the timer’s value is displayed. otherwise, the component falls back to the updated record value. opw-4922847 Forward-Port-Of: odoo/enterprise#95229 Forward-Port-Of: odoo/enterprise#94729
This update corrects a failing automated test for printing the planning calendar. It ensures the test uses the expected response value, helping keep planning calendar quality checks reliable without changing user-facing behavior.
Original PR description
This commit's purpose is to fix the planning calendar print test. Source of the issue: the empty dict that the mockrpc returns is evaluated as a truthy value and leads to an extra execute of the doAction function with an invalid value. Solution: Return false instead of an empty dict task-5079063 Forward-Port-Of: odoo/enterprise#95023
Small visual alignment issues in the spreadsheet topbar were corrected. Filter badges and collaborator avatars now appear more consistently positioned, giving users a cleaner and more polished interface.
Original PR description
- the global fitler badge was slightly misaligned - the user avatars in the collaborative status had a border created by a padding with a background color. We should use an a actual border instead, as the padding had a decimal value leading to the items inside looking slightly misaligned. Borders don't have this issue, as they are rounded to the nearest pixel. Task: [5086022](https://www.odoo.com/odoo/2328/tasks/5086022) Forward-Port-Of: odoo/enterprise#94737
This fix prevents payslip creation from failing when an employee payroll input is set to zero while the payslip has its own value. Payroll teams can now use zero values reliably without unexpected errors during payslip generation.
Original PR description
Reproduce: 1. Create a salary rule based on a salary input and make it available for both employee and payslip. 2. Configure the input on both employee and payslip. 3. Set the property value to zero on the employee form and give it a value on the payslip. 4. Try to create a new payslip for this employee. Issue: `dict(payslip.version_id.payroll_properties)` does not return the property if its value is zero. Fix: Use `version_properties.get(key, 0)` to avoid the KeyError. Task: 5082135 Forward-Port-Of: odoo/enterprise#94475
Credit notes for Mexico's public customer regime now keep the selected "Returns, discounts or bonuses" usage when allowed by SAT rules. This prevents generated tax XML from incorrectly switching to "No fiscal effects," helping businesses issue compliant credit notes.
Original PR description
**Steps to reproduce:** 1. Install `l10n_mx` and `l10n_mx_edi`. 2. Create an invoice with: * Enable *CFDI to Public*. * Confirm, then send to SAT. 3. Create a credit note with: * *Usage* = `Returns,…
**Steps to reproduce:** 1. Install `l10n_mx` and `l10n_mx_edi`. 2. Create an invoice with: * Enable *CFDI to Public*. * Confirm, then send to SAT. 3. Create a credit note with: * *Usage* = `Returns, discounts or bonuses` (G02). 4. Download the generated XML for the credit note. **Observed behavior:** - The `<UsoCFDI>` tag in the XML shows `S01` (No fiscal effects). **Expected behavior:** - The `<UsoCFDI>` tag should show `G02` for credit notes under regime 616 when explicitly selected. **Root cause:** - For regime 616 (`Público en general`), the code always defaults to `S01`. - The condition only allowed `G02` when refunding a global invoice (`is_refund_gi`), not for normal credit notes. **Solution:** - Allow `G02` usage to be preserved for credit notes (tipo_de_comprobante = 'E') even when `CFDI to public` is active, as this is now permitted by SAT regulations for fiscal regime 616. **ref:** http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/catCFDI_V_4_20250820.xls opw-5012917 Forward-Port-Of: odoo/enterprise#95246 Forward-Port-Of: odoo/enterprise#93071
This update adjusts an automated test for sales planning so it matches the latest Gantt scheduling behavior. It helps ensure the planning dialog opens correctly, reducing the chance of future scheduling issues going unnoticed.
Original PR description
Before this commit, the multi-create feature has been added to the gantt view of planning but the tour testing the planning gantt view has not been adapted accordingly. This commit adds a new step to make sure the plan dialog is opened as expected. runbot-error-230670 Forward-Port-Of: odoo/enterprise#95258
Sign requests in the Documents list are now ordered with the newest items at the top. This helps users find and open recent signature requests faster without scrolling through older entries.
Original PR description
Before: * New sign requests appeared at the bottom of the `Documents` list. * Users had to scroll down to find the latest requests. After: * The list is now sorted by creation date (newest first). * New sign requests appear at the top of the`Documents` screen. Impact: * Makes it easier for users to quickly find and access the most recent sign requests. task-5098740 Forward-Port-Of: odoo/enterprise#95104
Features or functions removed from Odoo
This update removes legacy permission-checking code from the HR Referral applicant flow as part of a broader cleanup. It helps keep the system aligned with the current access-control approach, reducing maintenance overhead without expected changes for business users.
Original PR description
odoo/odoo#226551
Code cleanup and technical improvements
This change removes unused legacy test helper code after most tests were moved to the newer testing approach. It reduces maintenance overhead for Documents, Sign, and Web Enterprise without changing customer-facing behavior.
Original PR description
*documents,sign,web_enterprise Now that almost all qunit tests have been converted to hoot, we can get rid of a lot of legacy helpers. This PR only aims at removing what is no longer used, or what can be trivially substituted. A further work will be necessary as some legacy helpers are used in tours. Moreover, the whole QUnit test suite system will still have to be removed, once the few remaining tests will be converted.
This update reorganizes accounting-related configuration options to make them easier to manage and maintain. It affects several accounting services such as invoicing, payment processing, bank reconciliation, electronic document exchange, and online synchronization, with limited expected impact for day-to-day users.
Original PR description
account.bill.predict.history.limit int account.custom_templates_facturx_list str account.display_name_in_footer bool account.pdf_generation_batch int account.show_sale_receipts bool account.skip_create_bank_account_on_reconcile bool account.tests_shared_js_python str account.use_invoice_terms bool account_iso20022.force_iso_20022_pain_09 bool account_online_synchronization.proxy_mode str account_online_synchronization.request_timeout int account_payment.enable_portal_payment bool account_peppol.edi.mode str account_predictive_bills.predict_product int account_sepa_direct_debit.disable_sdd_pre_notification str
9 changes
Resolved issues and error corrections
The Spanish SME balance sheet report now avoids counting the same payable accounts twice. This ensures the “Other current payables” total reflects the real accounting balance, improving accuracy for financial reporting.
Original PR description
In **`balance_pymes_line_32300`** (`CURRENT LIABILITIES > Current payables > Other current payables`), amounts are **doubled** because account **551** is included twice. * **Formula using…
In **`balance_pymes_line_32300`** (`CURRENT LIABILITIES > Current payables > Other current payables`), amounts are **doubled** because account **551** is included twice.
* **Formula using `account_codes`:**
```xml <field name="formula">-1034 - 1044 - 190 - 192 - 194 - 500 - 501 - 505 ...551 - 5566 - 5595 - 5598 - 560 - 561 - 569</field> ```
→ Explicitly includes account **551**.
* **Formula using `domain`:**
```xml <field name="formula" eval="['|', ('account_id.code','=like','550%'), '|', ('account_id.code','=like','551%'), '|', ('account_id.code','=like','554%'), ('account_id.code','=like','5525%')]"/> ```
→ Includes **all accounts starting with 551**, so **551** is also counted here.
This overlap causes the balance to be counted twice, inflating the reported value.
**steps to reproduce:**
1. With a Spanish company, go to **Accounting > Dashboard > Bank > Transaction > New**.
2. Select an account, search for **55100**, and add it.
3. Go to **Reporting > Balance Sheet > Other current payables**.
4. Notice that the reported amount is **double** the actual accounting data.
Overlapping formulas: specific account `551` and `5525` are counted in `account_codes`, while the `domain` formula already includes `551%`, leading to duplication.
**Fix**
Remove explicit account codes from `account_codes` if they are already covered by the `domain` prefixes to avoid double-counting. and also made sure to correct the same issue in the whole report.
opw-5075035
Forward-Port-Of: odoo/enterprise#94494Fixed an issue in the HTML editor that could cause an error when users changed a linked to-do item between numbered and bulleted lists. This improves editing reliability and prevents interruptions while formatting content.
Original PR description
Steps to Reproduce: 1. Go to To-Do 2. Create a link 3. Select all using Ctrl + A 4. Switch to order list and then unordered list. 5. Traceback occurs Description of the issue: - This issue occurs because a feff (zero-width no-break space) character is present inside the link. When the link is inside a list and the list type is changed, the `removeFEFF` method is triggered. `removeFEFF` removes the feff characters, but the selection is preserved based on positions from when those feffs were still present inside the link. As a result, after the list type is changed, restoring the selection causes a traceback. Solution: - Triggered `clean_handlers` before preserving the selection. This ensures feff characters are removed from the link before the selection is preserved, preventing invalid selection offsets and avoiding the traceback. task-5095561 Forward-Port-Of: odoo/odoo#227680
This fix prevents users from deleting the default barcode setup that other barcode features depend on. It avoids crashes when re-enabling barcode scanner settings, keeping inventory barcode configuration stable.
Original PR description
The system will crash with error when user tries to enable barcode scanner in settings. **Steps to produce: -** - Install `Inventory` module. - `Inventory > configuration > products > Barcode…
The system will crash with error when user tries to enable barcode scanner in settings.
**Steps to produce: -**
- Install `Inventory` module.
- `Inventory > configuration > products > Barcode Nomenclatures`.
- Delete the `Default Nomenclature` record.
- Go to settings uncheck `Barcode Scanner` and save settings.
- Now, again `enable` that and save.
Error: -
```py
ValueError: External ID not found in the system: barcodes.default_barcode_nomenclature
ParseError: while parsing /home/odoo/src/enterprise/saas-18.4/stock_barcode/data/data.xml:40, somewhere inside <record id='scale_up_alias_1' model='barcode.rule'>
<field name='name'>Scale Up Receipt</field>
<field name='type'>alias</field>
<field name='pattern'>WH-RECEIPTS</field>
<field name='alias'>WHIN</field>
<field name='barcode_nomenclature_id' ref='barcodes.default_barcode_nomenclature'/>
<field name='sequence'>0</field>
</record>
```
**Root cause: -**
- At [1], the records use the ref of `default_barcode_nomenclature` which is defined in barcode module. So, when the ref is deleted and we are trying to use it then it gives error.
**Solution: -**
- This commit resolves the error by prevent the deletion of `default nomenclature`.
[1]: https://github.com/odoo/enterprise/blob/400171c9cebc46ecdd907ada210c65f3bbd2dd66/stock_barcode/data/data.xml#L40-L71
**sentry-6823596992**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#226594This update corrects how default email recipients are selected in Accounting communications. It helps ensure accounting-related emails are addressed to the right partners, reducing manual corrections and potential communication mistakes.
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
Field service sales orders with zero-priced service lines now correctly show as invoiced once the related invoice is created and posted. This prevents orders from incorrectly remaining marked as needing invoicing, giving teams a more accurate view of billing status.
Original PR description
Steps: - Install sale and fsm module. - Enable anglo-saxon from the setting. - Create a service type product with fsm project as template. - Select that product on SO and set unit price to 0 on SOL. - Confirm that order and create and post invoice. Issue: - Sale order status still shows `To invoice` even though we create SOL related invoice. Cause: - In [PR] we made invoice status for anglo-saxon line `To Invoice` so it always say `To Invoice` even user create related invoice. Fix: - Make those lines `Invoiced` if there is related invoice by checking qty_invoiced is greater or equal to qty. [PR]: https://github.com/odoo/enterprise/pull/70132 opw-5055540 Forward-Port-Of: odoo/enterprise#94723
Opening Studio from a project dashboard no longer triggers an error when there are no project update records yet. This prevents a disruptive crash during project configuration and keeps the setup flow working as expected.
Original PR description
An error currently occurs when opening the studio view. Steps to reproduce: --- - Install `Project` and `web_studio` - Project > Configuration > Projects > Create a New Project - Click on the `Dashboard` button > Open studio view - Error in terminal Traceback: --- `TypeError: object of type 'bool' has no len()` This error occurs because `project.update` doesn’t have any records. When opening the studio view, at [1] it tries to compute the record’s name, which is `False`, and `False` has no length. [1]- https://github.com/odoo/odoo/blob/e0322e2cbc16d2405e66f3b16cbabeac2ad265e7/addons/project/models/project_update.py#L80 sentry-6830573412 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225070
This fix updates an automated test so it enables the discount and pricelist settings it needs before checking order calculations. It helps prevent false failures in validation systems when only the Sales app is installed, improving release reliability without changing customer-facing behavior.
Original PR description
This commit fix runbot issue cause by PR https://github.com/odoo/odoo/pull/226859 to compute discount depending on pricelist. Cause: - In subscription discount and pricelist are default enable that allow discount to compute properly and set it to 0 but when only sale is installed test was breaking because non of the condition was enabled require to compute discount properly. Fix: - Enabled discount and pricelist feature in testcase to compute discount properly runbot-232685 Forward-Port-Of: odoo/odoo#227706
The Live Chat channel screen no longer shows a misleading -1 rating percentage when no customer ratings have been received. This keeps reporting clearer for administrators by only displaying satisfaction percentages once at least one valid rating exists.
Original PR description
**Steps to reproduce:** - Install website_livechat - Initiate a conversation from the visitor's side - Close the conversation without providing a rating - Log in as 'Admin' - Go to Live Chat - Open the form view of the default channel **Current behavior before PR:** The stat button displays the `rating_percentage_satisfaction` field as -1, which is a fallback value used when there are no ratings. **Desired behavior after PR is merged:** The `rating_percentage_satisfaction` field is only displayed when we have received at least 1 valid rating. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Survey live session leaderboards now show score changes in a clearer sequence, so participants can better understand how points are added after each question. The leaderboard display size was also adjusted to prevent scores from appearing cramped or incorrect.
Original PR description
The way the score bars were animated was a bit confusing. We simplify the animation by: - Showing the score accumulated so far without the question - Animating the score bar towards the accumulated…
The way the score bars were animated was a bit confusing. We simplify the
animation by:
- Showing the score accumulated so far without the question
- Animating the score bar towards the accumulated score with the question
- Animating the numerical score on the left towards the accumulated score with the question while fading the numerical score increment on the bar ("+ x p")
- (reordering participants)
We also fix the size of the leaderboard as it was too small to display the score correctly.
How to reproduce
- Create a scored survey with time reward
- Add a question to get the name and toggle the nickname option
- Add a question with an answer that grants n points
- Start a live session
- After a user has completed the question
- Display the leaderboard
The score animation is confusion as it was going through:
- Showing the score accumulated so far without the question
- Animating towards 0: showing a minimal bar due to the minimum size of the score bar
- Animating towards the score question (on top of the minimal bar)
- And finally adding the score accumulated so far without the question
Task-4893763
Forward-Port-Of: odoo/odoo#22499627 changes
Resolved issues and error corrections
Credit notes for Mexican public invoices can now keep the selected “Returns, discounts or bonuses” tax usage when allowed by SAT rules. This prevents the XML from being generated with the wrong default value, reducing compliance errors for companies using fiscal regime 616.
Original PR description
**Steps to reproduce:** 1. Install `l10n_mx` and `l10n_mx_edi`. 2. Create an invoice with: * Enable *CFDI to Public*. * Confirm, then send to SAT. 3. Create a credit note with: * *Usage* = `Returns,…
**Steps to reproduce:** 1. Install `l10n_mx` and `l10n_mx_edi`. 2. Create an invoice with: * Enable *CFDI to Public*. * Confirm, then send to SAT. 3. Create a credit note with: * *Usage* = `Returns, discounts or bonuses` (G02). 4. Download the generated XML for the credit note. **Observed behavior:** - The `<UsoCFDI>` tag in the XML shows `S01` (No fiscal effects). **Expected behavior:** - The `<UsoCFDI>` tag should show `G02` for credit notes under regime 616 when explicitly selected. **Root cause:** - For regime 616 (`Público en general`), the code always defaults to `S01`. - The condition only allowed `G02` when refunding a global invoice (`is_refund_gi`), not for normal credit notes. **Solution:** - Allow `G02` usage to be preserved for credit notes (tipo_de_comprobante = 'E') even when `CFDI to public` is active, as this is now permitted by SAT regulations for fiscal regime 616. **ref:** http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/catCFDI_V_4_20250820.xls opw-5012917
Fixed an issue where importing certain electronic invoice files could fail if the file contained a zero base quantity. This makes invoice imports more reliable for customers receiving UBL/CII documents with that value.
Original PR description
**Steps to reproduce:** - Install Accounting - Go to "Accounting / Customers / Invoices" - Import a UBL file having a value of 0 for a `<cbc:BaseQuantity>` element **Issue:** The import fails due to a division by 0 at: `price_unit = (net_price_unit + rebate) / basis_qty` **Cause:** "basis_qty" is retrieved as followed: `basis_qty = float(self._find_value(xpath_dict['basis_qty'], tree) or 1)` If the element is not defined, it will fall back on 1. But if the element exists with a value of 0, the "_find_value" method will retrieve the string "0" which is not False and will not fall back on 1. Then it will become `0.0` once converted to float. opw-5062985 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The website shop sitemap generation now uses less memory when handling very large product catalogs. This helps prevent server crashes caused by search engines or web crawlers requesting product sitemap pages.
Original PR description
### Issue Server crashes with MemoryErrors when a database has a large product catalogs. ### Solution This commit disables the prefetcher to avoid MemoryErrors when generating the sitemap for large product catalogs as web crawlers would continously crash the server when requesting the sitemap. ### References opw-5001680 opw-4955333 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Brazilian service invoices with installments now exclude taxes from the installment data sent for validation. This prevents rejection errors where installment totals do not match line totals, helping invoices process correctly.
Original PR description
Service invoices require us to send installments without taxes. If we include taxes we get an error: **Errors**: Rejection: Total Installments doesn’t match Total Lines ∑ installments[m]grossValue - ∑ (lines[n].lineAmount-line[n].lineTaxedDiscount) <> 0 This **PR** clears taxes before tax calculation to ensure the installments we send are correct. **task**-4761630
The Mexican e-invoicing flow now handles customer names entered with accents when matching them against official legal names that omit accents. This helps prevent invoice stamping errors for PoS customers using the self-invoicing portal.
Original PR description
Currently, the self-invoicing portal lets client request an invoice after making a purchase in PoS. A form allows them to enter their personal informations such as their name. Many of them enter their name with accents, however the government has all the names without any accents which causes errors when trying to match the requesting party with their legal name during the stamping process of the CFDI. task-4952174
This fixes an error that could appear when restaurant staff repeatedly edited a kitchen note and quantity before sending an order. The change helps keep point-of-sale order preparation workflows reliable and avoids unnecessary log errors during service.
Original PR description
Currently a `TypeError` is arising when user select a meal, add the 'Kitchen Note', change the quantity and hit 'Order'. Steps to reproduce this error: - Select a dish and add a 'Kitchen note', hit 'Order'. - Now edit the 'Kitchen note' and the quantity, hit 'Order'. - Again edit the 'Kitchen note' and the quantity, hit 'Order'. - The error appears in the logs. Error: `TypeError: 'NoneType' object is not subscriptable` This commit solves the above issue by checking if the `old_quantity` is not `None`. sentry-6013783573
The update prevents crashes when employee or working schedule timezone information is missing by safely using UTC as a fallback. This improves reliability in payroll and related workflows where missing timezone settings previously caused errors.
Original PR description
Currently a traceback occurrs from multiple places when there is no tz for employee and used in the `pytz.timezone` method.…
Currently a traceback occurrs from multiple places when there is no tz for employee and used in the `pytz.timezone` method.
https://github.com/odoo/enterprise/blob/517983ae9deec37795eb11522134a1f5ade31e9b/hr_payroll/wizard/hr_payroll_payslips_by_employees.py#L131
For instance, if there is no tz in resource_calendar_id, it leads to a traceback.
Error:
```
AttributeError: 'bool' object has no attribute 'upper'
File "odoo/http.py", line 2364, in __call__
response = request._serve_db()
File "odoo/http.py", line 1892, in _serve_db
return self._transactioning(
File "odoo/http.py", line 1955, in _transactioning
return service_model.retrying(func, env=self.env)
File "odoo/service/model.py", line 137, in retrying
result = func()
File "odoo/http.py", line 1922, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "odoo/http.py", line 2169, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "odoo/addons/base/models/ir_http.py", line 329, in _dispatch
result = endpoint(**request.params)
File "odoo/http.py", line 727, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "addons/web/controllers/dataset.py", line 35, in call_kw
return call_kw(request.env[model], method, args, kwargs)
File "odoo/api.py", line 517, in call_kw
result = getattr(recs, name)(*args, **kwargs)
File "addons/web/models/models.py", line 70, in web_save
self.write(vals)
File "home/odoo/src/enterprise/18.0/hr_payroll/models/hr_contract.py", line 429, in write
res = super().write(vals)
File "addons/hr_work_entry_contract/models/hr_contract.py", line 453, in write
contract._recompute_work_entries(date_from, date_to)
File "home/odoo/src/enterprise/18.0/hr_payroll/models/hr_contract.py", line 441, in _recompute_work_entries
self._recompute_payslips(date_from, date_to)
File "home/odoo/src/enterprise/18.0/hr_payroll/models/hr_contract.py", line 453, in _recompute_payslips
all_payslips.action_refresh_from_work_entries()
File "home/odoo/src/enterprise/18.0/hr_payroll/models/hr_payslip.py", line 601, in action_refresh_from_work_entries
payslips._compute_worked_days_line_ids()
File "home/odoo/src/enterprise/18.0/hr_payroll/models/hr_payslip.py", line 1141, in _compute_worked_days_line_ids
slip_tz = pytz.timezone(slip.contract_id.resource_calendar_id.tz)
File "odoo/_monkeypatches/pytz.py", line 129, in timezone
return original_pytz_timezone(name)
File "__init__.py", line 183, in timezone
if zone.upper() == 'UTC':
```
To resolve this issue we can give a default value of `UTC` is there is no name. which makes the code more robust.
sentry-6134147853, 6119911834This fix prevents an error when users view or return to inventory quantity records that are missing location, lot, package, or owner details. The system now uses a default display name in those cases, helping users continue inventory updates without interruption.
Original PR description
Currently, an error occurs when computing a display name for stock quant. Step to produce: - Install the `stock` module(without demo data). - Go to inventory settings, enable Packages, Quality,…
Currently, an error occurs when computing a display name for stock quant. Step to produce: - Install the `stock` module(without demo data). - Go to inventory settings, enable Packages, Quality, Quality Worksheet, Reception Report, Variants, Units of Measure, Product Packagings, Lots & Serial Numbers, Display Lots & Serial Numbers on Delivery Slips, Expiration Dates, and Dropshipping. - Disable the Barcode Scanner. - After that, enable 'Display Lots & Serial Numbers on Invoices' in the Valuation section - Create a product and enable the 'Track Inventory' option. - In the product form view, click on On Hand in the breadcrumbs to navigate to the stock quantity list view - Create a new record to update the quantity. - Click on the 'View' button, remove the location, and try to come back to update quantity list view. `TypeError: sequence item 0: expected str instance, bool found` This error occurs because we compute the display name of stock quant and it is derived from location_id, lot_id, package_id, or owner_id. If none of these values are present in stock quant then the system tries to concate the False (bool) value with a string at [1] and an error occurs. Link [1]: https://github.com/odoo/odoo/blob/be6b327c17435947fc3f10d30fc8c4730c182aed/addons/stock/models/stock_quant.py#L585-L592 To resolve this issue, Assign a default display name of stock quant if none of the values of fields (location_id, lot_id, package_id, owner_id) are available. Sentry-6165002037 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixes an error that could stop users from printing and sending invoices when a related invoice report setting had been disabled. This helps ensure invoice delivery continues to work even when report options are customized.
Original PR description
Currently, An error occurs when the user print and send invoices and 'Invoice report' is disabled in reports 'report_invoice_with_payments'. Step to produce: - Install the `account` module. - Go to…
Currently, An error occurs when the user print and send invoices and 'Invoice report' is disabled in reports 'report_invoice_with_payments'. Step to produce: - Install the `account` module. - Go to Settings / Technical / Actions / Reports, Search 'report_invoice_with_payments', and disable the 'Invoice report'. - Go to Invoicing / Customers / Invoices, Create one invoice add a customer and invoice line, and Confirm it back to the list view of the invoice - Select this invoice and click on Print & Send. - After Opening a wizard, click the 'Print & Send' button. The issue occurs when the user tries to generate and send invoices and the system checks that 'is_invoice_report' is enabled for invoices at [1]. Link [1]: https://github.com/odoo/odoo/blob/658711aa1e1809b267006149ed6a547e548c1f90/addons/account/models/account_move_send.py#L658 To resolve this, we have to remove this comparison [1] as the user can disable 'is_invoice_report' from 'report_invoice_with_payments'. Sentry-6185986435 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users can now update the resource on multiple planning entries at the same time from My Planning without triggering an error. This improves reliability for teams managing schedules in bulk and avoids interruptions when editing several planning slots together.
Original PR description
Currently, An error occurs when trying to change(update) all resources in planning slot at once from the 'My Planning' list view. Step to produce: - Install the `sale_planning` module (with demo data). - Open a list view of 'My Planning', Select all records, and try to change(update) all resources at one time. `ValueError: Expected singleton: planning.slot(5, 7)` The error occurs because the system attempts to access a single value of fields (allocated_hours, allocated_percentage) from multiple records at [1]. Link [1]: https://github.com/odoo/enterprise/blob/a3de64e02ea62da0ebb06c589ed122dad44243ca/planning/models/planning.py#L2043-L2044 To resolve this issue, Use an iteration(for loop) to iterate records one by one. Sentry-6217013028
This fixes an invoice sending issue where users could choose postal delivery even after the related postal mail feature was uninstalled, causing an error. The send invoice wizard now only shows delivery methods that are currently available, helping users complete invoice sending without interruption.
Original PR description
Currently, a traceback is occurring when the user tries to send a customer invoice with the sending method as `By Post`. To reproduce this issue: 1) Install Accounting and Unistall `snailmail` 3)…
Currently, a traceback is occurring when the user tries to send a customer invoice with the sending method as `By Post`. To reproduce this issue: 1) Install Accounting and Unistall `snailmail` 3) Create a posted `Customer Invoice` with a customer having no Invoice Sending (Remove the value in customer's accounting page if he has the value) 4) Click the `Send` button and select the sending method as `To Post` 5) Click the `Send` button in wizard Error:- ``` ValueError: Wrong value for res.partner.invoice_sending_method: 'snailmail' ``` The selection value `snailmail` for `invoice_sending_method` is defined in `snailmail_acount`. But it will be uninstalled when the `snailmail` module installed. https://github.com/odoo/odoo/blob/636d76d6dcbbe472b9d57cbe403d0758d94ad81d/addons/snailmail_account/models/res_partner.py#L7-L9 But in the `account.move.send.wizard`, the sending_method values are getting from the computed method `_compute_sending_method_checkboxes`. https://github.com/odoo/odoo/blob/636d76d6dcbbe472b9d57cbe403d0758d94ad81d/addons/account/wizard/account_move_send_wizard.py#L130 We get all the selection values(including the inactive) for the field `invoice_sending_method`. When the user selects the `snailmail` checkbox (By Post)to send the invoice, the value of `invoice_sending_method` for res.partner will be assigned from the below line. https://github.com/odoo/odoo/blob/636d76d6dcbbe472b9d57cbe403d0758d94ad81d/addons/account/wizard/account_move_send_wizard.py#L269 This will lead to the above traceback as the `snailmail` value for the selection field `invoice_sending_method` in the partner is not valid. We can resolve this issue by accessing only the active selection values for the field `invoice_sending_method`. So only the user can select the valid value for sending_method. sentry-6091298443
The Accounting report send wizard no longer crashes when users remove all recipients before sending or editing the email template. This prevents an unexpected error and lets users continue their workflow even when recipients are optional.
Original PR description
Currently, a traceback is occurring when the user tries to send a report by removing the partner in the wizard. To reproduce this issue: 1) install `Accounting` 2) Open the Partner Ledger report 3) Change the Report, Account to `Customer Statement` and `Payable` respectively 4) Click the `Send` button, and a send wizard will be opened 5) Remove the `Recipients` and navigate to the mail template from the wizard 6) In Email Configuration, enable the `Default Recipients` Error:- ``` KeyError: False ``` This traceback is occurring because the user removed the `mail_partner_ids` which is indeed not a required field. This leads to the traceback from the below line when accessing the `partner.id` from the mail_field_values. https://github.com/odoo/enterprise/blob/28b6a5d30274f4265c978433b8d02b758d9a032e/account_reports/wizard/account_report_send.py#L92-L96 sentry-6348424386
Users adding images by URL will no longer see a technical crash when the remote image cannot be reached or takes too long to respond. Instead, Odoo shows a user-friendly error while still logging details for support teams to investigate.
Original PR description
Currently, multiple tracebacks are occurring when the tries to add an image through URL. Types of exceptions occurring currently are ConnectionError and TimeoutError. https://github.com/odoo/odoo/blob/e0584a789b4bca0ab0d6691642440eec04433332/addons/html_editor/controllers/main.py#L255 We can resolve this issue by showing a user exception and a logger warning(for debugging) instead of a traceback. sentry-6093300975
CodaBox connection management now shows a clear user-facing error when the selected accounting firm has no VAT number. This prevents a confusing technical crash and helps users correct the missing company information before continuing.
Original PR description
The system fails to retrieve vat number of accounting firm when computing `l10n_be_codabox_fiduciary_vat` field value Steps to Produce: 1. Install the `l10n_be_codabox` module and switch to `BE Company CoA` company. 2. Set Accounting firm without vat for BE Company CoA 3. Goto setting > Accounting section > CodaBox & SODA 4. Click `Manage Connection` or refresh icon of CodaBox Connection Error: `TypeError: expected string or bytes-like object, got 'bool'` Solution: Raise `UserError` if value of `account_representative_id.vat` is False Sentry - 6499169614
Odoo Studio now avoids crashing when a user saves a report after removing all report content. The change checks that the expected report element exists before trying to update it, so the save action can complete without an index error.
Original PR description
The error occurs when `main_qweb.xpath("//*[@id='wrapwrap']")[0]` is accessed,
but the XPath query returns an empty list. This leads to an `IndexError: list
index out of range`.
-Steps to produce:
1. Open Odoo Studio
2. Create an empty new report using studio
3. Click on EDIT SOURCES
4. Select studio customization in uses to edit report
5. remove all elements from <t t-name="studio_main_report">
6. click on save
Error: "IndexError: list index out of range"
-Solution:
Wrapped the XPath query inside a conditional check before accessing `[0]`.
Now, the code verifies whether the list is non-empty before proceeding with
element replacement.
If the element is missing, the operation is skipped, preventing the crash.
sentry-6197314021Users installing modules now receive a clean, understandable error if they upload a file that is not a valid ZIP archive. This prevents a technical crash message and improves the module installation experience.
Original PR description
The error could occur when a user uploads a non-ZIP or malformed ZIP file during module installation. The `zipfile.ZipFile` call raises `BadZipFile` when the file is invalid, but this was not properly caught in all cases. `Error: 'BadZipFile: File is not a zip file'` Solution: -Wrapped the `zipfile.ZipFile(BytesIO(zip_data), 'r')` and similar elements inside a `try...except` block to catch `BadZipFile` and raise a clean `ValidationError`, preventing unhandled exceptions and improving UX. sentry-6066860008
The PDF Quote Builder now blocks empty files before they are uploaded. This prevents users from hitting an error when configuring quotation headers or footers and keeps the setup flow smoother.
Original PR description
Currently, a error is encountered on uploading an empty file in a `PDF Quote Builder` . **Steps to reproduce:** - Install `Sales` - `Sales>Configuration>Settings` - Under `Quotations & Orders>PDF Quote builder>Headers/Footers`, upload an empty file or try this [demo_file](https://drive.google.com/file/d/1NePURnYY3EK63vXM_uz8weJZwDbUbHfc/view?usp=sharing) **Error:** `EmptyFileError: Cannot read an empty file` **Root Cause:** The error occurred because the system attempts to read the uploaded file at [1] triggered by [2]. If the uploaded file is empty, it raises an `EmptyFileError`. [1] - https://github.com/py-pdf/pypdf/blob/5735cb742a45a503e8eb7e409067f7c3d4cb9158/PyPDF2/pdf.py#L1691 [2] - https://github.com/odoo/odoo/blob/9463bfeb58fb40176ecf1131bac6627a1627d02c/odoo/tools/pdf/_pypdf2_1.py#L18 This commit ensures that users cannot upload empty files. sentry-6519503224,6519471276
A live chat rule with certain special characters in the URL field could cause the website to fail when opened. This update safely handles those characters so the website remains available even if a rule contains problematic input.
Original PR description
Setting special regex characters for`regex_url` inside live chat rules throws unhandled regex error.
**Steps to reproduce:**
- Install `website` and `im_livechat`
- Go to `livechat>YourWebsite.com Dropdown Menu>configure channel`
- Go to `channel rules>Add a line`
- Inside URL Regex field enter any of the quantifier regex such as `+`, `*`, `
`{any number}`, `[]`,`{any number range start,any number range limit}` and save
the rule.
-Open `website`.
Error:
`re.error: nothing to repeat at position 0`
**Solution:**
- We use `re.escape()` to safely handle user input that may contain special regex characters.
**Sentry-6538643923**Purchase bills in the Indian GSTR-2B workflow now return to a clean reconciliation state when reset to Draft. This prevents old return-period links or exceptions from carrying over, helping teams reconcile the bill correctly from the beginning.
Original PR description
When a purchase invoice (bill) is reset to Draft: - Reset GSTR-2B reconciliation status to "pending" - Unlink from GST return period - Clear any existing exceptions This ensures that the bill returns to its initial stage for proper reconciliation. Task ID: 5095582 Forward-Port-Of: odoo/enterprise#95026
Email Marketing now handles incorrectly encoded pasted images more gracefully when editing an email template. Instead of failing with a technical crash, the system can inform the user that the image content is invalid, helping prevent corrupted images from being used in mass mailings.
Original PR description
When user edits mail template html and pastes an image tag with invalid encoding it throws an error. **Steps to reproduce:** * Install Email marketing and activate developer mode. * Email…
When user edits mail template html and pastes an image tag with invalid encoding it throws an error. **Steps to reproduce:** * Install Email marketing and activate developer mode. * Email marketing>New>Mail Body> Start From Scratch>click `</>` icon * Paste any improper image element which doesn't have proper base64 encoding, for example: `<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU 5ErkJgg'/>` * Enter any Subject name and save. `binascii.Error: Invalid base64-encoded string: number of data characters (113) cannot be 1 more than a multiple of 4` **Solution:** * It would be better to let the user know about the error than to let them mass mail corrupted image element. * This can be done and handled by a try and except statement when the image element added is not proper. Sentry-6495526846 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents an unexpected error when users customize reports in Studio. It makes report editing more reliable by safely handling missing internal comparison data instead of interrupting the user workflow.
Original PR description
Currently, `KeyError: None` might occur when customizing the `Reports ` in **studio**. - The `KeyError` can occur in the `diff` method when the `DIFF_ATTRIBUTE` is absent in the `new_tree`. - This happens because the code at [1] attempts to access `self.map_id_to_node_old[new_tree.get(DIFF_ATTRIBUTE)]` without verifying if `new_tree.get(DIFF_ATTRIBUTE)` is `None`. [1]- https://github.com/odoo/enterprise/blob/c6148cd50e7446e43b3f327a4c25e7c0ffa03446/web_studio/controllers/keyed_xml_differ.py#L239 - This commit ensures the code handles cases where `DIFF_ATTRIBUTE` is missing and preventing KeyError. sentry-6430937782
Field service sales orders with zero-priced service lines now correctly move to an invoiced status once their related invoice is posted. This prevents orders from incorrectly remaining marked as needing invoicing, giving teams a clearer view of completed billing work.
Original PR description
Steps: - Install sale and fsm module. - Enable anglo-saxon from the setting. - Create a service type product with fsm project as template. - Select that product on SO and set unit price to 0 on SOL. - Confirm that order and create and post invoice. Issue: - Sale order status still shows `To invoice` even though we create SOL related invoice. Cause: - In [PR] we made invoice status for anglo-saxon line `To Invoice` so it always say `To Invoice` even user create related invoice. Fix: - Make those lines `Invoiced` if there is related invoice by checking qty_invoiced is greater or equal to qty. [PR]: https://github.com/odoo/enterprise/pull/70132 opw-5055540 Forward-Port-Of: odoo/enterprise#94723
Fixes an issue where automated cleanup of old Ecuador withholding wizard records could fail when related withholding lines still existed. This prevents background terminal errors and keeps scheduled maintenance running smoothly without affecting users in the interface.
Original PR description
Foreign key error occurs when a cron job deletes a `withhold (transient model)` still linked to a `withhold.line`. The error appears in the terminal, not the UI. To reproduce, ensure withhold records…
Foreign key error occurs when a cron job deletes a `withhold (transient model)` still linked to a `withhold.line`. The error appears in the terminal, not the UI. To reproduce, ensure withhold records in `l10n_ec_wizard_account_withhold` are old enough to be removed by `Auto-vacuum`. Refer to [this](https://github.com/odoo/odoo/blob/e062c9b5773ed0710503c13627e60f8233fcd0a5/odoo/models.py#L7493C1-L7493C87) to understand how transient models are cleaned by the `Auto-vacuum` process. **Steps to reproduce:** * Install `l10n_ec_edi` and `accountant` * Change company to `EC company` * `Accounting>Customers>Invoices>New` * Confirm invoice with customer as `EC company` and `Payment method (SRI)` as Credit card * Add Withhold > Set document number to `001-001-123456789` > Add withhold lines * `Create and Post`(error will occur when cron tries to delete transient model transient model after couple of hours.) `psycopg2.errors.ForeignKeyViolation:update or delete on table 'l10n_ec_wizard_account_withhold' violates foreign key constraint 'l10n_ec_wizard_account_withhold_line_wizard_id_fkey' on table 'l10n_ec_wizard_account_withhold_line'` **Solution:** * Unlink withhold lines first and then let normal unlink take place. **Sentry-6253783256**
This update adjusts spreadsheet-related testing assets to correct an issue in the FRGI test setup. It helps keep spreadsheet functionality more reliable by ensuring the relevant tests run as expected.
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
Sales orders now better identify coupon and global discount lines, so related integrations can report the correct discounted amount. This also prevents discount line values from being accidentally reset when their quantity changes, improving accuracy for order totals and delivery/payment workflows.
Original PR description
Issue ----- When using Shiprocket with the "Cash On Delivery", the request sent to the Shiprocket API doesn't contain the amounts discounted by coupons. Steps to reproduce ----- - Set an Indian…
Issue ----- When using Shiprocket with the "Cash On Delivery", the request sent to the Shiprocket API doesn't contain the amounts discounted by coupons. Steps to reproduce ----- - Set an Indian company up (with valid address and some dummy mail & phone) - Create a customer "IN Cust" (with valid address and some dummy mail & phone) - Create a product "IN Prod" - Sale price: 1000 INR - Weight: 100g - Set some reference, eg "INPROD" - Create a Shiprocket delivery method - Payment Method: COD - Set some "Shiprocket Channel" - Enable Debug requests - In settings, enable "Promotions, Loyalty & Gift Card" - Go to Sales > Products > Discount & Loyalty - Create a new program - Name: 50% off - Program Type: Coupons - Change the existing reward to 50% discount on order - Generate some coupon - Copy the code to the generated coupon - Create a SO our product and customer - Use the coupon code & apply the 50% discount - Add shipping - Shiprocket COD - Get rate - Confirm the SO - Go to the picking & validate it - Open logs (Settings/Technical/Database Structure/Logging) - Open the "shiprocket_request_external/shipments/create/forward-shipment" log --> total_discount is 0 Cause ----- The problem comes from https://github.com/odoo/enterprise/blob/a971f55e736f9645eda137fd6dcb574483886483/delivery_shiprocket/models/shiprocket_request.py#L301 There are 2 issues here. The first and most important one is how we find the discount lines. https://github.com/odoo/enterprise/blob/a971f55e736f9645eda137fd6dcb574483886483/delivery_shiprocket/models/shiprocket_request.py#L320 Discounts from coupons don't use the `sale_discount_product_id`, we'll have to define a new function to override in `sale_loyalty` for this. The second issue is that we use the untaxed discount amount. https://github.com/odoo/enterprise/blob/a971f55e736f9645eda137fd6dcb574483886483/delivery_shiprocket/models/shiprocket_request.py#L321 This leads to an incoherent total amount, since the tax is computed on the products' full prices. We should instead be forwarding the total discount value (with tax included to offset the taxes applied on the full product price). ----- Enterprise PR: https://github.com/odoo/enterprise/pull/92310 Ticket: opw-4755357 Forward-Port-Of: odoo/odoo#223517
Shiprocket cash-on-delivery shipments now include coupon-based discounts in the amounts sent to Shiprocket. This prevents customers and merchants from seeing incorrect COD totals when promotional coupons are applied, including tax-inclusive discount handling.
Original PR description
Issue ----- When using Shiprocket with the "Cash On Delivery", the request sent to the Shiprocket API doesn't contain the amounts discounted by coupons. Steps to reproduce ----- - Set an Indian…
Issue
-----
When using Shiprocket with the "Cash On Delivery", the request sent to the Shiprocket API doesn't contain the amounts discounted by coupons.
Steps to reproduce
-----
- Set an Indian company up (with valid address and some dummy mail & phone)
- Create a customer "IN Cust" (with valid address and some dummy mail & phone)
- Create a product "IN Prod"
- Sale price: 1000 INR
- Weight: 100g
- Set some reference, eg "INPROD"
- Create a Shiprocket delivery method
- Payment Method: COD
- Set some "Shiprocket Channel"
- Enable Debug requests
- In settings, enable "Promotions, Loyalty & Gift Card"
- Go to Sales > Products > Discount & Loyalty
- Create a new program
- Name: 50% off
- Program Type: Coupons
- Change the existing reward to 50% discount on order
- Generate some coupon
- Copy the code of the generated coupon
- Create a SO our product and customer
- Use the coupon code & apply the 50% discount
- Add shipping
- Shiprocket COD
- Get rate
- Confirm the SO
- Go to the picking & validate it
- Open logs (Settings/Technical/Database Structure/Logging)
- Open the "shiprocket_request_external/shipments/create/forward-shipment" log
--> total_discount is 0
Cause
-----
The problem comes from
https://github.com/odoo/enterprise/blob/a971f55e736f9645eda137fd6dcb574483886483/delivery_shiprocket/models/shiprocket_request.py#L301
There are 2 issues here.
The first and most important one is how we find the discount lines.
https://github.com/odoo/enterprise/blob/a971f55e736f9645eda137fd6dcb574483886483/delivery_shiprocket/models/shiprocket_request.py#L320
Discounts from coupons don't use the `sale_discount_product_id`. We can use the `_can_be_invoiced_alone` function to find both regular and loyalty discounts
https://github.com/odoo/odoo/blob/ee63fe7863dfa0083674dc927c1aa67c9e36c481/addons/sale/models/sale_order_line.py#L1033-L1041
def _can_be_invoiced_alone(self):
""" Whether a given line is meaningful to invoice alone.
It is generally meaningless/confusing or even wrong to invoice some specific SOlines
(delivery, discounts, rewards, ...) without others, unless they are the only left to invoice
in the SO.
"""
self.ensure_one()
return self.product_id.id != self.company_id.sale_discount_product_id.id
https://github.com/odoo/odoo/blob/ee63fe7863dfa0083674dc927c1aa67c9e36c481/addons/sale_loyalty/models/sale_order_line.py#L50-L51
def _can_be_invoiced_alone(self):
return super()._can_be_invoiced_alone() and not self.is_reward_line
We just have to be careful not to accidentally include delivery fees because of
https://github.com/odoo/odoo/blob/ee63fe7863dfa0083674dc927c1aa67c9e36c481/addons/delivery/models/sale_order_line.py#L18-L19
def _can_be_invoiced_alone(self):
return super()._can_be_invoiced_alone() and not self.is_delivery
The second issue is that we use the untaxed discount amount.
https://github.com/odoo/enterprise/blob/a971f55e736f9645eda137fd6dcb574483886483/delivery_shiprocket/models/shiprocket_request.py#L321
This leads to an incoherent total amount, since the tax is computed on the products' full prices. We should instead be forwarding the total discount value (with tax included to offset the taxes applied on the full product price).
-----
Community PR:
https://github.com/odoo/odoo/pull/223517
Ticket:
opw-4755357
Forward-Port-Of: odoo/enterprise#92310This fixes company filtering by country, which previously did not work because the country field could not be searched. Businesses using country-specific localizations, such as Belgium or Switzerland, can now apply company restrictions by country as intended.
Original PR description
As the company country_id field was computed and not searcheable, it was not possible to restrict the company domain per country. This is needed in some l10n, like BE or CH. This commit implements the search method for the country_id field of the company. Done as part of task-5096037 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
11 changes
Resolved issues and error corrections
Contacts in the Dominican Republic can now use valid 11-digit Cedula VAT identifiers, not only 9-digit RNC numbers. This prevents valid customer or company records from being incorrectly rejected during VAT checks.
Original PR description
**Issue** When inputting a VAT number with a length different from 9 digits, the check fails, even if the number is a valid Dominican RNC. **Steps to Reproduce** 1. Install Dominican localization and the VAT check module (base_vat), along with Contacts. 2. Go to Contacts, create a new contact for the Dominican Republic. 3. Insert "152-0000706-8" as the VAT. **Root Cause** The `check_vat_do` method only validated 9-digit RNC numbers via `stdnum.do.rnc.validate()`. 11-digit Cédula numbers are not supported. **Fix** - Updated `check_vat_do` to: * Validate 9-digit RNC numbers using `stdnum.do.rnc.validate()`. * Validate 11-digit Cédula numbers using `stdnum.luhn.validate()`. Opw-5004221 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Sign reminder process no longer fails when a document is sent without a “Valid Until” date. This keeps scheduled reminder emails running reliably and avoids error logs for affected signing requests.
Original PR description
Currently below error occurs when cron "Sign: Send mail reminder" is executed.
Error: `TypeError("'<' not supported between instances of 'bool' and
'datetime.date'") while evaluating 'model._cron_reminder()'`
### Steps to reproduce :-
- Open 'Sign' >> Go to 'Templates' >> Click 'Send' on a template.
- Set 'Valid Until' field as empty and 1 as the 'Reminder' >> click 'Send'.
- Run 'Schedule Action' (cron) **Sign: Send mail reminder** ( make sure it has
been 2/3 days since last reminder or change the date to 2/3 days from today.
- The error appears in the log.
This commit solves the above issue by making sure that `validity` is passed.
sentry-6168813276This fix prevents manufacturing work order planning from failing when no start date is available. If the start date is missing, the system now uses today’s date as a fallback, helping production scheduling continue without interruption.
Original PR description
The issue occurs when the system tries to convert different types of date or date objects into proper python datetime.datetime object but 'date_start' is False in vals at [1]. It might be write when…
The issue occurs when the system tries to convert different types of date or date objects into proper python datetime.datetime object but 'date_start' is False in vals at [1]. It might be write when `_plan_workorders` is executed and mrp workorder has not 'leave_id' [2]. The issue occurs when the system attempts to convert various date or date-related objects into a valid Python datetime.datetime object. However, at [1], 'date_start' in 'vals' is False [1]. This may be write when the '_plan_workorders' method is executed and the mrp workorder does not have a 'leave_id' [2]. Link [1]: https://github.com/odoo/odoo/blob/a848c3854c94b5c2b752edddbcf49337acf9d6ea/addons/mrp/models/mrp_production.py#L875 Link [2]: https://github.com/odoo/odoo/blob/a848c3854c94b5c2b752edddbcf49337acf9d6ea/addons/mrp/models/mrp_production.py#L1533-L1536 To resolve this, provide a default date as today if start date is not available Sentry-6255515427 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents an error in the accounting reconciliation wizard when journal items are not available to identify a company. The system now uses the current company as a safe fallback, helping users continue reconciliation without interruption.
Original PR description
The issue occurs when the system attempts to get a 'company_id' from the move line in the account reconciliation wizard, but the move lines are not available at [1]. Link [1]: https://github.com/odoo/enterprise/blob/0b8820aadfcdfaff4df4bbd26c161951fa95b67d/account_accountant/wizard/account_reconcile_wizard.py#L122 To resolve this, Provide a current company_id as default value if move lines are not available in the account reconciliation wizard. Sentry-6237590490
This fixes an issue where Accounting reports could crash if a report expression used an invalid subformula with the Aggregate Other Formulas engine. Instead of showing an error, the report now handles the invalid setup safely, improving reliability for users opening financial reports.
Original PR description
Currently, a traceback is occurring when the user tries to open a The report contains a subformula in the report expression that does not match. To reproduce this issue: 1) Install `Accounting` 2)…
Currently, a traceback is occurring when the user tries to open a The report contains a subformula in the report expression that does not match. To reproduce this issue: 1) Install `Accounting` 2) Open the `Profit & Losses` report and open any `line` 3) Add the subformula as `sum` for any `report expression` 4) Make sure the `Computation Engine` for expression as `Aggregate Other Formulas` 5) Now open the above report from the `Accounting Reporting` Error:- ``` AttributeError: 'NoneType' object has no attribute 'groupdict' ``` This error occurs when the user gives a subformula to the engine type `Aggregate Other Formulas`. Because it tries to match and group the subformula as `currency_1`, `amount_1`, `criterium`. To do this we need a valid subformula. https://github.com/odoo/enterprise/blob/0611a56074616bd935b0a9e5e7db98b23d8184f0/account_reports/models/account_report.py#L3007-L3013 When the user gives an invalid subformula, the regex results as None. which leads to the above traceback. We can resolve this issue by returning unbound_value if the regex is None. sentry-6325843987
The Product Routes Report now handles manufacturing routes that do not have a source location set. This prevents users from seeing an error when opening the route diagram for products configured for manufacturing.
Original PR description
This error occurs when users view the Product Routes Report. Steps to Reproduce: - Install the `mrp` modules. - Open `Products`. - In the Inventory tab, enable `Manufacture` in Routes. - Clear the `Production Location` field. - Click View `Diagram` in Routes. ValueError: False is not in list This error occurs because, in `Warehouse > Routes`, when a rule is created with the Manufacture action, the Source Location field is not required. However, when generating the Product Routes Report, the system attempts to access this field even if it is empty, resulting in an error. This commit ensures the Product Routes Report view correctly Sentry-6487434464 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Studio now shows a clear user-facing error when someone duplicates a report that points to a template that does not exist. This prevents an unclear system crash and helps users understand what needs to be corrected in the report setup.
Original PR description
This error occurs when a user duplicates the report using Studio. Steps to Reproduce: - Install the `web_studio` and `hr` modules. - Go to `Reporting > Reports`. - Click New, set the Model Name to hr.employee, and enter a non-existent template name like hr.demo in the Template Name field. - Go back and click the Studio icon. - Navigate to Employees > Reports, duplicate the newly created report. `ValueError: Expected singleton: ir.ui.view()` This error occurs because the user attempts to duplicate a report in Studio that references a non-existent template. This commit ensures that if a user duplicates a report with a non-existent template name, a UserError is raised. Sentry-6528691775
Website domain settings are now checked before they are saved, preventing invalid entries with spaces or overly long domain parts. This avoids errors when visitors or search engines access site files such as robots.txt and gives users a clear message to correct the domain.
Original PR description
The system did not previously validate the `website_domain` field, which could result in domains with invalid formats (e.g., containing spaces or exceeding the maximum acceptable length). The error is generated when the user sets the long domain and tries to access `/robot.txt`. **Steps to Produce:-** 1. Go to **Website's setting > set too long Domain > Save**. 2. Remove all after the first `/` from the URL and add **robots.txt**. **Error:-** `QWebException: Error while render the template` `UnicodeError: label too long` **Solution:-** - Added a constraint on the website_domain field. - The domain must: - Not contain any spaces. - Not exceed 71 characters. - Labels of domain should not exceed 63 characters. - A ValidationError is raised with a descriptive message if any of these conditions are violated. **sentry-6613845697** I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Kenyan eTIMS submissions no longer fail when a vendor bill includes an invoice line without tax. This prevents an error during submission and lets users continue processing valid vendor bills even when tax details are absent.
Original PR description
Currently, an error occurs when clicking the "Send to eTIMS" button on vendor bills. Steps to Reproduce: - Install the l10n_ke_edi_oscu module without demo data. - Create a new company with Kenya as the country and switch to it. - Go to Vendors > Bills, create a new bill, and add an invoice line without tax. - Confirm it, then click Send to eTIMS. StopIteration This error occurs because when the user removed the tax from the invoice line and clicked 'Send to eTIMS', the tax details got empty at [1]. As a result, no tax line is found using next(), which raises a StopIteration error. [1] https://github.com/odoo/enterprise/blob/e9cd1fa8c11d5d9a3dce7a8027a9ac9e19f44190/l10n_ke_edi_oscu/models/account_move.py#L234 This commit ensures that if there are no tax details present in the invoice line, the calculation of line_values is skipped for that case. sentry-6641334969
Swiss payroll now guides users to enter employee names in the expected first-name-then-last-name format. This also fixes the way legal first and last names are derived, helping SwissDEC payroll reports use the correct personal details.
Original PR description
* Add placeholder text to employee name field with Swiss cultural examples: "e.g. Roger Federer, Jean-Luc Godard, Johannna Spyri, ..." * Fix _compute_l10n_ch_legal_name method to correctly assign first_name and last_name from employee name (was previously reversed) * Update all SwissDEC test data to use correct "FirstName LastName" format instead of "LastName FirstName" to match the corrected computation logic task-5102851
This fix ensures timesheet reports correctly include related helpdesk ticket information when applicable. It resolves a prior report update that did not properly target the existing report section, helping users see the expected ticket context in exported or printed timesheet reports.
Original PR description
Description of the issue/feature this PR addresses: The previous commit attempted to extend the timesheet report to display tickets by using position="attributes" on a new . This approach does not work in Odoo reports because position="attributes" can only modify existing elements. There is no indication that the behavior of not displaying tickets was intentional, so this PR corrects that implementation. Current behavior before PR: The previous fix did not correctly locate the existing element for task/project info. Desired behavior after PR is merged: The existing is correctly found and updated to include show_ticket in its t-if.