Daily updates from Odoo
Saturday, July 26, 2025
35 changes
13 changes
Enhancements to existing features
Companies can now use a dedicated Peppol identifier that keeps activity in a local demo mode instead of contacting the real Peppol network. This makes it safer and easier to run training and trials while also improving scheduled processing for the correct company context.
Original PR description
When the company is registered with this particular EAS, Odoo will act as if it was in demo mode. No call to the real Peppol Network is performed, everything is mocked locally. This allows to do the trainings on /trial databases, and get the lastests improvements. Also fixing some crons that needed to be run with the right company. task-no (FP/WTA request) Forward-Port-Of: odoo/odoo#220641 Forward-Port-Of: odoo/odoo#219252
Online orders from UrbanPiper now show and calculate taxes more accurately based on the customer location and fiscal setup. This helps merchants avoid incorrect pricing or tax treatment, with special GST handling for India and clearer configuration expectations for other tax rates.
Original PR description
**: pos_urban_piper_zomato, pos_urban_piper_swiggy After this commit: --- - For orders outside India, price are received from UrbanPiper as tax-inclusive. Odoo now properly computes the unit price and applies taxes based on the fiscal position. - For India, special handling is implemented: - 5% GST is collected and paid by the aggregator, so only this tax is added via fiscal position mapping. - For other tax rates like 12% or 18%, the merchant is responsible, so these must be configured explicitly in the fiscal position. Note: --- - If a user does **not** want to receive a particular tax in the order, they must manually add a line for it in the fiscal position. Task: 4862417 Forward-Port-Of: odoo/enterprise#91036 Forward-Port-Of: odoo/enterprise#88118
Resolved issues and error corrections
Tax reports now calculate net amounts correctly when invoices use the same tax with different analytic distributions. This prevents undercounted or duplicated base values in grouped tax reports, improving accuracy for accounting and tax review.
Original PR description
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales…
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales (eg 10%) - Make sure the option "Analytic Accounting" is ticked in the settings - Create an invoice with a line, add the tax on it and change the analytic distribution - Do the same for another invoice with another analytic distribution - Confirm the invoices - Go to the tax report - Select the report "Group By: Account > Tax" - On the report the "Net" amount is only the one of the first invoice, the tax amount is correct ### Cause: The bug appeared after this [commit](https://github.com/odoo-dev/enterprise/commit/9a7142ef57503efad9538e571d2e35c4aaa59531) which fixed another issue with analytics. Now several lines with the same tax can be returned by the query if they have different analytics. This was used to avoid having the base amount doubled on the invoice when several lines from the same move had with different analytics: there is a line for each analytic but they all have the same base, in the end the base amounts was doubled for each different analytic. Now the query returns multiple lines but as they all have the same key the base amounts are not added together. This fixes the previous issue when several lines from the same move but with different analytics were added but it creates another issue when different invoices have the same tax and different analytic because these lines also have the same key. This result in only the base amount of the first invoice to be taken into account. ### Solution: The previous fix was incorrect. The correct fix is to not join the lines when there are two tax lines. To do this the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line_tax_details.py#L153) in the query needs to be the same as the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line.py#L984) that will duplicate the lines in python. The check on `use_in_tax_closing` was missing so we add it. opw-4766421 Forward-Port-Of: odoo/odoo#220662 Forward-Port-Of: odoo/odoo#220394
Sales quotations and orders now calculate fixed taxes correctly when an early payment discount is applied. This prevents fixed tax amounts from being doubled on discounted payment terms, improving invoice and quote accuracy.
Original PR description
### Issue: The fixed tax value is doubled in `sale` when an early payment discount is applied. Steps to reproduce: - Create a fixed tax of $20 for example - Create a payment term with an early…
### Issue: The fixed tax value is doubled in `sale` when an early payment discount is applied. Steps to reproduce: - Create a fixed tax of $20 for example - Create a payment term with an early discount of 10% if paid before 10 days - Select "Always (upon invoice)" - In Sale create a new quotation with a line of $100 and the fixed tax - Select the created payment term - The tax value is doubled ($40) ### Cause: To compute the payment terms `_add_base_lines_for_early_payment_discount` (added in this [commit](https://github.com/odoo/odoo/commit/781678fb07ab3dd4d132193a938bbb71e8395424)) is adding two lines: - one with the negative amount of the payment term and the taxes - one with the positive amount of the payment term The goal is to compute the taxes on the discounted untaxed amount of the line. The original line compute the taxes for the undiscounted amount. The first added line computes the taxes for the amount of the discount and is negative. When adding the two the result is the tax value computed from the discounted untaxed amount. The issue is that a fixed will always have the same value, this means that the tax amount of the first added line will be positive and the same as the original line. When adding the two the amount is doubled. ### Solution: We don't add taxes with fixed amount on the first add line. opw-4868011 Forward-Port-Of: odoo/odoo#220545 Forward-Port-Of: odoo/odoo#218816
Odoo now blocks users from archiving a pricelist that is still tied to an active loyalty or promotional program. This prevents discount codes from appearing invalid because their linked pricelist was hidden but still active in the background.
Original PR description
**Step to Reproduce:** 1. Install `sale_loyalty` and `sale` 2. Enable the `Pricelists` option in the settings. 3. Create a pricelist named demo. 4. Create a Discount & Loyalty named `test program`…
**Step to Reproduce:**
1. Install `sale_loyalty` and `sale`
2. Enable the `Pricelists` option in the settings.
3. Create a pricelist named demo.
4. Create a Discount & Loyalty named `test program` with type `Discount Code`,
5. Assign the demo pricelist to the loyalty program.
6. Copy the discount code from the program’s conditional rules.
7. Archive the demo pricelist.
8. create sale order for any product.
9. Try to apply the copied coupon code.
**Observation:**
- An error is shown: "This code is invalid".
- check loyalty program `test program` pricelist field is empty, that suggesting it's valid for all pricelists, but the coupon still fails.
**Issue:**
- When a linked pricelist is archived, it's hidden in the UI, but the relation still exists in the relational table.
```17_sale=# select id,name,active from product_pricelist;
id | name | active
----+------------------------------------+--------
1 | {"en_US": "Default USD pricelist"} | t
2 | {"en_US": "new"} | f
(2 rows)
17_sale=# select * from loyalty_program_product_pricelist_rel;
loyalty_program_id | product_pricelist_id
--------------------+----------------------
5 | 2
(1 row)
```
- While filtering the domain for coupon, the condition is not satisfied due to the program's pricelist.
https://github.com/odoo/odoo/blob/94d727bd9ba38116d3e14188c730c7566744e9f0/addons/sale_loyalty/models/sale_order.py#L636-L647
**Solution:**
- Display a validation error to the user when trying to archive a pricelist
that is linked to any active promotional programs.
opw-4841678
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#220301
Forward-Port-Of: odoo/odoo#214968This change prevents upgrade failures for companies using Documents with their own email alias domains. It ensures new email aliases are created using the correct company context, avoiding validation errors caused by mismatched company domains.
Original PR description
**Step to reproduce:** 1. Install documents in version 17.0. 2. create new company for that create document folder and set alias_domain 3. upgrade to 18.0 below menitoned traceback will raise…
**Step to reproduce:**
1. Install documents in version 17.0.
2. create new company for that create document folder and set alias_domain
3. upgrade to 18.0 below menitoned traceback will raise
**Issue** :-
previously fix was deployed https://github.com/odoo/upgrade/commit/edae53792f81859dd4c843d8da4307e4eae8e0ff in the upgrade forcefully creating the incoming mails.
**Cause** :-
``mail.alias.mixin`` is introduced in existing [model]( https://github.com/odoo/enterprise/commit/a32825ee00f2b330d99113f4d8c1488903fe744e#diff-b394e0e6aa5c87ff7d84c0317fa2ed372a90b7d3e730c462fcb81d4b747f46ebL34) As ``alias_id`` is kept as false according to this new alias records are creating but as it sudo it bringing all company records due to this and during upgrade env company is admin related company which is letting alias_domain_id [here](https://github.com/odoo/odoo/blob/9719feb1fac64e06c988b336b077a0aa47a2b96a/addons/mail/models/mail_alias.py#L262) of that company which is leading to validation error
**Fix:**
for fixing this is record have company_id so create mail alias
according to that
```
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/service/server.py", line 1361, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-13>", line 2, in new
File "/home/odoo/src/odoo/18.0/odoo/tools/func.py", line 97, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 129, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 480, in load_modules
processed_modules += load_marked_modules(env, graph,
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 365, in load_marked_modules
loaded, processed = load_module_graph(
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 206, in load_module_graph
registry.init_models(env.cr, model_names, {'module': package.name}, new_install)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 617, in init_models
func()
File "/home/odoo/src/odoo/18.0/addons/mail/models/mail_alias_mixin.py", line 49, in _init_column_alias_id
alias = self.env['mail.alias'].sudo().create(record._alias_get_creation_values())
File "<decorator-gen-136>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 495, in _model_create_multi
return create(self, [arg])
File "/home/odoo/src/odoo/18.0/addons/mail/models/mail_alias.py", line 266, in create
return super().create(vals_list)
File "<decorator-gen-120>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 496, in _model_create_multi
return create(self, arg)
File "/tmp/tmppqp1_15u/migrations/util/orm.py", line 249, in wrapper
return f(*args, **kwargs)
File "/tmp/tmppqp1_15u/migrations/base/0.0.0/pre-models-match_uniq.py", line 25, in create
return super().create(vals_list)
File "<decorator-gen-31>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 496, in _model_create_multi
return create(self, arg)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5017, in create
records = self._create(data_list)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5275, in _create
records._validate_fields(name for data in data_list for name in data['stored'])
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 1631, in _validate_fields
check(self)
File "/home/odoo/src/odoo/18.0/addons/mail/models/mail_alias.py", line 159, in _check_alias_domain_id_mc
raise ValidationError(_(
odoo.exceptions.ValidationError: We could not create alias Inactive Alias because domain bsiri.co.th belongs to company BSIRI Company Limited (HeadOffice) while the owner document belongs to company MindGift LL>
```
upg-3017582
opw-4941387
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#219223This update prevents invalid empty discount details from being added when preparing electronic invoices. It reduces the risk of invoice generation or sending failures for Nilvera e-invoicing users.
Original PR description
Description of the issue/feature this PR addresses: Fixes an issue in the _add_document_line_allowance_charge_nodes function in the account_edi_ubl_cii module. Previously, the function assigns a list…
Description of the issue/feature this PR addresses: Fixes an issue in the _add_document_line_allowance_charge_nodes function in the account_edi_ubl_cii module. Previously, the function assigns a list containing None to the 'cac:AllowanceCharge' key when the discount node was not applicable. This led to errors when attempting to assign values to 'cbc:AllowanceChargeReasonCode', as accessing properties on a None object will cause an error in l10n_tr_nilvera_einvoice under the _add_document_line_allowance_charge_nodes function. TypeError: 'NoneType' object does not support item assignment Current behavior before PR: The _add_document_line_allowance_charge_nodes function throws an error when generating or sending an E-Invoice to Nilvera, due to [None] being present in 'cac:AllowanceCharge'. Desired behavior after PR is merged: Ensure 'cac:AllowanceCharge' is only added to line_node when the returned node is valid or just an empty list. This avoids [None] values in the list and prevents assignment errors. Task: 4886128 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixes an issue where reducing the quantity of a sales order for a kit with dropshipped components could create incorrect negative purchase quantities. Purchase orders now keep the correct component quantities, helping avoid supplier order errors and fulfillment delays.
Original PR description
…d comp **Problem:** when updating the quantity of a sale order line for a kit whose components are dropshipped, the update of the quantity of the linked Purchase order lines is wrongly computed…
…d comp **Problem:** when updating the quantity of a sale order line for a kit whose components are dropshipped, the update of the quantity of the linked Purchase order lines is wrongly computed **Steps to reproduce:** - enable the dropshipping setting - create a new storable product - in the purchase tab set a vendor - in the inventory tab check only the dropship route - repeat these operations for another product - create a third storable product - create a BOM for this product and set it as "kit" - add the two first products you created in the components - create a new quotation for the kit product, set a quantity of 25 and confirm - modify the quantity to 10 and save - click on the purchase smart button **Current behavior:** the quantities of the two purchase order lines have been updated to -15 **Expected behavior:** it should be 10 **Cause of the issue:** When we change the quantity on the sale order line: The method action_stock_rule from SaleOrderLine is triggered. It will create a procurement: https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/sale_stock/models/sale_order_line.py#L338 To compute the quantity used for this procurement,the computation is : product_qty = line.product_uom_qty - qty where qty is line._get_qty_procurement https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/sale_stock/models/sale_order_line.py#L313 The error comes from the _get_qty_procurement - The "normal" behaviour of _get_qty_procurement is to compute the difference between outgoing moves and incoming moves https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/sale_stock/models/sale_order_line.py#L253-L263 - Basic _get_qty_procurement wouldn't work for a kit as a move is created for each components. So there is an override of the method to handle this case https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/sale_mrp/models/sale_order_line.py#L128-L141 this override calls _compute_kit_quantities on the stock moves linked to the sale order line via its move_ids attribute. _compute_kit_quantities does a computation of the ratios for each component and returns the minimum - Basic _get_qty_procurement wouldn't work either for a dropshipped product as no move is created when confirming the sale order. So there is another override of the method to compute this case https://github.com/odoo/odoo/blob/2e7fd1c45a0f68d123e85c95f3eb3a7fd5395527/addons/stock_dropshipping/models/sale.py#L42-L51 This override uses the purchase order line linked to the sale order line via its purchase_line_ids to compute the quantity. Neither of those two overrides would work for a kit with dropshipped components. The first one would fail because no stock moves are created. The second one would fail because adding the value of each purchase order line created returns a value too high **fix** for this specific case we just take the previous quantity opw-4743482 Forward-Port-Of: odoo/odoo#217070 Forward-Port-Of: odoo/odoo#211726
Order transfers in Point of Sale and Restaurant now work reliably, including floating orders and table-based orders. This prevents errors during service and helps staff move orders between tables or tickets without interruption.
Original PR description
While transferring a floating order to another or a table, a traceback was raised. Is now possible to transfer orders to anything independent of the table or order type. taskId: 4948719 Forward-Port-Of: odoo/odoo#219236
This fix prevents a failed website builder action from disrupting the whole editor. It also rolls back unsuccessful changes so pages are not left in an inconsistent state, improving reliability for content editors.
Original PR description
The goal of this commit is to better manage the apply fail of a BuilderAction. 1. Previewing an action that fails should not block the entire editor. 2. Apply an action that fails must be reverted to avoid leaving invalid mutations in the dom. 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
HR officers can now use the Employees app's Load Sample Data button without running into an access error. This prevents setup interruptions when authorized HR users are preparing or testing employee records.
Original PR description
Currently, an error occurs when a user with Officer access rights attempts to load sample data in the Employees app. **Steps to reproduce:** - Install the HR app without demo data. - Delete the…
Currently, an error occurs when a user with Officer access rights attempts to load sample data in the Employees app.
**Steps to reproduce:**
- Install the HR app without demo data.
- Delete the Administrator employee record.
- Create a new user and assign the access right "Office: Manage All Employees".
- Log in with the newly created user.
- Open the Employees app and click on the Load Sample Data button.
**Traceback:**
```
AccessError
Ops! Parece que você se deparou com alguns registros ultrassecretos.
Desculpe, Wendel Xavier de Miranda (id=2) não tem 'criar' acesso a:
- Contato (res.partner)
Se você realmente precisar de acesso, talvez valha a pena tentar conquistar o administrador com uns pães de queijo.
Esse parece ser um problema de várias empresas. Talvez seja possível acessar o registro mudando para a empresa: WM SERVICOS TECNICOS E COMISSIONAMENTO LTDA.
ParseError
while parsing /home/odoo/src/odoo/saas-18.4/addons/hr/data/scenarios/hr_scenario.xml:79, somewhere inside <record id="work_contact_eg" model="res.partner" forcecreate="1"> ...
ValueError - ParseError('while parsing /home/odoo/src/odoo/saas-18.4/addons/hr/data/scenarios/hr_scenario.xml:79 ....
```
**Cause:**
The issue occurs because the user doesn’t have the required rights to create res partner records when loading sample data.
**Fix:**
This commit resolves the issue by granting the user superuser rights.
sentry-6751634609Fixes tax reports grouped by account and tax so invoices using the same tax with different analytic distributions show the correct net amount. This prevents understated or duplicated tax base values, improving accuracy for accounting and tax reporting.
Original PR description
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales…
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales (eg 10%) - Make sure the option "Analytic Accounting" is ticked in the settings - Create an invoice with a line, add the tax on it and change the analytic distribution - Do the same for another invoice with another analytic distribution - Confirm the invoices - Go to the tax report - Select the report "Group By: Account > Tax" - On the report the "Net" amount is only the one of the first invoice, the tax amount is correct ### Cause: The bug appeared after this [commit](https://github.com/odoo-dev/enterprise/commit/9a7142ef57503efad9538e571d2e35c4aaa59531) which fixed another issue with analytics. Now several lines with the same tax can be returned by the query if they have different analytics. This was used to avoid having the base amount doubled on the invoice when several lines from the same move had with different analytics: there is a line for each analytic but they all have the same base, in the end the base amounts was doubled for each different analytic. Now the query returns multiple lines but as they all have the same key the base amounts are not added together. This fixes the previous issue when several lines from the same move but with different analytics were added but it creates another issue when different invoices have the same tax and different analytics. Because these lines also have the same key. This result in only the base amount of the first invoice to be taken into account. ### Solution: The previous fix was incorrect. The correct fix is to not join the lines when there are two tax lines. To do this the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line_tax_details.py#L153) in the query needs to be the same as the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line.py#L984) that will duplicate the lines in python. The check on `use_in_tax_closing` was missing so we add it. opw-4766421 Forward-Port-Of: odoo/enterprise#91065 Forward-Port-Of: odoo/enterprise#90936
Users with Planning access but no Employee permissions can now open role configuration without hitting an access error. This keeps planning setup usable for authorized planning users while still respecting employee access restrictions.
Original PR description
Trying to display the roles in the planning app is not possible if the user doesn't have hr_rights even with full planning rights. ** Step to reproduce ** - Connect to Odoo with an user that only have acces right for "Planning" (no employees). - Open Planning app - Configuration>Roles - It will trigger an Access Error (If it didn't trigger add a user to Ressources) ** Cause of the issue ** The acces for the default_role_id is limited to hr.group_hr_user: https://github.com/odoo/enterprise/blob/a7122011a0b0cdd111eccf59c917c6b8e2c25137/planning/models/resource_resource.py#L27 But is used in _compute_display_name: https://github.com/odoo/enterprise/blob/a7122011a0b0cdd111eccf59c917c6b8e2c25137/planning/models/resource_resource.py#L73 ** Fix ** Retrieve the information about the role with sudo opw-4908979 Forward-Port-Of: odoo/enterprise#90243
5 changes
Enhancements to existing features
Odoo can now use a special Peppol identifier that keeps trial or training databases in a safe demo mode. This prevents real Peppol network calls while still letting users practice the latest Peppol workflows, and related scheduled jobs now run under the correct company context.
Original PR description
When the company is registered with this particular EAS, Odoo will act as if it was in demo mode. No call to the real Peppol Network is performed, everything is mocked locally. This allows to do the trainings on /trial databases, and get the lastests improvements. Also fixing some crons that needed to be run with the right company. task-no (FP/WTA request) Forward-Port-Of: odoo/odoo#220544 Forward-Port-Of: odoo/odoo#219252
Online orders received through UrbanPiper, Zomato, and Swiggy now show and calculate taxes more accurately based on the customer's country and the configured fiscal position. This helps merchants apply the right tax responsibility, especially for Indian GST scenarios where aggregators and merchants may handle different tax rates.
Original PR description
**: pos_urban_piper_zomato, pos_urban_piper_swiggy After this commit: --- - For orders outside India, price are received from UrbanPiper as tax-inclusive. Odoo now properly computes the unit price and applies taxes based on the fiscal position. - For India, special handling is implemented: - 5% GST is collected and paid by the aggregator, so only this tax is added via fiscal position mapping. - For other tax rates like 12% or 18%, the merchant is responsible, so these must be configured explicitly in the fiscal position. Note: --- - If a user does **not** want to receive a particular tax in the order, they must manually add a line for it in the fiscal position. Task: 4862417 Forward-Port-Of: odoo/enterprise#90977 Forward-Port-Of: odoo/enterprise#88118
Resolved issues and error corrections
Fixed an issue where tax reports grouped by account and tax could show an incorrect net amount when invoices used the same tax with different analytic distributions. This helps businesses rely on accurate tax reporting when analytic accounting is enabled.
Original PR description
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales…
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales (eg 10%) - Make sure the option "Analytic Accounting" is ticked in the settings - Create an invoice with a line, add the tax on it and change the analytic distribution - Do the same for another invoice with another analytic distribution - Confirm the invoices - Go to the tax report - Select the report "Group By: Account > Tax" - On the report the "Net" amount is only the one of the first invoice, the tax amount is correct ### Cause: The bug appeared after this [commit](https://github.com/odoo-dev/enterprise/commit/9a7142ef57503efad9538e571d2e35c4aaa59531) which fixed another issue with analytics. Now several lines with the same tax can be returned by the query if they have different analytics. This was used to avoid having the base amount doubled on the invoice when several lines from the same move had with different analytics: there is a line for each analytic but they all have the same base, in the end the base amounts was doubled for each different analytic. Now the query returns multiple lines but as they all have the same key the base amounts are not added together. This fixes the previous issue when several lines from the same move but with different analytics were added but it creates another issue when different invoices have the same tax and different analytics. Because these lines also have the same key. This result in only the base amount of the first invoice to be taken into account. ### Solution: The previous fix was incorrect. The correct fix is to not join the lines when there are two tax lines. To do this the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line_tax_details.py#L153) in the query needs to be the same as the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line.py#L984) that will duplicate the lines in python. The check on `use_in_tax_closing` was missing so we add it. opw-4766421 Forward-Port-Of: odoo/enterprise#91065 Forward-Port-Of: odoo/enterprise#90936
Planning users without Employee app permissions can now open and view role configuration without encountering an access error. This keeps planning administration available to users who have the right Planning permissions, even if they do not manage employee records.
Original PR description
Trying to display the roles in the planning app is not possible if the user doesn't have hr_rights even with full planning rights. ** Step to reproduce ** - Connect to Odoo with an user that only have acces right for "Planning" (no employees). - Open Planning app - Configuration>Roles - It will trigger an Access Error (If it didn't trigger add a user to Ressources) ** Cause of the issue ** The acces for the default_role_id is limited to hr.group_hr_user: https://github.com/odoo/enterprise/blob/a7122011a0b0cdd111eccf59c917c6b8e2c25137/planning/models/resource_resource.py#L27 But is used in _compute_display_name: https://github.com/odoo/enterprise/blob/a7122011a0b0cdd111eccf59c917c6b8e2c25137/planning/models/resource_resource.py#L73 ** Fix ** Retrieve the information about the role with sudo opw-4908979 Forward-Port-Of: odoo/enterprise#90243
Fixes an issue where tax reports could show incorrect net amounts when invoices used the same tax with different analytic distributions. This helps ensure grouped tax reports reflect the full taxable base, improving reliability for accounting and reporting.
Original PR description
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales…
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales (eg 10%) - Make sure the option "Analytic Accounting" is ticked in the settings - Create an invoice with a line, add the tax on it and change the analytic distribution - Do the same for another invoice with another analytic distribution - Confirm the invoices - Go to the tax report - Select the report "Group By: Account > Tax" - On the report the "Net" amount is only the one of the first invoice, the tax amount is correct ### Cause: The bug appeared after this [commit](https://github.com/odoo-dev/enterprise/commit/9a7142ef57503efad9538e571d2e35c4aaa59531) which fixed another issue with analytics. Now several lines with the same tax can be returned by the query if they have different analytics. This was used to avoid having the base amount doubled on the invoice when several lines from the same move had with different analytics: there is a line for each analytic but they all have the same base, in the end the base amounts was doubled for each different analytic. Now the query returns multiple lines but as they all have the same key the base amounts are not added together. This fixes the previous issue when several lines from the same move but with different analytics were added but it creates another issue when different invoices have the same tax and different analytic because these lines also have the same key. This result in only the base amount of the first invoice to be taken into account. ### Solution: The previous fix was incorrect. The correct fix is to not join the lines when there are two tax lines. To do this the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line_tax_details.py#L153) in the query needs to be the same as the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line.py#L984) that will duplicate the lines in python. The check on `use_in_tax_closing` was missing so we add it. opw-4766421 Forward-Port-Of: odoo/odoo#220662 Forward-Port-Of: odoo/odoo#220394
13 changes
New functionality added to Odoo
Users can now bring survey results directly into Odoo spreadsheets using a new survey spreadsheet feature. This makes it easier for teams to analyze feedback, share insights, and build reports without exporting data to external tools.
Original PR description
This commits adds a new module `documents_spreadsheet_survey` that implements the `ODOO.SURVEY` function in the spreadsheet. This function allow to display survey results in a spreadsheet. Task: [3600662](https://www.odoo.com/web#id=3600662&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form)
Enhancements to existing features
Odoo Studio's report editor now makes it easier to select and reuse dynamic report fields by preserving their underlying expressions when copied and pasted. Formatting controls are also disabled where they could create conflicting report rules, helping users avoid unexpected layout issues.
Original PR description
This commit improves a few things in the report editor: - A node that is a t-field/t-out/t-esc is fully selected on click - that kind of node can now be copied/pasted, the expression and the human readable expression will be kept. - When selecting t-att-[class|style] nodes, the toolbar disables the formatting options. This is because in QWeb python, the t-att- overrides completely the static attribute definition and because it is too cumbersome to merge a string (style, class) with an expression. task-4914489
Task dependency links in the Gantt planning view are now easier to see when users hover over them. This helps project teams quickly understand which tasks are connected and plan work with less confusion.
Original PR description
This commit's purpose is to highlight the dependencies in the gantt view. When the user hover a link, the link and the linked tasks are now displayed more clearly. task-4613169
The checkout process for Chilean and Mexican eCommerce customers now skips an unnecessary confirmation page. This reduces extra clicks and helps shoppers move more directly from checkout to payment.
Original PR description
Description of the issue/feature this PR addresses: Streamlines the eCommerce checkout by removing the /shop/confirm_order route. Current behavior before PR: The checkout flow includes a redundant confirmation step (/shop/confirm_order), adding unnecessary complexity and extra user interaction. Desired behavior after PR is merged: Checkout proceeds directly from /shop/checkout to /shop/payment.. SEE ALSO: - Community PR:https://github.com/odoo/odoo/pull/204977 - Upgrade PR: https://github.com/odoo/upgrade/pull/7699 Affected version - master Task-4676202
Odoo now relies on a more reliable file type detection library on supported systems, reducing mistakes when identifying uploaded spreadsheet files. This helps prevent valid Excel imports from being confused with compressed files and fixes a corrupted sample import file used by accounting import tests.
Original PR description
The python3-magic is a undeclared POSIX-only dependency used in odoo.tools.mimetypes to determine the mimetype of a file given its content. It uses magic(5) as backend, which is not available on Windows. When the library is missing, it fallbacks on our own (very bad) pure-python magic implementation, which fail to distinguate .xlsx and .zip files apart may the file be larger than 1kB. Community: https://github.com/odoo/odoo/pull/219284
Field Service wording is updated from "worker" to "technician" across related screens, reports, and sales reporting areas. This makes the language clearer and better aligned with how service teams describe the people assigned to on-site jobs.
Original PR description
task-4801707
Resolved issues and error corrections
This update fixes how fixed-amount Cuota taxes are reported on Mexican electronic invoices, ensuring the tax rate, base quantity, and amount match official requirements. It reduces the risk of incorrect tax documents and also tidies related tests to make future validation easier.
Original PR description
**[FIX] l10n_mx_edi: Fix wrong management of Cuota taxes** Cuota taxes are wrongly reported. For example, a GAZ cuota tax expressed as 4.6555 per quantity has to be reported as TasaOCuota=4.6555 Base=quantity Importe=TasaOCuota * Base Currently, it's reported as: TasaOCuota=abs(tax_amount_currency/base_amount_currency) Base=base_amount_currency Importe is recomputed as TasaOCuota * Base instead of tax_amount_currency task-id: 4761658 **[IMP] l10n_mx_edi: Make test suite a bit less messy** Having a single test testing all taxes combination, testing 100% discount on it + IEPS breakdown and global invoice makes the whole thing difficult to debug. Also, it forces the generation of files that are not always relevant. Forward-Port-Of: odoo/enterprise#89801 Forward-Port-Of: odoo/enterprise#88357
Self-service orders now reach the preparation display only after payment succeeds when an online or terminal payment method is configured. This prevents staff from preparing unpaid orders, while still allowing mobile self-orders without online payment setup to be prepared as before.
Original PR description
pos_self_order*: pos_online_payment_self_order_preparation_display, pos_self_order_preparation_display Ensure self-orders are sent to the preparation display only after a successful payment, when a…
pos_self_order*: pos_online_payment_self_order_preparation_display, pos_self_order_preparation_display Ensure self-orders are sent to the preparation display only after a successful payment, when a valid payment method is configured. **Issue 1: Orders sent for preparation before successful payment** **Steps:** - Configure the kiosk with an online or terminal payment method. - Open the kiosk, add products, and proceed to payment. **Issue:** - Preparation orders were being sent even if the payment was not completed. **Fix:** - Restrict preparation flow to only orders with a successful payment when a valid payment method is configured. --- **Issue 2: Orders not sent for preparation in mobile mode without the online method** - Allow unpaid orders to be sent for preparation only in mobile mode when no online payment method is configured. Task-4845410 Related: https://github.com/odoo/odoo/pull/213493 Forward-Port-Of: odoo/enterprise#90923 Forward-Port-Of: odoo/enterprise#87173
Customers who receive a shared helpdesk ticket or a message about one are now automatically added as followers. This ensures they can view the ticket in the portal without extra manual steps, reducing access issues and follow-up work for support teams.
Original PR description
Before this commit, when a ticket was shared through the share wizard or when a message was sent to a customer via the chatter, the recipients were not added as followers of the ticket. As a result, they couldn't see the ticket in the portal. This commit ensures: - Recipients are now added as followers of the ticket when it is shared with them through the wizard. - A message to a customer in the chatter also adds them as a follower of the ticket. task-4781259 Forward-Port-Of: odoo/enterprise#90947 Forward-Port-Of: odoo/enterprise#86169
Membership benefits now apply correctly when a parent company or contact purchases or loses membership. Parent memberships are passed to child contacts, while child purchases stay with that child, preventing incorrect pricing or commission benefits from being retained.
Original PR description
Corrects the behaviour of the member level assignment in membership when childs partners are concerned. A partner buying a membership should forward the membership level and Pricelist to its children. A child buying a membership should get that membership without forwarding it to its parent. When removed, children should not keep the membership if the parent lose it. TASK-4801759 Forward-Port-Of: odoo/enterprise#86776
Colombian electronic invoices now send invoice type codes in the two-character format required by DIAN. This prevents rejections caused by incorrectly formatted EDI types and helps businesses submit invoices more reliably.
Original PR description
The DIAN endpoint only accepts Electronic Invoice types with a length of 2 characters. This fix adds zero-padding to the problematic edi types. task: 4882683 Forward-Port-Of: odoo/enterprise#89925
Users with Planning access but without Employee permissions can now open and view planning roles without encountering an access error. This ensures planning-only users can use the role configuration area as expected while keeping employee access restrictions in place.
Original PR description
Trying to display the roles in the planning app is not possible if the user doesn't have hr_rights even with full planning rights. ** Step to reproduce ** - Connect to Odoo with an user that only have acces right for "Planning" (no employees). - Open Planning app - Configuration>Roles - It will trigger an Access Error (If it didn't trigger add a user to Ressources) ** Cause of the issue ** The acces for the default_role_id is limited to hr.group_hr_user: https://github.com/odoo/enterprise/blob/a7122011a0b0cdd111eccf59c917c6b8e2c25137/planning/models/resource_resource.py#L27 But is used in _compute_display_name: https://github.com/odoo/enterprise/blob/a7122011a0b0cdd111eccf59c917c6b8e2c25137/planning/models/resource_resource.py#L73 ** Fix ** Retrieve the information about the role with sudo opw-4908979 Forward-Port-Of: odoo/enterprise#90243
Tax reports now calculate net amounts correctly when invoices use the same tax with different analytic distributions. This prevents undercounted or duplicated taxable bases in grouped tax reports, improving accuracy for accounting and tax review.
Original PR description
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales…
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales (eg 10%) - Make sure the option "Analytic Accounting" is ticked in the settings - Create an invoice with a line, add the tax on it and change the analytic distribution - Do the same for another invoice with another analytic distribution - Confirm the invoices - Go to the tax report - Select the report "Group By: Account > Tax" - On the report the "Net" amount is only the one of the first invoice, the tax amount is correct ### Cause: The bug appeared after this [commit](https://github.com/odoo-dev/enterprise/commit/9a7142ef57503efad9538e571d2e35c4aaa59531) which fixed another issue with analytics. Now several lines with the same tax can be returned by the query if they have different analytics. This was used to avoid having the base amount doubled on the invoice when several lines from the same move had with different analytics: there is a line for each analytic but they all have the same base, in the end the base amounts was doubled for each different analytic. Now the query returns multiple lines but as they all have the same key the base amounts are not added together. This fixes the previous issue when several lines from the same move but with different analytics were added but it creates another issue when different invoices have the same tax and different analytics. Because these lines also have the same key. This result in only the base amount of the first invoice to be taken into account. ### Solution: The previous fix was incorrect. The correct fix is to not join the lines when there are two tax lines. To do this the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line_tax_details.py#L153) in the query needs to be the same as the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line.py#L984) that will duplicate the lines in python. The check on `use_in_tax_closing` was missing so we add it. opw-4766421 Forward-Port-Of: odoo/enterprise#91065 Forward-Port-Of: odoo/enterprise#90936
4 changes
Resolved issues and error corrections
Invoice rounding differences are now spread across invoice lines instead of being applied to a single line. This helps generated UBL/Peppol invoices stay within validation limits and reduces the risk of rejected electronic invoices.
Original PR description
Before this commit, the behaviour of `_round_base_lines_tax_details` was to assign all the base line delta to the largest base line. However, when generating the UBL, the delta would then get included in the LineExtensionAmount, but BIS3 rule PEPPOL-EN16931-R120 enforces that the LineExtensionAmount must be at most 2 cents away from `(quantity * net price) + sum(charges) - sum(allowances)`. Effectively this means that we can put at most 2 cents base delta on each invoice line. After this commit, `_round_base_lines_tax_details` redistributes the base delta evenly over all the base lines. task-none
This fix prevents the same point-of-sale order from being sent to preparation printers by multiple devices. It checks whether an order was already sent and synchronizes the order after printing, reducing duplicate tickets and kitchen confusion.
Original PR description
Before this change, when a device sent an order in preparation via the ticket printer, this could result in the same order being printed by multiple devices, as the order was not synchronized after it was sent. The error is a bit tricky, because if the user had installed a preparation screen, the order was sent to the preparation screen via syncAllOrders. In this case, the order was correctly synchronized and the other devices were informed of the changes. This commit adds two things. - We check the server before sending the order to preparation to make sure it has not already been sent. - Even when the user does not have a preparation display, the order will be synchronized after being sent to a printer.
This fix prevents the same point-of-sale order from being sent to preparation printers by multiple devices. It checks whether an order was already sent and keeps devices synchronized after printing, reducing duplicate tickets and operational confusion in restaurants or stores.
Original PR description
*: pos_urban_piper_enhancements Before this change, when a device sent an order in preparation via the ticket printer, this could result in the same order being printed by multiple devices, as the order was not synchronized after it was sent. The error is a bit tricky, because if the user had installed a preparation screen, the order was sent to the preparation screen via syncAllOrders. In this case, the order was correctly synchronized and the other devices were informed of the changes. This commit adds two things. - We check the server before sending the order to preparation to make sure it has not already been sent. - Even when the user does not have a preparation display, the order will be synchronized after being sent to a printer.
Users with timesheet access can now start and stop timers on tasks they are allowed to access, even when the parent project is private. This prevents access errors and lets field service teams record time normally on assigned work.
Original PR description
Before this commit, when the project is private and the user can only access to some tasks inside that project, he can create timesheets but cannot stop timer in one of those tasks when `industry_fsm` module is installed. This commit makes sure the user can start/stop a timer on task for which he has access to even if the project is private and he does not have access to it. Steps to reproduce the issue: ---------------------------- 0. install industry_fsm module 1. Create a project A with "followers" as privacy visibility 2. Create a task A and assign it to a project user with lowest timesheet access right. 3. log in as that user 4. Start a timer on Task A 5. Stop the timer and confirm the wizard Expected Behavior: ----------------- The timesheet should be created without any issue Current Behavior: ---------------- An Access error is raised because the user has no access to the project. task-4680412 Forward-Port-Of: odoo/enterprise#84807