Daily updates from Odoo
Monday, May 18, 2026
56 changes · saas-19.3
Resolved issues and error corrections
This update simplifies the process of retrieving transactions from Codabox. Previously, a write access check was required, even with an established connection. This change removes that unnecessary check, streamlining the process and improving efficiency.
Original PR description
Currently, we use the `_l10n_be_codabox_verify_prerequisites` method before trying to fetch transactions. This method checks if the user has write access rights on res.company model which should not be mandatory to fetch transactions from codabox when the connexion is already created. opw-6108811 Forward-Port-Of: odoo/enterprise#117097
This update resolves an issue where pressing Enter after a styled heading created a new paragraph that incorrectly inherited the heading's formatting (like color). The fix ensures that newly created paragraphs are empty and without inherited styles, aligning with the expected behavior. This improves the consistency and predictability of the HTML editor.
Original PR description
Problem: Pressing Enter at the end of a styled heading (e.g., with a color) creates a new paragraph that inherits the heading styles. This is no longer the expected behavior. The new paragraph should be empty and without inherited styles. Solution: When splitting a heading at its boundaries and creating a base container, fill it with a `br` instead of carrying over styles. Steps to reproduce: - Add a heading. - Apply a style (e.g., color). - Place the caret at the end of the heading. - Press Enter. - Observe that the new paragraph still has the heading color. task-6147897 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264624 Forward-Port-Of: odoo/odoo#262150
This update resolves an issue where test emails sent through the Email Marketing app would leave a related attachment visible in the chatter of contact records. The fix ensures that test messages are properly removed from the Chatter after sending, preventing clutter and improving the user experience. This improves the clarity of communication within the system.
Original PR description
**Steps to reproduce:** - Go to Email Marketing app - Create a mailing campaign - Set its recipients to Contact - Upload a file in Settings > Attach a file - Click on the test button to send a test mail to any mail - Go to the first contact record - Related attachment appears in the chatter **Issue:** Before 18.2, messages created for testing were ignored by the Chatter as they were empty (and not unlinked). But if an attachment was provided, it was linked to the test message and not deleted afterwards (which means it shows up in the record chatter). **Fix:** Ensure the related messages are unlinked at the same time as the test mail in `send_mail_test` by setting `is_notification` to False to trigger the `unlink` logic and remove the related attachments at the same time. backport of: https://github.com/odoo/odoo/commit/526b3d73886558315f2435714b2ed82fec313e78 opw-6168632 Forward-Port-Of: odoo/odoo#263139 Forward-Port-Of: odoo/odoo#262152
This fix resolves an issue where generating closing entries in the Inventory Valuation view produced incorrect results when multiple companies were selected. The update ensures that the generated account move lines accurately reflect the stock valuation data for the selected main company, preventing mismatched balances.
Original PR description
**Problem:** In view Inventory valuation, generate entry doesn't work when multiple companies are selected. In the view only the main company matters. That means that even if multiple companies are…
**Problem:** In view Inventory valuation, generate entry doesn't work when multiple companies are selected. In the view only the main company matters. That means that even if multiple companies are selected, only the stock variation lines related to the main company selected are displayed (which is expected). But if you then click on 'generate entry' the account move lines created will have wrong values (not matching the values appearing in the view) **Steps to reproduce:** - create 2 new companies (to have clean accounting) - create a warehouse for both companies - for both comp, in settings for the 'fiscal localization' set Package : Generic Chart of account, if not already set (to have account journals). From company 1 : - create a storable prod with avco perpetual category - confirm PO for 2 @ 10, receive - bill only 1 @ 10 From company 2: - make sure the category is also perpetual average from this other company - confirm PO for 2 @ 50, receive, don't bill Notice how from the 'Inventory Valuation' view, rightfully, only the main company matters (no matter what other comp are selected): - If main comp is comp 1 there is stock variation lines for amount of 10 (which is expected because we have 20 in stock and only 10 in stock valuation account) - If main comp is comp 2 there is stock variation lines for amount of 100 (which is expected because we have 100 in stock and only 0 in stock valuation account) With comp 1 and 2 selected and comp 1 as main company: - click on 'Generate Entry' **Current behavior:** - both line have a balance of 110 **Expected behavior:** - they should have a balance of 10 as we saw on the 'inventory valuation' view **Cause of the issue:** To generate the data from the 'inventory valuation' view, inside _get_report_data() we call stock_value() and stock_accounting_value() to compare values from inventory and value from accounting. https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/stock_account/report/stock_valuation_report.py#L36-L37 stock_value() sums total_value() of each product in the valued accounts https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/stock_account/models/res_company.py#L90-L94 Whereas stock_acounting_value(), sums the balance of each account move line of each valuation account https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/stock_account/models/res_company.py#L112-L114 All of this is related to the main company because we call _get_report_data() with context 'allowed_company_ids' set to only the main company https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/stock_account/report/stock_valuation_report.py#L13 But when we click on generate entry, _get_stock_valuation_account_vals() is called with no context modification to 'allowed_company_ids' so when we call stock_value(), https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/stock_account/models/res_company.py#L238-L239 total_value will be based on both company https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/stock_account/models/res_company.py#L92 Note that stock_accounting_value() is still rightfully based only on main company because we use self.id in the domain https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/stock_account/models/res_company.py#L105-L108 opw-6168699 Forward-Port-Of: odoo/odoo#263946 Forward-Port-Of: odoo/odoo#262776
This update fixes a visual issue in the project timesheet reporting. Previously, the 'Time Remaining' value wasn't highlighted in red when it was a negative number, which could be confusing for users. The fix ensures the value is correctly colored red when negative, improving clarity and accuracy of time tracking data.
Original PR description
**Steps to reproduce:** - Open project shared form view. - Go to the Timesheets tab. - Observe the Time Remaining value. **Issue:** - The Time Remaining label is red properly but its value does not becomes red even when the value is negative. **Fix:** - Adjusted the logic to ensure the Time Remaining value is highlighted in red when value is negative **Task-id: 5404009** Forward-Port-Of: odoo/odoo#260996 Forward-Port-Of: odoo/odoo#240489
This update corrects a visual inconsistency in the project timesheet interface. Previously, the 'Time Remaining' value wasn't highlighted in red when the time was negative. This fix ensures that negative time values are correctly displayed with a red warning indicator, improving clarity and accuracy for users managing project time.
Original PR description
**Steps to reproduce:** - Open project shared form view. - Go to the Timesheets tab. - Observe the Time Remaining value. **Issue:** - The Time Remaining label is red properly but its value does not becomes red even when the value is negative. **Fix:** In hr_timesheet, the remaining_hours field has a decoration-danger applied In sale_timesheet_enterprise, this field is overridden as portal_remaining_hours So, Added the corresponding decoration-danger on portal_remaining_hours. task-5404009 Forward-Port-Of: odoo/enterprise#114836 Forward-Port-Of: odoo/enterprise#113632
This update fixes an issue where dependent taxes weren't correctly recalculated after a base tax was removed from a sales order or invoice. The fix ensures that tax amounts are accurately computed, particularly when using the 'Affect Base of Subsequent Taxes' setting. This improves the reliability of financial reporting.
Original PR description
**Steps to reproduce:** * Install the *Accounting* module with French localization (*l10n_fr_account*). * Create a *Sales Tax* with: * A new tax group (e.g., 'Codifab'). * Enable *Affect Base of…
**Steps to reproduce:** * Install the *Accounting* module with French localization (*l10n_fr_account*). * Create a *Sales Tax* with: * A new tax group (e.g., 'Codifab'). * Enable *Affect Base of Subsequent Taxes*. * Create a *Sales Order*: * Add the first tax (with *Affect Base of Subsequent Taxes*). * Then add the second tax (eg VAT tax). * Confirm the *Sales Order*. * Create a *Down Payment Invoice* (percentage-based). * Open the generated invoice and: * Remove the first tax (the one affecting the base). **Observed behavior:** * The amount of the second tax group does not update after removing the first tax, leading to incorrect tax computation. **Cause:** * In `_import_base_line_extra_tax_data`, the condition: `all(str(tax.id) in extra_tax_data['manual_tax_amounts'] for tax in sorted_taxes)` only ensured partial matching of taxes. * This allowed reuse of stale `manual_tax_amounts` when taxes were removed or modified, causing incorrect base values for dependent taxes (e.g., *Affect Base of Subsequent Taxes*). **Fix:** * Update the condition to enforce an exact match between current taxes and cached `manual_tax_amounts` by checking both size and membership. * Prevent reuse of outdated tax data when taxes change, ensuring proper recomputation of dependent taxes. * Align Python logic with the JS implementation for consistency between `account_tax.py` and `account_tax.js`. opw-6063970 Forward-Port-Of: odoo/odoo#264710 Forward-Port-Of: odoo/odoo#259566
This update fixes an issue where the FEC file parser would fail due to empty lines. The change now automatically skips these empty lines, ensuring all valid FEC files are processed correctly and preventing errors. This improves the reliability of the French localization import process.
Original PR description
It could happens that we have some empty lines in the fec files, the parser was returning an error when that happened. We still want to process the file so we will just skip the empty lines. task-6169168 Forward-Port-Of: odoo/enterprise#115758
This update corrects a technical issue in the French Intrastat export process. Previously, supplementary unit data for products with CN codes was being incorrectly omitted from the DEBWEB2 XML file. This fix ensures that all relevant quantity information is accurately included, improving the reliability of Intrastat reporting.
Original PR description
Steps to reproduce 1. In a French company with Intrastat enabled, set up a product whose commodity code has a CN supplementary unit (e.g. 8802 30 00, "p/st") and set…
Steps to reproduce
1. In a French company with Intrastat enabled, set up a product whose commodity code has a CN supplementary unit (e.g. 8802 30 00, "p/st") and set `intrastat_supplementary_unit_amount` on it.
2. Post EU customer invoices for that product.
3. Export the DEBWEB2 XML from the Intrastat report.
Issue
The FR export collapses engine rows a second time in `_group_items`, because the DEBWEB2 format groups more aggressively than the SQL. The aggregator only declares `value` and `weight`: https://github.com/odoo/enterprise/blob/6ae5d3df6e9305416e4d6f74259cd01753025f42/l10n_fr_intrastat/models/account_intrastat_report.py#L308-L313 Items are then rebuilt as `dict(zip(grouping_key, key_tuple)) | grouped_item_values`. `SU_code` survives (it is in the grouping key), but the numeric `supplementary_units` is in neither side and is silently dropped as soon as two engine rows merge. The template then skips the element because of its `t-if="item.get('supplementary_units')"` guard: https://github.com/odoo/enterprise/blob/6ae5d3df6e9305416e4d6f74259cd01753025f42/l10n_fr_intrastat/data/intrastat_export.xml#L61
opw-6139657
Forward-Port-Of: odoo/enterprise#117357
Forward-Port-Of: odoo/enterprise#117033A recent test for live chat duration was unreliable due to a race condition in how the system handled agent state changes. This fix addresses this issue by splitting the test to avoid the problematic state transitions, ensuring the test runs consistently. This improves the overall reliability of our live chat monitoring.
Original PR description
The `show looking for help duration in the sidebar` test has been flaky since [1]. The root cause is that the agent joins at the final step, resetting the state to in_progress, then immediately…
The `show looking for help duration in the sidebar` test has been flaky since [1]. The root cause is that the agent joins at the final step, resetting the state to in_progress, then immediately switches it back to `looking_for_help`. This creates several race conditions: - Bus notifications from `join_livechat_need_help`, new message events, and any other notification carrying stale state data. - Channel state fetched after the user joins via `/mail/data`. The mock server makes these races hard to guard against: notifications arrive one by one, and there's no UI signal that guarantees all stale data has been processed. This commit splits the test to preserve coverage while avoiding the problematic rapid state transition. runbot-242278 [1]: https://github.com/odoo/odoo/pull/252738 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#264666
This update resolves an issue preventing successful Envia deliveries in Chile. The problem stemmed from a mismatch between Odoo's state code mapping and Envia's API requirements. The Envia API expects a shorter state code (2-3 digits), which wasn't being applied correctly for the 'Metropolitana' region. This fix updates the mapping to ensure accurate data transmission to Envia.
Original PR description
### Steps to reproduce: - Install delivery_envia - Website > Configuration > eCommerce > Delivery Methods > Envia - Enable the delivery method, sync the carrier and Publish it - With a portal user >…
### Steps to reproduce:
- Install delivery_envia
- Website > Configuration > eCommerce > Delivery Methods > Envia
- Enable the delivery method, sync the carrier and Publish it
- With a portal user > Shop > Add any product to your cart > Checkout
- Register an address a valid 'Chile' address and confirm say:
'street and Number': Avenida Providencia 1432, Depto 402
'city': Santiago 'zip': 8320000
'country': Chile 'state': Metropolitana
#### > Envia Error: Invalid Option - String is too long at #->properties:destination
### Cause of the issue:
The problem is caused by the fact that Envia's api expects a 2-3 digits to represent state codes: https://docs.envia.com/reference/state-by-code
The mapping from Odoo's code state representation to envia's one is expected ot be performed by this mapping:
https://github.com/odoo/enterprise/blob/75cba6d5a88ebc4e0f35040a173ac1c443638daf/delivery_envia/models/envia_request.py#L27-L43 when the address is converted here:
https://github.com/odoo/enterprise/blob/75cba6d5a88ebc4e0f35040a173ac1c443638daf/delivery_envia/models/envia_request.py#L535-L542 That being said, the `Chile`'s code states of have been changed in [6694a3942c58ff1a56c9e4b36edbe126dd1e66f8](https://github.com/odoo/odoo/commit/6694a3942c58ff1a56c9e4b36edbe126dd1e66f8) to match the official Iso but not in the Envia's mapping leading a failling match keeping the 4 charracter long `CL-RM` of the `Metropolitan` state provided in to the Envia's api as address data.
opw-6210007
Forward-Port-Of: odoo/enterprise#117280A crash in the event registration modal was resolved by ensuring the modal is fully closed before attempting to manipulate its elements. This change prevents errors that occurred when switching between event views, improving stability and user experience.
Original PR description
Steps to reproduce: =================== 1. Go to Event, open an event page 2. Click "Register" & Select a ticket and confirm 3. Switch to edit mode => crash. Cause: ====== The cleanup callback called…
Steps to reproduce: =================== 1. Go to Event, open an event page 2. Click "Register" & Select a ticket and confirm 3. Switch to edit mode => crash. Cause: ====== The cleanup callback called `hide()` followed immediately by `dispose()`. Bootstrap's `hide()` is asynchronous — it registers a `transitionend` callback that fires `_hideModal()` after the CSS transition. `dispose()` nullifies `this._element` synchronously via `BaseComponent`, so when the `transitionend` fires and `_hideModal()` tries to access `this._element.style`, it crashes with: TypeError: Cannot read properties of null (reading 'style') This happened when switching to edit mode while the event registration modal was open: the `public.interactions` service stopped the interaction, triggering the cleanup. Solution: ========= Listen for `hidden.bs.modal` (fired at the end of `_hideModal`) and only `dispose()` inside that handler, ensuring `_element` is still valid throughout the transition. task-6133395 Forward-Port-Of: odoo/odoo#264365
A recent change in the Odoo system caused the remaining time for sales projects linked to orders to no longer be displayed correctly. This PR restores a key setting that ensures the remaining time is shown, resolving this visual issue for users managing sales projects. It's a minor fix impacting the display of project timelines.
Original PR description
Steps to Reproduce: - Open any project linked with a sales order - Open task and click on Sale Oder Item dropdown. Issue: - You can see that SOL's with time remaining don't show the amount of time left Reason: - In this PR https://github.com/odoo/odoo/pull/193079 a record (view_task_form2_inherit_sale_timesheet) has been removed. - So the context key `with_remaining_hours` required to show remaining time is missing. Fix: - Add the record back which updates context task-6170953 Forward-Port-Of: odoo/odoo#262746
This update resolves an issue where the Microsoft SwiftKey keyboard caused incorrect selection updates within the HTML editor, leading to unexpected focus shifts. By caching the selection on each change, the system now accurately reflects the user's intended selection, improving the editor's stability and usability.
Original PR description
Problem: When using the Microsoft SwiftKey keyboard, placing the caret at the beginning of a table cell and triggering a `beforeinput` event can result in `getSelection()` returning an incorrect selection. Notably, the selection immediately before the event is correct, but it changes unexpectedly without firing a `selection_change` event. Solution: Cache the selection whenever a `selection_change` event fires, ensuring we keep the last correct selection set by the user or editor. Steps to reproduce: - Edit a table with an empty cell. - Place the caret inside the empty cell. - Press Backspace. - Observe that the focus moves to the previous cell unexpectedly. task-6150731 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264769 Forward-Port-Of: odoo/odoo#259798
This update fixes an issue where the rental report was displaying incorrect dates. The fix ensures that each row in the report accurately reflects the start and return dates of the rental order, providing more reliable reporting data. This improves the accuracy of rental tracking and analysis.
Original PR description
The rental report is a daily report with x rows by rental order, with x the days between the start and return dates. With generate_series inside the select, the query was creating x rows with the same id, resulting in the date field not being correctly displayed (one unique date, the start date). This fix corrects the generation of the report to display the real date on each row. opw-5266525 Forward-Port-Of: odoo/enterprise#106235 Forward-Port-Of: odoo/enterprise#104764
This update resolves an issue where creating two overtime shifts on the same Saturday (ending at midnight) would trigger an error. The fix addresses a timing discrepancy in how overtime start and end times are calculated, preventing the 'Expected singleton' error. This ensures overtime is correctly registered for employees with complex shift schedules.
Original PR description
__ ## Short functional explanation of the error When we create 2 shifts for the same day for an employee, on a non-working day for their schedule. When trying to create the second one after setting…
__ ## Short functional explanation of the error When we create 2 shifts for the same day for an employee, on a non-working day for their schedule. When trying to create the second one after setting the end date to midnight, we get the error: `ValueError: Expected singleton: hr.attendance.overtime.line(2, 3)` ## Reproduction Steps 1. Create an Employee. In the Payroll tab, Make sure they have an active contract. Set their Working Hours to a fixed schedule, where they have saturdays as non-working days. In the Settings tab, set an Overtime Ruleset. 2. Click on the overtime ruleset. Then, for each rule, under Action, set the Work Entry Type To Use as Overtime Hours. 3. Go to Attendances. In Configuration > Settings, under Extra Hours, set the Extra Hours Validation as Approved By Manager. 4. Create an attendance for your Employee on a Saturday, from 12h to 18h. 5. Create a second attendance for your Employee on that same Saturday, from 18h to 00h00. Try to Save. Note: the timezone of your computer, the working schedule and the employee should be set at Brussels time. ### Expected behavior The Overtime is registered. ### Unexpected behavior An error occurs: `ValueError: Expected singleton: hr.attendance.overtime.line(2, 3)` ## Origin of the issue The end time of the overtime is defined as follows: https://github.com/odoo/enterprise/blob/47faff7d6c9da5572e3bad3ff5a55b40c2ba81ac/hr_work_entry_attendance/models/hr_version.py#L54-L56 However, in the case where our shift ends after the computed end of the day (in our case, the end time of the shift is 00:00:00 and the end of the day is set at 23:59:59), it creates some problems. The end time of the overtime is set 1 second too early. Later we compute the start time of the overtime as follows: https://github.com/odoo/enterprise/blob/47faff7d6c9da5572e3bad3ff5a55b40c2ba81ac/hr_work_entry_attendance/models/hr_version.py#L57 Thus, the time start of the overtime is also set one second too early. As our second shift starts right after the first one, after the execution of this code, we will get a second shift that starts before the end of the first one. Then, we add these values in a list: https://github.com/odoo/enterprise/blob/47faff7d6c9da5572e3bad3ff5a55b40c2ba81ac/hr_work_entry_attendance/models/hr_version.py#L59 which will contain overlapping timeframes, and with which we create an Interval: https://github.com/odoo/enterprise/blob/47faff7d6c9da5572e3bad3ff5a55b40c2ba81ac/hr_work_entry_attendance/models/hr_version.py#L60 But when we create an Interval with overlapping timeframes, we obtain only one interval as the timeframes are merged. https://github.com/odoo/enterprise/blob/47faff7d6c9da5572e3bad3ff5a55b40c2ba81ac/hr_work_entry_attendance/models/hr_version.py#L173 As a result, `overtime_intervals` will contain only one time frame with 2 different corresponding overtimes, which causes a singleton error when reaching: https://github.com/odoo/enterprise/blob/47faff7d6c9da5572e3bad3ff5a55b40c2ba81ac/hr_work_entry_attendance/models/hr_version.py#L179 __ opw-6096454 Forward-Port-Of: odoo/enterprise#117247 Forward-Port-Of: odoo/enterprise#114147
This update fixes an issue where scanning a packaging barcode (like '6' for a 6-pack) intermittently added quantities to the wrong line in the stock picking process. The fix ensures the barcode scan correctly identifies and updates the intended packaging unit, resolving the alternating quantity issue.
Original PR description
Issue ----- When there are 2 lines for a single product and different packaging uoms, scanning a packaging barcode alternates between lines. Steps to reproduce ----- - Enable packagings - Create a…
Issue ----- When there are 2 lines for a single product and different packaging uoms, scanning a packaging barcode alternates between lines. Steps to reproduce ----- - Enable packagings - Create a product AAA - barcode 1 - Create a packaging 6-Pack - 6 units - barcode for AAA set to 6 - Create a PO - one line for 30 units of AAA - one line for 5 6-Pack of AAA - Confirm PO and open picking in barcode - Scan "6" multiple times > Quantity increases on both lines, alternating for each scan Cause ----- Both lines can be found as matching lines when doing https://github.com/odoo/enterprise/blob/d279632db25713dd639a51385cad197dfdbd2bdc/stock_barcode/static/src/models/barcode_model.js#L1426 The reason it alternates between the lines is because we set the currently selected line first in the array - and since both lines match, the `foundLine` returned ends up being the non-selected line. https://github.com/odoo/enterprise/blob/d279632db25713dd639a51385cad197dfdbd2bdc/stock_barcode/static/src/models/barcode_model.js#L1823-L1832 We can avoid this y refining the `break` condition of the loop to also match the packaging uom. ----- Ticket: opw-6034572 Forward-Port-Of: odoo/enterprise#116961 Forward-Port-Of: odoo/enterprise#112578
This update resolves an issue preventing the MPESA payment method from correctly processing transactions initiated by Safaricom. It disables CSRF checks on callback endpoints and ensures URLs are consistently using HTTPS, addressing a common error related to invalid URLs. Additionally, the code now includes the till number for transactions, improving data accuracy.
Original PR description
1. The `MPESA` payment method needs a callback url where it does a `POST` request with the transaction details. Since the call comes from safaricom, CSRF will block those requests. This commit will…
1. The `MPESA` payment method needs a callback url where it does a `POST` request with the transaction details. Since the call comes from safaricom, CSRF will block those requests. This commit will disable CSRF checks on the callback endpoints which are expected to be called from an external service 2. Sometimes the `web.base.url` parameter is automatically set to http. But safaricom expects https for all the urls. So we need to ensure that the urls we send on `lipa_na_mpesa_register_urls` use https, otherwise the registration fails with an `invalid url` error. Additionally, I added the error message in case of error 4. In addition to the business short code we also need a till number for transactions. Since this is stable, I've added the till number as an extension of the business shortcode field and then parse it before usage. On master there is a new PR which will properly separate the fields Task-[6045833](https://www.odoo.com/odoo/project/1737/tasks/6045833) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254993
This update corrects a display issue with the Folder report layout when using Right-to-Left (RTL) languages like Arabic. The change involves adjusting the report's image styling to ensure it aligns correctly within the RTL layout, improving readability and presentation for users in those languages. This resolves a visual bug impacting invoice printing.
Original PR description
Steps: - Enable rtlcss - Install an RTL language (e.g Arabic or change english direction to rtl) - Enable RTL language - Go to settings - Configure report layout document - Select Folder type - Try to print an invoice - The header title style is broken the svg image used in the title should be mirrored to be displayed correctly on RTL opw-6140277 Forward-Port-Of: odoo/odoo#263115 Forward-Port-Of: odoo/odoo#262830
This update corrects a technical issue that prevented accurate payroll calculations when a payrun had no associated payslips. The fix ensures the system functions correctly regardless of the number of payslips processed, improving payroll accuracy and reliability. This resolves a potential disruption to payroll processing.
Original PR description
If the payrun does not have any payslips, the _get_payslip_stp is called on an empty recordset, which causes the compute to fail. This commit fixes the _get_payslip_stp compute for empty recordset. task-6215823 Forward-Port-Of: odoo/enterprise#117198
This update corrects a technical error in the 'my department' holiday reporting test. The test was incorrectly creating duplicate employee records, which could have caused data inconsistencies. The fix ensures the test uses the existing employee record for the demo user, preventing this issue and maintaining data integrity.
Original PR description
Issue: The test was creating a new employee linked to the demo user, but if the demo user already had an employee, it would violate the (user_id, company_id) uniqueness constraint. Fix: Before creating a new employee, we check if the demo user already has one. If not, we create it, otherwise we use the existing one. task-6050719 Forward-Port-Of: odoo/odoo#263224
This update resolves an issue where a warning message persisted after canceling a payslip in the payroll system. The change ensures that the warning is cleared, providing a cleaner and more intuitive user experience. This improves the reliability and usability of the payroll module.
Original PR description
. Clear payslip warning after cancelling the payslip . Add corresponding tests task-6199148 Forward-Port-Of: odoo/enterprise#117418 Forward-Port-Of: odoo/enterprise#116859
This update fixes an issue where pasting content into the composer created excessive nested divs, preventing users from correctly deleting pasted text. The fix also adds necessary plugins to properly handle links within the composer, ensuring accurate link selection and deletion.
Original PR description
Currently, when pasting content into the composer, we sanitize it by stripping all tags except a few allowed ones, and this creates a lot of nested divs in the pasted content. This prevents the content from being deleted correctly when the user is in the nested divs and presses backspace. For links, we currently missing the plugin that correctly handles them in the composer, this commit adds it and also adds the missing plugin LinkSelectionPlugin and OdooLinkSelectionPlugin for the composer. task-6214020 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264135
This update fixes a bug that prevented multi-day shift records from appearing on the live map. Now, technicians' locations and shifts are accurately displayed, and the map views (Gantt and Calendar) are optimized to show shifts on a daily basis, improving usability.
Original PR description
This commit changes the domains for the "My Map" and "Map By Resource" to only include shifts with a partner. Previously, it was including 'today' as part of the domain, which is incorrect as users may still want to view other days' shifts. task-6180159
This update ensures that all employee groups, regardless of their type, receive the correct employer-paid rent posting account in payroll. Previously, this setup was limited to a single group, leading to inconsistencies. This change maintains accurate and predictable payroll accounting.
Original PR description
Before this commit, the employer-paid rent setup was only applied to one employee group. This could leave other employee groups without the expected rent posting account. After this commit, the same rent posting setup is applied for each available employee group. This keeps payroll accounting behavior consistent. Task-6175007
A test was failing due to inconsistencies in how account reports were loaded during automated testing. This update ensures the test accurately reflects the system's behavior by generating the necessary account reports within the test itself. This resolves a runbot error and maintains the stability of the account reporting functionality.
Original PR description
Previously, embedded account reports always loaded the global account report. A fix introduced in version 19.0 changed this behavior so that the system now loads the most appropriate audit report,…
Previously, embedded account reports always loaded the global account report. A fix introduced in version 19.0 changed this behavior so that the system now loads the most appropriate audit report, specifically, the account report corresponding to the audit report's company (see: odoo/enterprise#101377). In version 19.1, a test was added to validate account report options. However, this test assumed that embedded account reports would always load the global account report (i.e., `account_reports.balance_sheet`). When tests run on runbot, demo data is not loaded. In that context, no report variants exist in the database, so the system falls back to the global account report, causing the test to pass. In environments where demo data is loaded, a report variant does exist, and the system correctly selects it instead of the global report. As a result, the test assertions are no longer valid and fail, leading to runbot errors. To address the issue, we will generate the account reports within the `setup` method of the test. This ensures that the assertions remain consistent, regardless of whether demo data is present. runbot-error-id~242235 Forward-Port-Of: odoo/enterprise#117075 Forward-Port-Of: odoo/enterprise#112486
This update fixes an issue where the departure date wasn't correctly displayed when an employee has multiple versions (e.g., contract and notice period). The change ensures the system accurately reflects the employee's departure date, improving payroll and reporting accuracy. This impacts how employees' end dates are tracked.
Original PR description
__ ## Short functional explanation of the error When we set the departure of an employee. The version is retrieved using the dismissal date. However, employees can work after their dismissal date,…
__ ## Short functional explanation of the error When we set the departure of an employee. The version is retrieved using the dismissal date. However, employees can work after their dismissal date, until their departure (in the case of a notice, for example). Therefore, the departure date should be chosen instead. ## Reproduction Steps 1. Go to Employees and create a new employee. In the Payroll tab, set a start date for their contract. Hit save. 2. This will create a version. You can see it top right, with the contract date. Click on the '+' next to it and set a date later. 3. Click on the cog in the top left and click End of Collaboration. Set an End Reason. Set the Dismissal Date to occur during the first version and the Departure Date to occur during the second version. Then, click Schedule. ### Expected behavior The Departure tab should appear when clicking on the second version, top right. ### Unexpected behavior The departure tab appears on the first version. ## Origin of the issue To select the version on which the departure occurs, we use this line of code: https://github.com/odoo/odoo/blob/be8b1bbad757fda27df579ce36cbc97324f58f62/addons/hr/models/hr_employee_departure.py#L117 `departure_date` should be used instead. __ opw-6079675 Forward-Port-Of: odoo/odoo#264667
This update ensures that employees on leave, even those in companies a user doesn't have access to, now correctly display a 'leave' icon in channel listings and avatar cards. Previously, the system was restricted by company access, leading to inaccurate status indicators. This change improves the user experience by providing a more complete and reliable view of employee availability.
Original PR description
* = hr_holidays Before this commit, when displaying the IM status icon for employees on leave of companies the user does not have access to, we would not display the `fa-plane` icon or the "Back on"…
* = hr_holidays Before this commit, when displaying the IM status icon for employees on leave of companies the user does not have access to, we would not display the `fa-plane` icon or the "Back on" indicator. Steps to reproduce: - Create a new company X - Create a new employee Y (with user) in company X - With a user who does not have access to company X open the General channel member list -> no leave icon, open the avatar card -> no icon This happens because since [1] the leave IM status icon is computed client side using the employee information, rather than computed on the `im_status` field itself. This however causes problem in a multi-company context due to the field `employee_ids@ResUsers` having a field-level domain restricting to the requesting user's active companies. This commit fixes the issue by fetching all of the user's employee_ids regardless of active company. [1] https://github.com/odoo/odoo/pull/210189 task-6191367 Forward-Port-Of: odoo/odoo#263024
This update resolves an issue where the chatbot restart button on the feedback panel could fail, leaving the live chat in an error state. Now, the button is disabled when the chatbot hasn't completed its process, preventing errors and ensuring a smoother user experience. This improves chatbot reliability.
Original PR description
Before this commit, it was possible to restart the chatbot on the feedback panel when closing the chat window. This was actually failing when the chatbot was stopped before the last step was completed and left the livechat state in error. Now, the button is simply disabled on feedback when we did not reach the end of the chatbot to avoid any issue. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258601 Forward-Port-Of: odoo/odoo#257891
This change fixes an issue where products were incorrectly displayed on the website when a user's website company was set to a different company than the product's assigned company. The update ensures product searches accurately reflect the user's current company setting, preventing incorrect product visibility and potential sales order errors. This improves data accuracy and sales process reliability.
Original PR description
# Setup Have 2 companies : A & B # How to reproduce - Set your website's company to Company B - Create product X : - Company : Company A - Published - Name : xyz - Go to Users > Any User > Acces…
# Setup
Have 2 companies : A & B
# How to reproduce
- Set your website's company to Company B
- Create product X :
- Company : Company A
- Published
- Name : xyz
- Go to Users > Any User > Acces Rights > Allowed Companies => leave only Company A
- Connect as that user on the website
- Go to the Shop tab and search xyz
# The problem
The product X is displayed, even though we currently use the company B's website and the product is limited to company A.
This causes problem later when Sales Order are created using that product.
If you set the Allowed Companies of the user to both Company A and Company B, then the product is correctly hidden
# Why
When you search something in the search bar, the server does a `_search_with_fuzzy()` that ends up calling a simple `model.search()`.
In our case, this search should not return product X because there is an `ir.rule` that hides product not in the current company :
https://github.com/odoo/odoo/blob/0bb5ac6c1a87367c1ebb343ad6e6e6e56188cf13/addons/product/security/product_security.xml#L34-L38
But the `website` module has some particular rule about setting the current company :
https://github.com/odoo/odoo/blob/0bb5ac6c1a87367c1ebb343ad6e6e6e56188cf13/addons/website/models/ir_http.py#L249-L261
So, in our case, since the user does not have company B in its allowed companies, then
`allowed_company_ids` = Company A. So `('company_id', 'parent_of', company_ids)` is trucy and the product is displayed
# Proposed solution
Doing the search with `with_company` raise an AccessError because the company is not present in the allowed_companies. Chaging the allowed companies logic seems risky because it
may lead to unintended side effects.
We instead enforce the website's company in the search's domain
opw-6115647
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#262635
Forward-Port-Of: odoo/odoo#260138This update fixes an issue where payroll account merges incorrectly combined employee analytic distributions, leading to inaccurate financial reporting. The change ensures that each employee's specific distribution is preserved, preventing the overwriting of percentage allocations when multiple employees use the same accounting account. This improves the accuracy of payroll accounting and financial data.
Original PR description
Steps to reproduce 1. Enable "Batch Account Move Lines" in the Payroll settings. 2. Configure two employees' versions with an analytic distribution on the same analytic account but with different…
Steps to reproduce
1. Enable "Batch Account Move Lines" in the Payroll settings.
2. Configure two employees' versions with an analytic distribution on the
same analytic account but with different percentages (e.g. {acc: 50}
for the first employee and {acc: 70} for the second).
3. Generate a payslip run containing both employees and validate it.
Issue
The generated account move aggregates the two payslips into a single
line whose analytic_distribution matches only the last employee being
processed; the other employee's percentage is silently lost.
`_get_existing_lines` decides whether an incoming line can merge into an
already accumulated one. When the incoming line has an analytic
distribution, the merge condition delegates to
`_check_partially_matching_accounts`:
https://github.com/odoo/enterprise/blob/e4a1326c7a8a74da7970aeaa9900c19d01634e31/hr_payroll_account/models/hr_payslip.py#L254-L271
https://github.com/odoo/enterprise/blob/e4a1326c7a8a74da7970aeaa9900c19d01634e31/hr_payroll_account/models/hr_payslip.py#L273-L283
That helper returns True as soon as any analytic account of the new
line appears anywhere in the existing line's distribution dict, without
comparing percentages. Two distributions such as {acc: 50} and
{acc: 70} share the same account, so the helper returns True, the
lines are merged, and whichever distribution ends up on the merged line
overwrites the other — the total amount is correct but the analytic
split is wrong.
The logic introduced in commit https://github.com/odoo-dev/enterprise/commit/e40a3166286a6bc546e9543b935233d2a110dc52 successfully addressed merging for rule-level distributions
with composite keys (e.g., {'13,7,12': 40}). However, that implementation is overly inclusive for employee-specific distributions.
It fails to differentiate between cases where the same analytic account is utilized across various employees but with different percentage allocations.
Because it only checks for an account overlap rather than a perfect distributional match, it incorrectly aggregates distinct financial dimensions into a single journal line
Solution
Compare the full analytic_distribution dict by strict equality. Lines
merge only when the distribution is identical (same keys AND same
percentages), keeping the batch feature anonymizing identically
configured employees while preserving one line per distinct
distribution.
opw-6102508
Forward-Port-Of: odoo/enterprise#114156This update corrects a minor visual glitch where overlays (like dialog boxes) sometimes appeared twice when initially displayed. The change improves the stability and reliability of the user interface by preventing unnecessary re-renders, resulting in a smoother user experience.
Original PR description
Before this commit, sometimes an overlay such as Dialog could flicker and render twice on mount. This comes from implementation details for detecting whether the overlay comes from shadow DOM or…
Before this commit, sometimes an overlay such as Dialog could flicker and render twice on mount. This comes from implementation details for detecting whether the overlay comes from shadow DOM or website, to determine which overlay container should decide to display the overlay [1]. The code relies on presence of the root id in the DOM and overlay container was relying on presence of `ref.el` to get the root id from DOM. This was motivated by `isVisible(overlay)` whose computation was also relying on the ref [2] but this has the drawback that `ref.el` was sometimes not yet available immediately on 1st rendering. Solution of [1] was to re-renderer whenever `ref.el` is set, but another solution that prevents a re-render is to have the root id in the `env`. This commit changes the solution of [1] by instead `rootId` in the `env`. The new solution has the benefit to not require a re-render of the overlay container, which prevents undesirable flickers that may happen on mounting an overlay for the 1st time. [1]: odoo#169264 [2]: odoo#154349 Forward-Port-Of: odoo/odoo#263860
This update fixes an issue where the average inventory cost calculation in the 'Inventory at Date' report was inaccurate. Specifically, when using the AVCO cost method, the calculation was incorrectly influenced by the standard price instead of actual costs, leading to incorrect reported values. This ensures accurate inventory valuation reports.
Original PR description
When we open the Stock report at date, we filter out moves anterior to that date and, if the cost method is AVCO, Odoo recompute the `avg_cost` up to that point of time with `_run_average_batch`. However, when iterating over the moves, `move._get_value(at_date)` might return a value calculated from the current standard_price if the move is not associated with any accounting entry or PO/SO. Steps to reproduce the issue: 1. Create a new product with AVCO cost method 2. On the product form, set the cost to 5$ 3. Manually adjust the inventory to 5 units 4. Create a PO and receive 5 products at a unit cost of 10$ > Total value: 75$ > Total quantity: 10 units > avg_cost: 7.5$ 5. Navigate to Stock report and run "Inventory at Date" at current time 6. avg_cost is 8.75$ instead of 7.5$ Ticket: opw-5951072 Forward-Port-Of: odoo/odoo#257705 Forward-Port-Of: odoo/odoo#253659
This update resolves an issue where livechat conversations wouldn't automatically mark as read after ending. Now, the system correctly triggers the 'read' state when a conversation is in focus, ensuring agents see accurate read statuses for closed chats. This improves agent efficiency and provides a clearer view of ongoing interactions.
Original PR description
**Description of the issue this PR addresses:** Previously, when a livechat conversation ended, it was never automatically marked as read. The existing `mark_as_read` mechanism depends on the…
**Description of the issue this PR addresses:** Previously, when a livechat conversation ended, it was never automatically marked as read. The existing `mark_as_read` mechanism depends on the composer being focused, but ended livechat conversations hides the composer, and the chat window does not focus the thread automatically (focus only happens on explicit click). This made it impossible for the read state to be triggered through the normal path, leaving agents with persistent unread indicators on closed livechat conversations. **Desired behavior after PR is merged:** - Focus the composer when present. - Focus the conversation otherwise. This ensures the read state is correctly triggered when the conversation is effectively in focus. task-[5900038](https://www.odoo.com/odoo/project/1519/tasks/5900038) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263607 Forward-Port-Of: odoo/odoo#253609
This update fixes a technical issue related to how Point of Sale orders are created. Specifically, it allows for the inclusion of important data during order generation, streamlining the process and ensuring more complete order information. This change is related to a larger effort to improve the Enterprise version of Odoo.
Original PR description
In this commit: ================ This commit allows `getEmptyOrder()` to receive `data` and apply it when creating an order. Task-6217580 Related Ent PR-https://github.com/odoo/enterprise/pull/117378
This update resolves an issue where depositing money in Point of Sale orders incorrectly triggered a preset selection popup. The change ensures that deposit orders are immediately identified as 'settling accounts,' preventing the popup and streamlining the deposit process. This improves the user experience for cash transactions.
Original PR description
Before this commit: ==================== depositing money for a partner in PoS with presets enabled could incorrectly trigger the preset selection popup. This happened because the order was not marked as is_settling_account early enough, so the preset selection logic did not ignore deposit orders. After this commit: ===================== is_settling_account is initialized during order setup and seeded immediately when the deposit order is fetched or created. As a result, deposit orders correctly bypass the preset selection flow. Task-6217580 Related Comm. PR-https://github.com/odoo/odoo/pull/264572
This update fixes an issue where Colorado state income tax calculations resulted in a positive value on payslips, which is incorrect. The fix aligns with established payroll tax principles, ensuring that taxes are always withheld from employee paychecks, not reported as refunds. This ensures accurate payroll reporting.
Original PR description
## Issue When generating a payslip for an employee of a company located in Colorado, the *CO State Income Tax* could end up positive. ## Steps to reproduce 1. Install *United States - Payroll*…
## Issue
When generating a payslip for an employee of a company located in Colorado, the *CO State Income Tax* could end up positive.
## Steps to reproduce
1. Install *United States - Payroll* (`l10n_us_hr_payroll`)
2. Set the current company's State to Colorado
3. Create an employee and a contract
- Wage: $0
- (Set the contract's status to *Running*)
- (In the payroll tab) State Withholding Allowance: $1000
4. Create a Payslip for the employee
- Structure: *"United States: Regular Pay"*
5. Compute Sheet
6. **In the _Salary Computation_ tab, the _CO State Income Tax_ line has a positive value**
## Justification
This fix is similar to the one applied for the AL(abama) state income tax by https://github.com/odoo/enterprise/commit/f0eeb55f1e3cf965c6a409675813d4a699e5fca6. That modification was justified by CAS (PO of US localizations for Payroll) in opw-5137280:
> *"Payroll taxes are always funds withheld from employee's paychecks, if there is a positive value it means the tax is a refund, not a withholding. Refunds happen when individuals file their income."*
## Note to reviewer
The test [`test_069_al_state_tax_0_income`](https://github.com/odoo/enterprise/blob/219d2a797ee2099c9d77c2defc9c9c5e1d504ffe/test_l10n_us_hr_payroll_account/tests/test_salary_rules.py#L957-L989) (added by the aforementioned commit https://github.com/odoo/enterprise/commit/f0eeb55f1e3cf965c6a409675813d4a699e5fca6) is wrongly indented and thus never executed. The test passes with the dedicated fix, and fails without it, as expected. Let me know if you want me to indent it correctly (in this commit or in an additional one).
opw-5999856
Forward-Port-Of: odoo/enterprise#117232
Forward-Port-Of: odoo/enterprise#112724This update corrects a bug where the 'Purchase Orders' button disappeared when changing an Analytic Account's plan. The fix adjusts how the system identifies purchase orders linked to analytic accounts, ensuring the button remains visible regardless of the plan setting. This ensures users can always access purchase order details linked to their accounts.
Original PR description
# How to reproduce - Enable the analytic accounting in the settings - Create a PO - Add a PO line - Set the Analytic Distribution of that PO line to an Analytic Account of your choice - Confirm the…
# How to reproduce
- Enable the analytic accounting in the settings
- Create a PO
- Add a PO line
- Set the Analytic Distribution of that PO line to an Analytic Account of your choice
- Confirm the PO
- Create a Vendor Bill from that PO and confirm the VB
- Go to the Analytic Account chosen before
- Change the Plan of that Analytic Account
# The problem
When the Plan is not set to the "Project Plan", the Purchase Orders smart button disappears
# Why
The Purchases Orders smart button is invisible if the variable purchase_order_count is equal to 0. That field is computed by a function that does a search with the following domain :
```py
[('order_line.invoice_lines.analytic_line_ids.account_id', '=', account.id)]
```
When we change the Plan of the Analytic Account, analytic_line_ids.account_id is set to NULL, so the search return nothing.
Why is that field set to NULL ?
Well, to reference its plan, an Analytic Line does not use a python-defined field. In fact, each time a new Analytic Plan is added to the database, a new column is added to the Analytic Line model. That column's name is x_plan{plan.id}_id or, for the specific case of the "Project Plan", it is account_id
When the Plan of an Analytic Account is changed, it takes every Analytic Line associated with that Plan and switch which column containing the id of the Analytic Account.
Take for exemple the following Analytic Line :
```
(account_id = NULL, x_plan2_id = NULL, x_plan3_id = 1)
```
When the associated Analytic Account's Plan is changed to the "Project Plan", it becomes :
```
(account_id = 1, x_plan2_id = NULL, x_plan3_id = NULL)
```
So, we need to adapt to search so that it uses the right plan's name.
opw-5897037
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#263652
Forward-Port-Of: odoo/odoo#248236This update corrects a bug where the payment button was incorrectly displayed, preventing users from completing transactions. Previously, the system relied on an outdated check for KYC completion, now the system correctly determines if payment initiation is active, ensuring the payment flow functions properly.
Original PR description
Currently, is_payment_enabled is used to determine whether the payment button should be displayed. However, this field only indicates that the TPP / institution allow payment initiation, not that it's active. Since 19.2, `/initiate_payment` no longer checks whether the KYC flow has been completed before initiating a payment. As a result, users can now reach a blocked state where the payment flow is exposed but cannot actually proceed. No task ID
This update fixes a potential issue where multiple payslips for the same month (specifically for employees not on contract) could incorrectly double-count worked hours when calculating the employment bonus. The change ensures accurate bonus calculations by only considering worked hours once, improving payroll accuracy for this employee group.
Original PR description
In the case of out of contract payslips, we might have multiple payslips with worked day lines for the same month. In that case, we need to be careful to not count these hours twice when computing the employment bonus, which depends on the total "workable" hours for the month. task-6208125
This update ensures Odoo correctly sets the `toStateCode` field for SEZ transactions when generating e-waybills. Previously, this was missing, causing API errors and preventing shipments from being processed. This fix ensures compliance with e-waybill regulations and avoids disruptions to international trade.
Original PR description
For SEZ transactions, the e-waybill API requires `toStateCode` to be set to 99. Previously, this value was not enforced, leading to API errors: - 373 for export transactions - 641 for supply and CKD/SKD/lots supply This fix updates the logic to derive `toStateCode` based on the invoice's GST treatment. When the transaction is identified as SEZ, `toStateCode` is correctly set to 99, ensuring compliance with e-waybill requirements and preventing API failures. task-6117694 Forward-Port-Of: odoo/odoo#259327
This update resolves an issue where intercompany invoices were incorrectly flagged with a tax validation error. The fix ensures that taxes are correctly recalculated when processing invoices between companies with different fiscal positions, improving the accuracy of intercompany accounting. This prevents disruptions to cross-border transactions.
Original PR description
**Steps to reproduce:** * Install the *Accounting* module. * Install localisation modules for two different regions: * *Belgium* (**l10n_be**) * *Luxembourg* (**l10n_lu**) * Configure two companies,…
**Steps to reproduce:** * Install the *Accounting* module. * Install localisation modules for two different regions: * *Belgium* (**l10n_be**) * *Luxembourg* (**l10n_lu**) * Configure two companies, each assigned to one of the above regions. * Create fiscal positions: * In the Belgium company, create a fiscal position for Luxembourg. * In the Luxembourg company, create a fiscal position for Belgium. * Go to *Accounting > Configuration > Settings*. Enable *Inter-Company Transactions*. Enable synchronization of *Vendor Bills and Invoices* for both companies. * Create an invoice in the Luxembourg company. Select a partner belonging to the Belgium company. Add a product with applicable taxes. **Observed behavior:** * A validation error is raised: 'This entry contains taxes that are not compatible with your fiscal position. Please check the country set in the fiscal position and in your tax configuration.' **Cause:** * During intercompany bill creation, a foreign fiscal position is applied before recomputing taxes. * If no mapped foreign taxes exist, the system keeps domestic purchase taxes. * This leads to a mismatch between taxes and fiscal position, triggering the validation error. **Fix:** * Add a safeguard in *_inter_company_create_invoices()*. * After *_inter_company_sync_invoice_line_taxes()* recomputes taxes, *_inter_company_has_incompatible_fiscal_position_taxes()* checks whether the fiscal position is incompatible. * If incompatible, the fiscal position is removed and taxes are recomputed without it. opw-6103671 Forward-Port-Of: odoo/enterprise#117450 Forward-Port-Of: odoo/enterprise#115085
This update fixes a calculation error in the Belgian payroll module (l10n_be_hr_payroll) that was incorrectly applying tax rules to employees outside of Belgium. The change ensures that the Niss (Non-Investment Savings Scheme) calculations are now accurate only for Belgian employees, improving the financial reporting and compliance of the system.
Original PR description
Forward-Port-Of: odoo/enterprise#117530
This update fixes an error in the Italian Annual VAT Report that was incorrectly calculating the balance amount for line VF25. The fix ensures the report accurately reflects the total taxable base as required by Italian tax regulations, aligning with official government guidelines. This ensures accurate VAT reporting for Italian businesses.
Original PR description
### Issue before this commit: In the Italian Annual VAT Report, the balance (base amount) for line VF25 displays incorrect values. Instead of computing the sum of the taxable bases for the passive…
### Issue before this commit: In the Italian Annual VAT Report, the balance (base amount) for line VF25 displays incorrect values. Instead of computing the sum of the taxable bases for the passive operations, the report erroneously mixes tax amounts into the balance column. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it 2. Go to Tax Report and visualize the Annual Tax Report (IT) 3. Go to VF VAT Report 4. See the VF25 is mixing taxes and balances ### Cause of the issue: The root cause lies in the aggregation_formula definition for the tax_annual_report_line_VF25 record. The formula was incorrectly configured to aggregate the .tax expressions for lines VF1 to VF13 (VF1.tax + VF2.tax + ...) instead of their respective .balance expressions, while correctly using .balance for the remaining lines (VF17 to VF24). https://github.com/odoo/odoo/blob/878c08cf522a3278b4e6ff5f3d18444989e9998d/addons/l10n_it/data/tax_report/annual_report_sections/vf.xml#L286-L299 It's just a typo in this commit: https://github.com/odoo/odoo/pull/164064/changes/f292ba119d6376dbfb3c1fac4960c9c56a74d938 ### Reason to introduce the fix: From documentation https://www.agenziaentrate.gov.it/portale/documents/20143/9602686/IVA_ANNUALE_2026_istr.pdf/2a42fb92-1b76-229a-d0f5-06069d79b514?t=1768504755711 : > Rigo VF25, colonna 1, va indicato il totale degli imponibili determinato sommando gli importi riportati ai righi da VF1 a VF23, colonna 1, diminuito dell’importo di cui al rigo VF24. In colonna 2 va indicato il totale delle imposte determinato sommando gli importi delle colonne 2 dei righi da VF1 a VF13. opw-6172791 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264379
This update corrects a technical error that caused the LNA (Long Polling Acknowledgement) feature to be enabled consistently for all IoT polling requests, regardless of the action being performed. Removing a mistakenly reintroduced parameter ensures the correct number of arguments are passed to the function, resolving this issue and restoring proper LNA behavior.
Original PR description
In odoo/enterprise#104157, the `headers` parameter was accidentally reintroduced to the `rpc` function of the longpolling class. This was causing `post` to be called with the wrong number of arguments, and a side-effect of this is that LNA was being enabled always for poll requests and never for action requests. This commit removes the headers parameter so that the function is called with the correct number of arguments.
This update corrects a visual issue where the 'Attendance' bubble incorrectly appeared on payruns. The fix ensures that payrun bubbles accurately reflect employee status changes, improving the user experience when navigating payrun details. It addresses inconsistencies in how payrun data is cached and displayed.
Original PR description
Two bugs stem from the payrun "step bubble" bar (Employees → Time [→ Attendance] → Payslips): 1. When a payrun not containing attendance-tracked employees is opened first and I change one of the…
Two bugs stem from the payrun "step bubble" bar (Employees → Time [→ Attendance] → Payslips): 1. When a payrun not containing attendance-tracked employees is opened first and I change one of the employee's tracking method to attendance, going back via breadcrumb I'd see that the Attendance bubble incorrectly appears for the latter. The root cause is that cachePayRunSteps is a Map iterated in insertion order: "attendance" is appended after "payslip" the first time it is encountered, so it always renders last regardless of the server-defined canonical order. Fixed by turning it into an array overridden at every data fetch. 2. When navigating back to the payrun list via breadcrumb after changing the last of an employee's work_entry_source (e.g. removing the last attendance-tracked employee from a payrun), the bubble still shows the previous state. Fixed by marking the payrun as fresh when following specific flow, preventing the reload of the bubbles using instead the previously cached ones. task-5959087
This update corrects a technical issue where an approval rule was being applied incorrectly due to a duplicate XML ID. The change ensures that approval rules are applied correctly based on user and manager roles, improving the reliability of approval workflows. This resolves a potential inconsistency in how approvals were handled.
Original PR description
The XMLID `approval_approver_manager` was defined twice, causing the rule to be applied with the last evaluated access configuration for both `group_approval_user` and `group_approval_manager`. This commit renames the first occurrence of the duplicated XMLID to `approval_approver_user` to restore the intended separation between user-level and manager-level approval access rules. task-6095010 Forward-Port-Of: odoo/enterprise#113480
This update fixes a discrepancy in how invoiced quantities are calculated for sales orders, specifically when dealing with packaged products. Previously, rounding differences led to a slight mismatch between the delivered and invoiced quantities. This change ensures consistent rounding, accurately reflecting the quantity invoiced.
Original PR description
Steps to reproduce: --- - Install the `Sales and Inventory` modules. - Enable `Units of Measure & Packagings` from Settings. - Go to `Sales > Configuration > Products > Units & Packagings.` - Create…
Steps to reproduce: --- - Install the `Sales and Inventory` modules. - Enable `Units of Measure & Packagings` from Settings. - Go to `Sales > Configuration > Products > Units & Packagings.` - Create a new unit > Pack of 12 with quantity 12 and unit Units. - Create a new product > enable Track Inventory, set Quantity On Hand to 100, and in the `sales` tab, under `Upsell & Cross-Sell`, set `packaging` as` Pack of 12`. - Create a Sales Order > add the product and set the quantity to 3, with a unit Pack of 12. - Confirm the order and validate the delivery. - Create and confirm the invoice. - Return `1 unit` from the delivery and validate it. - From the invoice, create a `credit note` with quantity 1 unit and confirm it. - Go back to the Sales Order. Issue: --- - On the Sales Order: `Delivered Quantity` shows` 2.92` while `Invoiced Quantity` shows `2.91`. Root cause: --- - At [1] & [2], in `_compute_qty_invoiced`, the `_compute_quantity` method is called without specifying a `rounding_method`, so it defaults to `UP` (1/12 rounded to 0.09), while `_compute_qty_delivered` explicitly uses `HALF-UP` (1/12 rounded to 0.08), leading to inconsistent rounding. Solution: --- - In this PR, the same rounding method (HALF-UP) is applied when computing the invoiced quantity to ensure consistency with the delivered quantity. [1]https://github.com/odoo/odoo/blob/64c1f1a7d3b24ca613d0b29a2412f1094fea08d9/addons/sale/models/sale_order_line.py#L896-L912 [2]https://github.com/odoo/odoo/blob/64c1f1a7d3b24ca613d0b29a2412f1094fea08d9/addons/sale_stock/models/sale_order_line.py#L193-L209 opw-6073690 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263300 Forward-Port-Of: odoo/odoo#258024
This update removes a confusing button on Sale Orders for products handled through subcontracting. By hiding the Manufacturing Order (MO) button, we prevent users from navigating to unnecessary back-end manufacturing documents and streamline the process managed through Purchase Orders and Subcontracting Receipts.
Original PR description
The Manufacturing Order (MO) smart button on a Sale Order is confusing when the product is subcontracted. In a subcontracting flow, the user manages the process via the Purchase Order and the Subcontracting Receipt. This commit ensures the MO smart button is hidden when the fulfillment is handled through subcontracting to prevent user confusion and unnecessary navigation to back-end manufacturing documents. Task-id: 6173877 Forward-Port-Of: odoo/odoo#263105
This update fixes an error in the calculation of basic salaries for employees in Mexico. Previously, unpaid leave wasn't correctly factored into the daily rate, leading to inaccurate payments. Now, the calculation accurately reflects total calendar days worked, ensuring correct payments for all employees, including those on unpaid leave.
Original PR description
In Mexico, the basic salary must be calculated based on the total calendar days of the period. This ensures that both worked days and non-working days (e.g. Sundays) contribute equally to the total…
In Mexico, the basic salary must be calculated based on the total calendar days of the period. This ensures that both worked days and non-working days (e.g. Sundays) contribute equally to the total payment. This calculation also applies to the daily schedule, as the proportional daily wage must be divided equivalently across the hours of the day. Current behavior: When an employee has an unpaid leave, the basic salary is incorrectly prorated using only the registered days/hours. Example: For a monthly wage of 30,000 MXN in a month with 22 scheduled days (21 attendances + 1 unpaid leave), the implicit daily rate becomes 1,363.63 (30,000 / 22). This leads to an incorrect basic salary of 28,636.36 MXN for the days worked. This also happens with unpaid leave for x hours, e.g., for 2 hours, the unpaid leave is calculated as 2 hours * (30,000 / (22 days * 8 hours)) = 340.90 MXN, which is incorrect. Expected behavior: The basic salary should be derived from the full period (e.g., 30 days for a month, 15 for a bi-weekly period). Example: For a 30,000 MXN wage, the daily rate should be 1,000 MXN (30,000 / 30 days). If there is 1 unpaid leave, the basic salary should be 29,000 MXN (29 days * 1,000 MXN), regardless of the number of scheduled working days in the calendar. For unpaid leaves by hours, e.g., for 2 hours, the unpaid leave should be calculated as 2 hours * (30,000 / (30 days * 8 hours)) = 250.00 MXN. To achieve this, the calculation of the days in the `_get_worked_day_lines` is: * Adjust worked days/hours for out-of-contract entries where necessary, ensuring that rest days(Sundays) are included in the count. * Get all worked hours in the lines. * Calculate the number of days to pay based on the total hours and the hours per day. ### Case: payslip does not cover the complete pay period Current behavior: If a payslip is created for a partial period, the total amount is the full period wage. Expected behavior: The total amount should be pro-rated based on the days of the period. For example, if a payslip is created for 25 days(with a monthly schedule pay), the total amount should be the daily salary multiplied by 25 days. To achieve this, `_compute_amount` is updated to calculate the wage based on the `l10n_mx_daily_salary`. Changes on tests: * Add: * `test_monthly_payslip_with_partial_leave`, `test_partial_payslip`, `test_partial_payslip_new_hire_month_31_days` and `test_partial_payslip_new_hire_month_28_days`. * `test_hourly_payslip_by_attendance` to validate when `Work Entry Source` is set to "attendance". * Update: * `test_hourly_payslip`, `test_monthly_payslip` and `test_partial_payslip_new_hire` to align with the new calculation. * Adjust payslips dates to match the `schedule_pay` in `test_regular_payslip_subsidy` and `test_weekly_schedule_pay_no_code` * Fix a one-day difference in `TestMxEdiHrPayrollCommon`(16 days instead of 15 days for a bi-weekly schedule), and update the corresponding CFDI values. * Refactor tests and add new helpers. ### Error on [warning issues generation][1] and [`_compute_is_wrong_duration`][2] The warning: `"The duration of the payslip is not accurate according to the structure type."` appears with these custom periods for Mexican Payroll, although the period is correct: * `10_days` * `14_days` * `bi-weekly` Steps to replicate: * Install `l10n_mx_hr_payroll` module. * Switch to "INNOVACION VALOR Y DESARROLLO SA SA" company. * Go to Employees and open "Cesar Osbaldo Cruz Solorzano". * Click on "Payroll" tab, change the "Pay Schedule" to any option listed above, for example "Bi-weekly". * Go to Payroll > Payslips > Payslips and create a new pay run. * Select Salary Structure 'Mexico: Regular Pay', Pay Schedule 'Bi-weekly' and the Period '01/01/2026 -> 01/15/2026'. * Click on "Continue", select Cesar and click on "Select". * It appears the warning issue. Problem: The warning is raised because of `slip.date_from + slip._get_schedule_timedelta() != slip.date_to` condition, because `_get_schedule_timedelta` function calls [`self._schedule_timedelta(schedule, self.date_from)`][3] without the `country_code` argument. In the Mexican Payroll [_schedule_timedelta is overriden][4] but it is necessary to call it with the country code to use the custom periods; similar to how the [`date_end` is computed][5]. Solution: Call `_get_schedule_timedelta` passing the `country_code` [1]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/hr_payroll/models/hr_payslip.py#L1367 [2]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/hr_payroll/models/hr_payslip.py#L1454 [3]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/hr_payroll/models/hr_payslip.py#L275 [4]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/l10n_mx_hr_payroll/models/hr_payslip.py#L58 [5]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/hr_payroll/models/hr_payslip_run.py#L211 target: 19.0 task-6073601 Forward-Port-Of: odoo/enterprise#115044 Forward-Port-Of: odoo/enterprise#112524
This update resolves a restriction in the l10n_mx_edi module that prevented credit notes (out-refunds) from utilizing Payment Policies (PPD) as required by Mexican tax regulations (SAT). The change allows credit notes to correctly align with SAT portal requirements, ensuring accurate financial reporting. This improves compliance and simplifies the process for handling refunds in Mexico.
Original PR description
Currently, credit notes cannot be PPD (payment_policy), however, SAT portal allows it. **STEP TO REPRODUCE** 1. Install the l10n_mx_edi module. 2. Create an invoice with PPD (either changing it or through payment terms). 3. After send CFDI, generate a credit note and try to set PPD **FIX** Allow move_type = 'out_refund' to be PPD. Task-6049654 Forward-Port-Of: odoo/enterprise#114886
This update corrects a UI issue where changes to cloned website snippets weren't properly reflected. The fix ensures that duplicated snippets are marked as 'dirty' when their content is updated, maintaining accurate state visibility within the website editor. This prevents outdated content and improves the user experience.
Original PR description
Steps to reproduce: 1. Open the website editor 2. Add a snippet containing text content 3. Clone the snippet 4. Change the website language 5. Switch to translation mode 6. Modify the content of the original snippet => The cloned snippet reflects updates from the original snippet due to shared content, but is not marked as `o_dirty` and remains in a clean (yellow) state. Expected behavior: Cloned snippets should be marked as `o_dirty` when their content changes indirectly, ensuring the UI accurately reflects the modified state. This fix ensures duplicated snippets are flagged as `o_dirty` on indirect updates, preventing silent UI inconsistencies and improving state visibility. task-6176337 Forward-Port-Of: odoo/odoo#261916
This update fixes a confusion issue in the split bill screen for point-of-sale orders. Previously, users couldn't easily identify which variant price corresponded to each order line when multiple variant options were selected. Now, order line attributes are displayed, making it easier to manage and understand split orders with different variant prices.
Original PR description
Currently, when using the split bill screen you cannot differentiate variants. That's problematic when each variant is assigned to an extra price and you have to determine which price corresponds to each variant. Steps to reproduce: ------------------- * Go to the product and search for the Bacon Burger * Assign a different extra price for each variant option * Open Restaurant * Order the bacon burger multiple times, one for each possible variant * Split the order > Observation: On the split screen you see multiple lines of bacon burger each with a different price but if you don't know all the extra price possible it's impossible to know which orderline corresponds to each variant. Why the fix: ------------ Attributes are only shown in display mode, we also show them in split mode. opw-6041713 Forward-Port-Of: odoo/odoo#264059 Forward-Port-Of: odoo/odoo#257265
This update resolves an issue where changes made to timesheet data in one Odoo tab weren't consistently reflected in other tabs. The fix ensures that all modifications are saved and synchronized across different windows, improving data accuracy and user experience. This enhancement guarantees that users always work with the most up-to-date timesheet information.
Original PR description
Steps to reproduce: - Open Odoo in two tabs - Open the systray in tab 1 - Change some fields - Close the systray to save - Open the systray in tab 2 All fields are not in line in both tabs. This commit, hence, ensures that all data changed in the inline form is saved and consistent across different windows. When switching window, the systray is closed and the data is saved to the local storage. When opening the systray in another tab, the local storage will be accessed to read the latests changes (i.e., the modifications done in the other tab). task-6180394 Forward-Port-Of: odoo/enterprise#116007
This update resolves an issue where Point of Sale orders would fail if a product used an archived Unit of Measure. We've now implemented a fix to load archived UOMs within the POS, ensuring order creation works smoothly regardless of UOM status. This improves the reliability of the POS system for all users.
Original PR description
If a product uses an archived UOM and an order is then created in the POS with this product, an error would occur because it could result in trying to use a UOM that wasn't loaded in the POS since it was archived. To fix this issue, we now load archived UOMs in the POS. --- Task: https://www.odoo.com/odoo/project/1737/tasks/6197465 Forward-Port-Of: odoo/odoo#264837 Forward-Port-Of: odoo/odoo#263838
This update fixes an issue where the reprint button was unavailable on preparation printers across different devices within the same order session. By moving data storage to a shared session variable, the reprint button now works consistently on all devices sharing the same order, streamlining the preparation process for restaurant orders.
Original PR description
When sending an order to a preparation printer, the reprint button was invisible on any device other than the one that originally sent the order. This happened because `lastPrints` was stored in the order's `uiState`, which is local to each device. Moving it to `last_order_preparation_change` — which is shared across devices in the same session — fixes the issue. The reprint button is now visible and functional on all devices sharing the same session. --- Task: https://www.odoo.com/odoo/project/1737/tasks/6196913 Forward-Port-Of: odoo/odoo#264426 Forward-Port-Of: odoo/odoo#263094