Friday, May 22, 2026
42 changes · saas-19.1
Resolved issues and error corrections
This update optimizes PDF report generation by compressing files after merging, reducing file sizes and memory usage. This addresses a previous memory leak and leverages newer PDF library versions for better performance, particularly with large reports. The result is faster report generation and smaller file sizes.
Original PR description
When merging pages with pypdf, the resulting content is uncompressed. A compression pass should be done right after to reduce the resulting file size. Additionally, this helps alleviate a memory leak in PyPDF2 where resources in the merged page are not properly released. Newer versions of pypdf (>=3.15.4) do not have this leak but still see benefits in the output file size. In practice the CPU overhead is negligible, and we actually see a speed increase in cases with high memory usage. Benchmark Printing 400 page annual report | |Print Time|Peak Memory|Output File| |------|----------|-----------|-----------| |Before|142s |3.6GB |103MB | |After |127s |0.4GB |5MB | opw-6148786 Forward-Port-Of: odoo/odoo#264451 Forward-Port-Of: odoo/odoo#261879
This update optimizes PDF generation within Odoo by compressing merged documents, reducing file sizes and improving performance. It addresses a previous memory leak issue and leverages newer PDF library versions for better results. The change results in significantly smaller PDF files and faster processing times, particularly with large documents.
Original PR description
When merging pages with pypdf, the resulting content is uncompressed. A compression pass should be done right after to reduce the resulting file size. Additionally, this helps alleviate a memory leak in PyPDF2 where resources in the merged page are not properly released. Newer versions of pypdf (>=3.15.4) do not have this leak but still see benefits in the output file size. In practice the CPU overhead is negligible, and we actually see a speed increase in cases with high memory usage. Benchmark Printing 400 page annual report | |Print Time|Peak Memory|Output File| |------|----------|-----------|-----------| |Before|142s |3.6GB |103MB | |After |127s |0.4GB |5MB | opw-6148786 Forward-Port-Of: odoo/enterprise#117308 Forward-Port-Of: odoo/enterprise#115550
This update resolves an issue where users without specific accounting permissions would encounter an error when loading certain knowledge article templates. The fix delays access to sensitive audit reporting data, ensuring that only authorized users can perform this action. This improves the stability and usability of the knowledge article feature.
Original PR description
Steps to reproduce: 1. Install `accountant_knowledge` with `demo data` 2. Remove demo user from bookkeeper access right and give some lesser right 3. Open knowledge and create a new artical with demo user 4. Click on Load template for example `Meeting Minutes` Issue: It gives a access error: `This operation is allowed for the following groups: - Accounting/Bookkeeper` Cause: - accountant_knowledge was doing accounting-only work during generic template loading. Immediately calling `target_article._get_inherited_audit_report()` that returns `inherited_audit_report_id`, which is a computed relation to audit report. `audit.report` is only readable by `account.group_account_user` Solution: - delay that access until it is actually needed, - only if the template contains data-embedded="accountReport" opw-6067390 Forward-Port-Of: odoo/enterprise#112946
This update corrects a bug where tax calculations were incorrectly split on discount lines, particularly when orders were set to the Quebec fiscal position. The fix ensures that taxes are applied correctly, avoiding duplicate tax displays and maintaining accurate financial reporting. This improves order accuracy and reduces potential accounting errors.
Original PR description
Steps to produce: --- - Install `website_sale`, `l10n_ca` & `accountant` modules with demo data. - Switch to a `Canadian (CA) company.` - Go to Settings and enable` Discounts, Loyalty & Gift Cards`.…
Steps to produce: --- - Install `website_sale`, `l10n_ca` & `accountant` modules with demo data. - Switch to a `Canadian (CA) company.` - Go to Settings and enable` Discounts, Loyalty & Gift Cards`. - Go to` Website > eCommerce > Loyalty > Discount & Loyalty.` - Create a new program > Set Program Type to Discount Code > Under Conditional Rules, set Minimum Purchase to 0 > Under Rewards, choose Discount on Order. - Go to `website > configuration > websites` > Create a new website for the CA company > Set it as default (first in sequence). - Create new product > Set Sales Taxes to` 14.975% GST + QST` > Publish the product. - Open the website in an incognito window > Add the product to the cart > Apply the discount code. - In the main tab > Go to Website > eCommerce > Orders > Open the corresponding order > In the Other Info tab, change the fiscal position to Quebec (QC) > Click to update taxes. Issue: --- - The tax on the discount line is split into: 14.975% GST + QST & 9.975% QST. Root cause: --- - When a discount is applied in the cart, the discount line initially carries split taxes: 5% GST and 9.975% QST. - After changing the fiscal position to Quebec (QC), the system replaces 5% GST with 14.975% GST + QST because 5% GST is present in replace of 14.975% GST. so at [1] it replaces 5% GST with 14.975% GST and do nothing for 9.975% QST. - In 17.0, the discount line directly uses 14.975% GST + QST (no tax splitting), so this issue does not occur. - In 18.0, at [2], taxes are explicitly split and added to the base line, and the same split taxes are reused during grouping. This leads to multiple taxes being displayed on the sale order line. Fix: --- - Avoid splitting taxes on the discount line in the sale order. - Keep the original tax structure intact to prevent duplication after fiscal position changes. [1]https://github.com/odoo/odoo/blob/c6d9fa5873eb759846e9be5b66eedb8b00c5ac11/addons/account/models/partner.py#L151-L156 [2]https://github.com/odoo/odoo/blob/c6d9fa5873eb759846e9be5b66eedb8b00c5ac11/addons/sale_loyalty/models/sale_order.py#L296 opw-6145674 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265233 Forward-Port-Of: odoo/odoo#262147
This update fixes an issue where the Point of Sale system incorrectly applied AvaTax fiscal positions even when AvaTax wasn't activated in the POS. The system now correctly ignores AvaTax fiscal positions when a customer doesn't have a configured fiscal position, ensuring accurate tax calculations. This prevents unintended tax application and improves POS functionality.
Original PR description
**Steps to reproduce:** - Install Accounting and Point of Sale - In Accounting settings, activate "AvaTax" - Configure the AvaTax fiscal position and activate "Detect Automatically" option - Make…
**Steps to reproduce:** - Install Accounting and Point of Sale - In Accounting settings, activate "AvaTax" - Configure the AvaTax fiscal position and activate "Detect Automatically" option - Make sure that the other fiscal positions don't have that option set or that they are ordered after the AvaTax one - Go to the settings of a point of Sale - Activate "Flexible Taxes" and configure "Default" and "Allowed" - Make sure that AvaTax fiscal position is not allowed - Do not activate "AvaTax PoS Integration" - Open a POS session - Select a customer with an address in the US and without fiscal position - Check the fiscal position **Issue:** The selected fiscal position is the AvaTax one even though AvaTax is not activated in the POS. **Cause:** We force the use of a fiscal position if it is configured on a customer. In this case, as no fiscal position is configured on the customer, we try to retrieve one that matches the condition and the AvaTax one is selected. **Solution:** When searching for the fiscal position of a customer, if AvaTax is not configured in the POS and if its fiscal positions are not allowed in POS, we ignore the fiscal positions using AvaTax. opw-6154089 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263342
This update fixes an issue where the POS system incorrectly applied AvaTax fiscal positions even when AvaTax wasn't activated in the POS settings. The system now correctly ignores AvaTax fiscal positions when a customer doesn't have a defined fiscal position, ensuring accurate tax calculations for Point of Sale transactions. This improves the reliability of the POS tax functionality.
Original PR description
**Steps to reproduce:** - Install Accounting and Point of Sale - In Accounting settings, activate "AvaTax" - Configure the AvaTax fiscal position and activate "Detect Automatically" option - Make…
**Steps to reproduce:** - Install Accounting and Point of Sale - In Accounting settings, activate "AvaTax" - Configure the AvaTax fiscal position and activate "Detect Automatically" option - Make sure that the other fiscal positions don't have that option set or that they are ordered after the AvaTax one - Go to the settings of a point of Sale - Activate "Flexible Taxes" and configure "Default" and "Allowed" - Make sure that AvaTax fiscal position is not allowed - Do not activate "AvaTax PoS Integration" - Open a POS session - Select a customer with an address in the US and without fiscal position - Check the fiscal position **Issue:** The selected fiscal position is the AvaTax one even though AvaTax is not activated in the POS. **Cause:** We force the use of a fiscal position if it is configured on a customer. In this case, as no fiscal position is configured on the customer, we try to retrieve one that matches the condition and the AvaTax one is selected. **Solution:** When searching for the fiscal position of a customer, if AvaTax is not configured in the POS and if its fiscal positions are not allowed in POS, we ignore the fiscal positions using AvaTax. opw-6154089 Forward-Port-Of: odoo/enterprise#116626
This update ensures that event tickets are automatically created when an offline POS sale is later synced to the system. Previously, a page reload would cause the ticket creation to fail. The fix corrects a logic error in how the system manages offline order data, guaranteeing accurate ticket generation.
Original PR description
When selling event tickets in POS while offline, the order could be synced later but without creating event registrations (tickets) after a page reload. Steps to reproduce: ------------------- * Open…
When selling event tickets in POS while offline, the order could be synced later but without creating event registrations (tickets) after a page reload. Steps to reproduce: ------------------- * Open a POS session with `pos_event` * Sell an event ticket * Switch to offline mode * Validate payment while offline (order becomes paid but unsynced) * Reload/close and reopen POS, then reconnect * Let the order sync > Observation: The `pos.order` is created on the backend, but `event.registration` and `event.registration.answer` are missing so tickets are not generated. Why the fix: ------------ `pos_event` used `order.finalized` as IndexedDB cleanup condition for `event.registration` and `event.registration.answer`. For paid-but-unsynced orders, `finalized` is already true, so those records can be removed from IndexedDB too early. After reload, the order is restored/synced but without its event registration payload. Implementation: --------------- Use `order.canBeRemovedFromIndexedDB` instead of `order.finalized` for `event.registration` and `event.registration.answer` retention rules, so records are kept locally until the order is truly synced (server id assigned) or canceled. Test Note: --------------- Use case is hard to simulate exactly. Add a basic unit test to assert both registration models are kept for paid unsynced orders and only removable once synced. opw-6056079 Forward-Port-Of: odoo/odoo#265201 Forward-Port-Of: odoo/odoo#256615
This update resolves an issue where signed PDFs lost their original bookmarks and links, disrupting navigation and document integrity. The fix ensures that signed documents retain their original structure and functionality, allowing users to easily navigate and access information within the signed PDF.
Original PR description
Version - 18.0 Steps to reproduce: 1. Upload a PDF document containing bookmarks and internal/external links. 2. Sign the document and download the signed PDF. 3. Open the downloaded file and check the bookmarks and links. Issue: When a signed document was downloaded, the original PDF bookmarks And the links were not working. This broke structured navigation and affected document integrity. Fix: The PDF signing process has been updated to preserve the original bookmarks and ensure internal and external links remain functional after signing. Impact: - Signed documents remain navigable and consistent with the original PDF. - Preserves document structure and integrity. Task- 4915124 Forward-Port-Of: odoo/enterprise#117881 Forward-Port-Of: odoo/enterprise#108684
This update fixes an issue where Peppol-imported invoices weren't automatically shown in the chatter window alongside their attachments. The change ensures that the XML invoice files generated from Peppol are correctly linked to the chatter message, providing better visibility for users. This improves the tracking and management of these invoices.
Original PR description
**Steps to reproduce:** 1) Install l10n_be and configure Peppol demo mode. 2) Open debug mode, search for 'Peppol: retrieve new documents' in scheduled action. 3) Open the generated vendor draft…
**Steps to reproduce:** 1) Install l10n_be and configure Peppol demo mode. 2) Open debug mode, search for 'Peppol: retrieve new documents' in scheduled action. 3) Open the generated vendor draft bill. 4) Observe that the imported XML is present in attachments but not in chatter. **Cause:** In the (`_import_ubl_invoice_post_processing()`) https://github.com/odoo/odoo/blob/27cc9b920ad6818563b471dd3391548913790ef3/addons/account_edi_ubl_cii/models/account_edi_ubl.py#L3344 chatter attachments were built from: `self._import_attachments(invoice, collected_values['tree'])` This only includes embedded extra documents and emits the source imported XML attachment. As a result, the XML remained stored on the move (ubl_cii_xml_file) but was not linked to the chatter message. **Solution:** Include the source attachment when building the chatter attachment set. opw-6197738 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264399
This update fixes an issue where discounted UBL invoice lines were being incorrectly removed during import. Previously, lines with a zero total amount were filtered out, even if the supplier had applied a discount, leading to lost data. Now, the system correctly retains lines with zero totals or discounts, ensuring accurate reconciliation with original invoices.
Original PR description
`_import_ubl_invoice_add_base_lines` filters out every imported line whose `total_included_currency` is zero, on the assumption that a zero-amount line carries no useful information. This is correct for truly empty rows, but wrong for 100%-discounted lines, an ecotax or excise row, or a returnable-packaging entry nets to zero precisely because the supplier discounted it entirely, and the line still carries data the customer needs to reconcile the bill against the original document opw-6176349 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265284
This update fixes an issue where calls were not accurately reflecting the number of open tickets associated with their parent partners. Previously, open tickets on child partners weren't counted. Now, all open tickets linked to a call's parent partner are correctly displayed, providing a more complete view of support requests.
Original PR description
Unlike most of *_count fields on res.partner, for example ticket_count, open_ticket_count didn't take into account of its child partners. To reproduce: 1. create parent parent P and child partner C 2. create a ticket for partner C and put it in a unfold stage 3. call partner P and open form view of this call the open ticket count on the smart button is 0 instead of 1 In this commit, we change it that when a child partner has open tickets, they will also be counted as parent partner's. Forward-Port-Of: odoo/enterprise#115303
This update fixes a visual issue in the termination fees report, ensuring payslips have a clean and properly aligned layout. The previous design used a fixed row count that caused misalignment when fewer lines were present. The fix dynamically adjusts the layout for better readability and consistency.
Original PR description
**Steps to Reproduce:** 1. Generate a termination slip for an employee 2. The generated payslip pdf layout looks clumsy and misaligned. **Bug Cause:** 1. The notice duration has rowspan="3" expecting 3 lines. When there are less than 3 lines, the following rows are affected and misaligned. 2. The border is missing. **Solution:** Added dynamic sizing for notice duration instead of static rowspan="3". Used index instead of line_count for both notice duration and banks to stay consistent and simple. Added table-bordered class as borders are not automatically applied like in previous versions. **Task:** 6193558
This update fixes an issue where alternating row colors were incorrectly applied, often resulting in the table header and first row having the same background color. The change ensures alternating row colors are consistently applied to odd rows, improving the visual clarity and readability of tables within the HTML editor.
Original PR description
### Purpose of this PR: Previously, alternating row colors were applied on even rows. When a table header was enabled, the header row and first body row could end up sharing the same background color. This PR updates the alternating row logic to apply colors on odd rows instead. task-6204622 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where applying a combo to an order already sent to the backend would cause the original order items to reappear after a page refresh. The fix ensures that the order is synchronized with the backend after a combo is applied, providing a consistent and accurate view for the user.
Original PR description
Steps to reproduce: - Make an order that could be a combo - Send the order to preparation - Apply the combo - Refresh page => A new combo appears and the original orderlines are still there. Issue: When applying a combo to an order that has already been sent to the backend it is not synched with the backend so when you refresh the original orderlines are fetched from the backend. Fix: If the orderlines have been sent to the backend sync the order after applying the combo. 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
This update fixes a problem where Point of Sale orders weren't correctly calculating payments and invoices, leading to errors. The fix ensures that order details are properly updated during the validation process, resolving the 'No cash statement found' error and preventing 'entry not balanced' issues when generating invoices. This improves the reliability of the POS system.
Original PR description
### Steps to reproduce: - Download 'Point of Sale' and 'Contacts' app - Create a customer with a pricelist that includes a percentage discount - Create a shop with the following properties: - Default…
### Steps to reproduce:
- Download 'Point of Sale' and 'Contacts' app
- Create a customer with a pricelist that includes a percentage discount
- Create a shop with the following properties:
- Default preset = 'Takeout' with a standard 40hr/week schedule
- Payments = 'Card' and 'Customer Account'
- Pricelists = a 'Default' and the discounted pricelist
- Create a POS order (without choosing a customer)
- Add products to the order, and select 'Customer Account' payment method
- Select the created customer
* Pricelist applies → Order total decreases.
* Payment now exceeds total → Negative change shown.
- Disable 'Invoice' checkbox.
- Click 'Validate' → Show popup 'No cash statement found for this session.'
- Again click 'Customer Account' → Add another payment line (negative).
- Process the order payment
- Close Session
- Try to create an invoice for the order
> Error: Entry not balanced
### Cause of Issue:
When 'Validate' is clicked for the first time and `syncAllOrders()` is called, `serializeForORM()`
clears the `_dirty` state tracking after the serialization. https://github.com/odoo/odoo/blob/418b103dab782d81a33d2a7afd8ec3767d7a82df/addons/point_of_sale/static/src/app/services/pos_store.js#L1501-L1534
When the 'No cash statement found' error occurs, the backend rolls back the changes made to the
order lines.
Then, since the `order.lines` weren't marked as dirty (no changes occured to them) and `payment.ids`
were marked as dirty, when 'Validate' is clicked for the second time, the js side doesn't send the
`order.lines` again, so the backend uses the existing, undiscounted lines.
The mismatch happens because while the product lines are undiscounted, the `payment.ids` are
correct (because a new 'Customer Account' line was added, so `payment.ids` were sent again).
Hence, `amount_total` and `amount_paid` were calculated with discounts applied, while individual
`line.price_unit` values remained at list price, resulting in invoice line amounts not matching
the amount paid and causing "entry not balanced" errors during invoice generation.
### Fix:
Preserved the `_ dirty` state commands, ensuring that when the order is reserialized on retry,
the line data are included in the second `sync_from_ui` payload.
opw-6080597
Forward-Port-Of: odoo/odoo#259636This update resolves an issue where the delivered quantity for dropship products was incorrectly set to 1 before order confirmation. The fix ensures the quantity accurately reflects stock availability and triggers the necessary calculations when a purchase order is created, improving dropship order accuracy.
Original PR description
### Steps to reproduce: - In the settings enable dropshipping - Create a storable product P, enable the dropshipping and set a vendor - Create and confirm a sale order for a field service - Open the…
### Steps to reproduce: - In the settings enable dropshipping - Create a storable product P, enable the dropshipping and set a vendor - Create and confirm a sale order for a field service - Open the related task > Products > Add 1 unit of P - Go back to the sale order > an RFQ has been created #### > The delivered quantity of P is set to 1 ### Cause of the issue: Since 2361368acfe7fecbffde2ca26392eb89aecdc9e1 the `_inverse_fsm_quantity` method manually adapts the delivered quantity based on the fact that the `product.service_type` is `manual` rather than the `qty_delivered_method` of the line or future line is. In particular, because these lines: https://github.com/odoo/enterprise/blob/8f4fe902cb71c49bdb3caf9915f9a5abfe6f237f/industry_fsm_sale/models/product_product.py#L82-L83 provide a value of the `qty_delivered` to the created purchase order line and since the `qty_delivered_method` is a precomputed field: https://github.com/odoo/odoo/blob/fdfd9851393ff82a265997478886bcad6da357d0/addons/sale/models/sale_order_line.py#L225-L237 The fact that the purchase order line will be created with a `stock_move` `qty_delivered_method` and that the generated PO does not generate any move prior to confirmation will not trigger the dependency of the `qty_delivered` to retrigger a computation of the `delivered_qty` of the product which is suppose to be based on stock pickings: https://github.com/odoo/odoo/blob/fdfd9851393ff82a265997478886bcad6da357d0/addons/sale/models/sale_order_line.py#L871-L876 https://github.com/odoo/odoo/blob/fdfd9851393ff82a265997478886bcad6da357d0/addons/sale_stock/models/sale_order_line.py#L193-L198 Leaving the created sol with a delivered quantity of 1 prior to confirmation of the PO (which will generate move_ids related to the sol and trigger the compute). Fix: The changes of 2361368acfe7fecbffde2ca26392eb89aecdc9e1 regarding the `_inverse_fsm_quantity` appears unjustified with respect to the purpose of the fix. In addition, the `qty_delivered` and changes are already expected to be properly computed when the `qty_delivered_method` is not manual, particularly since the '`manual'` `service_type` is actually the default `service_type` corresponding to any 'consu' product and looks unrelated by any mean to the `delivered_qty` computation: https://github.com/odoo/odoo/blob/fdfd9851393ff82a265997478886bcad6da357d0/addons/sale/models/product_template.py#L165-L167 opw-6104326 Forward-Port-Of: odoo/enterprise#117727 Forward-Port-Of: odoo/enterprise#115760
This update fixes an issue where the End Balance figures in the Romanian Trial Balance reports were inaccurate when the report hierarchy was enabled. The fix prevents double-counting of account groups, ensuring the trial balance totals align correctly and provide accurate financial reporting for Romanian businesses.
Original PR description
### Issue before this commit: The total row for the End Balance columns in the Romanian 4-column and 5-column Trial Balance reports displayed incorrect values when the report hierarchy was enabled. ### Steps to reproduce the issue: 1. Downaload Accounting and l10n_ro 2. Switch to RO company 3. Go to Trial Balance report and be sure that Posted Entries, Accrual Basis are setted on Hierarchy and Subtotals 4. See that the End Blance both debit and credit is not correct ### Cause of the issue: The _custom_line_postprocessor method iterated over all report lines indiscriminately, adding account group subtotals to the running accumulator and causing duplicate counting. ### Reason to introduce the fix: To eliminate group double-counting and providing consistency with the totals in all the trial balances reports. opw-6146200 Forward-Port-Of: odoo/enterprise#117855
This update resolves an issue where employees on flexible work schedules were incorrectly flagged for overtime. The fix adjusts how the system calculates expected work hours, now accurately considering the employee's flexible calendar hours instead of relying on outdated synthetic schedules. This ensures accurate overtime calculations for employees with varied work arrangements.
Original PR description
**Steps to reproduce:** - Create a flexible 32h/week calendar (8h/day, 4 days) - Assign it to an employee with the Default Ruleset - Create attendances: 8h on Monday, Tuesday, Friday, and Saturday…
**Steps to reproduce:** - Create a flexible 32h/week calendar (8h/day, 4 days) - Assign it to an employee with the Default Ruleset - Create attendances: 8h on Monday, Tuesday, Friday, and Saturday (32h total, matching the weekly budget) - Select the list view and go to the month of the attendances - Employee shows 16:00 Worked Extra Hours (8h on Fri + 8h on Sat) **Cause:** `resource.calendar._attendance_intervals_batch` generates work intervals for flexible calendars by front loading the weekly hour budget onto the first days of the week (Mon 8h, Tue 8h, Wed 8h, Thu 8h for a 32h calendar), But days beyond the budget (Fri, Sat, Sun) get zero hours. The two overtime rule paths relies on these synthetic intervals: 1) The quantity rule: `_get_daterange_overtime_undertime_intervals_for_quantity_rule()` computed `expected_duration` by intersecting the synthetic schedule with each day. For Fri/Sat the intersection was empty (expected = 0) -> all worked hours counted as overtime. https://github.com/odoo/odoo/blob/b31fd6816521ff43fb3a9ec37e79e9a9d628d357/addons/hr_attendance/models/hr_attendance_overtime_rule.py#L302-L304 **update** solved by: https://github.com/odoo/odoo/pull/265120/changes/94d4bfffa053cd78ce07ff07ab14b53e8d931053 2) The timing rule: `_get_rules_intervals_by_timing_type()` derived "work_days" from the synthetic schedule and inverted them to get "non_work_days". (Fri, Sat, Sun) were classified as non-working days, therefore, any attendance on those days triggered full overtime. https://github.com/odoo/odoo/blob/b31fd6816521ff43fb3a9ec37e79e9a9d628d357/addons/hr_attendance/models/hr_attendance_overtime_rule.py#L421-L433 **Solution:** For flexible calendars in the overtime rule consumer: - Quantity rules: read expected hours directly from the calendar's `hours_per_day` / `hours_per_week` instead of the synthetic schedule intervals, subtracting any leaves in the period - Timing rules: treat the entire attendance date range (minus leaves) as potential work days, so that `non_work_days` is empty for flexible employees (they can work any day of the week) opw-6067063 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263840
This update corrects a bug in the generic tax report that prevented error messages from appearing when dealing with negative net values. The fix ensures that the report accurately identifies discrepancies in tax amounts, even when balances are negative, improving report reliability. This resolves an issue impacting tax reporting accuracy.
Original PR description
**Issue:** In the generic tax report, a check is performed on the report lines to ensure that the declared tax amount is consistent with the expected amount. If the difference between the declared tax amount and the expected one is higher than 0.1% of the declared net amount, then a error message is displayed. If the net amount is negative, the error message is never displayed because the computed percentage of the tax difference is negative and therefore lower than 0.1% (i.e. 0.001). opw-6014350 Forward-Port-Of: odoo/enterprise#117990
This update resolves a display issue in the eCommerce mega menu builder. Previously, the menu would become empty and cause errors when a user had categories linked to the website but none of those categories had a product marked as 'published'. This change ensures the mega menu only appears when there are actual products to display, improving the user experience.
Original PR description
Steps to reproduce: =================== 1. Create a product, link it to an eCommerce category, keep it unpublished. 2. Create a mega menu, edit it. 3. Enable "eCommerce Categories" and try to change…
Steps to reproduce:
===================
1. Create a product, link it to an eCommerce category, keep it unpublished.
2. Create a mega menu, edit it.
3. Enable "eCommerce Categories" and try to change the number of columns.
=> Mega menu is empty and a JS error is logged in the console.
Cause:
======
The "eCommerce Categories" toggle in the mega menu builder appears whenever any `product.public.category` exists for the website. Once toggled, the eCommerce mega menu templates (`s_mega_menu_multi_menus`, etc.) are server-rendered and the resulting HTML is stored on `website.menu.mega_menu_content`.
Since [1] , those templates filter their with
`('has_published_products', '=', True)`. So when the user has categories but no published product, enabling the toggle produces an empty `<div class="row"></div>`. Clicking the column-count option on that empty row which won't have any children and it will cause an error.
Solution:
=========
Adapt the toggle on the same condition the templates use, so it is only offered when there is at least one category that will actually be rendered.
[1]: https://github.com/odoo/odoo/commit/120a7633505891ba3e02e879f0c1a8287a690456
opw-6218503
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#265615
Forward-Port-Of: odoo/odoo#265190This update resolves a bug that prevented invoices from being sent correctly in demo mode when using the Nemhandel integration. The fix involved updating the system's handling of data transmission to align with a recent architectural change, ensuring invoices can now be successfully processed. This improves the reliability of the demo environment.
Original PR description
Steps to reproduce:
1. Install l10n_dk_nemhandel.
2. Register user for Nemhandel in Demo mode.
3. Create and post an invoice.
4. Click Send, check 'By Nemhandel (Demo)', and send.
-> Traceback: IndexError: tuple index out of range in _mock_send_document.
Cause:
The Nemhandel mocking system was halfway refactored to align with the Peppol
mocking architecture. As a result, the `_call_nemhandel_proxy` method now
passes the request payload as a keyword argument (`params={...}`) instead of
positional argument (`args[1]`). The mock functions were still attempting to
access `args[1]`, causing the crash.
Solution:
Update the mock functions to extract the payload directly from
`kwargs.get('params', {})`, removing the obsolete positional argument (args)
fallback to align with the new EDI architecture.
task-6065372
Forward-Port-Of: odoo/odoo#260574This update resolves an issue where invoices sent to Jofotara were being rejected due to extremely small negative discount amounts. The fix ensures that discount amounts are always non-negative by applying an absolute value function, preventing errors and ensuring proper invoice processing. This improves compatibility with the Jofotara system.
Original PR description
Before this commit: 1. Create a POS order with no discount and a quantity that does not divide evenly into the unit price (e.g. price=10.0, qty=3) 2. Send the order to Jofotara Jofotara rejects the…
Before this commit:
1. Create a POS order with no discount and a quantity that does not divide evenly into the unit price (e.g. price=10.0, qty=3)
2. Send the order to Jofotara
Jofotara rejects the invoice because the AllowanceCharge/Amount on the invoice line is a small negative value like -0.000000001 with the error `"EINV_MESSAGE":"discount cannot be negative"`
This happens because _add_document_line_gross_subtotal_and_discount_vals computes the discount as: gross_subtotal - total_excluded_currency
where gross_subtotal goes through two independent rounding steps (round unit price, then round unit_price * qty). When the quantity is indivisible, the reconstituted gross_subtotal can land just below total_excluded_currency by a floating-point epsilon, producing a tiny negative discount. The same subtraction also produces a legitimate negative value for refund lines (negative quantity), which was already handled by abs() in _add_pos_order_discount_vals for the document-level total but was left unguarded at the per-line level.
After this commit:
Apply abs() to vals[f'discount_amount{currency_suffix}'] in _add_pos_order_line_allowance_charge_nodes so that discount_amount_currency is always non-negative.
opw-6183423
Forward-Port-Of: odoo/odoo#265159This update corrects a visual glitch in the Point of Sale (POS) Restaurant module where a notification badge continued to appear after a general note was removed. The fix ensures that removing a note resets the system to its correct state, eliminating the persistent badge and improving the user experience. This resolves an issue reported in the Enterprise version.
Original PR description
Steps to reproduce:
-----------
- Open POS Restaurant
- Add a General Note
- Remove the General Note
- The message badge on “Send to Kitchen” remains visible
Issue:
-----------
Removing a General Note set `general_note` to `undefined`, which was
detected as a change and kept the badge visible.
Fix:
--------------
Normalize empty General Notes to an empty string ("") so removing a note
restores the correct initial state.
Task-6101501
Related PR: odoo/enterprise#113514
Forward-Port-Of: odoo/odoo#265652
Forward-Port-Of: odoo/odoo#258632This update resolves an issue where removing a general note from a restaurant orderline caused the preparation display to incorrectly mark the line as cancelled and create a new one. The fix ensures that note history is recorded regardless of whether the note is confirmed, allowing the system to accurately update existing orderlines instead of creating duplicates.
Original PR description
Steps to reproduce: --------- 1. Create an order with an orderline general note. 2. Send the order to the preparation display. 3. Remove the note from orderline. 4. Resend the order Issue: --------------- Removing the note changes the preparation line key, so the preparation display marks the old line as cancelled and creates a new one instead of updating the existing line. Cause: ----------- The note history was only recorded when the note was confirmed. If the user simply removes/clears the note, no note history entry is generated, so the backend cannot match the previous key with the updated key. Fix: ---------- Record note history even when the note is discarded (not only when confirmed. This allows the backend to match the old and new keys and update the line instead of cancelling it. Task-6101501 Related PR - https://github.com/odoo/odoo/pull/258632 Forward-Port-Of: odoo/enterprise#117943 Forward-Port-Of: odoo/enterprise#113514
This update resolves an issue where users on Android 14 couldn't access their device's camera when selecting files through the image input field. The fix ensures users can now take photos directly through the image input, improving usability on this platform. This change addresses a compatibility problem with recent Android versions.
Original PR description
Since Android 14 we don't have option to take a photo on clicking on file input in Chrome.
This for example will allow only images but no option "Camera"
```html
<input type="file" accept="image/*/>
```
A workaround is to use a dummy mimetype (`*/*`), example `dummy/allowAndroidCamera` The fix will be applied on image widget in addition to the original `acceptedFileExtensions` to not override the existing `accept` attribute
You can test the different behaviour here: https://jsfiddle.net/n0vs6h3b/
Linked url
https://blog.addpipe.com/html-file-input-accept-video-camera-option-is-missing-android-14-15/ https://stackoverflow.com/questions/77876374/html-input-type-file-not-working-to-pull-up-camera-for-pixel-android-14-comb/79163998#79163998 https://issues.chromium.org/issues/40937303
opw-6040375
Forward-Port-Of: odoo/odoo#265750