Wednesday, March 11, 2026
32 changes · saas-19.2
New functionality added to Odoo
This update introduces a new 'Net Cost' salary rule for Saudi Arabia, addressing specific requirements for employer contributions related to GOSI and other payroll scenarios. It adjusts how salary deductions and employer costs are calculated, ensuring accurate reporting and compliance with local regulations. This change improves the accuracy of payroll calculations for employees in Saudi Arabia.
Original PR description
This PR introduces a new salary rule 'Net Cost' since setting appears_on_employee_cost_dashboard as True on the salary rule considers the sign on the rule, and for cases like the GOSI Employee Rule we need the sign to be negative to deduct from the employee but also increase the employer contribution amount. - adjusted provision rules to be part of a new category - adjusted remaining days to be allowance instead of company contribution - NET salary doesn't contribute to employer cost - New salary rule 'net cost' contributes to employer cost. Task-5894405 Forward-Port-Of: odoo/enterprise#106834
This update introduces support for accepting payments via MPESA, a popular mobile money service in Kenya, through two payment methods: Express and Lipa Na Mpesa. This allows businesses to offer a convenient payment option to customers, streamlining transactions and expanding market reach.
Original PR description
This pr introduces MPesa payment methods using Safaricom APIs for Kenya. There are two types of payment methods : - Mpesa Express: This is implemented with the M-Pesa Express API. It's the Merchant…
This pr introduces MPesa payment methods using Safaricom APIs for Kenya. There are two types of payment methods : - Mpesa Express: This is implemented with the M-Pesa Express API. It's the Merchant Initiated payment method. The merchant create a payment method M-Pesa Express with Safaricom payment provider. The merchant is allowed to ask for payment through the API with an USSD prompt on the customer phone number. Customer enters the PIN and the API call the callback of the POS to reconcile transaction with order. (https://daraja.safaricom.co.ke/dashboard/apis?api=MpesaExpressSimulate) - Lipa Na Mpesa: This is implemented with the Customer To Business (C2B) API. This payment method is different from the first one. It is a Merchant-Initiated payment method. The POS registers callback URLs through the register URL. The POS listen on its callbacks. Customer sends a payment through his Safaricom or MPesa application with some informations of the business. When a transaction is catch in the callback, POS displays it. The cashier needs, manually, to reconcile it with the current order. To reconcile, cashier see a popup with every transaction done on this business account number. (https://daraja.safaricom.co.ke/dashboard/apis?api=CustomerToBusiness) Dynamic QR Code API is also implemented to allow customers to scan the QR Code in the official Safaricom application and send the payment easily without errors of amount or till number. (https://daraja.safaricom.co.ke/dashboard/apis?api=DynamicQRCode) Note : The problem with this payment method is that there is two steps. The first step is a "Verification" step, which is optional. Businesses needs to manually sends an email to Safaricom to allows them to add this step. This step is useful because it is used to accept or reject a transaction before charging the customer. But, in reality, not all of the businesses ask Safaricom to add this step. So, we don't configure it for the moment. The second step is the "Confirmation" step, before this step, the customer is already charged. The API sends transaction data to the POS, we display it in the POS to allow cashier to reconcile the current order with a transaction. Requirements : If you want to test this API, https is needed and a valid kenyan (+254) phone number is also needed. But, you can simulate requests in the Daraja Portal. (https://daraja.safaricom.co.ke/dashboard/apis) task: 5886047 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#247615
Resolved issues and error corrections
This update fixes an issue where manually refunding products through the POS (using negative quantities) resulted in invoices instead of credit notes. The fix ensures that manual refunds are correctly processed as credit notes, accurately reflecting the transaction and improving financial reporting. This resolves a previous inconsistency in how POS refunds were handled.
Original PR description
Creating a POS order with negative quantity to manually refund a product (without using the Refund action, e.g. when the original order is not in the POS) and then requesting an invoice produced a…
Creating a POS order with negative quantity to manually refund a product (without using the Refund action, e.g. when the original order is not in the POS) and then requesting an invoice produced a customer invoice (INV) instead of a credit note (RINV). Steps to reproduce: ------------------- * Open a POS session. * Create a new order (do not use "Refund" from an existing order). * Add a product with negative quantity to simulate a manual refund. * Set a customer and request an invoice for the order. * Pay the order (negative amount). > Observation: The system creates a customer invoice (INV) instead of a credit note (RINV). Why the fix: ------------ * Invoice type was decided only from the `is_refund` flag, which is set only when the order is created via the Refund action. Manual refunds (negative qty) never had `is_refund` set, so they were treated as sales and got `out_invoice`. * `_prepare_invoice_vals` now treats an order as a refund when `is_refund` is True or `amount_total < 0`, so `move_type` is `out_refund` for manual refunds and a RINV is created. * `_get_invoice_lines_values` now uses the same condition (`is_refund or amount_total < 0`) to compute `is_refund_order` for the quantity sign. That way invoice lines keep positive quantities and the credit note has a positive total. opw-5898700 Forward-Port-Of: odoo/odoo#248791
This update resolves a problem where Razorpay payments failed due to customer names containing commas or exceeding 50 characters. The fix ensures Razorpay receives only clean names (without commas) and limits them to 50 characters, guaranteeing successful payment processing.
Original PR description
Steps: - Install and set up Razropay. - Create order and set customer with long name or name with comma. - Try to pay with Razorpay. Issue: - Error name is invalid. Cause: - Razorpay only take name without comma and upto 50 character, so having longer name or name with comma would cause an issue. Fix: - Replace comma with empty space and only take first 50 character of name while creating customer in Razorpay. Forward-Port-Of: odoo/odoo#252444
This update resolves an issue where the call dropdown wasn't appearing correctly, preventing users from accessing call features. The fix removes styling conflicts and ensures the dropdown opens as expected, improving the user experience for initiating calls. This was part of a broader task to enhance call functionality.
Original PR description
task-5263009 Forward-Port-Of: odoo/odoo#251462
This update fixes an issue where changing product quantities on a loaded order didn't save the changes, resulting in an outdated ticket screen. The fix ensures that quantity updates are now correctly synchronized with the server, providing accurate order information on the ticket.
Original PR description
Currently, modifying a loaded order (e.g., changing product quantity) does not save the changes, and the old order without modifications is shown on the ticket screen. ### **Steps to Reproduce:** 1)…
Currently, modifying a loaded order (e.g., changing product quantity) does not save the changes, and the old order without modifications is shown on the ticket screen. ### **Steps to Reproduce:** 1) Install the POS Restaurant app with demo data. 2) Open a Restaurant Session. 3) Click on 'Register' to create a Direct Sale. 4) Add a product (e.g., Water with Qty 2) and a customer (e.g., 'Billy Fox'). 5) Click on 'Orders' from the navbar and load the recently created order. 6) Update the quantity of Water from 2 to 5 and click on 'Orders' again. ### **Error:** The quantity of Water is not updated, the order line still shows a quantity of 2. Ref video: https://drive.google.com/file/d/1XR5W5Klyyll3KujirKb3UuAELjMcA7yD/view ### **Root Cause:** Clicking on 'Orders' calls `syncAllOrders` (see [1]), which is responsible for updating the orders. However, `this.getPendingOrder()` returns null in this scenario, causing the orders array to be empty and the function to return early without syncing. ### **Fix:** Override `updateSelectedOrderline` in `OrderSummary`. This method is invoked whenever the Numpad modifies an orderline. By calling `addPendingOrder` within this method, we ensure that Numpad modifications are correctly registered. This allows `syncAllOrders` to properly sync the updated order with the server when navigating away. [1]- https://github.com/odoo/odoo/blob/7fd5f90fe8fce4de49ec10c683f92e7a3557981a/addons/point_of_sale/static/src/app/services/pos_store.js#L1485-L1512 opw-5405402 Forward-Port-Of: odoo/odoo#240366
This update fixes a problem in the Odoo stock module where error messages about package consistency were unclear. Now, the messages specifically identify the problematic package, allowing customers to quickly diagnose and resolve issues during large product transfers. This reduces downtime and improves the overall user experience.
Original PR description
The current error does not specify which package is problematic. This cause issues on big transfers with many products / packages. Specifying the package in the error helps the customer identify the issue, and correct it themselves. OPW-5923839 --- <img width="673" height="252" alt="image" src="https://github.com/user-attachments/assets/0ccb45be-d813-4933-86fd-0dd3506d2775" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252351 Forward-Port-Of: odoo/odoo#249290
This update fixes an issue where combo items weren't always printed to preparation printers if their category differed from the main combo product. Now, items are printed based on their own category, ensuring accurate order preparation in self-order POS scenarios. This improves the reliability of order fulfillment.
Original PR description
Previously, combo choice items with categories assigned to a preparation printer were skipped when their category differed from the combo parent product’s category. This commit ensures that items are printed to the preparation printer based on their own product category. Task: 5902389 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#251051 Forward-Port-Of: odoo/odoo#249859
This update fixes an error in the overtime calculation for employees working night shifts that cross midnight. Previously, overtime was incorrectly calculated due to a bug in how the system handled time zones and rulesets. The fix ensures accurate overtime payments for employees with schedules spanning across midnight, resolving a potential revenue discrepancy.
Original PR description
**Steps to reproduce:** 1. Configure Working Hours: Set up a night-shift schedule that splits at midnight (Local Time): - Thursday: 20:00 to 24:00 - Friday: 00:00 to 04:00 2. Assign the above…
**Steps to reproduce:** 1. Configure Working Hours: Set up a night-shift schedule that splits at midnight (Local Time): - Thursday: 20:00 to 24:00 - Friday: 00:00 to 04:00 2. Assign the above calendar to an employee. 3. Set the Employee’s Timezone to Asia/Kolkata (UTC+5:30). 4. Assign an active Overtime Ruleset to the employee. 5. When the attendance calendar is in Europe/Brussels TZ - Check-in: Jan 15, 15:30 CET - Check-out: Jan 15, 23:30 CET Expected Behavior: Worked Hours = 8.0, Overtime (Extra Hours) = 0.0 Actual Behavior (Bug): Worked Hours = 8.0, Overtime = 4.0 **Bug Cause:** 1. The _update_overtime function normalized the Ruleset version periods using time.min for both the start and end of the day. This forced the validity period of the rules to end exactly at 00:00:00 UTC on the final day. 2. The overtime recalculation logic failed to delete existing overtime records because the search domain was incorrectly computed. Specifically, using relativedelta(SU) and relativedelta(MO(-1)) without the weekday= keyword argument did not shift the dates to the week boundaries. This resulted in an empty or incorrect deletion range, leading to duplicated overtime hours as new records were layered on top of un-removed old ones. **Solution:** 1. Modified the version_periods_by_employee mapping to use time.max (23:59:59) for the end of the version period. This ensures that the ruleset remains active through the entire final calendar day in UTC, allowing shifts that cross the midnight boundary to be fully captured. 2. Corrected the date range logic by explicitly passing the weekday argument to relativedelta. This ensures the domain correctly targets the full week window - from the preceding Monday to the following Sunday, ensuring all relevant stale overtime lines are purged before recalculation. 3. Updated Manual Edit Handling: Refined the logic to detect days with manual overrides or "To Approve" statuses before unlinking. If an attendance change triggers a recalculation on such a day, the system now replaces the manual entry with the mathematically correct value but flags the new record with a to_approve status for manager review. 4. Adjusted the expected overtime in test_weekly_overtime to 18.0 to correctly reflect the cumulative calculation of daily overtime (2h/day) plus the weekly overtime threshold reached on Friday. Task: 5710273 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#245247
This update resolves an issue preventing PDF export of composite reports containing journal report sections. The fix ensures that journal reports utilize their specialized PDF generation process, previously bypassed by the standard export flow. This now allows for correct PDF generation of complex accounting reports.
Original PR description
# Steps to reproduce: * Enable **Developer Mode**. * Go to **Accounting → Configuration → Accounting → Accounting Reports**. * Create a new report and enable **Composite Report**. * Add a new line of…
# Steps to reproduce: * Enable **Developer Mode**. * Go to **Accounting → Configuration → Accounting → Accounting Reports**. * Create a new report and enable **Composite Report**. * Add a new line of type **Journal Report**. * Save the report and create a menu item from the gear icon. * Open the report from the reporting menu. * Try to download the report in **PDF** format. # Observed behavior: * PDF export fails with a traceback. * Composite reports containing journal report sections cannot be exported as PDF. # Cause When exporting a composite report to PDF, the export flow iterates over each embedded sub-report and generates the HTML body used for PDF rendering. * The composite export relies on the base [`export_to_pdf`](https://github.com/odoo/enterprise/blob/a4e2c7c7d3aa50c8b57668c9ca73f523a31a5c41/account_reports/models/account_report.py#L5875) implementation from `account.report`, which directly calls `_get_pdf_export_html()` for each sub-report. * For standard reports, this works as expected because they use the base [`_get_pdf_export_html`](https://github.com/odoo/enterprise/blob/a4e2c7c7d3aa50c8b57668c9ca73f523a31a5c41/account_reports/models/account_report.py#L5944) method, which renders flat report lines into the default PDF template. * Journal reports, however, rely on a completely different PDF structure. Their templates expect `document_data` (journal entries grouped by journal/document) instead of flat report lines. * This `document_data` is generated exclusively by the journal report’s custom handler via its own [`export_to_pdf`](https://github.com/odoo/enterprise/blob/a4e2c7c7d3aa50c8b57668c9ca73f523a31a5c41/account_reports/models/account_journal_report.py#L240) flow. * The handler builds the required `document_data` using [`_generate_document_data_for_export`](https://github.com/odoo/enterprise/blob/a4e2c7c7d3aa50c8b57668c9ca73f523a31a5c41/account_reports/models/account_journal_report.py#L261C9-L261C22). * When a journal report is embedded inside a composite report, the composite export logic bypasses the custom handler and forces the report through the base `_get_pdf_export_html()` pipeline. * Since the base pipeline does not generate `document_data`, the journal report PDF template fails at render time with `KeyError: 'document_data'`. In short, journal reports embedded in composite reports were incorrectly routed through the standard PDF export pipeline instead of their specialized handler-based one. # Fix: * Add PDF export support to the journal report custom handler. * Centralize common print option logic in a shared helper. * Update composite report export logic to delegate PDF generation to custom handlers when available. * Journal reports inside composite reports now export to PDF correctly. opw-5477551 Forward-Port-Of: odoo/enterprise#109790 Forward-Port-Of: odoo/enterprise#105040
This update fixes inconsistencies in rental scheduling by ensuring that dates across rental orders, planning slots, and order quantities are always synchronized. It resolves issues where changes to one element didn't automatically update related elements, leading to potential scheduling conflicts. This improves data accuracy and simplifies rental management.
Original PR description
## [FIX] sale_renting_planning: fix sync between rental dates and planning slots dates Before this commit, it was possible to have `Planning Slots` with `Sync Shifts and Rental Orders` whose dates…
## [FIX] sale_renting_planning: fix sync between rental dates and planning slots dates Before this commit, it was possible to have `Planning Slots` with `Sync Shifts and Rental Orders` whose dates were different from the `Rental order`. This commit makes sure that all dates are always synced: - If the `Rental Order` dates are changed then all `Planning Slots`' dates changed to the new dates. - If a `Planning Slot` dates have changed then all other `Planning Slots` and the `Rental Order` Dates are changed to the new dates. ## [FIX] sale_renting_planning: fix sync between order line quantity and planning slots Before this commit, adding/removing a `Planning Slot` would not change the `SOL quantity` and changing the `SOL quantity` would not add/remove `Planning Slots` unless all slots are being deleted. This commit makes sure that when the `SOL quantity` is changed, the number of `Planning Slots` is changed accordingly, and if a Planning Slot` was added/removed, the `SOL quantity` would update accordingly. Note: The new sync behaviour from `SOL quantity` is ignored for `Products` with `hour UOM` because it is not clear yet how to update the `Planning Slots` if the new quantity of hours doesn't span a full rental interval. ## [FIX] sale_renting_planning: fix set multiple slots to resources Before this commit, adding multiple `Planning Slots` at the same time with the same `Role` can assign them to the same `Resource` even if they conflict with each other. This commit makes sure that when adding multiple `Planning Slots` none of them would conflict with each other after being added. task-5187356 Forward-Port-Of: odoo/enterprise#104771
This update resolves a payment issue where certain online payment providers (like Amazon) were failing due to a requirement for a registered customer on the order. The fix ensures that when these providers are used, a customer is automatically added to the order, allowing the payment process to proceed smoothly. This prevents 'signature mismatch' errors and maintains consistent payment functionality.
Original PR description
Currently some providers require a customer to be registered on the order because the email address needs to be sent with the request. We the order does not have a customer the payment cannot be made…
Currently some providers require a customer to be registered on the order because the email address needs to be sent with the request. We the order does not have a customer the payment cannot be made using that provider. Step to reproduce: ------------------ - Set up Amazon payment services on a online pos payment method - Set this method as the online payment method for a self and also set is as payment method of the pos - Place an order in the self or without a customer on the normal pos - Try to pay it > Observation: When the page is redirected to provider's checkout page, an error occurs: Signature mismatch Why the fix: ------------ On a normal pos shop we are simply ensuring that a customer with an address mail is registered on the order if the provider of an online payment method requires customer identification. - When selecting the payment method on the payment screen if the payment method is online, requires customer identification and there's no customer on the order, the validate order button will be unavailable and the customer button is highlighted. - When there is a customer the validate button is highlighted - When validating the order if the customer does not have an email it will not go through and warn the cashier that the customer needs an email. This behavior is similar to the present "Delivery" which, if the cashier disregarded all popups, will not have the validate button available until a cashier is registered. Also if the selected customer doesn't have an address it will show a popup upon validation. We are not doing anything regarding the self order as using presets like "Delivery" is compatible since the information required filled by the customer creates a partner in the db and sets it on the order. This preset ensures we always have a partner. Other preset don't but we don't want to block flows that are currently working. The list of providers requiring customer identification can be extended. opw-5406501 Forward-Port-Of: odoo/odoo#245016
This update fixes an issue where POS discounts weren't correctly applied when orders were modified. By updating the global discount through an effect, the system now accurately reflects changes to order discounts, ensuring accurate calculations and refunds for POS transactions. This improves the reliability of the Point of Sale system.
Original PR description
This commit uses an effect to update the global discount when changing the order. Fix the refound in when global discount since it was handeling only on discoud line where there could be various (one discount line per tax). Task-5421479 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#246864 Forward-Port-Of: odoo/odoo#241605
This update fixes an issue with how discounts are applied during order changes in the POS system. Previously, discounts were only applied to individual line items, leading to incorrect refund calculations. This change ensures discounts are correctly applied globally, improving the accuracy of POS transactions.
Original PR description
This commit uses an effect to update the global discount when changing the order. Fix the refound in when global discount since it was handeling only on discoud line where there could be various (one discount line per tax). Task-5421479 Forward-Port-Of: odoo/enterprise#109481
This update fixes an issue where the number of available time off allocations wasn't accurately reflecting allocations started in the previous year. The fix ensures that all valid allocations, regardless of their start date, are correctly counted on the time off type page, improving reporting accuracy.
Original PR description
__ ## Short functional explanation of the error When setting the start date for a time off allocation to the previous year, it is not taken into account when computing the count of employee…
__ ## Short functional explanation of the error When setting the start date for a time off allocation to the previous year, it is not taken into account when computing the count of employee allocations on the time off type page. ## Reproduction Steps 1. Go to Time off > Configuration > Time off Types and click on any time off type. 2. A smart button Allocations should appear with a number in it. Note the number and click on the button. 3. If no allocation exists yet, create one. Otherwise, click on an already existing allocation. 4. Set the start date of the validity period to any date last year. Set the ending date so that the allocation is still valid as of now. 5. Go back to the Time off type page and look at the number on the Allocations smart button. ### Expected behavior As the allocation we set is still valid, the number shouldn't have changed. ### Unexpected behavior The allocation number has been decreased. However, when we click on the smart button, the same number of valid allocations will show. This creates an inconsistency between the smart button and the allocation page, as the smart button should show the number of valid allocations, and when landing on the allocation page, the results are automatically filtered by validity. ## Origin of the issue The domain of the allocations to take into account when computing the count of valid allocations is defined here: https://github.com/odoo/odoo/blob/2264f330859b79010b227e3a9fda1075de8ed4e8/addons/hr_holidays/models/hr_leave_type.py#L297-L304 This doesn't take into account valid allocations that started during the previous year. The inconsistency with the allocation page can be seen here: https://github.com/odoo/odoo/blob/2264f330859b79010b227e3a9fda1075de8ed4e8/addons/hr_holidays/views/hr_leave_allocation_views.xml#L40-L46 Where the filter is defined based on today, rather than on the whole year, unlike above. __ opw-5504272 Forward-Port-Of: odoo/odoo#250992 Forward-Port-Of: odoo/odoo#248482
Previously, users couldn't respond to messages received from other companies within Odoo. This update fixes a bug that prevented replies, allowing users to now successfully respond to messages regardless of the originating company. This improves communication and collaboration across different business entities using Odoo.
Original PR description
Before these changes, messages from other companies were received, but when trying to reply to them, an error occurred that prevented the response. Steps to reproduce the issue in runbot: 1. In one tab, log in as admin, and in another incognito tab, open demo. 2. Make sure demo has Handle Notifications in Odoo enabled. 3. Set admin in one company and demo in another company. 4. Assign a task to demo. 5. Click on the notification to open the chatter and try to reply. An error is thrown With these changes, the response can be logged when the user has access to the company from which the task was assigned. cc @Tecnativa TT61176 ping @pedrobaeza --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#251555 Forward-Port-Of: odoo/odoo#250677
This update fixes an issue where Point of Sale sessions weren't correctly calculating and posting Cost of Goods Sold (COGS) when using 'real-time' product valuation. The change ensures COGS are accurately recorded regardless of the valuation setting, improving financial reporting within the POS system. This resolves a discrepancy in how COGS were calculated and prevents potential revenue misreporting.
Original PR description
When the product category valuation is set to `real_time` but the company is set to `periodic`, the POS session closing was not posting COGS entries as expected. If the product category valuation is…
When the product category valuation is set to `real_time` but the company is set to `periodic`, the POS session closing was not posting COGS entries as expected. If the product category valuation is set to `real_time`, it should always prevail over the company setting. And if no valuation is set on the product category, then the company setting should be used. Steps to reproduce: ------------------- * Create a product category with `Inventory Valuation` set to `real_time` (Perpetual). * Create a product in this category and make sure it is storable and has a cost price. * Set the company `Inventory Valuation` to `periodic` (Periodic). * Create a POS order with this product and pay it. * Close the POS session. > Observation: In the session no COGS entries are created for the sold product. Why the fix: ------------ We adapt the `_search_valuation` to correctly fallback on the company setting only if the product category valuation is not set. It was not working before because in some cases the product had no company set (it means that it is visible to all companies) and the domain was not matching. To fix that we check that the current company matches the search value, and if it does we also match all the products without company set. We also adapt the PoS code to use the `product_id.valuation` field to filter all the stock_moves that should create COGS entries when closing the session. opw-5885960 Forward-Port-Of: odoo/odoo#247011
This change corrects a restriction preventing the l10n_mx_edi_pos module from correctly updating invoices during cancellation. The fix allows the module to access `pos_order_ids` data, which was previously blocked due to access limitations. This ensures invoices can be processed accurately without requiring elevated permissions.
Original PR description
`l10n_mx_edi_pos` is now populating `pos_order_ids` [1]. l10n_mx_edi_pos is designed to send POS data into MX EDI without giving accounting users direct access to pos.order. So, we should consider…
`l10n_mx_edi_pos` is now populating `pos_order_ids` [1]. l10n_mx_edi_pos is designed to send POS data into MX EDI without giving accounting users direct access to pos.order. So, we should consider that in this module we won't have access to:
- `pos_order_ids` m2m on `l10n_mx_edi.document` (caused problems before [2])
- `pos_order_ids` o2m on `account.move`
- `pos.order` model
We add a minimal `sudo()` in
`_create_update_invoice_document_from_invoice` to be able to read from the `pos_order_ids` field on `account.move`:
```
File "/e19-1/l10n_mx_edi/models/account_move.py", line 1551, in _l10n_mx_edi_cfdi_invoice_document_cancel
return self.env['l10n_mx_edi.document']._create_update_invoice_document_from_invoice(self, document_values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/e19-1/l10n_mx_edi_pos/models/l10n_mx_edi_document.py", line 54, in _create_update_invoice_document_from_invoice
if invoice.pos_order_ids:
^^^^^^^^^^^^^^^^^^^^^
File "/c19-1/odoo/orm/fields_relational.py", line 967, in __get__
return super().__get__(records, owner)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/c19-1/odoo/orm/fields_relational.py", line 45, in __get__
return super().__get__(records, owner)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/c19-1/odoo/orm/fields.py", line 1743, in __get__
recs._fetch_field(self)
File "/c19-1/odoo/orm/models.py", line 3015, in _fetch_field
self.fetch(fnames)
File "/c19-1/odoo/orm/models.py", line 3055, in fetch
fetched = self._fetch_query(query, fields_to_fetch)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/c19-1/odoo/orm/models.py", line 3193, in _fetch_query
field.read(fetched)
File "/c19-1/odoo/orm/fields_relational.py", line 985, in read
raise AccessError(records.env._("Failed to read field %s", self) + '\n' + str(e)) from e
odoo.exceptions.AccessError: Failed to read field account.move.pos_order_ids
You are not allowed to access 'Point of Sale Order' (pos.order) records.
This operation is allowed for the following groups:
- Inventory/User
- Point of Sale/User
```
Afterwards `_create_update_document` in `l10n_mx_edi` will create or write this `pos_order_ids` value on the document without `sudo()`:
```
File "/home/jvo/Code/odoo/trees/e19-1/l10n_mx_edi/models/account_move.py", line 1551, in _l10n_mx_edi_cfdi_invoice_document_cancel
return self.env['l10n_mx_edi.document']._create_update_invoice_document_from_invoice(self, document_values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jvo/Code/odoo/trees/e19-1/l10n_mx_edi_pos/models/l10n_mx_edi_document.py", line 56, in _create_update_invoice_document_from_invoice
return super()._create_update_invoice_document_from_invoice(invoice, document_values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jvo/Code/odoo/trees/e19-1/l10n_mx_edi/models/l10n_mx_edi_document.py", line 1969, in _create_update_invoice_document_from_invoice
document = remaining_documents._create_update_document(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jvo/Code/odoo/trees/e19-1/l10n_mx_edi/models/l10n_mx_edi_document.py", line 1936, in _create_update_document
result_document = self.create({
^^^^^^^^^^^^^
File "/home/jvo/Code/odoo/trees/c19-1/odoo/orm/decorators.py", line 365, in create
return method(self, vals_list)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jvo/Code/odoo/trees/c19-1/odoo/orm/models.py", line 4021, in create
records = self._create(data_list)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jvo/Code/odoo/trees/c19-1/odoo/orm/models.py", line 4253, in _create
field.create([
File "/home/jvo/Code/odoo/trees/c19-1/odoo/orm/fields_relational.py", line 760, in create
self.write_batch(record_values, True)
File "/home/jvo/Code/odoo/trees/c19-1/odoo/orm/fields_relational.py", line 786, in write_batch
self.write_real(records_commands_list, create)
File "/home/jvo/Code/odoo/trees/c19-1/odoo/orm/fields_relational.py", line 1559, in write_real
raise AccessError(model.env._("Failed to write field %s", self) + "\n" + str(e))
odoo.exceptions.AccessError: Failed to write field l10n_mx_edi.document.pos_order_ids
You are not allowed to access 'Point of Sale Order' (pos.order) records.
This operation is allowed for the following groups:
- Inventory/User
- Point of Sale/User
```
We therefore take out `pos_order_ids` in an override and write it ourselves with another minimal `sudo()`.
[1] https://github.com/odoo/enterprise/pull/97060
[2] https://github.com/odoo/enterprise/pull/99590
opw-6000974
Forward-Port-Of: odoo/enterprise#109461This update fixes a potential issue where the ECPay integration for Taiwan customers wasn't consistently triggered. The change ensures the integration activates correctly for any company using Taiwan's fiscal localization, based on the company's fiscal country instead of its physical address. This improves the accuracy and reliability of ECPay processing for Taiwanese businesses.
Original PR description
Previously, the module checked `company_id.country_id.code == 'TW'` to determine if Taiwan's ECPay logic should be applied. However, `country_id` only represents the physical address of the company. This commit replaces `country_id` with `account_fiscal_country_id` across the sale order model and website controllers. This ensures that the ECPay integration correctly triggers for any company using the Taiwan fiscal localization. Task-6002433 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252464 Forward-Port-Of: odoo/odoo#251924
This update fixes an error in how project budget spending was calculated, leading to incorrect percentage displays. The fix ensures that negative budget amounts are handled properly, accurately reflecting actual spending and remaining balances. This improves the accuracy of budget reporting for projects.
Original PR description
Steps to reproduce: --------------------------- 1. Install the `project_account_budget` and `account_accountant` modules. 2. Create a new project and add an Analytic Account for it from the settings…
Steps to reproduce: --------------------------- 1. Install the `project_account_budget` and `account_accountant` modules. 2. Create a new project and add an Analytic Account for it from the settings page 3. Open the Project Kanban, click the three dots on the project card, and select Project's Updates. 4. Click Add Budget button and open the budget wizard. 5. Add a budget line in the wizard with a planned amount expressed as a negative value for an expense (for example: -10000). 6. Create a Vendor Bill using the same analytic account with an amount of 1000. 5. Confirm the bill. 6. Go back to Project's Updates and click New button to view the budget summary. Observation: --------------------------- The budget summary displays incorrect signs and percentages in Activities summary, for example: ``` -10.0% (-1,000.00) of the -10,000.00 budget has been spent. 110.0% (-11,000.00) of the budget is remaining. ``` This incorrectly shows -10% spent and 110% remaining instead of 10% spent and 90% remaining (-9,000). Issue: --------------------------- The project cost (already negative) was negated again when computing the spent amount in https://github.com/odoo/enterprise/blob/ac3f333d97eda5c86a0813490ac6204d4ec5721f/project_account_budget/models/project_update.py#L16 Double-negating the cost makes it positive, which then gets added to the expense budget instead of reducing it, producing inverted percentages and signs. Solution: --------------------------- For expense budgets (negative budgets), do not apply an extra negative sign when calculating the project cost so the spent, remaining, and percentage values are computed correctly. After the fix: ``` 10.0% ($ 1,000.00) of the $ -10,000.00 budget has been spent. 90.0% ($ -9,000.00) of the budget is remaining. ``` opw-5357854 Forward-Port-Of: odoo/enterprise#109880 Forward-Port-Of: odoo/enterprise#102126
This update fixes a warning in the Belgian VAT report caused by an incorrect negative sign for tax code 61. The change ensures the report aligns with current tax regulations, preventing potential rejection by tax authorities. This update corrects a data inconsistency within the Odoo accounting system.
Original PR description
Currently, in the Belgian VAT report, `61 – Various VAT regularizations in favor of the State` is displayed with a negative amount under `Taxes > IV Due`, which triggers a warning in the report.…
Currently, in the Belgian VAT report, `61 – Various VAT regularizations in favor of the State` is displayed with a negative amount under `Taxes > IV Due`, which triggers a warning in the report. **Steps to reproduce:** - Install the `l10n_be` module and switch to the `BE company CoA`. - Navigate to `Invoicing > Configuration > Taxes` and open any tax (e.g., 6%). - Replace the `Tax Grid` with `61` on the second line under `Distribution for Invoices`, then `save`. - Navigate to `Customers > Invoices` and create and confirm an invoice using this `tax`. - Navigate to `Reporting > Tax Report` and select the current month. **Observation:** - The report shows a warning: `The report contains negative amounts. This is normally not allowed and could cause the tax authorities to reject it.` - Case `61` under `Taxes > IV Due` displays a `negative` value. **Root Cause:** At [1], all formulas under `IV Due` use a negative sign (-XX) except for case `61`, which uses `61` instead of `-61`. Since the concept of `inverted tax tags` was removed in v19 in PR [2], case `61` must follow the same sign convention as the other `IV Due` cases to ensure correct reporting behavior. **Fix:** This commit updates the formula of case `61` to `-61`, aligning it with the other `IV Due` lines. As a result, the VAT report no longer displays an incorrect negative amount for case `61` and prevents the related `warning` from appearing. [1]: https://github.com/odoo/odoo/blob/f229f23d7bf3d837ff5577c36145bf2ba410ea22/addons/l10n_be/data/account_tax_report_data.xml#L497-L596 [2]: https://github.com/odoo/odoo/pull/225252 opw-5866225 Forward-Port-Of: odoo/odoo#248961
This update fixes a visual issue where 'looking for help' conversations with the user as a member had a distracting purple overlay, obscuring key information like the country flag and conversation name. By increasing the 'z-index', the overlay is now correctly positioned, ensuring all conversation details are clearly visible to users.
Original PR description
Before this commit, looking for help conversations with self user as member had poor readability on country flag, conversation name and description, and the language code. This happens because when a looking for help conversation has self member, there's a hatched purple background. This background is done with an overlay over the whole item, and some items were below it like country flag and conversation name, reducing clarity of these items. This commit fixes the issue with increased `z-index` just to be on top of this overlay. Before / After (see text and country flag with hatched pattern / purple tint that comes from overlay) <img width="878" height="503" alt="Screenshot 2026-03-10 at 15 36 20" src="https://github.com/user-attachments/assets/fa5764e9-436b-48bc-b920-20064b176e68" /> <img width="888" height="493" alt="Screenshot 2026-03-10 at 15 36 39" src="https://github.com/user-attachments/assets/1aadd167-9449-433c-bc5f-1505abe02a77" />
This update corrects an issue where the Partner Ledger incorrectly displayed residual amounts in the company's currency. The fix ensures that currency values are accurately shown based on the partner's currency, improving reporting accuracy. Additionally, a bug preventing the debug popover from functioning has been resolved.
Original PR description
# [FIX] account_reports: Partner Ledger residual amount currency wrong In the partner ledger, the residual amount currency had all it's results set to the currency from the company. Here, we do the same as from amount currency and set it to it's currency and aggregate it if all the currency from the partner / all the partners is the same currency. # [FIX] account_reports: Partner ledger debug popover not working To reproduce: - Open the partner ledger - Active the developper mode - click on the debug button on the line Open Items
This update fixes a bug that caused errors in logs when using computed fields in domain definitions for automation rules. The change ensures that domain validations are properly executed, preventing unexpected behavior and improving data integrity. This primarily impacts the CRM and Email Marketing modules.
Original PR description
An error is generated in the logs when a user opens a record after saving a computed field used in the domain, as demonstrated in the steps below. Step1: - install `crm` and `base_automation` -…
An error is generated in the logs when a user opens a record after saving a computed field used in the domain, as demonstrated in the steps below.
Step1:
- install `crm` and `base_automation`
- Create a new automation rule for the `Activity` module and set the `Apply On` domain as below: `[("res_model", "=", "crm.lead"), ("state","=","done")]`
- An error will occur in the log when you open this record.
Step 2:
- Install `mass_mailing`
- Go to Email Marketing and create a record as below data
- Recipients: `Contact`
- Set domain as `[("vat_label", "=", 'test')]`
- An error will occur in the log when user open this record.
This issue occurred because the recently refactored commit [1] used `validate` of Domain for the domain instead of `search_count`. The `validate` method only checks the structure of the domain and does not verify whether the domain is actually executed or not.
This commit fixes the issue by reverting commit [1], restoring the previous behavior where the domain is evaluated using `search_count`.
[1]: https://github.com/odoo/odoo/commit/a1434c32e9f4dd226d512677fd96e3051b908d8b
sentry-7004977102
Forward-Port-Of: odoo/odoo#252379This update resolves a restriction preventing users without the necessary HR group from accessing bank account information. Previously, accessing a bank account triggered an error, impacting data visibility. This fix ensures all users can manage bank accounts correctly.
Original PR description
The field `employee_salary_amount_is_percentage` is computed, but the computation[^1] relies on `hr_employee.salary_distribution`, a field restricted[^2] to members of `hr.group_hr_user`. If you try…
The field `employee_salary_amount_is_percentage` is computed, but the computation[^1] relies on `hr_employee.salary_distribution`, a field restricted[^2] to members of `hr.group_hr_user`. If you try to check a bank account without an hr group, you will get an access error: ``` odoo.exceptions.AccessError: You do not have enough rights to access the field "salary_distribution" on Employee (hr.employee). Please contact your system administrator. Operation: read User: 21 Groups: allowed for groups 'Employees / Officer: Manage all employees' ``` This also happens during the mock crawl test of upgrades if the admin lacks the group. To reproduce in standard: - Install contacts and hr. - Use a user without hr permissions. - Try to create a new bank account. [^1]:https://github.com/odoo/odoo/blob/57573994313988837d89329d77ab1def63a8cfdd/addons/hr/models/res_partner_bank.py#L26 [^2]:https://github.com/odoo/odoo/blob/57573994313988837d89329d77ab1def63a8cfdd/addons/hr/models/hr_employee.py#L147 --- I've also added another commit to make the percentage symbol stick to the salary amount. Before: <img width="366" height="38" alt="image" src="https://github.com/user-attachments/assets/ef890852-50ca-40b1-8c09-07c4aa2d330d" /> After: <img width="219" height="35" alt="image" src="https://github.com/user-attachments/assets/88e4a6c4-bc3f-483e-97f9-3080c6aa85c9" /> I know the number is not formated correctly but I don't think I can do more just from the view. Forward-Port-Of: odoo/odoo#239298
This update resolves a recurring issue causing nightly builds to fail due to timeouts. The changes include improvements to emoji loading, debugging tools, and asset caching to enhance stability and test efficiency. These updates ensure smoother and more reliable nightly builds.
Original PR description
Community: https://github.com/odoo/enterprise/pull/107499 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update addresses a recurring issue causing nightly timeouts within the Odoo Enterprise system. The team reorganized code to improve asset caching, allowing for more reliable testing and ultimately a more stable system. This change enhances the overall performance and stability of the Enterprise edition.
Original PR description
Enterprise: https://github.com/odoo/odoo/pull/248815
This update resolves an issue where Dutch tax returns appeared to be submitted but weren't actually sending data to the tax authorities. The fix ensures that the XBRL export is triggered when a Dutch tax return is submitted, accurately reflecting the status in the system and ensuring compliance.
Original PR description
Commit 647699eeb4b8a1cc37ca074fa57844871c5086c1 introduced account returns to the Dutch localization. However, the "Submit" action only updated the internal record state without triggering the actual XBRL export to the Dutch tax authorities. This led to a mismatch where the UI displayed "Submitted" despite no data being transmitted. This commit fixes the flow by: - Overriding `action_submit` on the account return to launch the XBRL wizard when the return type is a Dutch tax return. - Ensuring the SBR tax report wizard calls `_proceed_with_submission` on the associated account return to correctly finalize the process (including locking the period and generating the closing entry). opw-5974711 Forward-Port-Of: odoo/enterprise#110015 Forward-Port-Of: odoo/enterprise#109691
This update resolves an issue where large file uploads to forms would fail, resulting in error messages. The fix adjusts how the system handles request body sizes, ensuring compatibility with our web server's limits. This prevents form saving failures and improves the user experience when uploading files.
Original PR description
# How to reproduce - A reverse proxy needs to be set up between the client and the backend (for localhost, you can use nginx) - This reverse proxy needs to have a request max body size set below…
# How to reproduce - A reverse proxy needs to be set up between the client and the backend (for localhost, you can use nginx) - This reverse proxy needs to have a request max body size set below 128mb (for nginx : client_max_body_size) - If the system parameter web.max_file_upload_size is set, delete it and refresh your page - Pick any form view and add a file field with studio - Upload a file larger than the limit set in the proxy, but smaller than 128mb - Save the form # The problem The form is not saved and depending on the version, a Traceback will be shown (18.X) or a Connection Lost notification will be shown for a short period of time (19.0+) # Why When the system parameter web.max_file_upload_size is not set, the check for file size uses the default 128mb. A binary field added to a form via studio will upload its file in the json of the post request. This is done by encoding the file in base64. Our nginx servers set a limit for the request body size (usually 64mb). So if you add a file between 64mb and 128mb, it will bypass the default front-end size check but be stopped by the nginx reverse proxy. The proxy will send back an HTTP response with error code 413 to the client. Theses http responses are not correctly handled by the framework and are interpreted as a Connection Lost error because the response content cannot be parsed to json. Additionally, since we use base64 for the encoding and then use gzip to compress the json request, it's not really feasible to synchronize the front-end limit with the nginx one. opw-5891662 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252527 Forward-Port-Of: odoo/odoo#249025
This update resolves an issue where autocomplete fields weren't consistently saving manual changes made by the user. The fix ensures that the field's value is correctly updated after a user manually edits the input, preventing data discrepancies when saving the form. This improves data accuracy and reliability.
Original PR description
*google_address_autocomplete,partner_autocomplete This commit aims at fixing the behavior of 2 field widgets using the Autocomplete component. Those widgets rely on the `useInputField` hook, because…
*google_address_autocomplete,partner_autocomplete This commit aims at fixing the behavior of 2 field widgets using the Autocomplete component. Those widgets rely on the `useInputField` hook, because they basically render an input (spiced with the autocomplete feature), so they must handle "manual" updates (listen to `input`, `change`, `keydown` events), like regular input fields. However, the input also acts as a "search bar" for the autocomplete. As a consequence, it might happend that the `useInputField` hook internals weren't correctly reflecting the actual state of the field. Here's a faulty scenario to highlight the issue, involving any of the two widgets: - open a form view with the field set to value "XYZ" - type in the input "ABC" and select a suggestion from the autocomplete dropdown => say the value is now "Value ABC" - manually erase the content of the input and type "XYZ" as before - save => the value sent to the server was actually "Value ABC" The reason is that the hook still believes that the field is dirty after the value has been picked from the dropdown, and set (in the model) to "Value ABC", so `lastSetValue` isn't correctly updated to "Value ABC" (it's still "XYZ"). Later on, after the manual update to go back to the value "XYZ", we compare this value with `lastSetValue`, and as they are the same, we do nothing, so the value in the model remains "Value ABC". Those widgets need to use the hook, because the logic encapsulated inside it is really tricky and we don't want to duplicate it. But the hooks internals aren't exposed, and we don't want to expose them to keep it under control. So we did the fix inside the hook itself: in `useEffect`, so after a patch, if the value in the model is the same than the value in the input, it means that the field isn't dirty anymore, so we force-reset the flag to `false`. This scenario only makes sense for inputs that are handled both internally by the hook and externally (e.g. by the autocomplete). Task~6018655 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#252829
This update resolves a technical issue preventing users from generating ird reports when employees have multiple versions recorded within the same reporting period. The fix temporarily prioritizes the most recent version for report generation, ensuring report functionality is restored. This ensures accurate reporting for employees with complex payroll histories.
Original PR description
Fixes an issue that blocks users from generating ird reports if the employee has multiple versions in the period. For now, we will only keep the latest version at the time of reporting. task - 6023310
This update resolves an issue where the zoomable chart cursor was behaving unexpectedly, particularly with chart interactions. The changes enhance the chart's responsiveness and stability, ensuring a smoother user experience when zooming and interacting with charts. This improves the overall quality and reliability of the spreadsheet functionality.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/04d519e592 [REL] 19.2.3 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/04d519e592 [REL] 19.2.3 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/fdaade3e5c [FIX] spreadsheet: fix zoomable chart cursor [Task: 5012198](https://www.odoo.com/odoo/2328/tasks/5012198) https://github.com/odoo/o-spreadsheet/commit/ed7ce1c9e4 [FIX] Model: reject data that postdate the library version [Task: 5895572](https://www.odoo.com/odoo/2328/tasks/5895572) https://github.com/odoo/o-spreadsheet/commit/1c54150e4c [IMP] functions: Add `ISFORMULA` function [Task: 6013888](https://www.odoo.com/odoo/2328/tasks/6013888) https://github.com/odoo/o-spreadsheet/commit/32709c4560 [FIX] selection_input: disable spill references [Task: 5945112](https://www.odoo.com/odoo/2328/tasks/5945112) https://github.com/odoo/o-spreadsheet/commit/b0f06197d4 [FIX] charts: remove zoom slicer for scatter plot [Task: 5388389](https://www.odoo.com/odoo/2328/tasks/5388389) https://github.com/odoo/o-spreadsheet/commit/0cd9a76df9 [FIX] pivot_style: assert pivot is valid before creating a table [Task: 5932073](https://www.odoo.com/odoo/2328/tasks/5932073) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>