Thursday, July 30, 2026
10 changes · 17.0
New functionality added to Odoo
* = l10n_fr_pdp_pos last backported commit: 373711ba04bd2585f51be26cec31cd80d21d0571 The main difference for the e-invoicing part are the difference in - peppol (i.e. partner and company / settings) - the account move send wizard They were both refactored between 17.0 and 18.0 task-6356968 For the e-reporting part Co-authored-by: Jérémy Bazin (baje) <baje@odoo.com> #### [IMP] l10n_fr_pdp: backport Flow 10 e-reporting Flow 10 e-reporting is needed on 17.0 while its imple
Original PR description
* = l10n_fr_pdp_pos last backported commit: 373711ba04bd2585f51be26cec31cd80d21d0571 The main difference for the e-invoicing part are the difference in - peppol (i.e. partner and company / settings)…
* = l10n_fr_pdp_pos last backported commit: 373711ba04bd2585f51be26cec31cd80d21d0571 The main difference for the e-invoicing part are the difference in - peppol (i.e. partner and company / settings) - the account move send wizard They were both refactored between 17.0 and 18.0 task-6356968 For the e-reporting part Co-authored-by: Jérémy Bazin (baje) <baje@odoo.com> #### [IMP] l10n_fr_pdp: backport Flow 10 e-reporting Flow 10 e-reporting is needed on 17.0 while its implementation was introduced in 18.0. The business builder can be reused, but account EDI helper signatures and company account fields differ between versions. Keep the 18.0 dict_to_xml rendering so node ordering, omissions and control-character sanitization remain identical. Add the local tax compatibility required for configured exemptions, acquisitions, reverse charge and UoM codes. Also adapt account lookup to the 17.0 company field. Validate the generated report against the 0290 reserve fixture and cover invalid XML control characters. Compose the e-reporting chatter markup without concatenating translated strings. This preserves the reference payload while keeping e-reporting separate from the ongoing e-invoicing backport. task-6356968 #### [ADD] l10n_fr_pdp_pos: backport Flow 10 POS e-reporting POS e-reporting depends on closing entries being included in Flow 10. The 18.0 implementation relies on POS and accounting fields and APIs which are not available on 17.0. Detect closing entries through pos.session.move_id, adapt order creation tests to create_from_ui, and extend the Flow 10 query. Filter 17.0 POS counterpart lines because they are still marked as product lines. Preserve the sign of separate refund income lines so sales and refunds are reported net. This preserves the 18.0 reporting result without changing the e-invoicing path. task-6356968
Enhancements to existing features
Supersedes #275986 and fixes its approach: that PR updates the withholding rates **in place** on the existing tax records (`ret_10_income_person`, `ret_10_income_rent`, `ret_2_income_person`, and repurposes `ret_2_income_transfer` into a different concept). Those records exist in production databases with posted history behind them, and the pre-law rates remain legally applicable to operations dated before the law's entry into force, so rewriting them breaks prior-period postings, corrections an
Original PR description
Supersedes #275986 and fixes its approach: that PR updates the withholding rates **in place** on the existing tax records (`ret_10_income_person`, `ret_10_income_rent`, `ret_2_income_person`, and…
Supersedes #275986 and fixes its approach: that PR updates the withholding rates **in place** on the existing tax records (`ret_10_income_person`, `ret_10_income_rent`, `ret_2_income_person`, and repurposes `ret_2_income_transfer` into a different concept). Those records exist in production databases with posted history behind them, and the pre-law rates remain legally applicable to operations dated before the law's entry into force, so rewriting them breaks prior-period postings, corrections and reports. Following the approach used for equivalent legal rate changes in other localizations on stable branches (`l10n_ee`, `l10n_sk`, `l10n_fi`), this PR adds **new taxes** for the new rates, keeps the pre-law taxes active, archives the superseded 27% remittance withholding, gives the new 15% withholding its own payable account instead of reusing the one tied to L253-12, and leaves the module authorship untouched.
## Description
Dominican Republic Law 30-26 ("medidas pro-crecimiento económico, simplificación fiscal y mitigación de la crisis internacional"), enacted on June 18, 2026, amends several provisions of the Tax Code that affect taxes shipped with the `l10n_do` chart template:
| Concept | Before | After | Effective |
|---|---|---|---|
| ISR withholding on fees/services provided by individuals (art. 309 b) | 10% | 15% (payment on account) | July 2026 |
| ISR withholding on rents paid to individuals (art. 309 a) | 10% | 15% (single and final) | July 2026 |
| ISR withholding on payments abroad for software licenses/subscriptions, royalties, online advertising and cloud data storage (arts. 305-1 / 305-2) | 27% (general remittance rate) | 15% (single and final) | June 18, 2026 |
| ISR withholding on technical services provided by individuals (art. 309 rate over the 20% presumed base of art. 70, Regulation 139-98) | 2% effective | 3% effective | July 1, 2026 (DGII notice 10-26) |
Changes:
- New taxes `ret_15_income_person` and `ret_15_income_rent`. The pre-law 10% taxes are kept active since their rates remain applicable to operations dated before the law.
- New taxes `ret_3_income_person` and `ret_3_income_transfer` for the effective 3% withholding on technical services, posting to a new payable account `l10n_do_21030311` ("Other Withholdings (L30-26)") since their pre-law counterparts' accounts are tied to previous regulations; the pre-law 2% taxes also remain active.
- New tax `ret_15_income_remittance_tech`, posting to a new payable account `l10n_do_21030310` ("ISR Withheld on Remittances Abroad (L30-26)"), since the existing remittance account is tied to L253-12.
- `ret_27_income_remittance` is deactivated in the template, superseded by the new reduced withholding.
The new tax names follow the module's existing convention of tagging the enforcing law (as with "(L253-12)").
No changes are needed in the tax report: the ISR withholding taxes only distribute to payable accounts, without tax grids.
Scope note: Law 30-26 also raises the tax on checks and electronic transfers from 1.5‰ to 2.0‰ (art. 382 of Law 288-04, as amended), deliberately left out here: it is not an invoiceable tax — banks withhold it directly on account debits, so it is handled outside invoice accounting.
References:
- https://presidencia.gob.do/leyes/ley-30-26
- https://www.hacienda.gob.do/ley-30-26-no-dispone-impuestos-por-suscripciones-de-ciudadanos-a-plataformas-digitales-reduce-de-27-a-15-la-retencion-a-empresas-que-contratan-servicios-tecnologicos-en-el-exterior/Resolved issues and error corrections
This fix prevents the Journal Report from failing when an invoice uses a tax that was originally a group of taxes but later changed to a percentage tax. Accounting users can now open audit reports reliably even after tax configuration changes.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465
Miscellaneous changes
Backport of #275640 Despite resolving the conflicts (file moved) this version also checks the python version since PyUnstable_Type_AssignVersionTag does not exists in python 3.10 To be safer, the whole logic is skipped if python < 3.13
Original PR description
Backport of #275640 Despite resolving the conflicts (file moved) this version also checks the python version since PyUnstable_Type_AssignVersionTag does not exists in python 3.10 To be safer, the whole logic is skipped if python < 3.13
Quotations created from repair orders linked to helpdesk tickets now correctly use the salesperson assigned to the customer. This prevents missing sales ownership on these quotations and helps teams track responsibility and follow-up accurately.
Original PR description
Currently, when a quotation is created from a repair order generated from a helpdesk ticket, the salesperson is not set on the quotation even if the customer has a salesperson assigned. **Steps to…
Currently, when a quotation is created from a repair order generated from a helpdesk ticket, the salesperson is not set on the quotation even if the customer has a salesperson assigned. **Steps to Reproduce:** - Install `helpdesk_repair`. - Go to `Helpdesk` > `Configuration` > `Helpdesk Teams`. - Open a team recod and enable `Repairs`. - Create a `contact/customer` with a `salesperson` assigned. - Go to `Helpdesk`, create a ticket for that `customer`, and select the `helpdesk team` configured above. - Click `Repair`, then click `Create Quotation`. - Open the quotation and check the `Salesperson` field in the `Other Info` tab. **Current behavior:** The Salesperson field on the quotation remains empty. **Expected behavior:** The Salesperson field on the quotation should inherit the salesperson assigned to the selected customer/contact. **Cause of the issue:** When a repair order is created from a helpdesk ticket, default_user_id [1] is passed in the context . This value is propagated when creating the repair order [2] . Later, when creating the quotation from the repair order [3], the same context is reused. Because default_user_id is already present in the context, it overrides the precomputation of user_id from the customer. As a result, user_id is initialized with an empty value and remains unset. **Fix:** This commit ensures that default_user_id is removed from the context before creating the sale order. Without a default value for user_id, the field is correctly precomputed from the selected customer, and the salesperson is properly assigned. [1]- https://github.com/odoo/enterprise/blob/2662932c7ac8ebf3ed5a05d44d7ebfaff869fcbd/helpdesk_repair/models/helpdesk_ticket.py#L52 [2]- https://github.com/odoo/enterprise/blob/2662932c7ac8ebf3ed5a05d44d7ebfaff869fcbd/helpdesk_repair/models/helpdesk_ticket.py#L36-L40 [3]: https://github.com/odoo/odoo/blob/29328b8fccff833c14de317b51f3b4e5a8c40f75/addons/repair/models/repair.py#L357 opw-6344939
The JsonFormatter has two bugs - the ignore list is not working as expected - in 18.0-18.4 the 'test' key is broken This commit add tests to ensure those behavior works as expected While on it, also adds a `additional_record_keys` parameter to allow to specifically add keys to the default list, without having to override the whole list, and add additional default keys (exc_info and test) The previous `ignored_record_keys` default value was possible to remove by calling `JSONFormatte
Original PR description
The JsonFormatter has two bugs - the ignore list is not working as expected - in 18.0-18.4 the 'test' key is broken This commit add tests to ensure those behavior works as expected While on it, also…
The JsonFormatter has two bugs - the ignore list is not working as expected - in 18.0-18.4 the 'test' key is broken This commit add tests to ensure those behavior works as expected While on it, also adds a `additional_record_keys` parameter to allow to specifically add keys to the default list, without having to override the whole list, and add additional default keys (exc_info and test) The previous `ignored_record_keys` default value was possible to remove by calling `JSONFormatter(ignore_record_keys=[])` The purpose was to be able to easily include all keys and ignore the default ingnore list, but this makes the additional blacklisting of a few keys more tedious, and the general usage and implementation more complex `JSONFormatter(ignore_record_keys=[*JSONFormatter.DEFAULT_IGNORED_RECORD_KEYS, 'other key'])` To simplify the logic, **this is not the case anymore**, so to include all keys something like this would be needed `JSONFormatter(additional_record_keys=JSONFormatter.DEFAULT_IGNORED_RECORD_KEYS)` Or an hardcoded list.
- `s_three_columns` cards could end up with mismatched heights: `equalizeCardHeights` now measures header height directly instead of deriving it from the already-stretched card container. - Links appeared with a black background: exclude `btn-link` from background-color application. - Background images didn't stretch: pass `preserve_comments` so the DPI-scaling fix comment isn't stripped from the sent email. opw-6044725 --- I confirm I have signed the CLA and read the PR guidelines at w
Original PR description
- `s_three_columns` cards could end up with mismatched heights: `equalizeCardHeights` now measures header height directly instead of deriving it from the already-stretched card container. - Links appeared with a black background: exclude `btn-link` from background-color application. - Background images didn't stretch: pass `preserve_comments` so the DPI-scaling fix comment isn't stripped from the sent email. opw-6044725 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278862
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/974b7fa15b [REL] 17.0.105 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/45bd72d8f4 [FIX] ui_sheet: `getCellWidth` getter for non-active sheet [Task: 6409426](https://www.odoo.com/odoo/2328/tasks/6409426) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com>
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/974b7fa15b [REL] 17.0.105 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/45bd72d8f4 [FIX] ui_sheet: `getCellWidth` getter for non-active sheet [Task: 6409426](https://www.odoo.com/odoo/2328/tasks/6409426) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This commit fixes the verification JSON. For OSS taxes no_sujeto_loc and no_sujeto, CuotaTotal and ImporteTotal must Only include the base amount, not the tax amount. See the chatter in the task for AEAT guidelines. Also removed the validation error blocking no_sujeto_loc taxes with a non-zero amount, since OSS taxes legitimately have one in Odoo accounting (e.g. 22% IT VAT) even though it is excluded from the Veri*Factu json. upgrade :- https://github.com/odoo/upgrade/pull/10799 tas
Original PR description
This commit fixes the verification JSON. For OSS taxes no_sujeto_loc and no_sujeto, CuotaTotal and ImporteTotal must Only include the base amount, not the tax amount. See the chatter in the task for AEAT guidelines. Also removed the validation error blocking no_sujeto_loc taxes with a non-zero amount, since OSS taxes legitimately have one in Odoo accounting (e.g. 22% IT VAT) even though it is excluded from the Veri*Factu json. upgrade :- https://github.com/odoo/upgrade/pull/10799 task-5411766
The government has held off the `shipToGSTIN` changes until further notice. https://services.gst.gov.in/services/advisoryandreleases/read/668 Hence, this PR reverts those changes. task-6431622 ref - https://github.com/odoo/odoo/pull/266397
Original PR description
The government has held off the `shipToGSTIN` changes until further notice. https://services.gst.gov.in/services/advisoryandreleases/read/668 Hence, this PR reverts those changes. task-6431622 ref - https://github.com/odoo/odoo/pull/266397