Daily updates from Odoo
Tuesday, January 27, 2026
94 changes
23 changes
Enhancements to existing features
This update allows staff to temporarily hide products in the Point of Sale system by 'snoozing' them. When a product is snoozed, it appears grayed out on the product screen, but remains available for new orders. This helps manage stock levels and avoid overselling.
Original PR description
The PR will add an extra availability section on the product info popup which shows whether a product is currently available. From that section the product can then be 'snoozed', which will make it unavailable for a specified period of time. (1, 2, 4 hours, or for the entire session). When the product is unavailable there's a countdown timer on the popup showing when the product will be available again. Products which are 'snoozed' still show up on the product screen, but grayed out. The effect is purely cosmetic, as they can still be added to new orders. Task-[5170696](https://www.odoo.com/odoo/project/1737/tasks/5170696) Previous discussion-[#232625](https://github.com/odoo/odoo/pull/232625) Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update enhances the system administrator notifications displayed in Odoo Enterprise. It now allows for multiple messages with varying levels of urgency, providing more detailed and flexible alerts regarding server maintenance or other important events. This improves communication and allows for more targeted notifications.
Original PR description
Tweak #102239 to allow more flexibility and display multiple messages with different alert level.
The ir.config_parameter is sysadmin.message and should be a json loadable. The format shoud be something like this:
{
"replace": false,
"warning_type": "user",
"message": "<div class='alert alert-info'>A maintenance operation is planned on your server on <strong>2026-01-15</strong> between 14h and 15h</div>"
}
Forward-Port-Of: odoo/enterprise#105157Resolved issues and error corrections
This update resolves a crash that occurred when confirming purchase orders linked to multiple sales orders (grouped RFQs). The fix ensures that each purchase order is associated with only one sales order, preventing a data conflict. This improves the stability of the dropshipping process.
Original PR description
An error occurs when confirming a purchase order linked to multiple sales orders. Steps to reproduce: 1) Install sale_stock & sale_management and enable dropshipping. 2) Create a vendor with…
An error occurs when confirming a purchase order linked to multiple sales orders. Steps to reproduce: 1) Install sale_stock & sale_management and enable dropshipping. 2) Create a vendor with group_rfq 'always'. 3) Create a product with dropship route and add that vendor. 4) Create a Quotation with that product, confirm it, duplicate and confirm. 5) From the magic button go to Purchase Orders and confirm the PO. Reference video for steps : https://drive.google.com/file/d/1xglkuZAWNxcz0WSj_49Hemjkxx4KjSqv/view?usp=sharing Error: `ValueError: Wrong value for stock.picking.sale_id: sale.order(26, 27)` Root Cause: The computed field `sale_id` receives multiple `sale.order` records from `move_ids.sale_line_id.order_id` (see [1]). Since `sale_id` is a Many2one field, it can only accept one record or False. Assigning multiple records causes the error. Fix: * Create only one sale order per purchase order for drop-shipping picking types. For existing databases, set the value to the first available sale_id, or False if none exists. [1]- https://github.com/odoo/odoo/blob/38cffd1d1580693c56f0d897b8c8e60b938a8e85/addons/sale_stock/models/stock.py#L175-L179 opw-5344535 Forward-Port-Of: odoo/odoo#237945
This update fixes an issue where users couldn't adjust the quantity of optional products added through the portal's upsell feature. The change ensures that the 'optional' status is correctly applied to new order lines, allowing users to accurately update product quantities and manage their subscriptions.
Original PR description
Version: - 19.0 Steps to Reproduce: - Enable the Add Products option in the recurring plan. - Create a subscription with the same plan and add optional products. - Confirm the subscription and create invoice for current period. - From the portal, click on Add Quantity to create an upsell order. Before: - Users were not able to update the quantity of products added as optional products from portal. - This happened because the `is_optional` field value was not copied to the new order line created during the upsell. After: - The `is_optional` field value is now copied to the new order line created for upsell and renewal orders. - This allows users to update the quantity of optional products correctly. Impact: - Users can update the quantity of optional products from the portal without issues. task-5427585 Forward-Port-Of: odoo/enterprise#102670
This update enhances traceability for EDI and e-Way Bill requests by storing all request payloads as JSON attachments. This improves debugging, simplifies audits, and strengthens compliance efforts related to these important tax processes. Task 4896516.
Original PR description
Before this PR: - Request payloads sent for EDI and e-Way Bill generation were not persisted. making debugging and audits difficult. After this PR: - all EDI and e-Way Bill request payloads are stored as JSON attachments, ensuring better traceability, troubleshooting, and compliance support. Task: 4896516 Forward-Port-Of: odoo/odoo#241704
This update resolves a bug where overtime entries were being incorrectly generated and overlapping due to a flawed system for managing overtime rules. The fix ensures accurate overtime calculations and prevents overlapping entries, improving the reliability of attendance tracking.
Original PR description
STEP TO REPRODUCE:
------------------
0- Go to attendance > Configuration > Overtime Ruleset 1- Create the following overtime ruleset (all rules are paid and with the entry type overtime):
rule 1: timing rule on worked day with this timing : 0AM -> 8AM
rule 2: timing rule on worked day with this timing : 12AM -> 1PM
rule 1: timing rule on worked day with this timing : 5PM -> 12PM
2- Go to attendance > configuration > settings
3- Enable Time Management
4- ANd change the extra hours validation by automatically approved 5- create an employee and give to him this overtime ruleset 6- Create for an attendance for him from 6AM to 8PM 7- to go the form view of this attendance
8- Approve it; you wwill have a traceback
REASON:
-------
The way to handle the reorganization of the overtime line on an attendance was badly done; everything was shift with the same shift so some overtime was overlapping the others
Forward-Port-Of: odoo/enterprise#105173This update resolves an issue preventing NFC-e refunds from being processed correctly in Point of Sale. Previously, a technical error caused a 'not found' message when attempting to retrieve the original invoice. The fix ensures the system accurately identifies and uses invoice references during the refund process, enabling successful transactions.
Original PR description
**Steps to reproduce:**
- Setup a database that supports NFC-e
- Go to PoS, make a purchase, then refund it
- A traceback appears, saying we couldn't find the original invoice
**Why the fix:**
Before this commit the way we checked if there was already an invoice in the payload we give to the API was wrong, as it was always true. This happens because before the
*def _get_l10n_br_avatax_service_params(self):* call, we set res['invoice_refs'] as {}, then we were supposed to fill it. But if we check https://github.com/odoo/enterprise/blob/32b73b12f9f8f5600b820d9a938bfbb0cf10054d/l10n_br_edi_pos/models/account_move.py#L13 'invoice_refs' is found in res, even though it is empty, so we never entered the if statement.
We now check if there is a value in res['invoice_refs'] and if not we set it.
opw-5359407
Forward-Port-Of: odoo/enterprise#104987
Forward-Port-Of: odoo/enterprise#102770This update fixes an issue where the 'Inventory Reason' entered during barcode inventory counts wasn't being recorded in the system. Now, when completing an inventory count via the Barcode app, the specified reason is correctly logged in the Moves History, ensuring accurate tracking of inventory adjustments. This improves the reliability of inventory reporting.
Original PR description
## Issue When completing an *Inventory Count* from the Barcode app, the *Inventory Reason* requested to the user is not registered anywhere. ## Steps to reproduce 1. Install the *Barcode* app…
## Issue
When completing an *Inventory Count* from the Barcode app, the *Inventory Reason* requested to the user is not registered anywhere.
## Steps to reproduce
1. Install the *Barcode* app (`stock_barcode`)
2. In the *Barcode* app, click *Count Inventory*
3. Add a product and set a quantity for it
4. Click *Confirm* (do not scan to confirm)
5. Write an *Inventory Reason* and click *Apply Now*
6. Go to Inventory > Reporting > Moves History
- **The _Inventory Reason_ given in step 5 does not appear anywhere**
If the inventory adjustment is done through Inventory > Operations > Physical Inventory, the user can also provide an *Inventory Reason*, but this time, it will appear in the *Moves History* in the *Reference* (`stock.move.line.reference`) column.
## Cause
Since https://github.com/odoo/enterprise/commit/3efea75a88120519ef4be1a41c8faa7278bc332c, the value provided by the user is never passed to the Python side.
opw-5423934
Forward-Port-Of: odoo/enterprise#104763This update corrects a compatibility issue with the Bulgarian National Bank (BNB) exchange rate provider. Due to Bulgaria joining the Eurozone, the BNB now provides rates in EUR, not BGN. This change ensures that companies using EUR as their main currency can correctly sync exchange rates without errors.
Original PR description
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the…
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the BNB now provides rates against EUR. This caused the error "Your main currency (EUR) is not supported by this exchange rate provider" when Bulgarian companies with EUR as their main currency tried to sync exchange rates. refs: We can compare the data here from 31 December using the WayBackMachine: https://web.archive.org/web/20251231193558/https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm Compared to today: https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm And see the comparison used to be to BGN but is now for EUR Steps To Reproduce: 1. Create a company for Bulgaria with EUR as the main currency. 2. Go to Accounting Settings -> Automatic Currency Rates. 3. Select "[BG] Bulgaria National Bank" as the service provider. 4. Click the sync button. 5. Error appears: "Your main currency (EUR) is not supported by this exchange rate provider. Please choose another one." The fix updates the base currency from BGN to EUR, matching the current BNB XML format which now provides rates against EUR. Note: Companies with BGN as main currency will now get the same error, which is expected since the BNB no longer provides BGN-based rates. This behavior was discussed and confirmed with the PO. Ticket [link](https://www.odoo.com/odoo/project.task/5483771) opw-5483771 Forward-Port-Of: odoo/enterprise#105074
This update fixes an issue preventing bookings from being scheduled for the last hour of the day in the appointment system. The previous code incorrectly treated the end of the day as an unavailable slot, blocking bookings. This change ensures that appointments can now be booked for the full 24-hour period, resolving a common user frustration.
Original PR description
**Steps to reproduce:** - Go to Appointment app - Edit an appointment type - Ensure its availability is on resources - Set duration to 1 hour - Add a schedule slot ending in 00:00 - Save and go to…
**Steps to reproduce:** - Go to Appointment app - Edit an appointment type - Ensure its availability is on resources - Set duration to 1 hour - Add a schedule slot ending in 00:00 - Save and go to the website page of the appointment - Last slot is not showing (23:00-00:00) **Issue:** When computing the appointment slots of a resource using time range, the end of day is considered as an unavaibility resource slot with this interval in `_get_unavailable_intervals`: `i_start = 23:59:59.999999` `i_stop = 00:00` this conflicts with the given range (23:00-00:00) in `self._slot_availability_is_resource_available` It comes from `_attendance_intervals_batch`, as `float_to_time(24.0)` is converted to `time.max` (23:59:59.999999) by: `day_to = datetime.combine(day, float_to_time(attendance.hour_to))` This introduces the microsecond unavaibility at the end of the day, which blocks the booking. (it's working properly for availability on users appointments) **Fix:** Changed the condition so that 23:59:59.999999 is considered as equal to 00:00. opw-5163892 Forward-Port-Of: odoo/enterprise#104927 Forward-Port-Of: odoo/enterprise#100853
This update fixes a layout issue where image gallery indicators become cramped with many images and improves the overall responsiveness of image carousels, particularly on Firefox. By preloading images and optimizing the loading process, the gallery now appears smoother and more reliable.
Original PR description
## [FIX] website: add versioning for GallerySlider interaction The GallerySlider interaction (and its edit mode counterpart) is not up to date: the logic is still written for old snippets (before…
## [FIX] website: add versioning for GallerySlider interaction
The GallerySlider interaction (and its edit mode counterpart) is not up
to date: the logic is still written for old snippets (before [9042b1c],
so before 18.0).
In the meantime, the pagination for the indicators was lost, meaning
that if you add too many images, the indicators will have less and less
space.
Steps to reproduce:
- Drop an Image Gallery snippet
- Set the indicators to squared or rounded miniatures
- Add 15 or more images
=> All the indicators are crammed into the same line.
With this commit, we deprecate the old `GallerySlider` interaction and
create a `GallerySlider001` for the snippets dropped since 18.0.
For the indicators, instead of a pagination, we now use a horizontal
scrolling container which centers on the active indicator.
[9042b1c]: https://github.com/odoo/odoo/commit/9042b1c
## [FIX] website: preload available carousel images
As images are lazy loaded, it means that in the context of a carousel or
an image gallery, they only start loading once the user clicks either on
its indicator or on the previous / next button (or after completing an
auto-slide). While Chrome seems to optimize that to make it seemless, on
Firefox this causes the carousel slide to appear blank for a moment
before the image suddenly pops up, as the sliding animation arrives to
its end.
In effect, this causes a flicker and a feeling that the carousels, and
especially the gallery, is extremely laggy.
To mitigate that while trying to keep the advantages of image lazy
loading, this commit partially backports [08d837e], which loads the
images of the next and the previous carousel items.
Additionally, we prefetch the target images on pointerdown / keydown on
an indicator. That may seem like too small of a difference to be
interesting, but it actually gives a little bit of time between the
pointerdown and pointerup (which triggers the slide event) to start
loading the images, which with a correct connexion already goes a long
way towards mitigating the laggy feeling.
[08d837e]: https://github.com/odoo/odoo/commit/08d837e70f28a84a9bd97974f5d15d387a42b7c0
task-5245513
Forward-Port-Of: odoo/odoo#245144
Forward-Port-Of: odoo/odoo#232147This update resolves an issue where country-based filtering on payslips and payslip runs wasn't functioning properly, leading to errors. The fix ensures accurate country filtering, preventing module loading problems and improving the reliability of payroll reporting.
Original PR description
Issue: The country_id related field on payslip and payslip run was not stored, causing domain filters and search on this field to fail and triggering client-side errors. Fix: Use search parameter to write function so field can be used safely in search domains and filters. Impact: Country-based filtering now works correctly without triggering module loader errors. Task: 5406904 Forward-Port-Of: odoo/enterprise#104167 Forward-Port-Of: odoo/enterprise#103318
This update ensures that employee leave dates are automatically recalculated when their working schedule (calendar) changes. Previously, changes to an employee's schedule didn't correctly update their leave entitlements. This fix maintains accurate leave tracking for employees with dynamic work calendars.
Original PR description
purpose: Accepted leaves should be recomputed upon working schedule change. - made the `resource_calendar_id` change on the leave when it's changed on the corresponding employee/contract, then forced recomputation of its dates from the new resource calendar task-id: 5424312 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#243425 Forward-Port-Of: odoo/odoo#241284
This update resolves a bug that prevented the Gantt chart from correctly rescheduling tasks when using Date fields instead of DateTime fields. The fix ensures that the Gantt chart can now handle rescheduling tasks with Date fields, improving usability and flexibility for project management. This was caused by a previous limitation in the system.
Original PR description
…atetime
Steps to reproduce
==================
- Install web_studio,project
- Open a project task
- Open studio
- Add a new Date field in the form view
- Switch to the gantt view
- Change the Start Date Field to the newly create Date field
- Exit studio
- Open a task
- Set a value for the date field
- Switch to the gantt view
- Drag the record
```
start_date_field_name in vals and datetime.strptime(vals[start_date_field_name], '%Y-%m-%d %H:%M:%S')
^^^^^^^^
ValueError: time data '2025-12-22' does not match format '%Y-%m-%d
```
Cause of the issue
==================
Since https://github.com/odoo/enterprise/pull/84820 , it only works for DateTime fields
opw-5345470
Forward-Port-Of: odoo/enterprise#103068This update resolves an issue where image selections in the website builder were not consistently updating across related components. The fix ensures that the correct image element is always used when processing snippets, resulting in a more reliable and accurate website design experience. This improves the overall user experience when adding images to the website.
Original PR description
[FIX] html-builder, *: update snippet at each snippet dropped handler *: website In the `ImageSnippetOptionPlugin`, at the `on_snippet_dropped_handlers` call, the `snippetEl` received as argument is replaced by the image selected by the user in the media dialog. The problem is that the call to subsequent handlers is done with `snippetEl` that is not an element of the DOM anymore. This commit fixes this by updating `snippetEl` if needed after each call to a `on_snippet_dropped_handlers` handler. task-5785233 Forward-Port-Of: odoo/odoo#245594 Forward-Port-Of: odoo/odoo#243766
This update resolves an issue where negative lines on invoices generated for Ecuador (l10n_ec) were not correctly formatted in the XML export. The change aligns the process with Mexico (l10n_mx) to accurately distribute discounts and avoid rounding discrepancies, ensuring accurate tax calculations and invoice generation.
Original PR description
In **l10n_ec**, negative lines are not accepted in the XML. They must be dispatched as discounts on positive lines. The dispatching logic implemented in `60e1b41734f76a2d9268edc41286462a9d01a501` can…
In **l10n_ec**, negative lines are not accepted in the XML. They must be dispatched as discounts on positive lines. The dispatching logic implemented in `60e1b41734f76a2d9268edc41286462a9d01a501` can cause rounding issues when the decimal accuracy for `price_unit` is increased. ## Steps to reproduce With **l10n_ec**: 1. Change the decimal accuracy to 6 digits. 2. Set the rounding method to *global rounding*. 3. Create an invoice with the following lines: | Quantity | Price | Taxes | |-----------|----------|-----------| | 20 | 1.4235 | VAT 0% G | | 20 | 1.6425 | VAT 0% G | | 20 | 1.2337 | VAT 0% G | | 20 | 1.2337 | VAT 0% G | | 20 | 1.4235 | VAT 0% G | | 6 | 3.747768 | VAT 15% G | | 6 | 3.747768 | VAT 15% G | In the generated XML, some product lines show a `descuento` of `0.01` or `-0.01`. This happens due to rounding differences in how the `descuento` is computed in the `common_details_info_template` from **l10n_ec_edi**: format_num_2(line_edi_values['price_discount'] + abs(line.balance) - line_items[1]['base_amount']) where `line.balance` and `line_items[1]['base_amount']` can differ by 0.01 due to global rounding applied during tax aggregation, and that difference must be redistributed somewhere. This commit changes how negative lines are dispatched onto positive ones, aligning the behavior with **l10n_mx**. Instead of using `tax_details_per_record` to build the XML, we now use `base_lines`, where the negative lines have already been distributed. opw-5128612 Forward-Port-Of: odoo/enterprise#104659 Forward-Port-Of: odoo/enterprise#97337
A bug was preventing manufacturing administrators from completing work orders. This update adds sudo access to the failing process, ensuring these users can correctly finalize production tasks. This resolves a workflow issue and improves the usability of the manufacturing module for key personnel.
Original PR description
Steps to reproduce:
Create a user with admin access rights for Manufacturing and Quality only. Then, create a work center that has a cost per hour.
Create a product that has a BoM and create a MO then confirm it.
Add a work order that takes place in the created work center and has duration of 60 mins.
Using the created user, try to "Produce All".
Issue:
The user gets an access error when trying to "Produce All", eventhough they have manufacturing access rights.
Fix:
Add sudo access where the process fails to ensure that the workflow is as expected.
Note: a test will be added in anoher PR
opw-5480608
Forward-Port-Of: odoo/enterprise#104897This update fixes an issue where pricelist rules weren't correctly applied to product variants. Previously, rules only worked when editing in 'expanded' mode and would reset the display name. Now, when a variant is selected, the pricelist rule is properly applied, ensuring accurate pricing in sales quotations. This improves the reliability of pricing calculations.
Original PR description
Description of the issue/feature this PR addresses: - A pricelist rule never apply to a product variant, always its template when edited in "expanded" mode - This is because the `applied_on` field is…
Description of the issue/feature this PR addresses: - A pricelist rule never apply to a product variant, always its template when edited in "expanded" mode - This is because the `applied_on` field is missing on the `product.pricelist.item` form view. Current behavior before PR: - Install `sale_management` - Enable "Pricelist" setting - Go to Sales - Products - Pricelists and create a new "Sample" Pricelist. - Create 3 rules for the same product (template), one with price at 6666, a second one at 6667 and the last one at 3333 <img width="1416" height="649" alt="image" src="https://github.com/user-attachments/assets/1d50499e-cb49-4341-971c-5a2a5111b9ca" /> - Next step, edit 2 first rules for price 6666 and 6667 to set a variant **BUT before starting editing, open the form in expanded mode using two-arrows button** <img width="1416" height="889" alt="image" src="https://github.com/user-attachments/assets/056cb862-3dc6-4868-b6d3-a0917f3e7242" /> - Set the variant to the first price rule (as you can see, the rule name is immediately updated with "Variant: [REF] Product name" <img width="1421" height="428" alt="image" src="https://github.com/user-attachments/assets/168ad5fb-902b-494f-888a-419983324607" /> - Save the price rule (_note that the display name incorrectly resets to default_) <img width="634" height="370" alt="image" src="https://github.com/user-attachments/assets/ec915985-b1a3-4a69-9153-7384abdb190d" /> - Same thing for second rule <img width="695" height="375" alt="image" src="https://github.com/user-attachments/assets/69b9ae62-493c-4f0e-ae87-438975e1bceb" /> <img width="621" height="369" alt="image" src="https://github.com/user-attachments/assets/e1dc0342-7b87-42df-bf7d-6a3aace61253" /> - Create a new sale quotation with pricelist set to our "Sample" - Add product [6666] <img width="1207" height="420" alt="image" src="https://github.com/user-attachments/assets/07d4fb94-03b3-45ae-aeb4-feca4fee9c2c" /> - Add product [6667] <img width="1209" height="431" alt="image" src="https://github.com/user-attachments/assets/03e3a76a-2bb1-44e9-a819-ce3ca35703c7" /> - Incorrect prices in sale order <img width="1415" height="828" alt="image" src="https://github.com/user-attachments/assets/3626028d-31d0-4687-b09d-094c0212042a" /> Desired behavior after PR is merged: - Each variant must have its own price. - The added test simply edit the pricelist item using its own form. - The `applied_on` field is added to the pricelist item form to ensure that its value is saved. - If we edit the rule without expanded mode, it works fine only because the `applied_on` field exists in the list view as an invisible column. _Note 1_: `applied_on` is updated by `_onchange_rule_content` using `update` instead of `write` (for caching ?). But if the `applied_on` field is not on the form, then its value is never sent to low level `_write_multi`. _Note 2_: to clear the field value with the Form test component, we must set `=self.env["product.product"]` instead of `=False` .... --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#245603 Forward-Port-Of: odoo/odoo#245444
This update resolves a technical issue causing performance problems in the Mail app. Previously, field updates across tabs were creating a loop, leading to slow performance and potential system freezes. This fix prevents unnecessary updates to local storage, ensuring smoother and more reliable field synchronization.
Original PR description
Diccuss fields have a `localStorage` option. The field updates via the `onUpdate` function in the current tab and writes to the local storage. Other tabs use the `storage` event to update their field. This pattern can cause race conditions, leading to loops, high CPU usage, and freezes. When a tab receives a storage event, it may write back an outdated value, triggering further writes and conflicts across tabs. This commit ensures we don't trigger `storage` events recursively: upon the reception of a `storage` event, field is updated but local storage is untouched. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a critical issue where newly added modules to the Odoo Enterprise stable release were not properly included in the translation files (.weblate.json). This meant that the Greek language version of the software was unavailable. The fix adds the necessary module definitions to the .weblate.json file, guaranteeing proper translation support.
Original PR description
Modules added into stable without being properly added to .weblate.json file = never translatable. Forward-Port-Of: odoo/enterprise#105413 Forward-Port-Of: odoo/enterprise#104890
This update fixes a bug where customers exceeding their credit limits in the Point of Sale (PoS) system weren't receiving warnings. The fix ensures that the system accurately calculates order totals and displays appropriate alerts when a customer's spending exceeds their established credit limit, improving financial control.
Original PR description
Steps to reproduce: ------------------- 1. Install pos_settle_due and accountant 2. In Accounting settings, enable "Sales Credit Limit" 3. Create a new customer, enable its "Partner Limit" and set it…
Steps to reproduce: ------------------- 1. Install pos_settle_due and accountant 2. In Accounting settings, enable "Sales Credit Limit" 3. Create a new customer, enable its "Partner Limit" and set it to 100 4. Open PoS, select that partner, and select products such that the total exceeds 100 Notice that even though we have exceeded that partner's limit of 100, there are no indicators on the customer button (orange background on hover), nor there are warnings on the partners list modal nor on the payment page. Why the bug ----------- In `getPartnerCredit`, we are using `order.amount_total` to get the current ordre amount, however, this field is `undefined` for a new order and it's been assigned a value in `setOrderPrices`, which since [9538698](https://github.com/odoo/odoo/commit/9538698), is only called before sending the order to the backend. The fix ------- Now we read the total amount from the getter `order.priceIncl`, and round it as we would do in `setOrderPrices`. opw-5489975 Forward-Port-Of: odoo/enterprise#104591
This update enhances the monitoring of our AI usage by changing key logs from 'debug' to 'info', making them easier for our team and database administrators to track. Additionally, the system now accurately reports token usage from the LLM providers, resolving an issue where previous estimates were significantly inaccurate.
Original PR description
In this commit we change some important llm api usage logs from debug to info so they can be more easily monitored by us and database admins. We also change the usage reporting from a naive estimation (which greatly under-reported the token usage) to the actual token usage given to us by the LLM prodivers in the response. Forward-Port-Of: odoo/enterprise#105364
This update resolves an issue preventing electronic invoices in Latin American countries (Argentina, etc.) from printing correctly. The fix ensures that invoice headers and footers are dynamically generated based on the customer's fiscal country code, rather than relying on outdated chart templates. This guarantees accurate invoice formatting for all users.
Original PR description
This commit fixes a bug introduced here https://github.com/odoo/odoo/commit/3f7d79731fd5e5a751f7f1aeae63379c6211de5c because some old databases do not have set the chart template so it is needed to render the header and footer of the report template layouts taking in consideration the account fiscal country code instead of the chart template. Replicate printing the pdf of a customer electronic invoice on an argentinen company without chart template. Ticket Adhoc side: 105739 Task latam: 1373 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244102 Forward-Port-Of: odoo/odoo#238033
3 changes
Enhancements to existing features
This update enhances the system administrator notifications displayed in Odoo Enterprise. It now allows for more flexible messaging, including multiple alerts with varying levels of urgency. This provides administrators with clearer and more detailed information about important server updates and maintenance schedules.
Original PR description
Tweak #102239 to allow more flexibility and display multiple messages with different alert level.
The ir.config_parameter is sysadmin.message and should be a json loadable. The format shoud be something like this:
{
"replace": false,
"warning_type": "user",
"message": "<div class='alert alert-info'>A maintenance operation is planned on your server on <strong>2026-01-15</strong> between 14h and 15h</div>"
}
Forward-Port-Of: odoo/enterprise#105157Resolved issues and error corrections
This update corrects a compatibility issue with the Bulgarian National Bank (BNB) exchange rate provider. Due to Bulgaria's adoption of the Euro, the BNB now provides rates in EUR, not BGN. This change ensures that companies using EUR as their main currency can correctly sync exchange rates without errors.
Original PR description
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the…
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the BNB now provides rates against EUR. This caused the error "Your main currency (EUR) is not supported by this exchange rate provider" when Bulgarian companies with EUR as their main currency tried to sync exchange rates. refs: We can compare the data here from 31 December using the WayBackMachine: https://web.archive.org/web/20251231193558/https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm Compared to today: https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm And see the comparison used to be to BGN but is now for EUR Steps To Reproduce: 1. Create a company for Bulgaria with EUR as the main currency. 2. Go to Accounting Settings -> Automatic Currency Rates. 3. Select "[BG] Bulgaria National Bank" as the service provider. 4. Click the sync button. 5. Error appears: "Your main currency (EUR) is not supported by this exchange rate provider. Please choose another one." The fix updates the base currency from BGN to EUR, matching the current BNB XML format which now provides rates against EUR. Note: Companies with BGN as main currency will now get the same error, which is expected since the BNB no longer provides BGN-based rates. This behavior was discussed and confirmed with the PO. Ticket [link](https://www.odoo.com/odoo/project.task/5483771) opw-5483771 Forward-Port-Of: odoo/enterprise#105074
This update resolves an issue where users without superuser privileges could encounter access errors when generating global invoices in the Mexican CFDI module. The fix addresses a caching problem and ensures proper access rights are managed when creating or retrieving invoice sequences, preventing unexpected errors and improving stability.
Original PR description
**PROBLEM** 1. When generating a global invoice with a user without super user access, a access error may occur on the ir.sequence model. 2. There is an issue with the cache of the field…
**PROBLEM** 1. When generating a global invoice with a user without super user access, a access error may occur on the ir.sequence model. 2. There is an issue with the cache of the field `l10n_mx_edi_global_invoice_sequence_id`. (this is why problem can sometimes resolves itself on restarting the odoo instance). **STEP TO REPRODUCE** 1. Create 1 invoice with CFDI to public checked. 2. Goes to the list view for invoices, select the invoice, and apply the action "create global invoice" to it. 4. A access error may appear (depending on cache value). **CAUSE** 1. In `_get_global_invoice_cfdi_sequence()`, we get or create the ir.sequence used for global invoices. We are creating it with sudo(), so a user without sudo privilege can write to it. But, when we are retrieving a ir.sequence record that already exist, when don't use sudo(), this causes an access error for user without sudo privilege. 2. In `_get_global_invoice_cfdi_sequence()`, we try to get the computed field `l10n_mx_edi_global_invoice_sequence_id`. If it doesn't exist, we create a ir.sequence, but we forget to assign it to the field. Because we already trigger the compute method of the field by trying to access it, there is a None value in cache for it. This means we will always create a ir.sequence, despite one already existing for the company until the cache expires or the compute method is re-triggered. opw-5472552 Forward-Port-Of: odoo/enterprise#104181
12 changes
Enhancements to existing features
This update enhances the system administrator notifications within Odoo Enterprise. It now allows for more flexible messaging, including multiple alerts with varying levels of urgency, improving communication about server maintenance and other important updates. This change ensures system administrators receive timely and detailed information.
Original PR description
Tweak #102239 to allow more flexibility and display multiple messages with different alert level.
The ir.config_parameter is sysadmin.message and should be a json loadable. The format shoud be something like this:
{
"replace": false,
"warning_type": "user",
"message": "<div class='alert alert-info'>A maintenance operation is planned on your server on <strong>2026-01-15</strong> between 14h and 15h</div>"
}
Forward-Port-Of: odoo/enterprise#105157Resolved issues and error corrections
This update fixes an issue where dialog boxes were hidden behind chat windows, making them difficult to use. Now, dialogs appear above all chat windows except the AI chat window, ensuring a clearer and more intuitive user experience.
Original PR description
**Description of the issue this PR addresses:** ------------------------------------------------ Dialogs were rendered behind chat windows, making them difficult to see and interact with. **Current behavior before PR:** --------------------------------- - The dialog appears behind the chat window **Desired behavior after PR is merged:** ----------------------------------------- - Dialogs are displayed above all chat windows except AI - The AI chat window remains intentionally above dialogs **Task:** 5367135
This update resolves an issue preventing portal users from filtering job listings by department. The fix corrects a permissions error that restricted access, ensuring all users can utilize the department filter on the Jobs page. This improves the user experience for job seekers.
Original PR description
## Issue: Filtering by Department on the Jobs page as a Portal user raised a Forbidden Error ## Cause: Portal users lacked access rights on hr.department, even though public users have it ## Steps to reproduce: You need a portal user and a published job position in a department (you can use demo data) - Open the Website > Jobs page as Admin - Edit > Customize > Enable Department filter > Save - Login with Portal User - Access the jobs page and set a Department filter opw-4948838
This update addresses a limitation in the account online synchronization process where access tokens expire quickly. We've implemented a new consent token system – a unique, secure identifier linked to the user – to ensure reliable consent management and continued synchronization functionality. This change improves the user experience and maintains data consistency.
Original PR description
In this commit:bf5b7d0 we introduce a message on the account_online_link to be able to manage the consent. (one needed fix in this commit:https://github.com/odoo/enterprise/commit/1c84804fd3f0c0d1d23916b9f6a388616f66ac7e) This commit will change the way we manage the consent since the access token is in fact available only for 30 min, so the link in the chatter would not work. We decided to have a consent token which is a uuid4 encoded in base64 (url safe) and link it to the odoofin user. task-5187621 Forward-Port-Of: odoo/enterprise#105392 Forward-Port-Of: odoo/enterprise#105202
This update fixes a bug where users could successfully pay invoices with expired Sales Orders. Now, the system automatically prevents payment attempts when the Sales Order's expiry date has passed, ensuring accurate financial records and preventing incorrect payments. This improves the reliability of our payment processing.
Original PR description
## Issue: Payment link should expire if payment is expired. #### Steps to reproduce: 1- Create a new quotation. 2- Set the expiry date in the past. 3- Open the action menu and generate a payment link. 4- Open the payment link and pay. Expected result: The payment should fail if the so is expired. opw-5478691 Forward-Port-Of: odoo/odoo#245601 Forward-Port-Of: odoo/odoo#244061
This update corrects a bug that prevented companies using the Euro as their main currency from syncing exchange rates correctly. The BNB now provides rates in EUR, and this change ensures the system recognizes and utilizes the updated data. Companies with BGN as their currency will also experience this error.
Original PR description
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the…
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the BNB now provides rates against EUR. This caused the error "Your main currency (EUR) is not supported by this exchange rate provider" when Bulgarian companies with EUR as their main currency tried to sync exchange rates. refs: We can compare the data here from 31 December using the WayBackMachine: https://web.archive.org/web/20251231193558/https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm Compared to today: https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm And see the comparison used to be to BGN but is now for EUR Steps To Reproduce: 1. Create a company for Bulgaria with EUR as the main currency. 2. Go to Accounting Settings -> Automatic Currency Rates. 3. Select "[BG] Bulgaria National Bank" as the service provider. 4. Click the sync button. 5. Error appears: "Your main currency (EUR) is not supported by this exchange rate provider. Please choose another one." The fix updates the base currency from BGN to EUR, matching the current BNB XML format which now provides rates against EUR. Note: Companies with BGN as main currency will now get the same error, which is expected since the BNB no longer provides BGN-based rates. This behavior was discussed and confirmed with the PO. Ticket [link](https://www.odoo.com/odoo/project.task/5483771) opw-5483771 Forward-Port-Of: odoo/enterprise#105074
This update resolves an issue where the quantity of products transferred during the MRP process was sometimes incorrectly calculated. The fix adds extra steps to ensure the filtering and quantity updates are synchronized, leading to more accurate product transfers and a smoother user experience. This improves the reliability of the MRP workflow.
Original PR description
Error message ----- ``` FAIL: TestTourMrpOrder.test_mrp_multi_step_product_catalog_component_transfer Traceback (most recent call last): File "/data/build/odoo/addons/mrp/tests/test_order.py", line…
Error message
-----
```
FAIL: TestTourMrpOrder.test_mrp_multi_step_product_catalog_component_transfer
Traceback (most recent call last):
File "/data/build/odoo/addons/mrp/tests/test_order.py", line 5433, in test_mrp_multi_step_product_catalog_component_transfer
self.assertEqual(component_transfer.product_uom_qty, 2)
AssertionError: 1.0 != 2
```
Cause
-----
It looks like somehow one of the 2 clicks on the product is either not registered, or the update of the POL's quantity isn't triggered / doesn't happen fast enough, so the tour ends with a quantity of 1 for the product. I see 2 possible causes for this:
1. The product is visible in the initial view. So when the view updates (because of the filtering step), the next step - clicking on the product - the clicks can already be triggered, which might lead to an inconsistent state.
2. There is some synchronicity issue with the quantity update's debounce
https://github.com/odoo/odoo/blob/11292070870ef22663364eda5a4b243dea68856a/addons/product/static/src/product_catalog/kanban_record.js#L16-L18
Solution
-----
Add extra steps to wait for filtering to be applied. Also add extra steps to ensure correct update of the POL's quantity.
-----
Runbot error 237956This update fixes an issue where the quantity delivered on sale orders wasn't accurately updated after a partial refund with a 'Ship Later' option. Previously, the system incorrectly reported zero delivered quantities. The fix ensures that delivered quantities are correctly calculated, including those associated with refunded orders, to provide accurate inventory tracking.
Original PR description
The qty_delivered on sale.order.line was not correctly computed when the original order was refunded with a ship later. Steps to reproduce: ------------------- * Create a sale order for 5 quantities of any product * Confirm the sale order * Settle the order in the PoS * At this point the qty_delivered on the sale order line is 5 * Now go back to the PoS and refund partially the order for 3 quantities and use the "Ship Later" option > Observation: The qty_delivered is 0 instead of 2 Why the fix: ------------ We group the pos.order.line by procurement group and then check if all pickings related to these lines are done before adding the qty to the qty_delivered. We also make sure to include the refund lines in the computation opw-5059560 Forward-Port-Of: odoo/odoo#244008 Forward-Port-Of: odoo/odoo#240945
This update fixes an issue where dialog windows were hidden behind the AI chat window, making them difficult to use. Now, dialogs are consistently displayed above all chat windows except the AI chat window, ensuring a clearer and more intuitive user experience.
Original PR description
**Description of the issue this PR addresses:** ------------------------------------------------ Dialogs were rendered behind chat windows, making them difficult to see and interact with. **Current behavior before PR:** --------------------------------- - The dialog appears behind the chat window **Desired behavior after PR is merged:** ----------------------------------------- - Dialogs are displayed above all chat windows except AI - The AI chat window remains intentionally above dialogs **Task:** 5367135
This update resolves an issue where users without administrative privileges could encounter errors when generating global invoices in the Mexican CFDI module. The fix addresses a caching problem and incorrect access control within the invoice generation process, ensuring reliable global invoice creation for all users.
Original PR description
**PROBLEM** 1. When generating a global invoice with a user without super user access, a access error may occur on the ir.sequence model. 2. There is an issue with the cache of the field…
**PROBLEM** 1. When generating a global invoice with a user without super user access, a access error may occur on the ir.sequence model. 2. There is an issue with the cache of the field `l10n_mx_edi_global_invoice_sequence_id`. (this is why problem can sometimes resolves itself on restarting the odoo instance). **STEP TO REPRODUCE** 1. Create 1 invoice with CFDI to public checked. 2. Goes to the list view for invoices, select the invoice, and apply the action "create global invoice" to it. 4. A access error may appear (depending on cache value). **CAUSE** 1. In `_get_global_invoice_cfdi_sequence()`, we get or create the ir.sequence used for global invoices. We are creating it with sudo(), so a user without sudo privilege can write to it. But, when we are retrieving a ir.sequence record that already exist, when don't use sudo(), this causes an access error for user without sudo privilege. 2. In `_get_global_invoice_cfdi_sequence()`, we try to get the computed field `l10n_mx_edi_global_invoice_sequence_id`. If it doesn't exist, we create a ir.sequence, but we forget to assign it to the field. Because we already trigger the compute method of the field by trying to access it, there is a None value in cache for it. This means we will always create a ir.sequence, despite one already existing for the company until the cache expires or the compute method is re-triggered. opw-5472552 Forward-Port-Of: odoo/enterprise#104181
This update fixes an issue preventing Latin American electronic invoices from printing correctly in PDF format. The change ensures the invoice header and footer are accurately displayed, regardless of whether a chart template is set up in the database, addressing a problem with older systems. This ensures accurate invoice generation for businesses in Argentina, Chile, Brazil, and other Latin American countries.
Original PR description
This commit fixes a bug introduced here https://github.com/odoo/odoo/commit/3f7d79731fd5e5a751f7f1aeae63379c6211de5c because some old databases do not have set the chart template so it is needed to render the header and footer of the report template layouts taking in consideration the account fiscal country code instead of the chart template. Replicate printing the pdf of a customer electronic invoice on an argentinen company without chart template. Ticket Adhoc side: 105739 Task latam: 1373 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244102 Forward-Port-Of: odoo/odoo#238033
This update enhances the security and reliability of our Peppol integration by safely handling server deregistration when a client leaves. The system now allows for a controlled reset of configurations, enabling users to re-register without disruption. This change was prompted by a previous incident and improves the overall stability of the Peppol connection.
Original PR description
Reintroduce server-initiated deregistration on `client_gone`, but only for implementations that explicitly handle it. The base proxy client now just raises the error. Peppol opts in by soft-resetting its configuration so users can re-register. See the IAP postmortem for the rationale and incident history. https://github.com/odoo/iap-apps/pull/1317 no-task Forward-Port-Of: odoo/odoo#245567 Forward-Port-Of: odoo/odoo#239254
7 changes
Enhancements to existing features
This update enhances the system administrator panel by allowing for more flexible and customizable notifications. Previously, only a single system message could be displayed. Now, administrators can configure multiple messages with different alert levels, providing clearer and more targeted information about important events and maintenance schedules. This improves communication and operational visibility.
Original PR description
Tweak #102239 to allow more flexibility and display multiple messages with different alert level.
The ir.config_parameter is sysadmin.message and should be a json loadable. The format shoud be something like this:
{
"replace": false,
"warning_type": "user",
"message": "<div class='alert alert-info'>A maintenance operation is planned on your server on <strong>2026-01-15</strong> between 14h and 15h</div>"
}
Forward-Port-Of: odoo/enterprise#105157Resolved issues and error corrections
This update corrects a bug in the automatic currency rate syncing process. Due to Bulgaria's adoption of the Euro, the BNB now provides exchange rates in EUR, not BGN. This fix ensures that companies using EUR as their main currency can correctly access and sync exchange rates from the BNB provider.
Original PR description
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the…
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the BNB now provides rates against EUR. This caused the error "Your main currency (EUR) is not supported by this exchange rate provider" when Bulgarian companies with EUR as their main currency tried to sync exchange rates. refs: We can compare the data here from 31 December using the WayBackMachine: https://web.archive.org/web/20251231193558/https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm Compared to today: https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm And see the comparison used to be to BGN but is now for EUR Steps To Reproduce: 1. Create a company for Bulgaria with EUR as the main currency. 2. Go to Accounting Settings -> Automatic Currency Rates. 3. Select "[BG] Bulgaria National Bank" as the service provider. 4. Click the sync button. 5. Error appears: "Your main currency (EUR) is not supported by this exchange rate provider. Please choose another one." The fix updates the base currency from BGN to EUR, matching the current BNB XML format which now provides rates against EUR. Note: Companies with BGN as main currency will now get the same error, which is expected since the BNB no longer provides BGN-based rates. This behavior was discussed and confirmed with the PO. Ticket [link](https://www.odoo.com/odoo/project.task/5483771) opw-5483771 Forward-Port-Of: odoo/enterprise#105074
This update corrects a technical issue preventing proper validation of vendor bills on ARCA. The 'CodAutorizacion' field was incorrectly named, causing errors and preventing the system from correctly processing invoices. This ensures accurate bill validation and avoids disruptions to the ARCA workflow.
Original PR description
In this commit https://github.com/odoo/enterprise/pull/103370/changes#diff-2459e118c605cf039bb94c62561285ad753b6a27c571f10a25547ee9b01aa318R289 where a refactor has been made, the field 'CodAutorizacion' was left as 'invCodAutorizacion' on _l10n_ar_edi_get_request_data_verify. This leads to errors when validating vendor bills on ARCA, since the organism could not find the required field. <img width="640" height="163" alt="image" src="https://github.com/user-attachments/assets/74a0cdc6-c007-474c-a67b-fd12d484838f" /> Forward-Port-Of: odoo/enterprise#105362
This update fixes an issue where the Gantt chart controls would overlap the user interface, particularly when using custom date ranges or smaller screen sizes. The change ensures that Gantt controls are displayed correctly, improving usability and preventing visual clutter, especially on mobile devices.
Original PR description
Steps to reproduce ================== - Switch to dutch - Emulate an iPhone SE viewport in the browser settings - Open a project - Switch to the gantt view - Use a custom date range -> The gantt controls are displayed on top due to the daterange format being to long | Before | After | |--------|--------| | <img width="736" height="1542" alt="image" src="https://github.com/user-attachments/assets/7c573ab1-fbf8-4f31-83ba-21d66ebc504d" /> | <img width="736" height="1542" alt="image" src="https://github.com/user-attachments/assets/62ab3d47-701e-4e2d-aaef-5c92675236cb" /> | opw-5340869 Forward-Port-Of: odoo/enterprise#104821
This update resolves an issue where users without administrative privileges could encounter access errors when creating global invoices (CFDI). The fix addresses a caching problem and ensures proper access rights are managed when retrieving existing invoice sequences, preventing errors and improving stability.
Original PR description
**PROBLEM** 1. When generating a global invoice with a user without super user access, a access error may occur on the ir.sequence model. 2. There is an issue with the cache of the field…
**PROBLEM** 1. When generating a global invoice with a user without super user access, a access error may occur on the ir.sequence model. 2. There is an issue with the cache of the field `l10n_mx_edi_global_invoice_sequence_id`. (this is why problem can sometimes resolves itself on restarting the odoo instance). **STEP TO REPRODUCE** 1. Create 1 invoice with CFDI to public checked. 2. Goes to the list view for invoices, select the invoice, and apply the action "create global invoice" to it. 4. A access error may appear (depending on cache value). **CAUSE** 1. In `_get_global_invoice_cfdi_sequence()`, we get or create the ir.sequence used for global invoices. We are creating it with sudo(), so a user without sudo privilege can write to it. But, when we are retrieving a ir.sequence record that already exist, when don't use sudo(), this causes an access error for user without sudo privilege. 2. In `_get_global_invoice_cfdi_sequence()`, we try to get the computed field `l10n_mx_edi_global_invoice_sequence_id`. If it doesn't exist, we create a ir.sequence, but we forget to assign it to the field. Because we already trigger the compute method of the field by trying to access it, there is a None value in cache for it. This means we will always create a ir.sequence, despite one already existing for the company until the cache expires or the compute method is re-triggered. opw-5472552 Forward-Port-Of: odoo/enterprise#104181
This update resolves an issue where sales orders with missing address information in Mexico prevented online payments from being correctly processed. The fix automatically enables ‘CFDI to Public’ when the address is incomplete, ensuring transactions are validated and payments are recorded as required by Mexican regulations. This improves payment reliability and compliance.
Original PR description
### Issue: On a Mexican sale order, it was possible to have an invalid partner address while `CFDI to Public` was not enabled In this situation, an online payment could be initiated, but a silent…
### Issue: On a Mexican sale order, it was possible to have an invalid partner address while `CFDI to Public` was not enabled In this situation, an online payment could be initiated, but a silent error occurred during move validation: the transaction was created, but the payment was never recorded, and no error appeared in the portal or the SO chatter ### Cause: The CFDI validation error is raised internally but never surfaced to the user https://github.com/odoo/enterprise/pull/91655 The PO (MIAL) recommended automatically enabling `CFDI to Public` when the partner address is incomplete, forcing the user to complete the data This also ensures that the payment can be confirmed properly ### Steps to reproduce: - Install `l10n_mx_edi_sale` and switch to the MX company - Configure a Payment Provider and Payment Method (e.g., demo) - Create a customer without ZIP or country - Create a Sale Order for that customer - In Other Info, set Online Payment to 100% - Send the quotation and open the link in a private window - Sign and Pay Before the fix: the transaction is created, but no payment is recorded, and no error is shown opw-5023724 Forward-Port-Of: odoo/enterprise#101881
This update resolves an issue where AvaTax was failing due to orders lacking at least one line item. This prevented proper tax calculations and reporting, particularly in scenarios involving subscription management or the industry_fsm_stock module. The change automatically filters out orders without lines, ensuring accurate tax processing.
Original PR description
Backport of https://github.com/odoo/enterprise/pull/101643. Original commit message for completeness: Calling Avatax without lines results in an error and blocks flows: ``` Odoo could not fetch the…
Backport of https://github.com/odoo/enterprise/pull/101643. Original commit message for completeness: Calling Avatax without lines results in an error and blocks flows: ``` Odoo could not fetch the taxes related to MXXX - SOXXX/XXX. Please check the status of `Sales Order XXX` in the AvaTax portal. Transactions must have at least one line. ``` There are various cases this can happen: 1/ if industry_fsm_stock is installed, empty orders are confirmed [1], 2/ if you put the end_date of a subscription before the next_invoice_date, then none of the lines are considered invoiceable [2] and you get the error when viewing the subscription in the portal This commit filters out orders without lines. It's also possible to filter this on the level of the models by doing it in _get_and_set_external_taxes_on_eligible_records(). However, this means doing it separately for each model, and requires every implementer do it manually. [1] https://github.com/odoo/enterprise/blob/703e7fd413e93a8287da98286aa93b9699ae3e96/industry_fsm_stock/models/project_task.py#L159 [2] https://github.com/odoo/enterprise/blob/c7bf4367a9bf6757a36a9f34a872a6e35a19a3a5/sale_subscription/models/sale_order_line.py#L475 opw-5214609 opw-5247727 opw-5311132 opw-5385960 Forward-Port-Of: odoo/enterprise#105587
19 changes
Enhancements to existing features
This update significantly enhances the Payroll Dashboard by introducing automated warning scheduling, improved UI for displaying deadlines, and email alerts for overdue warnings. The changes streamline payroll processes and ensure timely compliance with critical deadlines.
Original PR description
`*` = `l10n_xx_hr_payroll`, `hr_holidays_fleet`, `hr_contract_salary_payroll`, `hr_payroll_account_iso20022` - renamed `hr.payroll.dashboard.warning` to `hr.payroll.warning` - changed every…
`*` = `l10n_xx_hr_payroll`, `hr_holidays_fleet`, `hr_contract_salary_payroll`, `hr_payroll_account_iso20022`
- renamed `hr.payroll.dashboard.warning` to `hr.payroll.warning`
- changed every occurrences of `hr.payroll.dashboard.warning` to `hr.payroll.warning` in data records and references.
- removed specified warnings
- removed specified warnings from `hr_payroll` and `hr_payroll_fleet`
- removed unused dashboard components
- removed all the other dashboard components apart from the warning one, and removed their methods from `hr_payslip` and related tour and tests from `test_dasboard`
- reworked dashboard
- added a mandatory onboarding process to obtain payrun related data
- reworked Dashboard UI to show warnings with their deadlines
- added some fields on `hr.payroll.warning` to compute warning deadline
- added email alerts when warning overdue
- now, user can choose from Python Code or Domain while creating a warning
- also added new warnings
Task [link](https://www.odoo.com/odoo/project.task/5252854)
task-5252854This update enhances the Frontdesk module by ensuring accurate notification handling and robust host selection. It clarifies notification settings, enforces required contact information (email or phone) for hosts, and prevents data saving if this information is missing, improving data integrity.
Original PR description
The purpose of this change is to ensure proper host selection and accurate notification handling with clear validation. This PR includes the following changes: - Removed the user-related Discuss notification warning and updated the checkbox description to clarify that Discuss notifications are only sent to hosts with a user account. - Added a validation to ensure that hosts always have either an Email or Phone. - Prevented saving when any host lacks Email/Phone. - Applied the same behavior to both the frontdesk and visitor views. - Updated the notification option descriptions for Email and SMS to be clearer. Related Upgrade PR: https://github.com/odoo/upgrade/pull/9299 task-5082882
This update simplifies the process for creating and editing global filters within the spreadsheet edition, now handled directly in the side panel. Previously, inconsistent flows led to user confusion. Now, the filter value list is exclusively used for global filters in dashboards via the search bar, streamlining the user experience.
Original PR description
Current behavior before PR: - Clicking the filter button opened a dialog for configured filters. - Creating a filter used the dialog, but editing required the side panel. - This resulted in an unexpected and inconsistent user flow. Desired behavior after PR is merged: - Creating and editing global filters is handled in the side panel - The filter value list is now used only for global filters in dashboards via the search bar. Task: [5447040](https://www.odoo.com/odoo/project/2328/tasks/5447040)
This update enhances the display of recent call history in the Voip module by ensuring icons are always fully visible and by streamlining the user interface. The 'Go to' buttons have been reorganized for a more intuitive experience. This improves usability and reduces potential confusion for users.
Original PR description
### Adjust tab entry layout Prior to this PR, extra icons in recent entries could be truncated depending on the subtitle length. This commit adapts the entry layout to ensure that extra icons are…
### Adjust tab entry layout Prior to this PR, extra icons in recent entries could be truncated depending on the subtitle length. This commit adapts the entry layout to ensure that extra icons are always fully visible. This PR also moves the "Go to Call" and "Go to Activity" buttons into the "Go to" dropdown for a more predictable user experience. ### Adapt call suggestion separator This PR updates the call suggestion separator to improve readability. --- task-5413528 --- ### Avoid extra icons truncation | Before | After | |--------|--------| | <img width="367" height="63" alt="Capture d’écran 2026-01-16 à 12 04 26" src="https://github.com/user-attachments/assets/ec117119-7d90-4de0-87e2-c2bd5d8e3eab" /> | <img width="362" height="61" alt="Capture d’écran 2026-01-16 à 12 06 30" src="https://github.com/user-attachments/assets/caef103b-e324-4ed0-a180-22271f3efa0d" /> | ### Move Go to button | Before | After | |--------|--------| | <img width="367" height="63" alt="Capture d’écran 2026-01-16 à 12 04 26" src="https://github.com/user-attachments/assets/ec117119-7d90-4de0-87e2-c2bd5d8e3eab" /> | <img width="364" height="380" alt="Capture d’écran 2026-01-16 à 12 07 50" src="https://github.com/user-attachments/assets/3ae631d0-0315-445f-b6f8-1d2ba2306d6d" /> | ### Adapt call suggestion separator | Before | After | |--------|--------| | <img width="377" height="145" alt="Capture d’écran 2026-01-16 à 12 08 53" src="https://github.com/user-attachments/assets/0d92689f-31d7-40c1-9e98-23e894dbe94e" /> | <img width="379" height="133" alt="Capture d’écran 2026-01-16 à 12 09 06" src="https://github.com/user-attachments/assets/95640f67-0c15-4142-ae4d-c98e0ffaa093" /> |
This update enhances the Partner Ledger report to include grouping by PAN entity, a key requirement for Indonesian accounting standards. The changes involve adding a new field to the accounting records and removing duplicate code to streamline the report generation process. This ensures accurate reporting aligned with local regulations.
Original PR description
This PR contains two commits:
First Commit :-
Adds a Partner Ledger Variant report to show partner ledger group by
PAN Entity.
A new related field has been introduced in `account.move.line` to
support group by.
Second Commit :-
The Partner Ledger report contained duplicated `account.report.line`
logic introduced by commit https://github.com/odoo/enterprise/commit/7ee125d0fa693b842014881620129b579018b718
task-4975468Resolved issues and error corrections
This update fixes a critical issue where the Moroccan tax report XML export incorrectly handled cash basis taxes. The change ensures bills are accurately reflected in the export, aligning with Moroccan tax regulations. This improves data consistency and report reliability.
Original PR description
[FIX] l10n_ma_reports: tax report: properly consider cash basis taxes in the XML export Moroccan taxes are cash basis by default. The former version of the XML generation completely disregarded that,…
[FIX] l10n_ma_reports: tax report: properly consider cash basis taxes in the XML export Moroccan taxes are cash basis by default. The former version of the XML generation completely disregarded that, and always reported all bills in the period. Solving this requires using an SQL query so that cash basis can be properly computed, like in the report. This also makes the export much more efficient, and resilient to bigger amount of data. Steps to reproduce: - Install `l10n_ma_reports` and switch to the MA company - Create and confirm a bill: Bill Date: 10/01/2025 Vendor: Azure Interior Invoice Lines: Price 100, Taxes 20% (S 140) - Go to `Bank Reconciliation` - Add a transaction (Vendor: Azure Interior, Amount: -120 DH, any Memo) - Select the transaction and the invoice, then click Validate - Open the Tax Return for November. Section D should show data linked to the created invoice - Export the XML using the Gear → XML The created bill is missing in the XML and others may be present, showing inconsistent data opw-5002779 [IMP] l10n_ma_reports: call the report to compute the prorata value Searching explicitly for external values is a bad practice ; calling the report ensures consistency between the data displayed, and the one exported into the file. Forward-Port-Of: odoo/enterprise#105106 Forward-Port-Of: odoo/enterprise#104619
This update corrects a bug in how overtime entries are generated within the attendance system. Previously, overtime rules were incorrectly applied, leading to overlapping entries and errors. This fix ensures accurate overtime calculations and approval processes.
Original PR description
STEP TO REPRODUCE:
------------------
0- Go to attendance > Configuration > Overtime Ruleset 1- Create the following overtime ruleset (all rules are paid and with the entry type overtime):
rule 1: timing rule on worked day with this timing : 0AM -> 8AM
rule 2: timing rule on worked day with this timing : 12AM -> 1PM
rule 1: timing rule on worked day with this timing : 5PM -> 12PM
2- Go to attendance > configuration > settings
3- Enable Time Management
4- ANd change the extra hours validation by automatically approved 5- create an employee and give to him this overtime ruleset 6- Create for an attendance for him from 6AM to 8PM 7- to go the form view of this attendance
8- Approve it; you wwill have a traceback
REASON:
-------
The way to handle the reorganization of the overtime line on an attendance was badly done; everything was shift with the same shift so some overtime was overlapping the others
Forward-Port-Of: odoo/enterprise#105173This update resolves an issue where invoices, sale orders, and POS orders defaulted to an invalid payment method ('Por Definir') in the MX region. This caused fiscal inconsistencies, particularly with the 'PUE' payment policy. The fix removes this default, ensuring accurate financial reporting and compliance.
Original PR description
### Issue: The payment method `99 – Por Definir` was used as the default value for invoices, sale orders, and POS orders This leads to fiscal inconsistencies, especially when invoices use the `PUE`…
### Issue: The payment method `99 – Por Definir` was used as the default value for invoices, sale orders, and POS orders This leads to fiscal inconsistencies, especially when invoices use the `PUE` payment policy, where this payment method is invalid ### Cause: In the `_compute_l10n_mx_edi_payment_method_id` methods, the default value was always set to `Por Definir` ### Fix: After discussion with the PO (MIAL), the chosen solution is to archive the payment method `99 – Por Definir`and remove it as a default value All valid cases should already be handled explicitly, making it clear to the user that something is missing when the data is blank ### Steps to reproduce: - Install `l10n_mx_edi` and switch to the MX company - Create an invoice with today’s invoice date - The payment policy is set to PUE - Before the fix, the payment method is set to `Por Definir` For Sale Order and POS Order tests, it's the default value as soon as you create an order opw-5406038 Forward-Port-Of: odoo/enterprise#105344 Forward-Port-Of: odoo/enterprise#104164
This update optimizes how Odoo handles incoming VoIP calls, preventing duplicate call creation caused by multiple users connecting simultaneously. By using a server-side mechanism and PostgreSQL's UPSERT feature, the system now efficiently manages call records, improving performance and reliability for all users.
Original PR description
## Context Each Odoo client (e.g., a browser tab), establishes a WebSocket connection with the VoIP provider. This causes problems with incoming calls: each instance receives the notification, which leads to the associated callbacks being called as many times as there are running Odoo clients. ## Current state To avoid creating a voip.call record for every connected client, we introduced a "get_or_create" method that first attempts to retrieve the record and then creates it if it doesn't exist. If the operation fails due to concurrent updates, the client simply retries it after some jitter. This is not ideal because each attempt results in a round trip. ## After this commit This commit improves the current handling of concurrent updates by managing them on the server side. It leverages the [UPSERT](https://wiki.postgresql.org/wiki/UPSERT) mechanism of PostgreSQL to implement the "get or create" logic and relies on Odoo's automatic retry feature to manage concurrent updates.
This update enhances the accuracy of achievement reports by using a new method for calculating and storing key data. Specifically, the system now utilizes materialized views and indexing to speed up report generation and ensure data consistency, addressing potential calculation inaccuracies.
Original PR description
Investigation in process. task-5477432
This update resolves an issue where Stripe expense data was being duplicated, causing confusion and errors in the Odoo system. The changes now skip the Stripe KYC steps during demo setup, speeding up the process and ensuring accurate data. This improves the demo experience and prevents data inconsistencies.
Original PR description
Prevent expenses automatically created by Stripe Issuing to be duplicated. Currently, it adds a lot of noise on customer dbs. The payment method is duplicated and it can lead to errors (eg: employee submit duplicatas instead of the original expenses. The automatic reconciliation doesn't happen afterwards) task-5246475 Forward-Port-Of: odoo/enterprise#102034
This update resolves an issue where smart buttons on the voip call forms were missing access groups and causing singleton errors. The fix ensures that smart buttons work as intended, displaying the correct information and improving the user experience. This impacts users interacting with voip calls across various modules like CRM, Helpdesk, and Sales.
Original PR description
1. Tickek/Application smart buttons on voip.call form miss access groups. 2. In voip.call form, when clicking the application smart button, a singleton error will raise. 3. Incorrect numbers on smart button. Task-[5461729](https://www.odoo.com/odoo/5778/tasks/5461729) Forward-Port-Of: odoo/enterprise#103233
This update fixes an issue where users couldn't adjust the quantity of optional products added through the portal's upsell feature. The change ensures that the quantity of these products is correctly updated, allowing users to manage their subscriptions and renewals accurately. This improves the user experience and prevents order discrepancies.
Original PR description
Version: - 19.0 Steps to Reproduce: - Enable the Add Products option in the recurring plan. - Create a subscription with the same plan and add optional products. - Confirm the subscription and create invoice for current period. - From the portal, click on Add Quantity to create an upsell order. Before: - Users were not able to update the quantity of products added as optional products from portal. - This happened because the `is_optional` field value was not copied to the new order line created during the upsell. After: - The `is_optional` field value is now copied to the new order line created for upsell and renewal orders. - This allows users to update the quantity of optional products correctly. Impact: - Users can update the quantity of optional products from the portal without issues. task-5427585 Forward-Port-Of: odoo/enterprise#102670
This update resolves an issue where the VoIP ringtone played incorrectly due to multiple tabs receiving notifications. A new system directs incoming call notifications to a central SharedWorker, ensuring only one tab plays the ringtone and addressing potential problems with connection loss or tab inactivity. This enhances the reliability of the Odoo VoIP system.
Original PR description
Each Odoo tab establishes a WebSocket connection with the VoIP provider. This causes problems with incoming calls: each tab receives the notification, which leads to the associated callbacks being…
Each Odoo tab establishes a WebSocket connection with the VoIP provider. This causes problems with incoming calls: each tab receives the notification, which leads to the associated callbacks being called as many times as there are open tabs. This used to be particularly annoying with the ringtone, which would play in unison. To solve this problem, we decided that only the "main tab" should be responsible for playing the ringtone. Since there can only be one main tab at a time, there can only be one ringtone at a time. Problem solved. This seemed to be an easy and effective solution. However, we were informed that sometimes the call wouldn't ring at all 🤬 This called the reliability of the system into question. What would happen if: - The main tab loses the WebSocket connection? - The main tab is throttled? - The main tab was never interacted with, preventing us from playing audio? - The notification arrives after the main tab is killed and before a new main tab is elected? This commit attempts a new approach ⋆✴︎˚。⋆ All tabs receiving incoming call notifications will now send a message to a central authority—The _SharedWorker_ 🙀—along with information about whether or not they can play audio. The SharedWorker then selects the first tab that can play audio and assigns it the task of playing the incoming ringtone. This is expected to solve the problems mentioned above, as it guarantees that the "player tab" is a tab that: - effectively received the incoming call notification - is allowed to play audio [Task-5411760](https://www.odoo.com/odoo/project.task/5411760)
This update fixes an issue where employees with multiple bank accounts for salary distribution were receiving payment advice that only showed the first account and incorrectly allocated the full salary. Now, the payment advice (PDF and XLSX) accurately reflects all bank accounts and salary amounts, ensuring accurate payment reporting.
Original PR description
Issue: When an employee had multiple bank accounts with salary distribution, the payment advice (PDF and XLSX) was displaying only the first bank account and assigning the full salary amount to that account. This resulted in incorrect payment information being generated. Fix: When multiple bank accounts are configured with salary distribution, the payment advice now displays the correct information in both PDF and XLSX reports. task-5390429 Forward-Port-Of: odoo/enterprise#104073 Forward-Port-Of: odoo/enterprise#101818
This update addresses a limitation in the account online synchronization process where access tokens expire quickly. We've replaced the token system with a consent token, a unique identifier linked to the user, ensuring a more reliable and persistent consent management experience. This change improves the stability and functionality of the online synchronization feature.
Original PR description
In this commit:bf5b7d0 we introduce a message on the account_online_link to be able to manage the consent. (one needed fix in this commit:https://github.com/odoo/enterprise/commit/1c84804fd3f0c0d1d23916b9f6a388616f66ac7e) This commit will change the way we manage the consent since the access token is in fact available only for 30 min, so the link in the chatter would not work. We decided to have a consent token which is a uuid4 encoded in base64 (url safe) and link it to the odoofin user. task-5187621 Forward-Port-Of: odoo/enterprise#105392 Forward-Port-Of: odoo/enterprise#105202
This update corrects a compatibility issue with the Bulgarian National Bank (BNB) exchange rate provider. Due to Bulgaria's adoption of the Euro, the BNB now provides rates in EUR, not BGN. This fix ensures that companies using EUR as their main currency can correctly sync exchange rates without errors.
Original PR description
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the…
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the BNB now provides rates against EUR. This caused the error "Your main currency (EUR) is not supported by this exchange rate provider" when Bulgarian companies with EUR as their main currency tried to sync exchange rates. refs: We can compare the data here from 31 December using the WayBackMachine: https://web.archive.org/web/20251231193558/https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm Compared to today: https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm And see the comparison used to be to BGN but is now for EUR Steps To Reproduce: 1. Create a company for Bulgaria with EUR as the main currency. 2. Go to Accounting Settings -> Automatic Currency Rates. 3. Select "[BG] Bulgaria National Bank" as the service provider. 4. Click the sync button. 5. Error appears: "Your main currency (EUR) is not supported by this exchange rate provider. Please choose another one." The fix updates the base currency from BGN to EUR, matching the current BNB XML format which now provides rates against EUR. Note: Companies with BGN as main currency will now get the same error, which is expected since the BNB no longer provides BGN-based rates. This behavior was discussed and confirmed with the PO. Ticket [link](https://www.odoo.com/odoo/project.task/5483771) opw-5483771 Forward-Port-Of: odoo/enterprise#105074
This update fixes an issue where the basic salary was incorrectly calculated for employees in Saudi Arabia. The system now verifies the presence of 'WORK100' in employee workdays, ensuring the basic salary is only applied when appropriate, aligning with payroll regulations. This prevents overpayment and improves payroll accuracy.
Original PR description
purpose: we should check if there are WORK100 in the worked days, but as of now, we dont, and that results in having the basic salary triggered even when it shouldn't. - made basic salary only computed when work entry source is calendar or WORK100 in the worked days (there are attendances for the employee) and made its amount adapt with the worked days task-id: 5472853 Forward-Port-Of: odoo/enterprise#104090 Forward-Port-Of: odoo/enterprise#103493
This update resolves an issue where country-based filtering on payslips wasn't functioning properly, leading to errors. The fix ensures that country selections are correctly stored and used for filtering, eliminating module loader problems and improving payroll accuracy.
Original PR description
Issue: The country_id related field on payslip and payslip run was not stored, causing domain filters and search on this field to fail and triggering client-side errors. Fix: Use search parameter to write function so field can be used safely in search domains and filters. Impact: Country-based filtering now works correctly without triggering module loader errors. Task: 5406904 Forward-Port-Of: odoo/enterprise#104167 Forward-Port-Of: odoo/enterprise#103318
12 changes
New functionality added to Odoo
This update introduces a new module to help companies prepare reports aligned with the EU's CSRD and VSME frameworks. It leverages existing Odoo data (like emissions and employee information) and AI suggestions to streamline the reporting process, improving sustainability disclosures for investors and stakeholders.
Original PR description
In this PR, we add the possibility to create and manage a complete CSRD/VSME report, integrated with AI, knowledge, survey and HR. The Corporate Sustainability Reporting Directive (CSRD) is a legal…
In this PR, we add the possibility to create and manage a complete CSRD/VSME report, integrated with AI, knowledge, survey and HR. The Corporate Sustainability Reporting Directive (CSRD) is a legal framework in the EU that requires companies to report on their sustainability performance. It aims to standardize ESG reporting across the EU and make the information more comparable and reliable for investors and other stakeholders. On the other hand, the Voluntary Sustainability Reporting for Micro and Small Enterprises (VSME) is a framework designed to support smaller companies in reporting on their sustainability performance. It encourages clear, comparable, and meaningful ESG disclosures while remaining proportionate to the size and capacity of the business. Our reporting feature facilitates the steps involved in preparing a CSRD/VSME report by using the data we already have in Odoo, such as emissions (Scope 1, 2, 3), employee data, supplier and client information, or fleet metrics. As well as using AI to make suggestions, and integrating knowledge articles and surveys. More precisely, the feature is composed of two main models: - A new model (`esg.metric)` that is only used if the CSRD reporting is enabled (and only used in the context of CSRD reporting). It is linked to an ESRS data point (either Environmental, Social or Governance category) and can be of different types (Positive/Negative Impact, Risk or Opportunity). It is used to assess if a topic is material or not (Double Materiality Assessment), depending on the impact severity and financial severity scores. As well as scores obtained from the stakeholder reviews (we get those scores from surveys that have been completed, the surveys are sent with the action "Stakeholder Review"). To help the user to create relevant metrics, we added an AI feature allowing to generate suggestions of metrics. Provided that the user gives a description of the company (size, revenues, activity, etc) to give as much context as possible to the AI prompt (see action "AI Suggest"). - A new model (`esg.report`) where you can specify the type of the report (CSRD or VSME), the dates (reporting date and base reference date), and additional information about the company. Once created, the report is linked to a knowledge article that contains the template of a complete CSRD/VSME report that you can edit, fold/unfold sections, add content, etc. When printing it to PDF, a lot of information is automatically filled in (data about your employees, accounting data, etc), including the carbon report, dynamic tables. That is done by replacing placeholders from the knowledge article when generating the PDF (an appendix includes all available placeholders with a small explanation for each). For CSRD reports only, there is the ability to automatically fold/unfold the ESRS sections of the articles depending on whether the data points we get from the metrics are material or not (see action "Update Materiality"). For VSME reports only, there is a "Basic Module + Comprehensive Module" type that will include additional sections (C1-C9). Note that you can also load them manually from the root article with the "Load Template" action. task-5172829
Enhancements to existing features
This update enhances the system administrator panel by allowing for more flexible and customizable notifications. Previously, only a single message could be displayed. Now, administrators can configure multiple messages with different alert levels, providing more targeted and informative updates about server maintenance or other critical events.
Original PR description
Tweak #102239 to allow more flexibility and display multiple messages with different alert level.
The ir.config_parameter is sysadmin.message and should be a json loadable. The format shoud be something like this:
{
"replace": false,
"warning_type": "user",
"message": "<div class='alert alert-info'>A maintenance operation is planned on your server on <strong>2026-01-15</strong> between 14h and 15h</div>"
}
Forward-Port-Of: odoo/enterprise#105157Resolved issues and error corrections
This update enhances the monitoring of our AI usage by changing key logs from 'debug' to 'info', making them easier for administrators to track. Additionally, the system now accurately reports token usage from the LLM providers, resolving previous underreporting issues. This provides better visibility and control over AI costs.
Original PR description
In this commit we change some important llm api usage logs from debug to info so they can be more easily monitored by us and database admins. We also change the usage reporting from a naive estimation (which greatly under-reported the token usage) to the actual token usage given to us by the LLM prodivers in the response.
This update addresses a limitation in the account online synchronization process where access tokens expire quickly. We've implemented a new consent token system – a unique, secure identifier linked to the user – to ensure reliable consent management and continued synchronization functionality. This change improves the user experience and stability of the online connection.
Original PR description
In this commit:bf5b7d0 we introduce a message on the account_online_link to be able to manage the consent. (one needed fix in this commit:https://github.com/odoo/enterprise/commit/1c84804fd3f0c0d1d23916b9f6a388616f66ac7e) This commit will change the way we manage the consent since the access token is in fact available only for 30 min, so the link in the chatter would not work. We decided to have a consent token which is a uuid4 encoded in base64 (url safe) and link it to the odoofin user. task-5187621 Forward-Port-Of: odoo/enterprise#105392 Forward-Port-Of: odoo/enterprise#105202
This update corrects a compatibility issue with the Bulgarian National Bank (BNB) exchange rate provider. Since Bulgaria adopted the Euro, the BNB now provides rates in EUR, not BGN. This fix ensures that companies using EUR as their main currency can correctly sync exchange rates, resolving a previous error.
Original PR description
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the…
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the BNB now provides rates against EUR. This caused the error "Your main currency (EUR) is not supported by this exchange rate provider" when Bulgarian companies with EUR as their main currency tried to sync exchange rates. refs: We can compare the data here from 31 December using the WayBackMachine: https://web.archive.org/web/20251231193558/https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm Compared to today: https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm And see the comparison used to be to BGN but is now for EUR Steps To Reproduce: 1. Create a company for Bulgaria with EUR as the main currency. 2. Go to Accounting Settings -> Automatic Currency Rates. 3. Select "[BG] Bulgaria National Bank" as the service provider. 4. Click the sync button. 5. Error appears: "Your main currency (EUR) is not supported by this exchange rate provider. Please choose another one." The fix updates the base currency from BGN to EUR, matching the current BNB XML format which now provides rates against EUR. Note: Companies with BGN as main currency will now get the same error, which is expected since the BNB no longer provides BGN-based rates. This behavior was discussed and confirmed with the PO. Ticket [link](https://www.odoo.com/odoo/project.task/5483771) opw-5483771 Forward-Port-Of: odoo/enterprise#105074
This update resolves an issue where payment reports were inconsistently using different export formats (NACHA or localization-specific). The fix ensures that payment reports now automatically use the correct format based on the company's localization, improving report accuracy and usability for users. This change also includes added testing.
Original PR description
\* = l10n_{ae, au, ch, in, sa, us}_hr_payroll + hr_payroll_account_iso20022
Issue:
The current behavior looks deterministic: when clicking on "Create Payment Report" it -sometimes- shows the current company's export format by default, other times it shows the "NACHA" type. Or it could be the last installed module's export format value for the other companies.
Solution:
I fixed it in this PR: https://github.com/odoo/enterprise/pull/93683 and now backporting the changes to version 18.0
task-5189295
Forward-Port-Of: odoo/enterprise#104086
Forward-Port-Of: odoo/enterprise#100126This update fixes a bug in the Austrian Tax Report where VAT from vendor bills was incorrectly subtracted instead of added. The change adjusts a key formula to accurately reflect the total, aligning with previous versions and ensuring correct tax reporting. This ensures accurate tax calculations for Austrian businesses.
Original PR description
### Issue: In 19.0, VAT from vendor bills was subtracted from the total in the Austrian Tax Report, instead of being added ### Cause: The expression `tax_report_line_l10n_at_tva_line_7_total` uses an incorrect formula: `<field name="formula">AT_0004.vat - AT_0005.vat + AT_090.vat</field>` It should instead be: `<field name="formula">AT_0004.vat + AT_0005.vat + AT_090.vat</field>` This matches the behavior of previous versions In 18.0, there was no aggregated AT_0005 line All values were summed together, which effectively resulted in the same total ### Steps to reproduce: - Install `l10n_at_reports` - Switch to AT Company - Open the Tax Return and note the last line value for the current month - Create and confirm a vendor bill with 20% VAT - Compare the new value in Tax return Before the fix, the total line was decreased instead of increased opw-5349445 Odoo PR: https://github.com/odoo/odoo/pull/244471
This update fixes an issue where negative lines on invoices generated for Ecuador (l10n_ec) were not correctly processed in the XML format. The change aligns the handling of these lines with Mexico (l10n_mx), ensuring accurate discount application and preventing rounding errors that could impact invoice accuracy. This improves the reliability of financial reporting.
Original PR description
In **l10n_ec**, negative lines are not accepted in the XML. They must be dispatched as discounts on positive lines. The dispatching logic implemented in `60e1b41734f76a2d9268edc41286462a9d01a501` can…
In **l10n_ec**, negative lines are not accepted in the XML. They must be dispatched as discounts on positive lines. The dispatching logic implemented in `60e1b41734f76a2d9268edc41286462a9d01a501` can cause rounding issues when the decimal accuracy for `price_unit` is increased. ## Steps to reproduce With **l10n_ec**: 1. Change the decimal accuracy to 6 digits. 2. Set the rounding method to *global rounding*. 3. Create an invoice with the following lines: | Quantity | Price | Taxes | |-----------|----------|-----------| | 20 | 1.4235 | VAT 0% G | | 20 | 1.6425 | VAT 0% G | | 20 | 1.2337 | VAT 0% G | | 20 | 1.2337 | VAT 0% G | | 20 | 1.4235 | VAT 0% G | | 6 | 3.747768 | VAT 15% G | | 6 | 3.747768 | VAT 15% G | In the generated XML, some product lines show a `descuento` of `0.01` or `-0.01`. This happens due to rounding differences in how the `descuento` is computed in the `common_details_info_template` from **l10n_ec_edi**: format_num_2(line_edi_values['price_discount'] + abs(line.balance) - line_items[1]['base_amount']) where `line.balance` and `line_items[1]['base_amount']` can differ by 0.01 due to global rounding applied during tax aggregation, and that difference must be redistributed somewhere. This commit changes how negative lines are dispatched onto positive ones, aligning the behavior with **l10n_mx**. Instead of using `tax_details_per_record` to build the XML, we now use `base_lines`, where the negative lines have already been distributed. opw-5128612 Forward-Port-Of: odoo/enterprise#104659 Forward-Port-Of: odoo/enterprise#97337
This update resolves an issue where Stripe-created expense records were being duplicated, causing data inconsistencies and errors. The fix prevents duplication and streamlines the demo setup by skipping Stripe KYC steps, improving the user experience. It also ensures demo buttons are always visible.
Original PR description
Prevent expenses automatically created by Stripe Issuing to be duplicated. Currently, it adds a lot of noise on customer dbs. The payment method is duplicated and it can lead to errors (eg: employee submit duplicatas instead of the original expenses. The automatic reconciliation doesn't happen afterwards) task-5246475
This update fixes an issue where the VoIP ringtone played incorrectly across multiple Odoo tabs. The system now uses a central SharedWorker to intelligently select a tab to play the ringtone, ensuring it only plays once and addressing potential problems with connection loss or tab inactivity. This enhances the overall reliability of incoming call notifications.
Original PR description
Each Odoo tab establishes a WebSocket connection with the VoIP provider. This causes problems with incoming calls: each tab receives the notification, which leads to the associated callbacks being…
Each Odoo tab establishes a WebSocket connection with the VoIP provider. This causes problems with incoming calls: each tab receives the notification, which leads to the associated callbacks being called as many times as there are open tabs. This used to be particularly annoying with the ringtone, which would play in unison. To solve this problem, we decided that only the "main tab" should be responsible for playing the ringtone. Since there can only be one main tab at a time, there can only be one ringtone at a time. Problem solved. This seemed to be an easy and effective solution. However, we were informed that sometimes the call wouldn't ring at all 🤬 This called the reliability of the system into question. What would happen if: - The main tab loses the WebSocket connection? - The main tab is throttled? - The main tab was never interacted with, preventing us from playing audio? - The notification arrives after the main tab is killed and before a new main tab is elected? This commit attempts a new approach ⋆✴︎˚。⋆ All tabs receiving incoming call notifications will now send a message to a central authority—The _SharedWorker_ 🙀—along with information about whether or not they can play audio. The SharedWorker then selects the first tab that can play audio and assigns it the task of playing the incoming ringtone. This is expected to solve the problems mentioned above, as it guarantees that the "player tab" is a tab that: - effectively received the incoming call notification - is allowed to play audio [Task-5411760](https://www.odoo.com/odoo/project.task/5411760) Backport of https://github.com/odoo/enterprise/pull/104885
This update resolves a JavaScript error that occurred when opening the Shop Floor through the replenishment/forecast flow. The fix ensures the application name is correctly identified, preventing a traceback and allowing users to consistently access the Shop Floor functionality. This improves the reliability of the manufacturing process.
Original PR description
Opening the Shop Floor via the replenishment/forecast flow can raise a js traceback. **Steps to produce:** - Install `mrp` module. - Enable `multi-step routes` from the settings. - Inventory >…
Opening the Shop Floor via the replenishment/forecast flow can raise a js traceback. **Steps to produce:** - Install `mrp` module. - Enable `multi-step routes` from the settings. - Inventory > Configuration > Warehouse Management > Routes. - In Manufacture route, make sure route is Applicable On `products`. - Inventory > Products > Products > New. - Click on forcasted button on product > Click on replenish button > Confirm. - Click the Manufacturing Order shown in the notification. - Confirm the MO and click Shop Floor. **Issue:** A JavaScript error occurs: `TypeError: Cannot read properties of null.` **Root cause:** The Shop Floor view relies on the menu service to determine the current application name by calling `this.menu.getCurrentApp().name`. When the Shop Floor is opened from the replenishment/forecast flow, the navigation occurs through action-based triggers rather than through the main menu. As a result, no menu selection is performed and `setCurrentMenu()`[1] is not executed beforehand.This leaves the current application undefined, causing `menu.getCurrentApp()` to return undefined and leading to a js traceback when `.name` is accessed. [1]: https://github.com/odoo/odoo/blob/c646cb61d0752250b2600413d6d63deabd1d3e6d/addons/web/static/src/webclient/menus/menu_service.js#L57-L64 simillar fix : https://github.com/odoo/enterprise/pull/93043 Note: A tour is possible but unnecessary for this small use-case. opw-5462965 ---
This update corrects a technical issue preventing proper validation of vendor bills on ARCA. The 'CodAutorizacion' field was incorrectly named, causing errors and preventing the system from correctly processing invoices. This ensures accurate bill validation and avoids disruptions to the accounting process.
Original PR description
In this commit https://github.com/odoo/enterprise/pull/103370/changes#diff-2459e118c605cf039bb94c62561285ad753b6a27c571f10a25547ee9b01aa318R289 where a refactor has been made, the field 'CodAutorizacion' was left as 'invCodAutorizacion' on _l10n_ar_edi_get_request_data_verify. This leads to errors when validating vendor bills on ARCA, since the organism could not find the required field. <img width="640" height="163" alt="image" src="https://github.com/user-attachments/assets/74a0cdc6-c007-474c-a67b-fd12d484838f" /> Forward-Port-Of: odoo/enterprise#105362
10 changes
Enhancements to existing features
This update enhances the system administrator alerts displayed in Odoo Enterprise. It now allows for more flexible message formatting, including multiple alerts with different severity levels, improving communication about server maintenance and other important notifications. This change provides administrators with greater control over how critical information is presented.
Original PR description
Tweak #102239 to allow more flexibility and display multiple messages with different alert level.
The ir.config_parameter is sysadmin.message and should be a json loadable. The format shoud be something like this:
{
"replace": false,
"warning_type": "user",
"message": "<div class='alert alert-info'>A maintenance operation is planned on your server on <strong>2026-01-15</strong> between 14h and 15h</div>"
}
Forward-Port-Of: odoo/enterprise#105157Resolved issues and error corrections
This update resolves a problem where custom tax groups (beyond the standard 6) were causing efaktur printing errors. The fix ensures that efaktur printing works correctly with user-defined tax groups, while also correcting how tax values are calculated for invoices with mixed tax groups.
Original PR description
Description of the issue/feature this PR addresses: This issue occured because in the previous update we add a condition to restrict multiple tax groups excluding the STLG. Apparently there is a case…
Description of the issue/feature this PR addresses: This issue occured because in the previous update we add a condition to restrict multiple tax groups excluding the STLG. Apparently there is a case where some users create their own tax groups (for example for PPH) so when they want to print an efaktur it will raise an error. Current behavior before PR: If a user create their own tax with a new tax group (outside of the 6 groups defined in `l10n_id`) and use it in invoice line along with one of the 6 tax groups excluding the STLG then it will blocked the print efaktur because it will raise an error Desired behavior after PR is merged: - The restriction in tax groups only applied for the 6 tax groups in l10n_id so if an invoice line has multiple tax groups as long as there no more than one of the 6 tax groups excluding the STLG then it should be able to print the efaktur. - Also when building the efaktur coretax value, the new tax group should not be included in the regular_tax variable which will cause the value to be 11/12 of the original value. - Add new condition to block the print efaktur if there is a tax inside the invoice but none of it belong to the 6 ppn tax groups (there is already a condition to block if no tax is given, but now since there are cases where they use tax group outside of the defined tax groups then it will print the efaktur) - If an invoice line does not have any ppn_tax_groups but there are other line in the same invoice that has it then it will still be able to print the efaktur, but the line without the ppn tax will have the OtherTaxBase and VATRate set to zero which will calculate the VAT as 0 too. [5434656](https://www.odoo.com/odoo/project.task/5434656) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241979
This update fixes an issue where loyalty discounts weren't correctly shared between restaurant sessions. The change removes unnecessary data to prevent errors during order validation and payment, ensuring discounts are applied consistently across all sessions. This improves the customer experience and accuracy of loyalty rewards.
Original PR description
Steps: - Install `pos_restaurant_loyalty` - Create a discount for example: if 2 coca -> 10% - Open a restaurant session - Open another restaurant session with the same user in incognito - Add 2 coca…
Steps: - Install `pos_restaurant_loyalty` - Create a discount for example: if 2 coca -> 10% - Open a restaurant session - Open another restaurant session with the same user in incognito - Add 2 coca + sushi in session 1 and press "Order" - In session 2 products are automatically added, in live - Try to validate the order from session 2 - Traceback Traceback is due to the fact that, in order to synchronize, session 1 must send data to the server, which in turn sends further data to all sessions. The problem is that as coupons are only created once the order has been validated, they are not yet “really created” on the customer side. To avoid sending “invalid” records, we remove them from the data via an override of the `serialize` method in `Base`. But since python doesn't receive coupons, it can't send coupons to other sessions, so if we try to pay with the session that didn't initially get the discount, it will cause a traceback. The solution is to remove `is_reward_line` as well. Because it already makes no sense to have a `PosOrderLine` which is a reward line without a coupon, and then because it will regenerate the discounts in the new session. opw-4892767
This update fixes an error in the SYSCOHADA Profit and Loss report that resulted in incorrect gross margin calculations. The report was incorrectly adding instead of subtracting RA from TA, leading to inaccurate financial reporting. This ensures the report aligns with the official SYSCOHADA guidelines.
Original PR description
The SYSCOHADA gross margin is defined on page 330 - 331 of the document [Guide-d-application-du-SYSCOHADA.pdf](https://www.ohada.com/uploads/actualite/3504/Guide-d-application-du-SYSCOHADA.pdf). It…
The SYSCOHADA gross margin is defined on page 330 - 331 of the document [Guide-d-application-du-SYSCOHADA.pdf](https://www.ohada.com/uploads/actualite/3504/Guide-d-application-du-SYSCOHADA.pdf). It is TA (701) - RA (601) +/- RB (6031). TA and RA should always be positive and negative, respectively.
In the report "Profit and Loss (SYSCOHADA)", the line RA is negated. XA then subtracts this value from TA, adding the two values instead of subtracting them.
Steps to reproduce:
1. Create a new company on runbot.
2. In Accounting > Configuration > Settings, set their Fiscal Localization to Ginea - SYSCOHADA for Companies.
3. Make a MISC journal entry.
1. Set a credit of 110,000,000 on account 701100 and balance it with 411100.
5. Set a debit of 75,000,000 on account 601100 and balance it with 401100.
6. Set a credit of 5,000,000 on account 603100 and balance it with 411100.
7. Post the entry.
8. Navigate to Accounting > Reports > Profit and Loss.
9. Set the l10n version, Profit and Loss (SYSCOHADA).
10. Set the current date.
11. See XA = 110 million + 75 million + 5 million = 190 million; this does not match the example given on pg 357 of Guide-d-application-du-SYSCOHADA.pdf, where XA = 40 million.
[opw-5482300](https://www.odoo.com/odoo/project.task/project.task/5482300)
Forward-Port-Of: odoo/enterprise#104479This update resolves an access issue preventing administrators from viewing serial numbers linked to sales orders. Previously, restrictions on user permissions caused errors when calculating the number of sales orders associated with a serial number. This change ensures all users, regardless of their sales order ownership, can access this critical inventory information.
Original PR description
Steps to reproduce the bug - Create a storable product P1: - Tracking: Serial Number - Log in as Marc Demo - Create a sales order with 1 unit of P1 - Validate the delivery using serial number SN1 -…
Steps to reproduce the bug
- Create a storable product P1:
- Tracking: Serial Number
- Log in as Marc Demo
- Create a sales order with 1 unit of P1
- Validate the delivery using serial number SN1
- Log in as Mitchell Admin
- Go to Settings:
- Manage Users
- Mitchell Admin
- Sales: User: own documents only
- Go to the Serial Numbers list view:
- Try to open SN1
**Problem:**
An access error is triggered:
```
Uh-oh! Looks like you have stumbled upon some top-secret records.
Sorry, Mitchell Admin (id=2) doesn't have 'read' access to:
- Sales Order Line, S00025 - P1 (Deco Addict) (sale.order.line: 51)
Blame the following rules:
- Personal Order Lines
```
When clicking on SN1, the `stock.lot` form view.
it's contains the field "sale_order_count", which is a computed field that needs to access all `sale.order` records using the serial number in order to compute the count.
Since Mitchell Admin is restricted to his own sales orders only, an access error is raised during the computation.
There is also a many2many view widget that triggers an access errors. This widget can be removed since the smart button is now available. The widget has already been removed in v19.
**Solution:**
In this view, any stock user, admin or not, must be able to see how many sales orders use a given serial number, regardless of whether those sales orders belong to them or not.
opw-5400731This update fixes a bug where the Delivery Date wasn't appearing on the DIN 5008 sale order report and its preview. The change ensures that this critical date is now correctly displayed, as confirmed by functional experts, allowing for accurate reporting according to DIN 5008 standards. This improves data visibility for sales and accounting processes.
Original PR description
**Steps to reproduce:** 1. Install modules `sale_management` and `l10n_din5008_sale` 2. Go to Settings, Configure Document Layout and set layout to DIN 5008 3. Create a new Sale Order 4. Set a…
**Steps to reproduce:** 1. Install modules `sale_management` and `l10n_din5008_sale` 2. Go to Settings, Configure Document Layout and set layout to DIN 5008 3. Create a new Sale Order 4. Set a customer, add a product, and fill in the Delivery Date (Other Info) 5. Click on Print and Preview **Issue:** The Delivery Date (commitment_date) is not displayed on: - The DIN 5008 sale order report - The sale order preview (portal view) Functional experts confirmed that the Delivery Date must be visible when using the DIN 5008 layout. **Cause:** The `commitment_date` field was not included in the DIN 5008 sale order report template nor in the preview view. **Solution:** This commit adds the Delivery Date information to: - The DIN 5008 sale order report template - The sale order portal/preview view **opw-5490651** **Before:** <img width="560" height="145" alt="image" src="https://github.com/user-attachments/assets/fb29cda1-d668-4682-aa04-12c613f248d8" /> <img width="861" height="268" alt="image" src="https://github.com/user-attachments/assets/615f259f-e0ff-4fb5-9852-1fdd75cda4c9" /> **After:** <img width="589" height="145" alt="image" src="https://github.com/user-attachments/assets/3f1a8d25-783a-4600-b07e-11b547bb326b" /> <img width="824" height="271" alt="image" src="https://github.com/user-attachments/assets/46b37469-5c72-4556-95e2-eaea0824c166" />
This update corrects a bug in the l10n_es_edi_facturae module that resulted in incorrect tax calculations when negative amounts (like discounts) were used on invoices. The previous fix introduced an issue where the absolute value of amounts was incorrectly applied, leading to inaccurate VAT and withholding tax totals. This change ensures accurate tax calculations for all invoice scenarios, including those with discounts.
Original PR description
Issue: When using negative amounts, for example to explicitly show a discount, the tax calculation is incorrect due to the application of the `abs` function. Furthermore, the way to find out if a tax…
Issue:
When using negative amounts, for example to explicitly show a discount, the tax calculation is incorrect due to the application of the `abs` function. Furthermore, the way to find out if a tax is of the withholding type is based on the sign of the value, which can lead to error in these cases.
Cause:
A previous change (#237235) added the `abs` function so the `TotalTaxesWithheld` would be always with positive value. But this also affects the calculation of taxes `TotalTaxOutputs` in some cases, such as if the invoice line has negative values.
Steps to reproduce:
- Install `l10n_es_edi_facturae`
- With the ES company, create an invoice with some standard lines and one line with negative amounts, as an explicit discount
- Confirm the invoice and send (facturae)
- Open the XML attached in the chatter
- Observe that the taxes amounts (VAT and WITHHOLDING) are erroneous
A correct invoice should be for example:
```
Product Price Taxes Amount
---------------------------------------------
PRODUCT-A 1000 21%VAT 15%WHI 1000
Discount -100 21%VAT 15%WHI -100
---------------------------------------------
Untaxed amount 900
Withholding 15% -135
VAT 21% 189
-----------------------
TOTAL 954
```
This PR replaces #240808
---
I confirm I have signed the [CLA](https://github.com/odoo/odoo/pull/157955) and read the PR guidelines at www.odoo.com/submit-prThis update resolves a performance issue in the timesheet report that prevented it from loading with large datasets. The team optimized the query by using a more efficient join method (CROSS LATERAL JOIN) to reduce the amount of data processed, resulting in a faster loading time of approximately 2 seconds. This improves the user experience for reports with many records.
Original PR description
After this commit https://github.com/odoo-dev/enterprise/commit/6c33bde74342b634d9f6fbda4ef407ffe9bac54f we introduced a new left join which seems that it slowed down the query a lot. So the report doesn't load at all if we have a lot of records. In this PR we are introducing CROSS LATERAL JOIN as we want to generate only the the relevant dates not all dates between the min starting date and max ending date of all slots. Query plan after modification https://explain.dalibo.com/plan/eh5293ba2354f43c The testing cardinality of the tables: `planning.slot` 7178 rows `hr.employee` 332 rows `resource.resource` 332 rows `resource_calendar_leaves` 4061 rows `account_analytic_line` 267376 rows `generate_series()` will produce 206417 rows | Before | After | |-----------------------------------------|-------| | Query keep being active with no results | ~2s | opw-5089052 Forward-Port-Of: odoo/enterprise#102283
This update resolves an issue where sale orders with incomplete partner addresses in Mexico prevented online payments. The fix automatically enables 'CFDI to Public' when the address is missing, ensuring transactions are validated and payments are correctly recorded. This improves the reliability of payment processing for Mexican customers.
Original PR description
### Issue: On a Mexican sale order, it was possible to have an invalid partner address while `CFDI to Public` was not enabled In this situation, an online payment could be initiated, but a silent…
### Issue: On a Mexican sale order, it was possible to have an invalid partner address while `CFDI to Public` was not enabled In this situation, an online payment could be initiated, but a silent error occurred during move validation: the transaction was created, but the payment was never recorded, and no error appeared in the portal or the SO chatter ### Cause: The CFDI validation error is raised internally but never surfaced to the user https://github.com/odoo/enterprise/pull/91655 The PO (MIAL) recommended automatically enabling `CFDI to Public` when the partner address is incomplete, forcing the user to complete the data This also ensures that the payment can be confirmed properly ### Steps to reproduce: - Install `l10n_mx_edi_sale` and switch to the MX company - Configure a Payment Provider and Payment Method (e.g., demo) - Create a customer without ZIP or country - Create a Sale Order for that customer - In Other Info, set Online Payment to 100% - Send the quotation and open the link in a private window - Sign and Pay Before the fix: the transaction is created, but no payment is recorded, and no error is shown opw-5023724
This update resolves a bug where the 'Not Sent' filter in payment views incorrectly displayed or returned no results. The fix ensures this filter accurately identifies and displays payments that haven't been processed, providing users with a reliable view of pending actions.
Original PR description
The "Not Sent" filter in Payments list view was not returning the expected records. This was due to an incorrect domain condition in the search view. This commit updates the filter logic to properly…
The "Not Sent" filter in Payments list view was not returning the expected records. This was due to an incorrect domain condition in the search view. This commit updates the filter logic to properly identify payments that haven't been processed or sent, ensuring the filter displays the correct records to the user. **Description of the issue/feature this PR addresses:** This PR fixes a bug in the "Not Sent" search filter within the Payment views (Account Payments). Currently, the filter fails to accurately identify and display records that have not been sent, leading to an empty or incorrect list of results regardless of the sending payment's actual status. **Current behavior before PR:** When a user applies the "Not Sent" filter in the Payments list view (including both Customer and Vendor payments), the system returns incorrect records or no records at all. This is caused by an inconsistent domain definition that doesn't align with the internal field tracking the "sent" status of the payment. **Desired behavior after PR is merged:** The "Not Sent" filter will correctly filter the list to show only those payments where the "Sent" status is not True. This will provide users with an accurate view of pending actions for both Customer and Vendor payments, ensuring consistency across the accounting module. **Steps to reproduce:** 1. Navigate to the Accounting (or Invoicing) module. 2. Go to Vendors > Payments or Customers > Payments (the issue is global). 3. Ensure there are several payments in the list, some marked as "Sent" and others not yet sent. 4. Click on the Filters dropdown menu in the search bar. 5. Select the "Not Sent" filter. 6. Observe the results: Notice that the list either becomes empty or continues to show records that do not match the "Not Sent" criteria, failing to filter the data correctly. **video** https://drive.google.com/file/d/1NTKQ1tHWyZWfs3CPolfDTOMrqaDD9OcN/view --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
8 changes
Enhancements to existing features
This update enhances the system administrator panel by allowing multiple, customizable notifications with varying alert levels. The system now supports a flexible JSON format for messages, providing greater control over important server updates and maintenance alerts. This improves communication and ensures critical information is clearly displayed.
Original PR description
Tweak #102239 to allow more flexibility and display multiple messages with different alert level.
The ir.config_parameter is sysadmin.message and should be a json loadable. The format shoud be something like this:
{
"replace": false,
"warning_type": "user",
"message": "<div class='alert alert-info'>A maintenance operation is planned on your server on <strong>2026-01-15</strong> between 14h and 15h</div>"
}
Forward-Port-Of: odoo/enterprise#105157Resolved issues and error corrections
This update fixes an issue where the 'Average hours per day' calculation in employee scheduling was inaccurate. The fix ensures that all attendance records are considered when determining daily hours, providing a more reliable and consistent view of employee time. This change improves the accuracy of scheduling and reporting.
Original PR description
Steps to reproduce: ------------------- 1. Install hr_employee 2. Open Working Schedules and select any record 3. Enable the Start Date or End Date optional column 4. Set a start or end date on one…
Steps to reproduce: ------------------- 1. Install hr_employee 2. Open Working Schedules and select any record 3. Enable the Start Date or End Date optional column 4. Set a start or end date on one of the working hours Issue: ------ The "Average hours per day" value changes unexpectedly after setting a start or end date on an attendance line. Cause: ------ The `_compute_hours_per_day` method relies on `_get_global_attendances`, which excludes attendances having `date_from` or `date_to`. https://github.com/odoo/odoo/blob/67e4cd087de179a7b06c23321cfc4e6d5aa2a9dd/addons/resource/models/resource_calendar.py#L165-L169 Solution: --------- Compute the `hours_per_day` independently of attendance `date_from` or `date_to` by including all attendances in the computation, ensuring a consistent and correct value. **NOTE:** The `date_from` and `date_to` fields are removed from version 19.0. related commit: 77f860f opw-5417724 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where the copy-to-clipboard feature in Odoo 17 was misconfigured, leading to incorrect text copying. By updating the widget's configuration, the feature now correctly uses the intended copy text and aligns with how it's used in project sharing, improving usability.
Original PR description
**Description of the issue/feature this PR addresses:** The `CopyClipboardField` widget previously relied on the `string` attribute inside `attributes` to determine the text of copy button. In Odoo…
**Description of the issue/feature this PR addresses:** The `CopyClipboardField` widget previously relied on the `string` attribute inside `attributes` to determine the text of copy button. In Odoo 17+, the `string` attribute is no longer inside `attributes` but defined outside, causing the widget to break. Additionally, using `string` for copy text caused confusion between the field label and the text to copy (`copyText`). The correct approach is to use widget options for defining `copyText`, as intended in the project share link. In the Payment Wizard button, the widget was inherited and `extractProps` was overridden to handle the `string` attribute manually, which is no longer necessary with the new approach. **Current behavior before PR:** - `CopyClipboardField.extractProps` reads the removed `string` attribute from `attributes`. - The copy text could be confused with the field label (`string`). - Project share link usage fails to read copy text correctly because the widget does not read options. - `PaymentWizardCopyClipboardButtonField` overrides `extractProps` unnecessarily to fix copy text handling. **Desired behavior after PR is merged:** - `CopyClipboardField` reads `copyText` from widget options, no longer relying on the removed `string` attribute. - Copy text is clearly separated from field labels. - Project share link now works correctly using the new `copyText` option. - `PaymentWizardCopyClipboardButtonField` no longer needs to override `extractProps` and copy text is set directly in field options --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where AvaTax was failing due to orders lacking at least one line item. Specifically, it filters out orders without lines to prevent errors that blocked key business flows, such as invoice generation. This ensures AvaTax data is always accurate and reliable.
Original PR description
Backport of https://github.com/odoo/enterprise/pull/101643. Original commit message for completeness: Calling Avatax without lines results in an error and blocks flows: ``` Odoo could not fetch the…
Backport of https://github.com/odoo/enterprise/pull/101643. Original commit message for completeness: Calling Avatax without lines results in an error and blocks flows: ``` Odoo could not fetch the taxes related to MXXX - SOXXX/XXX. Please check the status of `Sales Order XXX` in the AvaTax portal. Transactions must have at least one line. ``` There are various cases this can happen: 1/ if industry_fsm_stock is installed, empty orders are confirmed [1], 2/ if you put the end_date of a subscription before the next_invoice_date, then none of the lines are considered invoiceable [2] and you get the error when viewing the subscription in the portal This commit filters out orders without lines. It's also possible to filter this on the level of the models by doing it in _get_and_set_external_taxes_on_eligible_records(). However, this means doing it separately for each model, and requires every implementer do it manually. [1] https://github.com/odoo/enterprise/blob/703e7fd413e93a8287da98286aa93b9699ae3e96/industry_fsm_stock/models/project_task.py#L159 [2] https://github.com/odoo/enterprise/blob/c7bf4367a9bf6757a36a9f34a872a6e35a19a3a5/sale_subscription/models/sale_order_line.py#L475 opw-5214609 opw-5247727 opw-5311132 opw-5385960
This update resolves an issue where customer claims weren't being processed correctly when multiple invoices sharing the same VAT number were involved. Specifically, the system was limiting searches to a single partner per VAT number, causing it to miss account moves linked to child invoices. This ensures accurate claim processing and updates.
Original PR description
When we process new customer claims, we need to search for the corresponding account moves in order to update their `l10n_cl_dte_acceptation_status`. Currently, we only expect 1 partner per VAT number when searching for a partner to match with the account move. However, this is not always true. For instance, a child invoice contact will share the same VAT number than the parent partner. This can lead to the selection of the wrong partner in the search domain and consequently, the account move not being found. Related ticket: opw-5257481
This update corrects a bug in the Point of Sale (PoS) refund invoicing process. Previously, refund invoices incorrectly showed payment statuses as 'reversed' instead of 'paid'. This change ensures accurate payment tracking for refunded transactions, improving financial reporting and reconciliation.
Original PR description
When invoicing a refund in the PoS the payment status would be 'reversed' when it should be 'paid' Steps to reproduce: ------------------- * Open PoS and make a sale * Refund the order and invoice it when processing the payment * Go to the backend and check the invoice status > Observation: The payment status is 'Reversed' Why the fix: ------------ When computing the payment status of an invoice we check if there are any payment linked to it. In the normal flow of an invoice we look for 'account.payment' records linked to the invoice. However in the PoS we create 'pos.payment' records linked to the invoice instead. opw-5080947
This update ensures that when a user confirms an upsell on a subscription, all remaining alternative quotations are automatically cancelled. Previously, only the confirmed upsell was processed, leaving other upsells in a pending state. This improves the subscription management process and prevents unnecessary orders.
Original PR description
Currently, when creating multiple upsells for a specific subscription, confirming one of them leaves the others in the sent state instead of cancelling them. This fix ensures that all other upsells for the same subscription are cancelled once one upsell is confirmed. task-5270139
This update resolves a memory issue that occurred when exporting large financial reports (FEC) from Odoo. By streaming the export data instead of loading the entire file into memory, the system now handles large databases more efficiently, preventing errors and improving performance.
Original PR description
On large databases (millions of account moves), The FEC exported file can be huge. This resulted in memory error since at some point we have the entire file in memory. This commit aims to overcome this issue by streaming the content of the file to the user. task-5404142 Forward-Port-Of: odoo/odoo#240981