Tuesday, August 25, 2026
22 changes · master
Resolved issues and error corrections
Fixes an Accounting issue where reversing and recreating foreign-currency invoices with cash-basis taxes could skip exchange difference and cash-basis journal entries. This ensures credit notes created through the standard reversal flow reflect currency rate changes automatically, avoiding manual draft/reset workarounds and improving accounting accuracy.
Original PR description
### Issue before this commit: When using the "Reverse and Create Invoice" feature on a posted invoice with a foreign currency and Cash Basis enabled, the expected Exchange Difference and Cash Basis…
### Issue before this commit: When using the "Reverse and Create Invoice" feature on a posted invoice with a foreign currency and Cash Basis enabled, the expected Exchange Difference and Cash Basis tax entries are not generated upon the automatic reconciliation. The credit note is successfully created and reconciled with the original invoice, but the P&L exchange difference and the cash basis transition lines are completely missing. Currently, the only workaround is to manually reset the generated credit note to draft and re-post it, which forces the system to correctly calculate the currency rate differences and generate the missing entries. ### Steps to reproduce the issue: 1. Download Accounting 2. Go to Settings > Cash basis. Tick it and set as 'Base Tax Received Account' an account like 201000 Current Liabilities 3. Go to Chart of Accounts > search your account (ex. 201000 Current Liabilities) and be sure the flag of 'Allow Reconciliation' is on 4. Go to Taxes > 15% sales > set 'Tax Exigibility' as Based on Payment and 'Cash Basis Transition Account' always as 201000 Current Liabilities 5. Go to Currencies and set a new currency like MXN inserting tax rates as: 1. 1 july 2026: 20$ 2. 15 july 2026: 15$ 6. Create a new invoice with price 100 and 15% tax, set MXN as currency for the journal, set the date as 1 july and confirm it 7. Click on 'Credit Note', then 'Reverse and Create Invoice' and confirm it 8. go back to the invoice and see that after the total amount there is a new line 'Reversed on...' 9. After that line there should also be the line with the Exchange Difference since the tax rates for MXN currency were different at the moment of the invoice and at the moment of the credit note. This is only created by resetting to draft the credit note and confirm it again. ### Cause of the issue: In the account.move.reversal wizard, when is_modify = True (Reverse and Create), the system triggers _reverse_moves with cancel=True. At the end of the _reverse_moves method, the newly created reverse moves are automatically posted and reconciled. However, this automatic posting is executed with move_reverse_cancel=True injected into the context: reverse_moves.with_context(move_reverse_cancel=cancel)._post(soft=False). When the reconciliation engine (_reconcile_plan_with_sync and _create_exchange_difference_moves) detects this specific context key, it intentionally bypasses the creation of both the exchange difference P&L moves and the cash basis entries, treating the reversal as a pure administrative cancellation rather than a financial operation with currency fluctuations. ### Reason to introduce the fix: To ensure financial accuracy and compliance, especially when cash basis and multi-currency are involved, a reversal on a different date must reflect the actual exchange rate fluctuations and properly trigger cash basis rules. By removing the move_reverse_cancel context injection during the automatic posting of the reverse moves, we allow the native reconciliation engine to evaluate the newly computed balance (based on the credit note's date) against the original invoice. This ensures that exchange differences and cash basis journal entries are automatically and accurately generated on the first attempt. opw-6399867 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283306 Forward-Port-Of: odoo/odoo#281498
Cloud storage download links can now be generated with a longer expiry time when needed by workflows that send files to external services. Existing behavior remains unchanged by default, reducing disruption while preventing delayed downloads from failing.
Original PR description
Some features hand a cloud storage download URL to an external service that may fetch it later. The default five-minute lifetime is too short for those flows. ### Steps to reproduce 1. Configure a cloud storage provider (e.g. cloud_storage_google). 2. Upload a large file from the web client, so it is stored in the cloud. 3. Generate a download URL for a consumer that may fetch it after five minutes. 4. The URL expires before the consumer fetches it. ### Cause The Google and Azure providers always use the default download URL lifetime, so callers cannot request a longer-lived URL. ### Fix Read an optional cloud_storage_download_url_time_to_expiry context value when generating a download URL. Keep the existing five-minute lifetime as the default for all current callers. opw-5424132 Related Enterprise PR: odoo/enterprise#105967 Forward-Port-Of: odoo/odoo#246443
This update corrects how replacement pay is calculated on Belgian payslips in specific absence and contract situations. It prevents replacement amounts from being filled when a regular amount is already present, and sets them to zero for unpaid non-assimilated leave and out-of-contract lines, improving payroll accuracy.
Original PR description
. If Amount is filled, Replacement Amount is empty. . LEAVE_UNPAID_NON_ASSIMILATED categories, will have zero Replacment amount . Out Of Contract lines, will have zero Replacment amount . Add the Corresponding tests task-6479842
Fixed an issue that could cause an error when users edited the text of a social media post. This helps ensure smoother content editing and prevents interruptions while preparing social posts.
Original PR description
Bug === A traceback is raised when editing the body of a text field with `onchange_on_keydown`. This happen in social when editing the post body. Task-6323897
WhatsApp messages now send attachments stored in cloud storage as working file links instead of empty files. This ensures recipients receive the intended documents while preserving the existing behavior for locally stored files.
Original PR description
WhatsApp attachments were delivered as empty (0 byte) files when they were stored through the cloud_storage module. ### Steps to reproduce 1. Install and set up whatsapp and a cloud storage module (e.g. cloud_storage_google). 2. Send a file through WhatsApp. 3. The recipient receives an empty file. ### Cause A cloud stored attachment keeps only a reference to its remote data, so its raw field holds no bytes. The integration uploaded those empty bytes to WhatsApp. ### Fix Use the attachment HTTP stream to generate a long-lived cloud storage URL and pass it to WhatsApp as the media link. Pass ordinary remote attachment URLs directly, and keep uploading local attachment bytes as before. opw-5424132 Related Community PR: odoo/odoo#246443 Forward-Port-Of: odoo/enterprise#105967
This fix prevents Odoo from crashing when a user navigates away from a view while embedded content in an HTML field is still loading. The system now safely cancels that pending display action, improving stability without changing normal user workflows.
Original PR description
[Adoption of Owl v3.0.0-alpha.42] in Odoo codebase introduced timing differences when mounting a new App (sub-)root. This timing difference could cause a crash when mounting an embedded component in…
[Adoption of Owl v3.0.0-alpha.42] in Odoo codebase introduced timing differences when mounting a new App (sub-)root. This timing difference could cause a crash when mounting an embedded component in a html field, if the main App switched view away from the field where embedded components were waiting for their root to prepare, the root host wouldn't be in the DOM anymore, but the code would still try to mount these components. To avoid the issue, this commit makes use of `onBeforeComplete` to abort a pending mount if the owner instance (Component, editor plugin, ...) was destroyed before the mount could be initiated. This is the best strategy to silently ignore crashes caused by premature destruction of an ancestor while still keeping errors thrown when the host was removed from the DOM for other reasons that may need investigation. Aborting when the host is disconnected is the best strategy to avoid the crash entirely, but then we might miss those other reasons. [Adoption of Owl v3.0.0-alpha.42]: https://github.com/odoo/odoo/commit/acb95b28ab807b37ee86b381b555e38fae36ae93 runbot-944116 Forward-Port-Of: odoo/odoo#284206
This update makes time- and date-based labels refresh automatically, so open Odoo screens no longer show stale values such as yesterday's messages marked as today. It also improves efficiency by only updating these time-based values when they are actually being viewed.
Original PR description
Dates are currently not reactive, so they don't play well when used inside reactive contexts (components, computed, ...). Changes to date are never detected, which can lead to inconsistencies. This PR introduces several commit to fix this issue in an efficient way. See individual commits for details. https://github.com/odoo/enterprise/pull/128366
This fixes an error that could appear when using the QR code feature in Point of Sale self-ordering. Businesses can expect a smoother experience for staff and customers when generating or accessing QR codes.
Original PR description
In this commit: ------------------ - Fixed the incorrect way of accessing props, which was causing a traceback. Props are now accessed correctly using `this.props..` instead of `props....` task: 6395641
This fixes an internal error that could occur when opening the Purchase reporting pivot view. The change makes report query handling more robust when grouping data, helping users access purchase analysis without interruption.
Original PR description
Use the freehash because the arguments can be mutable (like a list which will become an ARRAY).
Before this, in Purchase -> Reporting -> Purchase -> Use pivot view, the code `SQL(", ").join(unique(grouping_sets_sql))` can raise because 2 sets can contain lists.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prWebsite charts and other canvas-based visuals are now better recognized by screen readers, reducing accessibility gaps for visually impaired users. Chart snippets can also include a description so assistive technologies can explain the chart content more clearly.
Original PR description
Adding role="img" to a <canvas> element forces assistive technologies like screen readers to treat the pixel-based drawing as a single static image. Without it, screen readers cannot parse the visual content inside the canvas, resulting in a blind spot for visually impaired We'll work to add a description on canvas elements later. Task-6009931
The website mega menu now appears in the same aligned position whether submenus open on click or on hover. This improves navigation consistency while preventing menus from closing unexpectedly as users move the cursor.
Original PR description
### Issue: The mega menu position is inconsistent between the two "Sub Menus" options. With "On Click", the mega menu opens below the navbar, which is its default position. With "On Hover", it opens…
### Issue: The mega menu position is inconsistent between the two "Sub Menus" options. With "On Click", the mega menu opens below the navbar, which is its default position. With "On Hover", it opens directly below the mega menu toggle, making it visually misaligned with the "On Click" behavior. ### Reason: The different positioning for "On Hover" was intentional. If the mega menu were placed in its default position, the gap between the toggle and the mega menu would cause the cursor to briefly leave both elements while moving between them, unintentionally closing the mega menu. To prevent this, the mega menu was positioned directly below the toggle, removing that gap. ### Fix: Restore the mega menu to its default position for "On Hover" to match the "On Click" behavior. To prevent the original issue of the mega menu closing while the cursor travels from the toggle to the mega menu, introduce an invisible hover bridge. The bridge is implemented as a pseudo-element of the mega menu toggle, ensuring the cursor never leaves the hover area while crossing the gap. For header templates, such as "Menu - Sales 1" and "Menu - Sales 4", the hover bridge overlaps interactive content in the navbar. To avoid this, position the mega menu below the menus container instead of below the navbar for these specific headers in both "Sub Menus" options. This results in a consistent mega menu position while preventing unintentional menu closure during cursor movement. task-[6116253](https://www.odoo.com/odoo/all-tasks/6116253) Co-authored-by: Arib Ansari <<aans@odoo.com>> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Orders placed online for in-store pickup with payment on site are now shown correctly in the POS order list. This lets store staff find and fulfill those orders as expected, avoiding missed or delayed pickups.
Original PR description
Step To Reproduce: - install `sale_management` and `website_sale_collect` and POS with demo - go to shop page, add a product -> checkout - Use `Pick Up in Store` feature and `Pay on site` payment…
Step To Reproduce:
- install `sale_management` and `website_sale_collect` and POS with demo
- go to shop page, add a product -> checkout
- Use `Pick Up in Store` feature and `Pay on site` payment method -> confirm
- notice a Sale order is created for this
- Open POS, try to fulfill the linked SO, by clicking on `Quotation/Order`
Observation:
- The SO is not visible in the list view
Cause:
- clicking on `Quotation/Order` initiates a search with domain `["amount_unpaid", ">", 0]`
https://github.com/odoo/odoo/blob/21e3b547e486951421e39733c19a8a2d54361e00/addons/pos_sale/static/src/app/components/screens/product_screen/control_buttons/control_buttons.js#L16
- `amount_unpaid` depends on `amount_paid` which is sum of all transaction in ("authorized", "done") state
https://github.com/odoo/odoo/blob/21e3b547e486951421e39733c19a8a2d54361e00/addons/sale/models/sale_order.py#L913-L916
- after commit [1], transactions with payment method of type `postpaid` are considered as `done` (`Pay on site` is postpaid)
https://github.com/odoo/odoo/blob/21e3b547e486951421e39733c19a8a2d54361e00/addons/website_sale_collect/models/payment_method.py#L9-L14
https://github.com/odoo/odoo/blob/21e3b547e486951421e39733c19a8a2d54361e00/addons/payment_custom/models/payment_transaction.py#L40-L41
- this makes `amount_paid ` to be full order amount and `amount_unpaid = 0` for the order and search fails in pos
[1] https://github.com/odoo/odoo/commit/9d01784fa9980fb9e4989e6e4e9f35909665e6ca
Fix:
- Fix the compute of `amount_unpaid` and do not count transactions amount from
postpaid payment method
Note: issue occurs for POS only, hence, we avoid changing anything from sale side
while keeping changes to minimum
opw-6424288
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#280864Fixed an issue in Restaurant Point of Sale where splitting a bill with combo meals could select only one repeated combo item instead of the full quantity. This helps restaurant staff split orders accurately and avoid billing mistakes when customers choose the same combo option multiple times.
Original PR description
Steps to reproduce: --- - Install `pos_restaurant` demo data. - Open a session for `Restaurant`. - Go to any table. - Add a Sushi Lunch Combo line with the same sushi choice multiple times. - Click the "More" button and select "Split". - Click on any combo product line. Issue: --- - Only one quantity is selected instead of the full combo choice quantity. Cause: --- - Combo child lines were incremented by a fixed value of `1` during split, without considering the quantity ratio between the combo root line and combo child lines. Fix: --- - Compute the selection step based on the combo line quantity relative to the combo root line quantity. - Properly update split quantities for repeated combo choices. - Added test coverage for combo lines with repeated quantities. task-6197879 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283876 Forward-Port-Of: odoo/odoo#264049
Sales users limited to their own documents can now cancel confirmed sales orders that include loyalty programs without hitting an access error. This prevents unnecessary administrator intervention and keeps order cancellation workflows moving smoothly.
Original PR description
Steps to produce: --- - Install `sale_management` and `sale_loyalty` module without demo. - From sales > products > discounts & loyalty, create new loyalty card program and save. - Now create new…
Steps to produce: --- - Install `sale_management` and `sale_loyalty` module without demo. - From sales > products > discounts & loyalty, create new loyalty card program and save. - Now create new product of 100$. - Create a user which have sales rights as `user: own documents only`. - With that user, create new sale order with product and confirm. - Try to cancel the order. Issue: --- - It shows the access error: ```py You are not allowed to delete 'Sale Order Coupon Points - Keeps track of how a sale order impacts a coupon' (sale.order.coupon.points) records. This operation is allowed for the following groups: - Sales/Administrator Contact your administrator to request access if necessary. ``` Root cause: --- - Users with the `Sales: Own Documents Only` access right only have read permissions ([1]). When they cancel a Sales Order, the `_action_cancel` method attempts to clean up the temporary pending points allocated to the order by calling `self.coupon_point_ids.unlink()`. Because this call is executed without elevated privileges, the system blocks the deletion and raises an Access Error Solution: --- - Added `.sudo()` to the `unlink()` call for `coupon_point_ids` in the `_action_cancel` method. This ensures the pending point records are cleaned up with the necessary elevated privileges. [1]https://github.com/odoo/odoo/blob/23af2b443735c6d3a2f64e44f9ea5da45638b052/addons/sale_loyalty/security/ir.model.access.csv#L16 opw-6453016 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284122 Forward-Port-Of: odoo/odoo#281477
This fix prevents customer and pickup details from disappearing when a guest returns from the online payment page in restaurant self-ordering. It ensures order information is saved before leaving for payment, reducing lost draft data and improving checkout reliability.
Original PR description
**Setup** * Increase the debounce time of `debouncedSynchronizeLocalDataInIndexedDB` to **5 seconds** to reproduce the issue deterministically. * Configure a restaurant with **Self Ordering** enabled…
**Setup** * Increase the debounce time of `debouncedSynchronizeLocalDataInIndexedDB` to **5 seconds** to reproduce the issue deterministically. * Configure a restaurant with **Self Ordering** enabled (`QR Menu + Ordering`). * Configure **Mollie** as the **only** online payment method. **Reproduction** 1. Place a **takeout** order through the mobile menu. 2. Select a pickup time, enter the required customer information (including a mobile number), and proceed to the payment page. 3. Verify from the backend that the draft order contains the expected data (customer/partner and `preset_time`). 4. Press the browser **Back** button to return from the payment page. 5. Check the draft order in the backend again. [video](https://drive.google.com/file/d/1kNWpYuo79mYMV3eMelwJ5IDFeWUc7zsD/view) **Observed result** * The draft order loses its previously synced information. In particular, the **partner/customer** data (and other synced fields such as `preset_time`) are removed. **Expected result** * Returning from the payment page should not modify the draft order. All previously synced data should remain intact. **Cause** - When there's only a single payment method, it's [auto-selected](https://github.com/odoo/odoo/blob/161715c850496d3683baa5d1600380470d0b5ff5/addons/pos_self_order/static/src/app/pages/payment_page/payment_page.js#L21-L22) and `checkAndOpenPaymentPage` immediately opens the payment page via[ window.open()](https://github.com/odoo/odoo/blob/161715c850496d3683baa5d1600380470d0b5ff5/addons/pos_online_payment_self_order/static/src/app/pages/payment_page/payment_page.js#L35). - The order's local data is saved to IndexedDB on a 300ms debounce. If the redirect fires before that debounce completes, the save is cancelled, leaving IndexedDB out of sync with the in-memory order **Fix** - Before opening the payment URL, explicitly flush the order to IndexedDB using the `synchronizeLocalDataInIndexedDB`, ensuring the local data is persisted before the page navigates away. opw-6231478 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283800 Forward-Port-Of: odoo/odoo#272724
Payslip reports and payroll screens now display titles, labels, worked days, and line items in the correct language instead of mixing employee, location, and user languages. This improves Belgian bilingual payslip compliance and makes payroll information clearer for HR teams and employees.
Original PR description
Payslips in Belgium must be printed in two languages (DMFA location and employee). However, the translation didn't seem to work as intended and there was an awkward mix of languages across both…
Payslips in Belgium must be printed in two languages (DMFA location and employee). However, the translation didn't seem to work as intended and there was an awkward mix of languages across both reports and views. While printed reports showed the payslip lines correctly translated, their labels and title stayed in the employee's language, and worked days reflected the active user's language. In backend views, the title used the employee's language, the lines used the DMFA language, and worked days used the active user's language. This behavior was caused by context language overriding and how the names were handled: - The XML report templates explicitly forced the language context to the employee's language, bypassing the Python logic that already set the correct environment language before rendering the templates. This is why the static text of the report stayed in the employee's language. - The `name` fields on `hr.payslip.line` and `hr.payslip.worked_days` acted as editable virtual related fields fetching a string from `salary_rule_id` or `work_entry_type_id`, with additional logic. Fields like that cannot be translated directly, and they were not being recomputed when the environment language changed (impossible for a stored field anyway). As a result, they were locked in the language they were first created in. - In Python, the language context was manually forced during line evaluation to the employee's language (or DMFA language in Belgium) specifically to populate those stored `line.name` fields upon creation. Combined with how the `name` field was defined, this locked the strings shown in backend views to that initial DMFA language. - To translate lines in reports despite those locked values, the XML templates used a workaround: checking if the slip was translated to print the translatable `line.salary_rule_id.name` instead of `line.name`. This explains why the payslip lines were the only part of the report that was translated correctly. - The payslip's `name` field was also a stored computed field that explicitly forced the employee's language both when translating the title string and when formatting period dates. Besides fixing the translations on printed reports, we decided it makes more sense for backend views to have everything in the active environment language. To fix this consistently across both views and reports, this commit applies the following changes: - Removed context language overrides from all report templates. - Removed the helper method forcing language context during computation. - Introduced a `custom_name` field on `hr.payslip.line` and `hr.payslip.worked_days`. - Made the `name` fields on `hr.payslip.line` and `hr.payslip.worked_days` non-stored computed fields depending on context language. They now return `custom_name` if set, or dynamically recompute the translated default string. The inverse method saves manual user edits to `custom_name`. - Cleaned up the reports to simply print the `name` field of each payslip line, removing the fallback workaround logic. - Updated the payslip's `name` field compute method (and date formatting helpers) to rely and depend on `self.env.lang` instead of the employee's language. Made this `name` field non-stored as well: storing it was useless since it was not editable in the form view (only `title` is), and would have prevented recomputation based on environment language changes. - Adapted the rest of the code, including half-day management in Belgium by adding a new `l10n_display_half_day` field to properly compute the name like before. - Deleted every assignment for the `name` fields that are now unstored. See odoo/upgrade#11092 Task-6432137
Point of Sale now includes partially paid invoices when preparing customer account settlements. This lets staff complete outstanding balances directly from the PoS instead of needing a separate back-office step.
Original PR description
Before this commit: ------------- - Only unpaid invoices were loaded into the PoS for settlement. - Partially paid invoices were not loaded and therefore could not be settled from the PoS. After this commit: ------------- - Load partially paid invoices into the PoS so they can also be settled from the PoS. Task-6438716
Fixed an issue that could prevent shortcuts from being created for documents shared with a group. The update also makes owner access handling more reliable when group-based access is assigned, helping teams share and organize documents without unexpected access problems.
Original PR description
Reproduce: try creating a shortcut for a document shared with a group. \+ increase robustness of logging owner access when creating a documents with an access command regarding a group. Task-6344800 Forward-Port-Of: odoo/enterprise#128926
Fixed an issue that prevented Colombian electronic vendor bill PDFs from being generated after the reception workflow. The system now correctly reads the invoice data when it is stored inside a compressed attachment, avoiding server errors and ensuring users can print the PDF as expected.
Original PR description
**Steps to reproduce:** * Install the **l10n_co_dian** module. * Go to **Settings** and, under **Colombian Electronic Invoicing**: * Disable **Testing Mode**. * Enable **DIAN Demo**. * Create a…
**Steps to reproduce:**
* Install the **l10n_co_dian** module.
* Go to **Settings** and, under **Colombian Electronic Invoicing**:
* Disable **Testing Mode**.
* Enable **DIAN Demo**.
* Create a vendor bill with a tax and confirm it.
* Click **Acknowledge Reception**.
* Click **Receive Goods**.
* Click **Accept**.
* From the gear menu, click **Print → Invoice PDF**.
**Observed behavior:**
* A server error is raised:
```
lxml.etree.XMLSyntaxError: Start tag expected, '<' not found, line 1, column 1
```
* The PDF cannot be generated.
**Cause (two-step):**
1. **ZIP not unwrapped:** The original code called `etree.fromstring(self.l10n_co_dian_attachment_id.raw)` directly for all move types. For vendor bills (`in_invoice`) the attachment is stored as a ZIP file, so `raw` is compressed binary data — not XML. Passing it to `etree.fromstring` directly produces the `XMLSyntaxError` above.
2. **AttachedDocument wrapper not unwrapped:** Once the ZIP is correctly decompressed with `xml_utils._unzip`, the resulting XML is an `AttachedDocument` wrapper, not a plain `Invoice`. The actual invoice XML is embedded as CDATA inside `cac:Attachment/cac:ExternalReference/cbc:Description`. `_get_qr_code_value` expects the inner document and searches for nodes like `cac:AccountingSupplierParty`, `cac:LegalMonetaryTotal`, and `sts:QRCode` — none of which exist on the outer wrapper, so the QR code was blank or the method crashed.
**Fix:**
* In `_l10n_co_dian_get_invoice_report_qr_code_value`, for vendor bills (`in_invoice`/`in_refund` without support document), unzip the attachment and immediately attempt to extract the inner invoice XML from `cbc:Description` using `findtext('.//{*}Description')` (lxml namespace wildcard). If the node is present, parse its text as the actual document; otherwise fall back to the unzipped bytes directly.
**Note:**
* A unit test for the `AttachedDocument` unwrapping path was not added because the test would require a zipped fixture file (the vendor bill attachment is stored as a ZIP) which is not appropriate to commit.
* A regression test was added in `test_accept_by_customer`: after the full commercial event flow the method is called inside a `try/except etree.XMLSyntaxError` block so that any XML parse failure surfaces as a proper test *failure* rather than an unhandled test *error*.
opw-6417422
Forward-Port-Of: odoo/enterprise#128908
Forward-Port-Of: odoo/enterprise#126463This fixes an issue in Brazilian POS electronic invoicing where the system could select the wrong tax configuration when sales and purchase taxes shared the same code. The correction helps prevent unbalanced accounting entries, improving reliability of POS tax reporting and bookkeeping.
Original PR description
The chart template gives the same Avatax code and price_include_override to the sale and the purchase tax, and creates both in the same transaction. Without an explicit type_tax_use the lookup used to return either of them at random, and picking the purchase one left the entry unbalanced. The purchase taxes got their Avatax code in 18.4+. https://github.com/odoo/enterprise/pull/101072 runbot-945969 Forward-Port-Of: odoo/enterprise#128872 Forward-Port-Of: odoo/enterprise#128476
Restores the HSBC H2H MRI file export option for Hong Kong payroll and autopay users after it was unintentionally removed. This ensures businesses can generate bank payment files with the required header format when submitting payments through HSBC.
Original PR description
In 19.2, during a refactor, the H2H feature for MRI file export (HSBC) was wrongly removed from the system. This makes it impossible to export a file with the correct file level header when needed. It would be difficult to add it back in stable, so we first update the master version to make sure it is back by Odoo 20. Note that instead of a setting like before, we decided to reintroduce it as a separate file type instead. task-6500843
VoIP user synchronization now has more time to complete before timing out. This helps reduce failed setup or update operations for phone users, especially when the process takes longer than expected.