Thursday, April 9, 2026
28 changes · 19.0
Resolved issues and error corrections
This pull request brings several accounting and localization corrections that help invoices, electronic documents, and compliance checks work more reliably. It also adds a small usability improvement for imported vendor bills by allowing lines to be grouped by tax, reducing clutter for accountants.
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
Payments linked to fully reconciled vendor bills now move out of the in-process status as expected. This prevents confusion when early payment discounts or specific journal settings previously made paid bills appear unfinished.
Original PR description
Currently, payments may remain in the 'in_process' state even when the associated vendor bills are fully paid. This occurs primarily when using early payment discounts (EPD) and journals without…
Currently, payments may remain in the 'in_process' state even when the associated vendor bills are fully paid. This occurs primarily when using early payment discounts (EPD) and journals without outstanding accounts. Steps to reproduce: - Create an early payment term. - Create a Vendor Bill with EPD and post it. - Register a payment for this bill (no outstanding account set on journal => no move created). - Create a bank transaction fully paying the bill. - Reconcile the transaction with the bill. Issue: Access the payment of the bill. The payment state remains 'in_process' instead of 'paid'. Analysis: The issue occurs because the reconciliation process misses the trigger to set the payment state to 'paid'. Specifically: - The payment amount does not match the bill total due to the EPD. - The payment compute method does not monitor 'reconciled_bill_ids', causing it to ignore the status of linked vendor bills. This change adds 'reconciled_bill_ids' to the compute dependencies and ensures that if a payment is reconciled with any moves (invoices or bills), their payment_state is considered to determine the final state of the payment. Test in enterprise: https://github.com/odoo/enterprise/pull/112398 opw-5881976 Forward-Port-Of: odoo/odoo#256486
Sales orders for Indian customers with SEZ GST treatment now select the SEZ fiscal position instead of incorrectly treating them as exports. This helps ensure taxes and compliance settings are applied correctly when selling to SEZ partners.
Original PR description
Before this commit: When creating a sale order, if the GST Treatment of partner is SEZ, then the Fiscal position is set as Export instead of SEZ. Reason: The default `foreign_state` obtained currently is searched on base of state whose country is not India, so any random state is fetched. But in the fiscal position of SEZ, we want "Foreign State", so while selecting fiscal position from `_get_fiscal_position` method, the Export fiscal gets higher ranking and gets selected. This commit fixes this issue by returning the correct Foreign State if fiscal position is set to SEZ. task-5958903 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254887
This fix lets standard manufacturing users split or complete manufacturing orders even when accounting analytics are created in the background. It removes unnecessary access blockers while preserving the existing restriction that these users should not directly access accounting analytic records.
Original PR description
### Issue: In certain flows, basic mrp users (mrp.group_mrp_user) can not mark MO's as done or split production due to the associated automatic creation of accounting analytics. As concrete examples,…
### Issue: In certain flows, basic mrp users (mrp.group_mrp_user) can not mark MO's as done or split production due to the associated automatic creation of accounting analytics. As concrete examples, the tests: - test_automatic_backorder_no_redirect - test_change_qty_produced can not be performed with a user with basic mrp access rights. ### Steps to reproduce: - Incarnate a user with only mrp user rights - Create and confirm an MO for 2 units with an operation - Click on the cog wheel icon > Split production > split #### > Access Error: You are not allowed to access 'Analytic Line' (account.analytic.line) records. ### Cause of the issue: To begin with, members of the `mrp.group_mrp_user` do not and should not have read nor create access rights with respect to the `account.analytic.line` model. However, as soon as `mrp_account` is installed the `button_mark_done` can end up requiring such access. 1. The `_split_productions` fails for multiple reasons: This line: https://github.com/odoo/odoo/blob/master/addons/mrp/models/mrp_production.py#L2000 fails because of the assignment since this call: https://github.com/odoo/odoo/blob/0c2ad21773d4a7b23038b9bed19d64952d841fa1/addons/mrp_account/models/mrp_production.py#L27-L35 requires write and read access on the `account.analytic.line` model. This line: https://github.com/odoo/odoo/blob/master/addons/mrp/models/mrp_production.py#L2002 fails because the `copy_data` now checks that the user has the `read` access rights of the comodel when copying `many2many` data's: https://github.com/odoo/odoo/blob/0c2ad21773d4a7b23038b9bed19d64952d841fa1/odoo/orm/models.py#L4781-L4783 This is an issue for instance for the `wip_move_ids` field that can not be copied since mrp users do not have a read access to the `account.move` comodel: https://github.com/odoo/odoo/blob/0c2ad21773d4a7b23038b9bed19d64952d841fa1/addons/mrp_account/models/mrp_production.py#L15 This line: https://github.com/odoo/odoo/blob/0c2ad21773d4a7b23038b9bed19d64952d841fa1/addons/mrp/models/mrp_production.py#L2017 will fail since it checks the read access right on the comodel `account.move` of the `wip_move_ids` fields. 2. The `_post_inventory`: https://github.com/odoo/odoo/blob/afc6f4b41c63800efaa8e3ca15afe5cff5cfa0f9/addons/mrp/models/mrp_production.py#L2221 Fails as it sets the duration: https://github.com/odoo/odoo/blob/afc6f4b41c63800efaa8e3ca15afe5cff5cfa0f9/addons/mrp/models/mrp_production.py#L1922 which calls the `_create_or_update_analytic_entry`: https://github.com/odoo/odoo/blob/afc6f4b41c63800efaa8e3ca15afe5cff5cfa0f9/addons/mrp_account/models/mrp_workorder.py#L18-L21 which it self creates and update `account.analytic.lines` to which you do not have any read access. backport of b5c7d5fed2d893bcd5ea2c2c5ed1cb9d8dfa2424 opw-6066674 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix stops duplicate stock delivery records from being created when a point of sale order is invoiced more than once from the backend. It helps keep inventory and accounting records accurate in specific POS stock-closing setups.
Original PR description
Calling `action_pos_order_invoice` on an already-invoiced POS order (e.g. a backend user clicking "Invoice" more than once) would unconditionally invoke `_create_order_picking`, producing one extra `stock.picking` per click under anglo-saxon + update_stock_at_closing configurations. opw-6092999 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257509
This change reduces the amount of accounting data loaded when calculating running balances, so the system no longer tries to process every journal item at once. It significantly lowers memory use and improves response time for large accounting datasets, making list views more reliable for high-volume companies.
Original PR description
The _compute_cumulated_balance() method performs a query over every existing move lines to get a dict associating the record id with the cumulated sum at this point. When there is a lot of move…
The _compute_cumulated_balance() method performs a query over every existing move lines to get a dict associating the record id with the cumulated sum at this point. When there is a lot of move lines, the result returned by fetchall() hits the memory limit and the server crashes. We propose to encapsulate the original query to only return the result for the account move lines present in self. Benchmarks --------------- The following benchmarks were generated with a customization of the account.move.line list view to display the cumulated_balance field. Memory usage during the self.env.cr.execute and the dictionary population: | Operation | Before the fix | After the fix | |---------------|----------------|---------------| | populate dict | 1.5 GB | 17.1 MB | | execute query | 430 MB | 8.3 MB | 100 000 lines were displayed at the same time to get a significant size. So the number of records in self is more than 7 000 000 without the fix and 100 000 with the fix. Time spent in the _compute_cumulated_balance method: | No of AML | Before the fix | After the fix | |-----------|----------------|---------------| | 7 000 000 | 10.4 s | 6.8 s | opw-6053720 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256658 Forward-Port-Of: odoo/odoo#255780
Polish KSeF connection tokens will now be renewed automatically before they expire. This helps keep invoice sending and incoming bill retrieval working without users needing to manually re-authenticate each week.
Original PR description
The KSeF refresh token issued by the Polish Ministry of Finance expires after a week. Once it expires, the automatic fetching of incoming bills and sending of invoices will fail until the user manually re-authenticates in the settings. To ensure uninterrupted synchronization with the KSeF API, this commit adds a new scheduled action that runs every 6 days to automatically renew the tokens. task-6041758 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 Forward-Port-Of: odoo/odoo#256700
Purchase bills now reuse the account from the original down payment bill when creating the final vendor bill. This prevents down payment lines from being posted to the wrong default expense account, improving accounting accuracy and reducing manual corrections.
Original PR description
Steps to reproduce: 1/ install purchase and accountant 2/ create and setup an expense account dedicated to your downpayments (typically code 60-, account type "expense"), ACC1. 3/ setup a service type product named "downpayment" 4/ set the default expense account on that product to be ACC1. 5/ create a PO for any product other than the downpayment (PO1). take note of the partner. 6/ create a bill for the same partner as the one set on PO1. Call it BILL1. 7/ On BILL1, add one invoice line with the "downpayment" product. Set a unit price. 8/ Confirm BILL1 and match it with PO1 via the "bill matching" smart button. Add it as a downpayment. 9/ Back on PO1, receive the products. Create a bill (BILL2). => The account suggested for the downpayment line in BILL2 will use the default expense account instead of ACC1. After this commit, the account suggested will be the one used in BILL1 for the downpayment line. opw-5253877 Forward-Port-Of: odoo/odoo#245518
Users can now save a contact assigned to another company when its receivable and payable accounts belong to that same company. This prevents an incorrect error in multi-company setups and keeps accounting links aligned with the contact's company.
Original PR description
**Steps to reproduce:** - Install contacts and account - Create a second company - Stay in the first company - Create a new contact: * Company: [the second company] * Account Receivable: [create a…
**Steps to reproduce:** - Install contacts and account - Create a second company - Stay in the first company - Create a new contact: * Company: [the second company] * Account Receivable: [create a new one in the second company] * Account Payable: [create a new one in the second company] - Save **Issue:** A UserError is raised because "Account Receivable" and "Account Payable" don't belong to the current company. **Cause:** Those fields are company-dependent. As their value is registered for the current company, they are forced in that company, even if the linked record belongs to another one. It would be weird for a company-dependent field to belong to another company than the one it is defined in. However, it is also weird to create a record that belongs to a company and that have fields belonging to another company. **Solution:** In "_check_company" method, verify that the company set on the company-dependent co-records is the same than the company of the record when it is set. opw-5409503 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Company-paid expenses using SEPA credit transfer now require a vendor before they can be posted. This prevents invalid payments that later block corrections and SEPA file generation, reducing accounting cleanup work.
Original PR description
**Steps to reproduce:** * Install `account_iso20022` and `hr_expense` module. * Create an expense with `Paid by Company` and `SEPA credit transfer` as the payment method. * Leave the `Vendor` field…
**Steps to reproduce:** * Install `account_iso20022` and `hr_expense` module. * Create an expense with `Paid by Company` and `SEPA credit transfer` as the payment method. * Leave the `Vendor` field empty. * Submit, approve, and post the expense. **Observed behavior:** * The expense is posted successfully without a vendor, creating a payment with `partner_id = False`. * The payment cannot be reset to draft due to the missing vendor, and SEPA XML generation fails because the creditor name (`<Cdtr><Nm>`) requires a partner. **Cause:** * The `hr_expense` module overrides `_compute_show_require_partner_bank`. to set `require_partner_bank_account = False` for expense payments, bypassing the partner bank validation in `account.payment.action_post`. * `_prepare_payments_vals` uses `self.vendor_id.id` for `partner_id`, which evaluates to `False` when no vendor is set. * The `_post` method on `account.move` only validates partner presence for invoices (sale/purchase documents), not for `entry` type moves, which payments use. **Fix:** * Add a validation in `hr.expense.action_post` that checks whether the payment method is `sepa_ct`. If so, `vendor_id` must be set before posting. * This catches the issue early in the expense flow, before the payment and journal entry are created. opw-5930687
This update makes URL auto-linking in the editor behave more predictably when users press space, Enter, or paste text. Undo now removes the unwanted link conversion first, and pasted URLs wrapped in backticks no longer include the backtick in the link address.
Original PR description
[FIX] html_editor: undo link autoconvert before space insertion When adding a space after an URL, the URL text is converted to an URL. When pressing undo, first the space is undone, then the link is…
[FIX] html_editor: undo link autoconvert before space insertion When adding a space after an URL, the URL text is converted to an URL. When pressing undo, first the space is undone, then the link is undone. This is wrong because if the user did not want a link, after undoing the link, inserting a new space will again convert to a link. This commit splits `handleAutomaticLinkInsertion` into two parts: determining if a link must be created, and actually inserting the link. This makes it possible to execute code within the condition before and after the insertion. To fix the similar behavior for enter and shift-enter, another before input handler is also added in order to let the default before input be executed before creating the link. Steps to reproduce: - Go to a "To do" note - Type "odoo.com" - Press space/enter/shift-enter - Undo a single time => The insertion was undone instead of the link transform. task-5936310 [FIX] html_editor: not include surrounding backtick in pasted URL When pasting an URL surrounded by backticks, the ending backtick is included inside the link's HREF. This commit fixes the regex for URL to also exclude backticks (like it did with `"` and `'`). Steps to reproduce: - Copy the following text in the clipboard: ``` `odoo.com` ``` - Go to a "To do" note - Paste => The link's URL was ``` odoo.com` ``` task-5936310 Forward-Port-Of: odoo/odoo#258188 Forward-Port-Of: odoo/odoo#248619
Fixes a crash in the mass mailing editor when users replace an image with an illustration. The editor now correctly recognizes valid illustration files and serves converted images properly, improving reliability when creating email campaigns.
Original PR description
Currently, in the mass mailing editor, an error occurs when a user replaces an image with an illustration. Steps to reproduce: 1. Open the mass mailing editor 3. Drag and drop a snippet containing an…
Currently, in the mass mailing editor, an error occurs when a user replaces an image with an illustration. Steps to reproduce: 1. Open the mass mailing editor 3. Drag and drop a snippet containing an image 4. Double-click on the image 5. In the image search bar, type "test" and press `Enter` 6. Select an illustration => A traceback is raised. When an illustration is selected, it is automatically stored as an attachment with the mimetype `image/svg+xml; charset=utf-8`. The editor then loads the image using the attachment URL (e.g. `/html_editor/shape/illustration/usability-testingsvg-258?...`). When the media dialog is closed (via `on_media_dialog_saved_handlers`), the editor attempts to process the image and calls the `/html_editor/get_image_info` route to retrieve the image info. This route retrieves the corresponding attachment from the database using the attachment url, but filters results based on a predefined set of allowed mimetypes. The issue arises because this set does not account for valid mimetypes that include optional parameters such as `charset=utf-8`. As a result, the attachment is not found, preventing the image from being processed and ultimately causing the crash. To fix the issue, we will update the domain used to retrieve image attachments so that it accepts valid mimetypes with optional parameters (e.g. `image/svg+xml; charset=utf-8`). During image processing, the transformed image is temporarily encoded in base64 and stored in the src attribute. When the record is saved, this base64 image is converted into a new attachment via the `/html_editor/modify_image/<id>` route. **This conversion step is necessary because many email clients have limited support for SVG images. Converting the illustration to PNG ensures better compatibility and visibility across mail clients.** After conversion, the image url is then set to `/html_editor/shape/illustration/335/usability-testingsvg-258?...` This URL is handled by the `html_editor/shape/<module>/<path:filename>` route. Its purpose is to process SVG files and dynamically adjust their colors based on query parameters (e.g. the `c1` parameter). However, once the image has been converted to PNG, this logic no longer applies. To address this, an additional conditional check will be introduced: if the file is not an SVG, the route will bypass the SVG-specific transformation logic and instead serve the image directly. Task-5977962 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where marketing emails written in right-to-left languages, such as Arabic, could arrive with left-to-right formatting. The mail editor now preserves the text direction styling so recipients see the message as intended.
Original PR description
**Steps to reproduce:** - Install Mail Marketing app - Change user language to a RTL language (such as Arabic) - Create a marketing campaign with RTL content - Send it (with the campaign, test mail works properly) - Mail received changes from RTL to LTR **Issue:** Table `direction` style is removed by the `_Cleaner` as it is not in its `_style_whitelist` during the composer creation. **Fix:** Add it to the valid styling to ensure rtl mails are properly formatted by the rtlcss library. related fix: https://github.com/odoo/odoo/commit/4ac3766fa5b458864c1728441cf4a157df943d39 sanitize on `mail.composer.mixin`: https://github.com/odoo/odoo/commit/24731938f75358fd3c72b91465b72ab80d62d208 opw-5982854 Forward-Port-Of: odoo/odoo#257886
This fix ensures Google Ads tracking cookies are blocked when visitors decline optional cookies, including when the tracking code is added through website custom header or footer code. It helps businesses keep their websites aligned with visitor consent choices and privacy expectations.
Original PR description
# How to reproduce - Go to Website app > Configuration > Websites > Select your website > Custom Code - In the "Custom <head> code" section add the script given at the last section of this PR (with a…
# How to reproduce
- Go to Website app > Configuration > Websites > Select your website > Custom Code
- In the "Custom <head> code" section add the script given at the last section of this PR (with a proper TAG_ID)
- Go to a new Incognito Tab and go to the Website front page
- Refuse the optionnal cookies
- Open the browser's console and go to Application > Storage > Cookies
# The problem
The Google Ads cookies are present (prefixed by _ga)
# Why
This commit introduced the blocking of 3rd party cookies :
https://github.com/odoo/odoo/commit/958b41c4acec7e1700ca4d6e0b25ee0ad2aac9f1
It works by doing 2 things, but none of them works in our case :
First, it edits the view rendering to replace the `src` value with "about:blank" for watched
tags, but this does not work for `website.custom_code_head` (our case) and `website.custom_code_footer` because it is t-out'ed which bypasses this code :
https://github.com/odoo/odoo/commit/958b41c4acec7e1700ca4d6e0b25ee0ad2aac9f1#diff-a27798e1ecfe96676dd48766e0aa9d12fbc0784e328ac1a3ec82b1ce199fc58bR121-R166
Second, it adds a script in the head of the page that patches the setter for the `src`
property of the script tags. If the value that we try to set is a URL to a site that we
block and the cookies are not yet accepted, we replace the `src` value with "about:blank".
https://github.com/odoo/odoo/blob/e906eb23d698061f146ba67aae420eb7bb5e8a68/addons/website/static/src/js/content/cookie_watcher.js#L8
This sadly does not work for parser-inserted scripts that are directly parsed from the HTML.
Indeed, they do not use the setter of `HTMLScriptElement.prototype`.
It is possible to verify this by adding a `MutationObserver` that checks for new script
insertions and adding breakpoints in this observer and in the patched setter. For the
first scripts of the page, the breakpoint in `MutationObserver`is triggerred while the
one in the setter is not.
# Proposed solution
We move this code into new helper functions :
https://github.com/odoo/odoo/blob/95dc247ecd773044ef9c9f1512c7d86d73df836c/addons/website/models/ir_qweb.py#L130-L135
And use these helper functions to create another helper function that allows us to check
an html field for trackers that would need to be removed
We then use this helper function on `website.custom_code_head` and `website.custom_code_footer`
# The script
```html
<!-- Google tag (gtag.js) -->
<script async src="[https://www.googletagmanager.com/gtag/js?id=TAG_ID"></script](https://www.googletagmanager.com/gtag/js?id=TAG_ID%22%3E%3C/script)>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'TAG_ID');
</script>
```
Source : https://developers.google.com/tag-platform/gtagjs
opw-6007810
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prEvent descriptions downloaded for Outlook Calendar now show readable content instead of raw HTML code. This makes calendar invites clearer for attendees and avoids confusion when users export events from the website.
Original PR description
### Steps to reproduce: - Download Events app. - Pick an event and click "Go to website". - Download the Outlook Calendar. ### Issue: - The HTML content within the event description is displayed as raw code and not converted properly - This happens because outlook takes the description as text and displays it in the ics file without conversion ### Solution: - Since we're working with *Outlook Calendar*, X Alt formatting was added to format HTML to text opw-5237027 Forward-Port-Of: odoo/odoo#257978 Forward-Port-Of: odoo/odoo#246603
Accounting administrators can now reopen the Inventory Valuation report after generating a stock valuation closing entry. This prevents an access rights error and keeps the report available for month-end or inventory accounting work.
Original PR description
### Issue before this commit: After generating a stock valuation closing entry from the Inventory Valuation report, reopening the report raised an access rights error. Users with Accounting…
### Issue before this commit: After generating a stock valuation closing entry from the Inventory Valuation report, reopening the report raised an access rights error. Users with Accounting permissions could no longer access the report. ### Steps to reproduce the issue: 1. Access the database with a user having Accounting Admin rights. 2. Go to the Inventory Valuation report. 3. Click to generate a closing entry. 4. Try to open the Inventory Valuation report again. 5. Result: System shows an access rights error. ### Cause of the issue: The method _get_last_closing_date() retrieves the field state of the model account.move by querying the technical model ir.model.fields. However, accounting users do not have read access to this model. When the report tries to compute the last closing date after a closing entry exists, this lookup triggers an error. ### Reason to introduce the fix: The lookup of account.move.state is only used internally to inspect tracking values in the chatter and determine the posting date of the closing entry. Since this requires reading a technical metadata model, the query is executed with sudo() to bypass the restriction while keeping the functional access to accounting data unchanged. opw-5998151 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
User mentions now work correctly when a person's name includes characters like &, <, or >. This ensures those users are properly notified by email when mentioned in messages or notes, reducing missed communications.
Original PR description
**Description of the issue/feature this PR addresses:** The `Store.getMentionsFromText` method fails to identify mentions for users with special characters (&, <, >) in their names. Because the…
**Description of the issue/feature this PR addresses:** The `Store.getMentionsFromText` method fails to identify mentions for users with special characters (&, <, >) in their names. Because the function processes raw HTML, these characters are encoded as entities, causing them to be [filtered out](https://github.com/odoo/odoo/blob/a2b3a10255dba290ea462b9193ae11c54d8dd5e0/addons/mail/static/src/core/common/store_service.js#L599-L601) In order to resolve this, I translate the entities back into their normal representation, allowing our includes to find them. **Steps to reproduce bug:** 1) Create a user with a name containing &, <, > 2) Set it so they receive emails for notifications 3) Mention them in a long note 4) Observe that no email is sent **Current behavior before PR:** https://drive.google.com/file/d/1itBlz6havFmFi2G3mbOm3qh2_WH6uM76/view?usp=drive_link **Desired behavior after PR is merged:** https://drive.google.com/file/d/1PC2_hjBAhhC6ZSOEzs9SPYjSHrZbaplp/view?usp=drive_link opw-5895188
The online shop category sidebar now loads nested categories much more efficiently. This reduces page load delays for stores with many categories, improving the shopping experience without changing functionality.
Original PR description
Before this commit, the product categories templates recursively rendered on new recordsets created using `filtered()`. This caused a performance regression when there were nested categories, as `_prefetch_ids` would be cleared, generating N+1 queries when fetching each child category. This commit changes the t-foreach to iterate over the original recordset, in order to preserve _prefetch_ids and improve caching performance. Benchmarks opening /shop with sidebar categories |Category count |Time before|Queries before|Time after|Queries after| |----------------|-----------|--------------|----------|-------------| |2000, nested |29.52s |4843 |0.83s |76 | |2000, not nested|0.89s |91 |0.80s |75 | opw-5969878 Forward-Port-Of: odoo/odoo#254415
This update resolves an issue where negative values in the Mod 390 tax report were not being properly marked with the 'N' indicator, as required by Spanish tax regulations. The fix adds a necessary parameter to ensure accurate reporting, aligning with official documentation and improving compliance.
Original PR description
### Issue: Negative values in the Mod 390 report were not properly marked with the N indicator for several fields ### Cause: The parameter `signed=True` was missing on some fields where negative…
### Issue: Negative values in the Mod 390 report were not properly marked with the N indicator for several fields ### Cause: The parameter `signed=True` was missing on some fields where negative values should include the N indicator in the BOE export ### Note: According to the official specification, negative amounts must be explicitly marked with N Latest documentation: https://sede.agenciatributaria.gob.es/static_files/Sede/Disenyo_registro/DR_300_399/archivos_25/dr390e2025.xlsx ### Steps to reproduce: - Install `l10n_es_reports` with demo data and switch to the ES company - Create a Bill (Price: 100, Taxes: 21% G) - Go to Tax Report and select Tax Report (Mod 390) (ES) for the full year - Open the VAT Deductible tab - The last line (65) should be negative - Export the BOE file using the gear menu - Check the last value of section 4 in the file ### Before the fix: Negative values were not marked with N opw-5482706 Forward-Port-Of: odoo/enterprise#113200 Forward-Port-Of: odoo/enterprise#111262
This update resolves a bug that caused PDF attachments to be incorrectly re-parented during the Send & Print process, leading to data inconsistencies. The fix prevents the creation of a document when a PDF attachment lacks a defined model, ensuring proper attachment management and preventing data loss.
Original PR description
Steps to reproduce: - Set a journal with documents folder sync (by default with demo data) - Create and post a customer invoice - Add an image or pdf attachment via a log note (it becomes…
Steps to reproduce: - Set a journal with documents folder sync (by default with demo data) - Create and post a customer invoice - Add an image or pdf attachment via a log note (it becomes message_main_attachment_id and creates a documents.document with res_model=False) - Click Send & Print Issue: KeyError: `proforma_pdf_attachment` Cause: During Send & Print, _link_invoice_documents creates the invoice pdf attachment (res_model='account.move', res_field='invoice_pdf_report_file') and sets it as invoice.message_main_attachment_id. During the acoun_move write, in `documents_account`, it searches for an existing document matching the previous `message_main_attachment_id` (`initial_attachment`) and sets `document.attachment_id` to the invoice pdf. https://github.com/odoo/enterprise/blob/6bdcc357b195faa0aad8c05eac23aa0a762dd76b/documents_account/models/account_move.py#L41-L54 This triggers the versioning logic which resets the parent of the attachment when its `res_model` and `res_id` differs from the document. Because the document has res_model=False, the condition always matches and the pdf is re-parented to `documents.document`, deleting res_field's binding to account.move. After invalidate_recordset https://github.com/odoo/odoo/blob/95666545fcd934bf4084f680e692633783ae5603/addons/account/models/account_move_send.py#L477 invoice_pdf_report_id recomputes to an empty recordset. https://github.com/odoo/odoo/blob/7b384a6ec13c372b44e2a58134c61d54de152395/addons/account/models/account_move.py#L2205 _get_invoice_extra_attachments returns empty, Eventually, we try to access move_data['proforma_pdf_attachment'] which was never set (fallback for otehrscenario) https://github.com/odoo/odoo/blob/95666545fcd934bf4084f680e692633783ae5603/addons/account/models/account_move_send.py#L856 -> KeyError. Solution: We prevent the creation of a document if no res_model is set. And extra guard-rail is kept: Skip re-parenting in DocumentsDocument.write() when the incoming attachment has res_field set. Attachments linked via a Binary field are owned by their model and must never be moved to documents.document regardless of the document's own res_model. opw-5930888
This update addresses an issue where delivery confirmations were failing due to missing tracking information from Easypost. The fix ensures that picking validation occurs correctly and prevents shipping creation in Easypost when tracking data is unavailable. Easypost support suggested a slight delay between order placement and tracking retrieval as a potential workaround.
Original PR description
Problem: 'tracker' object in response from GET /orders/:id request can sometimes be null. This means that when the mail template 'mail_template_data_delivery_confirmation' is sent, a traceback occurs…
Problem: 'tracker' object in response from GET /orders/:id request can sometimes be null. This means that when the mail template 'mail_template_data_delivery_confirmation' is sent, a traceback occurs with error: TypeError: 'NoneType' object is not subscriptable. As a result the picking is not validated in odoo but a shipping has succesfully been created in the easypost backend. Solution: Prevent traceback form happening, picking gets correctly validated and carrier_tracking_url field is empty. Transcript from Easypost support: << I'm also seeing the tracker showing as null when reviewing the response. I'll go ahead and create a ticket for the engineering team to investigate. I can see that the tracking code is being returned in the request, but the full tracking object is not. Since this appears to be happening on a case-by-case basis, you may want to allow more time between the BUY and the GET requests, as I noticed they are being triggered very close together. I'm not certain if that's related, but it may be worth trying as a troubleshooting step while we have this under review. >> opw-5402415 Forward-Port-Of: odoo/enterprise#111833
This update corrects a problem where the '&' character in vendor bill references was incorrectly exported as '&' in SEPA payment files. This prevented successful processing of payments by banks, ensuring compliance with SEPA regulations and accurate financial reporting. The fix replaces '&' with '+' to adhere to the required character set.
Original PR description
Steps to reproduce: 1. Install modules `account_batch_payment` and `l10n_ch`. 2. Configure SEPA Credit Transfer for a CH company. 3. Create a vendor bill with a reference containing `&` (e.g. "Net &…
Steps to reproduce: 1. Install modules `account_batch_payment` and `l10n_ch`. 2. Configure SEPA Credit Transfer for a CH company. 3. Create a vendor bill with a reference containing `&` (e.g. "Net & Cost"), confirm it and register a payment using SEPA Credit Transfer. 4. Create a batch payment with the SEPA payment and validate it. Issue: The `&` character is exported as `&` in the generated PAIN XML, while according to the SIX specification it should be replaced with `+` Cause: The payment reference is inserted into the PAIN XML file without replacing the '&' character. During XML generation this produces an invalid entity (`&`) which results in an `XMLSyntaxError` and prevents the payment file from being processed. Solution: Replace the `&` character with `+` when sanitizing the payment communication so that the generated value complies with the SEPA/SIX character set and produces valid XML. Reference[Pg: 9]: https://www.europeanpaymentscouncil.eu/sites/default/files/KB/files/EPC217-08%20Draft%20Best%20Practices%20SEPA%20Requirements%20for%20Character%20Set%20v1.1.pdf opw-5941724 Co-authored by @bhra-odoo Forward-Port-Of: odoo/enterprise#110809
This update fixes an issue where Odoo incorrectly consumed stock from the wrong location when scanning serial numbers on manufacturing orders. The fix ensures the correct warehouse location is used, preventing errors in stock tracking and improving order fulfillment accuracy. This resolves a potential problem with inventory management.
Original PR description
Steps to reproduce: - Create a Manufacturing Order with a serial-tracked component. - Open the Shop Floor. - Scan the serial number barcode to register the component. - Observe which location the component was consumed from. Issue: When a product is received from a vendor, Odoo creates two quants for the same serial number — one at Partners/Vendors location and one at WH/Stock location. Because get_quant_from_barcode searched for a matching serial number with no location filter, it returned whichever quant had the lowest database ID — which was always the Partners/Vendors or Production quant created first — instead of the correct WH/Stock quant. Solution: Prevent selecting a quant from an incorrect location when multiple quants exist for the same serial number, as this can lead to consuming stock from the wrong location. opw-5974474 Forward-Port-Of: odoo/enterprise#112691
This fix resolves an issue where the bank reconciliation process would fail when using the liquidity account as an outstanding payment account. The update prevents automatic reconciliation in this scenario, ensuring data integrity and preventing a persistent error message. This improves the reliability of bank statement matching.
Original PR description
# How to reproduce - Create a new Journal - Go to the Configuration of the Journal > Outgoing Payments > Set the Outstanding Payment accounts for the Manual payment Payment Method to the liquidity…
# How to reproduce - Create a new Journal - Go to the Configuration of the Journal > Outgoing Payments > Set the Outstanding Payment accounts for the Manual payment Payment Method to the liquidity account - Go to the Transactions of the Journal - Add a new Transaction for partner X and amount Y - Add a second Transaction also for partner X and amount Y # The issue A popup appears that can never be saved # Cause When we click on "Add & New" or "Add & Close", we run the `validate()` function : https://github.com/odoo/enterprise/blob/9abb50b9b29e01897b4fb90ae228beecbdfcd5af/account_accountant/static/src/components/bank_reconciliation/quick_create/quick_create.xml#L14-L16 Which tries to do a model save, but it fails so it show the Form dialog : https://github.com/odoo/odoo/blob/6e77d840a2876e45544b21a911be05b2f32b8afb/addons/web/static/src/views/kanban/kanban_record_quick_create.js#L159-L163 The save fails because : This commit (https://github.com/odoo/enterprise/commit/e2b3439dcda26f84b9a290c8d5fb819dd3250825) changed the the logic behind auto-reconcilation with an outstanding account. When there is an outstanding account, we try to auto-reconcile the bank statement with that account and succesfully do so : https://github.com/odoo/enterprise/blob/e2b3439dcda26f84b9a290c8d5fb819dd3250825/account_accountant/models/account_bank_statement.py#L381-L385 https://github.com/odoo/enterprise/blob/e2b3439dcda26f84b9a290c8d5fb819dd3250825/account_accountant/models/account_bank_statement.py#L245 But this should not happen when the outstanding account is the liquidity account, because it will end up throwing an error when the amount is matched more than once: https://github.com/odoo/odoo/blob/6e77d840a2876e45544b21a911be05b2f32b8afb/addons/account/models/account_bank_statement_line.py#L727-L737 opw-6063654 Forward-Port-Of: odoo/enterprise#112750
This update corrects a previous issue where the Amazon fulfillment channel in the sales module was incorrectly displayed as read-only. The change ensures users can now modify this setting, streamlining the process for managing Amazon sales operations. This improves flexibility and control over fulfillment options.
Original PR description
Commit 67c45d6494f082e2ee83b9a84611e8b8fe8f4fd5 intended to make `amazon_channel` editable by users. However, the field was displayed with the `badge` widget, which is read-only, so it remained uneditable. Use an editable display for `amazon_channel` so the original fix works as intended. Forward-Port-Of: odoo/enterprise#113196 Forward-Port-Of: odoo/enterprise#112866
This update corrects the calculation of the employment bonus in the Odoo Enterprise accounting module for Belgium. The change reflects the latest regulations from Partena Professional, ensuring accurate bonus payments up to April 2026. This update maintains compliance with Belgian tax laws and avoids potential financial discrepancies.
Original PR description
https://www.partena-professional.be/fr/le-bonus-lemploi-au-1er-avril-2026?utm_source=sfmc&utm_medium=email&utm_campaign=InfoFlash+Daily+Mail+-+FR&utm_content=article-read-more-cta&utm_term=All%20Subscribers&utm_id=81873&sfmcContactKey=litom@odoo.com Forward-Port-Of: odoo/enterprise#112970
A bug was preventing users from deleting timesheet records when a confirmation dialog was open. This was due to the timer hotkey incorrectly responding to the Enter key. This update ensures that pressing Enter in the timesheet list view now correctly triggers the deletion process, resolving a key usability issue.
Original PR description
When a delete confirmation dialog is open in the timesheet list view, pressing Enter starts/stops the timer instead of confirming the dialog. This happens because the timer's window keydown handler does not check for active modals before intercepting the Enter key. Add a `.modal` check consistent with the grid renderer's onKeyDown. Steps to reproduce: 1) Open timesheet list view 2) Select a record and delete it 3) When the confirmation dialog opens, hit ENTER key Current behavior: The Timer starts recording timesheet Expected behavior: The record should be deleted For ref: https://youtu.be/tzm_3RNe1ig Forward-Port-Of: odoo/enterprise#112583
This update corrects a discrepancy in the FAIA XML export format for Luxembourg accounting reports. It ensures that invoice transaction and account IDs are consistently linked across the system, resolving potential export errors and improving data accuracy. This change is part of a larger effort to enhance the reliability of financial reporting.
Original PR description
This is one of several commits fixing the FAIA xml export. The `Invoice/TransactionID` element in `SourceDocuments/SalesInvoices` and `SourceDocuments/PurchaseInvoices` must match the corresponding `Transaction/TransactionID` in the `GeneralLedgerEntries` section. As the latter uses the entry `name` since PR #58728, the former should too. The `Invoice/Line/AccountID` element in `SourceDocuments/SalesInvoices` and `SourceDocuments/PurchaseInvoices` must match an account defined in `MasterFiles/GeneralLedgerAccounts/Account/AccountID`. As the latter uses `account_code` since PR #65221, the former should too. opw-5427296