Daily updates from Odoo
Wednesday, October 8, 2025
123 changes
15 changes
Enhancements to existing features
When uploading bill XML files from bank reconciliation, the system now activates the bill currency automatically if it is inactive. This removes a manual step for users and makes bill upload faster and smoother.
Original PR description
Before: - When the user uploads an XML file from the bank reconciliation widget using 'Upload Bills' button and a currency of that bill is not active, then we ask the user to activate that currency manually. - Since users know the currency of Bill at the moment, we should directly activate the currency. After: - Now we activate the currency of Bill directly if it is not active, without asking to the user. Impact: - Improves user experience by not manually activating the currency of the bill. - Save users' time when uploading Bills in the bank reconciliation line. Task-5108103 Forward-Port-Of: odoo/enterprise#95513
Resolved issues and error corrections
UPS shipping rates can now be checked during express checkout using only the limited delivery details collected at that step. This prevents shoppers from being blocked by unnecessary street and phone requirements, making checkout smoother for ecommerce customers.
Original PR description
Express checkout in ecommerce does an initial rate check with shipping connectors that does not require all of the fields normally required by that shipping connector. For UPS, this meant express checkout was failing due to an unnecessary `street` and `phone` field check since the only required delivery fields for express checkout are: (city, zip, country_code, state_code) For more info, see: https://github.com/odoo/odoo/blob/b403d5d74dd545f926a38a6aa6d18118d34e83b7/addons/website_sale/controllers/delivery.py#L181-L188 opw-[4447700](https://www.odoo.com/web#id=4447700&view_type=form&model=project.task) Forward-Port-Of: odoo/enterprise#78788
This fix corrects how service discounts are handled when calculating Brazilian taxes through Avalara. It prevents discounts from being subtracted twice, helping ensure more accurate tax amounts on affected service invoices.
Original PR description
Confusingly, Avalara's service API already accounts for the discount in lineNetFigure, whereas their goods API does not. In <saas-18.4 this was handled by _l10n_br_get_line_total(), but it got lost in the big refactor in saas-18.4 [1]. [1] https://github.com/odoo/enterprise/pull/82623 opw-5147143
New user invitation emails now generate website and email links correctly. This prevents recipients from receiving malformed links, making account setup smoother and reducing support friction.
Original PR description
Website and email links were malformed on the New User Invite email template. Later versions also have this issue on the other templates will change those in forward ports. Renderer was treating the string formatting as a string itself when using the double curly braces on variables. Removed the curly braces so the variable was properly evaluated and inserted into the string. opw-4977756 Forward-Port-Of: odoo/odoo#221487
Saudi Arabia localization taxes are now correctly linked to fiscal positions. This prevents invoice taxes from being unintentionally removed when a tax localization is applied, helping ensure accurate tax calculation and invoicing.
Original PR description
Starting 18.4, if the tax position linked to an invoice is not set to any tax => it removes the taxes from the invoice (RD task 5017278). For l10n_sa, no tax is linked to a tax position so if a tax localization is set then product taxes will be removed. This commit set fiscal positions to l10n_sa taxes to avoid this. opw-5011877 
ISO 20022 payment files for Danish banks can now include the required local clearing instruction, preventing bank rejections when this information is needed. Businesses can configure whether payments use overnight or same-day clearing; if left unset, files remain unchanged.
Original PR description
The denmark banks were refusing ISO20022 documents because there was a missing field: "//PmtInf/PmtTpInf/LclInstrm/Cd" or "//PmtInf/CdtTrfTxInf/PmtTpInf/LclInstrm/Cd". One of those field should be filled by either 'ONCL' or 'SDCL' which means 'Over Night Clearing' or 'Same Day Clearing'. To fix this we added a config parameter with a key: account_iso20022.local_instrument_code where we can set OCNL or SDCL to add the required field to the iso document. If nothing is set, the field will not be added. opw-5073076 Forward-Port-Of: odoo/enterprise#96190 Forward-Port-Of: odoo/enterprise#95903
This fixes an accounting issue where credit notes created after a sales down payment did not reverse the related cost of goods sold. Businesses now get accurate stock and expense accounting when refunding invoices that included down payments.
Original PR description
**Problem:** When we do a downpayment on an invoice then pay the rest and do a credit note, the credit note does not reverse the cogs **Steps to reproduce:** - create a storable product invoiced on…
**Problem:** When we do a downpayment on an invoice then pay the rest and do a credit note, the credit note does not reverse the cogs **Steps to reproduce:** - create a storable product invoiced on ordered quantity - set the category of the product as avco and "inventory valuation" of the category as automated - set an onhand quantity and a positive cost - create a SO for 1 quantity of this product and confirm - click on create invoice, select downpayment percentage and 25% - click on create draft and confirm it - click on create invoice, select regular, create draft - confirm and select credit note - write something in the reason field and click on reserve - confirm it **Current behavior:** if you open the "Journal Items" page of the credit note you'll see that there is no line revresing the cogs (there would be if we didn't do a downpayment but invoiced all at once) **Expected behavior:** There should be: - A line crediting "600000 Expenses" (or the account that was debited for the cogs on the original invoice) with the amount being the cost of your product. - A line debiting "110300 stock interim (delivered)"(or the account that was credited for the cogs on the original invoice) with the amount being the cost of your product. **Cause of the issue:** Since this commit https://github.com/odoo/odoo/pull/163251/commits/d7b0510908d341c205461ca18b1730c93b88e445 (slightly modfified for efficieny reasons by this commit https://github.com/odoo/odoo/commit/4f9c52c03c65a497937053530e8d6c775d305e35), when _stock_account_prepare_anglo_saxon_out_lines_vals is called on the account move (the credit note) it calls _get_anglo_saxon_price_ctx. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/stock_account/models/account_move.py#L114 One of the invoice lines of the account move is linked via sale_line_ids attribute to a sale order line that is a downpayment. As a consequence, inside _get_anglo_saxon_price_ctx, move_is_downpayment will be populated with this line. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/sale_stock/models/account_move.py#L136-L139 Then _stock_account_prepare_anglo_saxon_out_lines_vals calls _stock_account_get_anglo_saxon_price_unit. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/stock_account/models/account_move.py#L131 Inside this method, because move_is_downpayment is populated, is_line_reversing will stay false https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/sale_stock/models/account_move.py#L163-L164 As a consequence, - qty_to_invoice will become - qty_to_invoice - account_move will be populated - therefore posted_cogs will be populated https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/sale_stock/models/account_move.py#L166-L174 So _compute average price will be called with a qty_invoiced of 1 instead of 0 and a qty_to_invoice of -1 instead of 1. So it will return 0 instead of the cost of the product because "missing" will be negative. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/stock_account/models/product.py#L915 **fix** The use case of this commit https://github.com/odoo/odoo/pull/163251/commits/d7b0510908d341c205461ca18b1730c93b88e445 is this one : - SO for qty of 10 (product invoiced on delivered qty). - 100% downpayment. - deliver 6. - invoice. In that case the invoice is actually a credit note but it still has to include the cogs (not reversed), so move_is_downpayment needs to be populated However in our use case the cogs has to be reversed (so move_is_downpayment has to be None). One difference between those two use case is that in our use case the account move has a reversed_entry_id. opw-5041783 Forward-Port-Of: odoo/odoo#229774 Forward-Port-Of: odoo/odoo#226809
This fix ensures FIFO product costs are recalculated from the actual inventory valuation rather than a manually set cost that may no longer match stock value. Businesses get more accurate product costs after revaluation, reducing accounting and inventory valuation discrepancies.
Original PR description
**Steps to reproduce:** - create a storable product with fifo category - update the cost to 200 - click on the on hand smart button and add a quant of 1 quantity - update the cost to 300 - click on…
**Steps to reproduce:** - create a storable product with fifo category - update the cost to 200 - click on the on hand smart button and add a quant of 1 quantity - update the cost to 300 - click on the on hand smart button and update the quantity to 2 - the value should be 500, which makes a 250 value per product - open Inventory/valuation and search your product - group by product, select your product and click on "+" icon to open the revaluation widget - add 200 (so +100 per unit) - go back to the product form **Current behavior:** the cost is now at 400 **Expected behavior:** the cost should be at 350 (250 + 100) If we change the standard_price we should change it in accordance with the valuation **Cause of the issue:** In action_validate_revaluation, during the update of the standard_price, the current standard_price (set by the user and disconnected from the valuation) is used in the computation. https://github.com/odoo/odoo/blob/5118f7cb80744f901d7028dc75c29aba9591b83b/addons/stock_account/wizard/stock_valuation_layer_revaluation.py#L127 opw-5028848 Forward-Port-Of: odoo/odoo#229977 Forward-Port-Of: odoo/odoo#228457
This fix ensures country-specific point-of-sale session information for Chile and Peru is kept when sessions sync across multiple devices. Businesses using multi-device PoS setups avoid losing required localization data after real-time updates.
Original PR description
Before this commit, the special fields were added to the PoS session in the `_load_pos_data` function. However, they were not included when sending synchronization notifications to other devices. As a result, in multi-device setups, these fields would be removed after a WebSocket notification. related: https://github.com/odoo/odoo/pull/228419 opw-5073848 Forward-Port-Of: odoo/enterprise#95455
This fixes Nuvei payment handling when customers return from the payment page without completing payment, avoiding validation errors caused by missing notification data. It also ensures Webpay payments are checked using the right whole-number amount format, helping valid payments complete successfully.
Original PR description
Since https://github.com/odoo/odoo/pull/163860, all notifications from providers are checked to see that they have the correct currency and amount in their flow before processing the notification. However, this has two issues with Nuvei: 1. The process when a customer hits "Go back" on the payment page instead of paying does not send any notification data. As such trying to compare these values will not work. 2. Certain payment methods within Nuvei use different decimal precision than the currencies on odoo. Webpay must always be in whole values even for USD, as such, we need to pass the correct number of precision digits to the validation method otherwise Webpay will never be able to go through. opw-5108631
Duplicated CRM leads without an assigned salesperson now stay eligible for rule-based assignment. This prevents missed sales ownership when teams duplicate leads and later update them to match assignment criteria.
Original PR description
Currently, leads are not automatically assigned via rule-based assignment when duplicating an existing lead, even if the duplicated lead matches the assignment criteria. **Pre-requisites:** 1) Set up…
Currently, leads are not automatically assigned via rule-based assignment
when duplicating an existing lead, even if the duplicated lead matches
the assignment criteria.
**Pre-requisites:**
1) Set up rule-based lead assignment in the CRM settings.
2) Configure the sales team's assignment domain:
`[("user_id", "=", False)]`
3) Configure the sales team members' domain:
`[("probability", ">=", 10)]`
**Steps to Reproduce:**
1) Create a lead that matches the above assignment rules.
2) Remove the salesperson (user_id) and sales team from the lead.
3) Duplicate the lead.
4) Update the probability to a valid value (e.g., ≥ 10).
5) Manually trigger the `Rule-Based Assignment`.
**Issue:**
The original lead gets assigned, but the duplicated one does not.
**Cause:**
When duplicating, the system sets date_open to the current date by default,
even if the duplicated and original leads have no assigned users.
https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_lead.py#L929-L931
However, `rule-based assignment` only considers leads where `date_open` is False https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_team_member.py#L136-L141
**Solution:**
Set `date_open` to False during duplication if the original lead has no `user_id`.
This ensures the new lead remains eligible for assignment.
opw-5003529
Forward-Port-Of: odoo/odoo#229512
Forward-Port-Of: odoo/odoo#227387This fix ensures Spanish point-of-sale compliance fields remain available when sessions sync between multiple devices. It prevents important fiscal data from disappearing after real-time updates, improving reliability for businesses using these localization features.
Original PR description
Before this commit, the special fields were added to the PoS session in the `_load_pos_data` function. However, they were not included when sending synchronization notifications to other devices. As a result, in multi-device setups, these fields would be removed after a WebSocket notification. related: https://github.com/odoo/enterprise/pull/95455 opw-5073848 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228419
Public mail-related pages now correctly translate their visible text for users. This fixes an issue where translated content could appear in the original source language, improving the experience for multilingual visitors.
Original PR description
Human-readable content defined in public page components isn't translated. This is because we forgot to give Owl a translation function, so it falls back to returning the source terms as they are (identity function). This commit resolves the issue by providing the missing translation function. Task-4493082 Task-5140665 Forward-Port-Of: odoo/odoo#230266 Forward-Port-Of: odoo/odoo#230129
This fixes Razorpay payment failures that could occur when a provider had both Key ID/Secret credentials and OAuth connected. Odoo now avoids sending conflicting authentication methods, preventing 403 errors during mobile website payments.
Original PR description
In a specific context, Razorpay rejects connections using both Key ID/Secret and an access token simultaneously. To reproduce, it's require a real production Razorpay account since Oauth is not available in test mode. Step to reproduce: - Configure Key ID/Secret and connect via OAuth on the Razorpay payment provider. - On iOS/Android, making a payment on the website triggers a "403 Forbidden" error because Razorpay redirect to /payment/razorpay/return and the signature from Razorpay not correspond to the expected signature computed with the Key Secret. This fix prioritizes call with Key ID/Secret over token authentication. opw-5100194 opw-4989944 opw-5039880 opw-5099580 Forward-Port-Of: odoo/odoo#229468
The update ensures page components finish loading before edit-mode change tracking resumes. This prevents pages such as the login screen from being incorrectly marked as modified, reducing confusion for website editors.
Original PR description
*web, website Before this commit, `PublicComponentInteraction` was not awaiting the mounting of Owl components. Consequently, the DOM mutations generated by the components were not always ignored. After this commit, the mounting is awaited before restarting the mutation listener. ** HOW TO REPRODUCE THE PROBLEM ** One case were the problem is evident is the `/web/login` page. 1. Navigate to `/web/login` 2. Enter edit mode 3. Inspect the page searching for `o_dirty` 4. The page is already dirty. This happened because of `UserSwitch` not being awaited.
14 changes
Enhancements to existing features
Peppol UBL invoice exports now include the delivery party in the delivery information. This gives recipients clearer shipping details by using the shipping contact when available, or the customer name otherwise, without changing existing delivery date or location behavior.
Original PR description
Previously, the Peppol UBL export only covered the mandatory delivery fields and did not include the `delivery party`. This commit adds the `<cac:DeliveryParty>` element under `<cac:Delivery>` to improve the exported information. - Include `<cac:DeliveryParty>` in the `<cac:Delivery>` section of UBL invoices. - Use the shipping partner name if set; otherwise, fallback to the customer name - Keep existing `<cac:DeliveryLocation>` and delivery date logic unchanged. <img width="766" height="306" alt="image" src="https://github.com/user-attachments/assets/d07c1b37-4c6d-42d1-99b4-66c5abc8e298" /> ----- task-5022404 Forward-Port-Of: odoo/odoo#223756
When users upload XML bills from bank reconciliation, Odoo now activates the bill currency automatically if it was inactive. This removes a manual step and helps users complete bill uploads faster.
Original PR description
Before: - When the user uploads an XML file from the bank reconciliation widget using 'Upload Bills' button and a currency of that bill is not active, then we ask the user to activate that currency manually. - Since users know the currency of Bill at the moment, we should directly activate the currency. After: - Now we activate the currency of Bill directly if it is not active, without asking to the user. Impact: - Improves user experience by not manually activating the currency of the bill. - Save users' time when uploading Bills in the bank reconciliation line. Task-5108103
Resolved issues and error corrections
The new user invitation email now creates website and email links correctly. This prevents recipients from receiving broken links and helps ensure a smoother signup experience.
Original PR description
Website and email links were malformed on the New User Invite email template. Later versions also have this issue on the other templates will change those in forward ports. Renderer was treating the string formatting as a string itself when using the double curly braces on variables. Removed the curly braces so the variable was properly evaluated and inserted into the string. opw-4977756 Forward-Port-Of: odoo/odoo#221487
This fix prevents saved work order time tracking lines from being accidentally removed when their time periods overlap. It keeps displayed work order duration and saved time entries aligned, improving reliability for manufacturing teams reviewing production time.
Original PR description
Issue: In this bug, workorder duration inverse is causing some time_ids to be deleted. To reproduce: 1- Create a db with mrp installed, and enable work orders in Setting 2- Create a MO, and confrim…
Issue:
In this bug, workorder duration inverse is causing some time_ids to be deleted.
To reproduce:
1- Create a db with mrp installed, and enable work orders in Setting
2- Create a MO, and confrim it
3- Add a new work order to the MO
4- Add two time tracking lines:
- First one an arbitary duration
- Second one sub-duration of the first one
5- As you see, duration reflects duration of first line as it is the interval duration
6- Save and close work center form. Then save MO form.
7- Open work orders again: As you see second line is unlinked
Cause:
The reason to this bug, is because in Enterprise, the `_compute_duration` override changes the logic of how duration is computed but the inverse function doesn't reflect the same logic.
To be specific this is the compute function override: https://github.com/odoo/enterprise/blob/3cbe2bbbfd989a3daaa32769a843aeaa09c7ed3e/mrp_workorder/models/mrp_workorder.py#L757-L766
In which duration is calculated using get_duration: https://github.com/odoo/enterprise/blob/3cbe2bbbfd989a3daaa32769a843aeaa09c7ed3e/mrp_workorder/models/mrp_workorder.py#L828-L837
Which doesn't sum the durationw, but calculates the intervals duration counting overlaps only once.
However, there is no override of inverse method in Enterprise, meaning that the logic behind inverse will not match with this logic. In the inverse it is assumed duration is sum of all time_ids intervals:
https://github.com/odoo/odoo/blob/9b286285a6c66bc2d629eacf651c3439cffb55cc/addons/mrp/models/mrp_workorder.py#L355-L400
As a result, if time_ids overlap:
new_order_duration < old_order_duration
As a result some time_ids will be unlinked and some will have duration changed.
Fix:
The issue can be fixed by overriding inverse method `_set_duration`:
```diff
- old_order_duration = sum(order.time_ids.mapped('duration'))
+ old_order_duration = order.get_duration()
```
In order to not repeat unchanged logic in override, the unchanged part is packed into `_sync_duration_changes`.
opw-5082477UPS shipping rates can now be checked during express checkout using only the delivery details required at that early step. This prevents customers from being stopped because street address or phone details have not yet been entered.
Original PR description
Express checkout in ecommerce does an initial rate check with shipping connectors that does not require all of the fields normally required by that shipping connector. For UPS, this meant express checkout was failing due to an unnecessary `street` and `phone` field check since the only required delivery fields for express checkout are: (city, zip, country_code, state_code) For more info, see: https://github.com/odoo/odoo/blob/b403d5d74dd545f926a38a6aa6d18118d34e83b7/addons/website_sale/controllers/delivery.py#L181-L188 opw-[4447700](https://www.odoo.com/web#id=4447700&view_type=form&model=project.task) Forward-Port-Of: odoo/enterprise#78788
ISO20022 payment files for Danish banks can now include the required local clearing instruction code, helping prevent rejected payment submissions. Administrators can configure overnight or same-day clearing, while leaving it unset keeps the previous behavior.
Original PR description
The denmark banks were refusing ISO20022 documents because there was a missing field: "//PmtInf/PmtTpInf/LclInstrm/Cd" or "//PmtInf/CdtTrfTxInf/PmtTpInf/LclInstrm/Cd". One of those field should be filled by either 'ONCL' or 'SDCL' which means 'Over Night Clearing' or 'Same Day Clearing'. To fix this we added a config parameter with a key: account_iso20022.local_instrument_code where we can set OCNL or SDCL to add the required field to the iso document. If nothing is set, the field will not be added. opw-5073076 Forward-Port-Of: odoo/enterprise#96190 Forward-Port-Of: odoo/enterprise#95903
The appraisal skills list now scrolls horizontally on mobile again, so users can see the justification field and the add or remove buttons. This restores access to important appraisal skill details and actions on smaller screens.
Original PR description
Horizontal scrolling has been disabled on the appraisal skills list. An unwanted side effect of that is that the justification field along with the add and remove buttons are not visible on mobile. This PR re-enables the scrolling and removes some dead css. task-5001344 Forward-Port-Of: odoo/enterprise#96527 Forward-Port-Of: odoo/enterprise#91882
This fix ensures country-specific point of sale session fields are preserved when sessions synchronize between multiple devices. Businesses using Spanish electronic invoicing features avoid losing required session information after real-time updates.
Original PR description
Before this commit, the special fields were added to the PoS session in the `_load_pos_data` function. However, they were not included when sending synchronization notifications to other devices. As a result, in multi-device setups, these fields would be removed after a WebSocket notification. related: https://github.com/odoo/enterprise/pull/95455 opw-5073848 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228419
Point of Sale sessions in Chilean and Peruvian localizations now keep their required fiscal fields when data is synchronized across multiple devices. This prevents those fields from disappearing after device updates, helping stores avoid disrupted checkout or compliance data issues.
Original PR description
Before this commit, the special fields were added to the PoS session in the `_load_pos_data` function. However, they were not included when sending synchronization notifications to other devices. As a result, in multi-device setups, these fields would be removed after a WebSocket notification. related: https://github.com/odoo/odoo/pull/228419 opw-5073848 Forward-Port-Of: odoo/enterprise#95455
The purchase reporting issue is fixed so vendors' on-time rate graphs appear even when purchased products have no category. This helps purchasing teams keep visibility on supplier performance after confirming and receiving purchase orders.
Original PR description
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and…
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and validate the generated receipt. 5-In the vendor form view, click the On-time Rate smart button → no graph is visible. **Issue:** https://github.com/odoo/odoo/blob/77b3956ed5635d79ae8dc19423140dc6a10098f1/addons/purchase_stock/report/vendor_delay_report.py#L46-L50 ``` The On-time Rate graph is not displayed in the Vendor Delay report. ``` **Cause:** - From version 18.2, `categ_id` was removed as a required field. The report query still uses an inner join on `categ_id`, which excludes products without a category and prevents data from being generated. - Commit which make `categ_id` non require - https://github.com/odoo/odoo/pull/166323/commits/b039caecbeb04057fbccb1cc88d03a4946f88e8e **Solution:** - Replace the inner join with a left join so that products without a `categ_id` are also included in the report (with null values when the category is not set). **opw** - 4991367 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225557
Public-facing mail pages now show translated text instead of always displaying the original source language. This improves the experience for visitors and users working in languages other than the default.
Original PR description
Human-readable content defined in public page components isn't translated. This is because we forgot to give Owl a translation function, so it falls back to returning the source terms as they are (identity function). This commit resolves the issue by providing the missing translation function. Task-4493082 Task-5140665 Forward-Port-Of: odoo/odoo#230266 Forward-Port-Of: odoo/odoo#230129
Duplicated CRM leads without a salesperson now remain eligible for rule-based assignment. This prevents sales opportunities from being skipped by automatic assignment workflows, helping teams route leads more reliably.
Original PR description
Currently, leads are not automatically assigned via rule-based assignment when duplicating an existing lead, even if the duplicated lead matches the assignment criteria. **Pre-requisites:** 1) Set up…
Currently, leads are not automatically assigned via rule-based assignment
when duplicating an existing lead, even if the duplicated lead matches
the assignment criteria.
**Pre-requisites:**
1) Set up rule-based lead assignment in the CRM settings.
2) Configure the sales team's assignment domain:
`[("user_id", "=", False)]`
3) Configure the sales team members' domain:
`[("probability", ">=", 10)]`
**Steps to Reproduce:**
1) Create a lead that matches the above assignment rules.
2) Remove the salesperson (user_id) and sales team from the lead.
3) Duplicate the lead.
4) Update the probability to a valid value (e.g., ≥ 10).
5) Manually trigger the `Rule-Based Assignment`.
**Issue:**
The original lead gets assigned, but the duplicated one does not.
**Cause:**
When duplicating, the system sets date_open to the current date by default,
even if the duplicated and original leads have no assigned users.
https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_lead.py#L929-L931
However, `rule-based assignment` only considers leads where `date_open` is False https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_team_member.py#L136-L141
**Solution:**
Set `date_open` to False during duplication if the original lead has no `user_id`.
This ensures the new lead remains eligible for assignment.
opw-5003529
Forward-Port-Of: odoo/odoo#229512
Forward-Port-Of: odoo/odoo#227387Restaurant owners can now print POS sales reports while a session is still open. This removes the need to go through the backend, making day-to-day sales checks faster and easier during service.
Original PR description
- Restaurants owners need to be able to print a sales report during a session. Before this commit, they were only available to print the report via the backend. task-id: 5076080
Vendor credit notes created through purchase order matching now show the correct positive quantity when reversing an over-billed purchase. This prevents confusing negative quantities and helps keep purchase billing records accurate.
Original PR description
Steps to reproduce:- - Create a Purchase Order with Product A(invoicing policy: received quantities) and Quantity 3. - Create Vendor Bill with Product A and Quantity 3 and match it with the PO. - Receive only 2 on PO. - Now on PO, Quantity: 3, Received:2, Billed:3 - Create a Vendor Credit Note for that partner, add an empty line and save. - Click on PO Matching at the top. - Select line from Vendor Credit Note and line from PO, click match. Problem: In Vendor Credit Note Quantity: -1 (which should be 1) Before this commit: When credit note values are prepared from purchase order, quantity to invoice on purchase order is set as quantity on credit note. After this commit: When credit note values are prepared from purchase order, inverse(-ve) of quantity to invoice on purchase order is set as quantity on credit note. task-4975200 Forward-Port-Of: odoo/odoo#230372 Forward-Port-Of: odoo/odoo#221203
2 changes
Resolved issues and error corrections
Gantt view group headers now keep their sticky behavior when users scroll, even when the schedule has many or wide columns. This prevents headers from drifting out of alignment or overflowing the page, with the biggest benefit on mobile devices.
Original PR description
Gantt group headers could stop being sticky because their width was fixed based on the number and size of columns. Even though they were set to position: sticky, oversized headers could no longer remain aligned when scrolling, as they extended beyond the viewport and were constrained by the document width. This was especially noticeable on mobile, where group headers are often wider than the screen. The fix applies a max-width style to these headers, capping their size to the available space so they remain sticky without overflowing the document. task-4970992 Forward-Port-Of: odoo/enterprise#96015
UPS shipping rate checks during ecommerce express checkout now work with only the limited address information collected at that step. This prevents customers from being blocked by unnecessary street and phone requirements before they have completed checkout.
Original PR description
Express checkout in ecommerce does an initial rate check with shipping connectors that does not require all of the fields normally required by that shipping connector. For UPS, this meant express checkout was failing due to an unnecessary `street` and `phone` field check since the only required delivery fields for express checkout are: (city, zip, country_code, state_code) For more info, see: https://github.com/odoo/odoo/blob/b403d5d74dd545f926a38a6aa6d18118d34e83b7/addons/website_sale/controllers/delivery.py#L181-L188 opw-[4447700](https://www.odoo.com/web#id=4447700&view_type=form&model=project.task) Forward-Port-Of: odoo/enterprise#78788
26 changes
New functionality added to Odoo
Bulgarian companies can now use the new tax return feature with Intrastat reporting schedules that match local requirements. This helps ensure periodic reporting and submission deadlines are configured correctly for Bulgaria.
Original PR description
As part of the new tax return feature introduced in 18.3, we are implementing country-specific periodicities and deadlines for Intrastat reports across all European localizations. This **PR** introduces the configuration required for the Bulgarian localization, aligning it with the national requirements for Intrastat reporting. **task**-4987898
Enhancements to existing features
IoT box information is now cached so connected devices can keep communicating when the internet connection is unavailable. This reduces unnecessary server calls and improves reliability for IoT-based flows such as self-ordering and printing.
Original PR description
In order to make the `iot_http` service work offline, we cache the iot box records until there is a full action failure. This avoids useless orm calls and in the meantime, allow making requests to the iot box without internet connection. Community PR: odoo/odoo#226839 Forward-Port-Of: odoo/enterprise#96332 Forward-Port-Of: odoo/enterprise#93895
Businesses in Colombia can now create and send invoices for free samples or commercial gifts that must be reported to the government. This makes it easier to stay compliant with Colombian electronic invoicing requirements when goods are given away at no charge.
Original PR description
Colombian companies are able to give away free samples/commercial gifts, but these have to be declared to the government. This commit allows for easy creation and sending of these invoices. task: 4782963
The Point of Sale IoT Box status icon now shows the most recent communication method used, helping staff better understand how the box is connected. The old longpolling on/off setting was removed because WebRTC is now the main communication method.
Original PR description
We updated the IoT Box status icon in PoS to display the last protocol used to communicate with the box. We removed the longpolling enable/disable toggle as the main protocol now is WebRTC. Task: 5116840 Forward-Port-Of: odoo/enterprise#96405
This update improves live currency rate handling so businesses can work more reliably with conversion rates for historical transactions and demo scenarios. It helps accounting teams get more accurate currency conversions when reviewing or entering transactions dated in the past.
Original PR description
WIP task-5046193
IoT boxes now let the backend choose the correct messaging channel and starting point when they connect. This prevents old messages from being replayed on first connection, reducing the risk of a device being accidentally unpaired right after setup while keeping compatibility with older IoT software.
Original PR description
Community PR: https://github.com/odoo/odoo/pull/230475 Before this commit, the IoT box would use the websocket channel name from the `/iot/setup` result to make its subscribe message, and use a last message ID of either 0 or a previously saved value. The main issue with this approach is that on first connection, the websocket could receive stale messages, including `server_clear` which could immediately unpair the IoT box after it connects. After this commit, we no longer send the channel to the IoT box. Instead, the IoT box sends its token in the subscribe message, and we override the subscribe method in the backend to set the correct channel and the latest message ID. This both simplifies the process and fixes the stale message problem. For now the `/iot/setup` controller will still return the websocket channel, to ensure compatibillity with old IoT code.
French companies can now choose the correct ROF type, such as TVA1, TVA2, or TVA3, when preparing VAT declarations. This helps prevent VAT return rejections caused by using an incorrect default ROF type.
Original PR description
By default, most French companies use ROF type TVA1 for VAT declarations, but some require TVA2, TVA3 etc. Using the wrong ROF leads to automatic rejection of the VAT return. In this commit: --- - Add a new field `l10n_fr_rof_type` to select the ROF type (TVA1, TVA2, TVA3...), with TVA1 as the default. - The selected ROF type is now dynamically used when generating VAT declaration EDI files. --- task-4963376
When users upload XML bills from bank reconciliation, the system now automatically activates the bill currency if it was inactive. This removes a manual interruption and helps users complete bill uploads faster.
Original PR description
Before: - When the user uploads an XML file from the bank reconciliation widget using 'Upload Bills' button and a currency of that bill is not active, then we ask the user to activate that currency manually. - Since users know the currency of Bill at the moment, we should directly activate the currency. After: - Now we activate the currency of Bill directly if it is not active, without asking to the user. Impact: - Improves user experience by not manually activating the currency of the bill. - Save users' time when uploading Bills in the bank reconciliation line. Task-5108103 Forward-Port-Of: odoo/enterprise#95513
Manufacturing planners now get a smoother MPS workflow for indirect components, which are set up for manual replenishment instead of requiring extra configuration. The replenishment row tooltip is clearer, helping users understand planning color indicators without prior system knowledge.
Original PR description
With this commit:
-----------------
- MPS Replenishment Trigger:
- Set ‘Manual’ as the replenishment trigger in MPS when the component is
marked as indirect, since such components—added via BoM—defaulted to ‘Never’
and should instead allow manual planning as they represent indirect demand.
- This improvement removes that extra step, speeding up the workflow and
improving overall UX.
- MPS Replenishment Tooltip:
- Improved tooltip text to clearly explain the color codes in the
replenishment row. This improves usability and removes the need for prior
knowledge of Odoo’s MPS color semantics.
task-4868885
Forward-Port-Of: odoo/enterprise#88724Resolved issues and error corrections
This fix restores reliable lookup of SEPA Direct Debit payment transactions after a recent internal search change. It helps ensure incoming payment processing can match the right transaction and continue without unnecessary failures.
Original PR description
After commit 772d8a6f2e66b13f352b56621912e33e7edcccc2,transaction search was changed to rely only on `provider_code`, instead of `custom_mode`. However, the `sepa_direct_debit` logic was not updated accordingly, resulting in transactions no longer being found. This commit adapts the code to the new search logic by using `provider_code` for transaction lookup. Forward-Port-Of: odoo/enterprise#96418
Fixes an issue where customized Unrealized Currency Gains/Losses report grouping could incorrectly block adjustment entry creation with a “No adjustment needed” message. Businesses using custom report layouts can now generate the expected draft journal entries reliably.
Original PR description
**Steps to reproduce** - Edit "Unrealized Currency Gains/Losses" report configuration as follows: - Lines > Accounts To Adjust, set GroupBy to 'currency_id, partner_id, account_id, id' - Lines > Excluded Accounts, set GroupBy to 'currency_id, partner_id, account_id, id' - In Options, check 'Unfold All' - View the report > Click 'Adjustment Entry' **Issue** Instead of creating a draft journal entry an user error "No adjustment needed" will block the action **Solution** The issue occurs because when retrieving the lines we assume they are grouped as per default, by 'currency_id, account_id' In case users modify the expression line default grouping to something else, like 'currency_id, partner_id, account_id', we no longer collect values correctly. In order to fix the issue we can unfold all and manually group values by currency_id, account_id opw-4792502 Forward-Port-Of: odoo/enterprise#90894
This fix prevents the AI assistant from crashing when users request pivot-style sales reports, such as rankings by revenue. It improves reliability for Sales and AI users by correctly validating report measures before running the query.
Original PR description
The system crashes with an error when a user adds a prompt in AI and searches. **Steps to produce:** - Install the `Sales and AI` module with demo data. - Go to sales and click on the AI button on…
The system crashes with an error when a user adds a prompt in AI and searches. **Steps to produce:** - Install the `Sales and AI` module with demo data. - Go to sales and click on the AI button on top. - Add query that used pivot view like `Top 5 sales reps by revenue also make pivot view`. - Try multiple times (error only comes in terminal). **Error:** ValueError: Measure 'price_subtotal:sum' not found in model 'sale.report' for menu ID 331. **Cause:** - Here at [1], we split the measure_str and assign the first element to `measure_name`. - At [2], we try to find a field in the model using this `measure_name`, which fails. - The issue is that `measure_name` can contain both the `field` and its `aggregation` function (e.g., product_qty:sum), which is not a valid field. **Solution:** - In this PR, a new method `validate_measures` has been added to ensure that the provided measures are valid and properly defined. [1] https://github.com/odoo/enterprise/blob/f838bbd0ce425d24444b510e49752c3da8068712/ai/models/ai_agent.py#L1244-L1245 [2] https://github.com/odoo/enterprise/blob/f838bbd0ce425d24444b510e49752c3da8068712/ai/models/ai_agent.py#L1264-L1265 **sentry-6917511363,6915439025** Forward-Port-Of: odoo/enterprise#96247
The Spanish VAT Book report could fail to open due to an outdated interface reference. This update corrects that reference so users can access the report normally and continue reviewing VAT information without interruption.
Original PR description
Step to reproduce - setup company for l10n_es i.e. spain localization - Go to Accounting > Reporting > Spain > VAT Book. Observation: - Traceback found Issue: - Template `l10n_es_reports.VatBooksLineName` tries to replace a xpath https://github.com/odoo/enterprise/blob/d0c17835ecc4a911bc8c8c57946eaef9e73245ab/l10n_es_reports/static/src/components/vat_books/line_name.xml#L2-L6 which do not exists, after [1] Fix: - we fix the xpath to hide the chatter/annotation button. [1] odoo/enterprise@8fae6a058bc20732bccc6e3732144d4ea2aafdad opw-5106583 Forward-Port-Of: odoo/enterprise#95724
This fixes UK tax report submissions that could be rejected by HMRC because an invalid saved device identifier was being reused. Odoo now clears the bad saved value so a valid identifier can be used, helping affected users submit successfully.
Original PR description
There are still Odoo requests that are sent to hmrc with invalid 'Gov-Client-Device-ID' header. They are showing this error: "Submit a UUID which is 128 bits or 32 hex characters long". A possible explanation, is that some users have some garbage value in the localStorage for 'hmrc_gov_client_device_id', that does not correspond to a uuid. This value would then be sent each time in the headers, and get rejected. The fix here is to clear the localStorage value if it is not a uuid. task-4627086 Forward-Port-Of: odoo/enterprise#96409 Forward-Port-Of: odoo/enterprise#87335
This update ensures IoT payment terminal drivers send device information in a format the database now accepts. It prevents communication errors with connected payment devices after a recent platform change.
Original PR description
This PR fixes the bytestrings being sent as such when using ctypes C/C++ libraries in iot drivers. After the PR https://github.com/odoo/odoo/pull/206903 the bytestrings are not supported anymore in the requests sent to the database from the iot and need to be decoded first. Related PR for saas-18.4: https://github.com/odoo/enterprise/pull/96547 opw-5129596 Forward-Port-Of: odoo/enterprise#96537
ISO20022 payment files can now include the Danish bank clearing instruction required by some banks. This helps prevent payment file rejections when using overnight or same-day clearing, while leaving files unchanged if no setting is configured.
Original PR description
The denmark banks were refusing ISO20022 documents because there was a missing field: "//PmtInf/PmtTpInf/LclInstrm/Cd" or "//PmtInf/CdtTrfTxInf/PmtTpInf/LclInstrm/Cd". One of those field should be filled by either 'ONCL' or 'SDCL' which means 'Over Night Clearing' or 'Same Day Clearing'. To fix this we added a config parameter with a key: account_iso20022.local_instrument_code where we can set OCNL or SDCL to add the required field to the iso document. If nothing is set, the field will not be added. opw-5073076 Forward-Port-Of: odoo/enterprise#96190 Forward-Port-Of: odoo/enterprise#95903
Chilean electronic invoice emails containing accented characters could fail during XML processing. This change lets the XML parser handle the original invoice data directly, preventing those import crashes and improving reliability for affected invoices.
Original PR description
### Issue:
The invoice XMLs having special characters like "Ó" received in DTE emails will trigger a traceback.
### Cause:
`.decode('utf-8')` will try decoding the bytes in utf-8 but Ó is not UTF-8, so there is a traceback:
```
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcd in position 1734: invalid continuation byte
```
In any case, it crashes at the next line: `xml_content = etree.fromstring(xml_dte)` because the XML specifies the encoding (i.e. unicode) but the true encoding is `utf-8` so an error is raised:
```
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.
```
### Solution:
Remove `.decode('utf-8')` when decoding. The method `fromstring` accepts bytes and will use the encoding specified in the XML.
opw-5124661
Forward-Port-Of: odoo/enterprise#96410This fix prevents errors when users add files or binary content while creating records before they are fully saved. It ensures the AI feature handles those temporary files consistently, reducing interruptions during quick creation and uploads.
Original PR description
Before this fix, when unsaved binary fields are present in a record during quick creation or file uploading, the `ir.attachment` is not yet created for that record. This causes `raw bytes` to remain in `vals[fname]` and later crashes `_get_ai_context()` during `json.dumps()`. Now `_ai_read` always generates a proper `file_ref` for unsaved binaries, using the same logic as the non-attachment branch, ensuring consistent `files_dict` entries and preventing crashes. task-19060 Forward-Port-Of: odoo/enterprise#94470
Adds coverage to ensure rental products added from the shop use the correct default rental dates instead of falling back to a 24-hour period. It also helps prevent customers from mixing overnight rental periods with other rental periods, reducing checkout errors and pricing confusion.
Original PR description
task-5065762 Forward-Port-Of: odoo/enterprise#94283
Appointment bookings with multiple staff members now calculate manual confirmation thresholds using the combined capacity of all assigned users. This prevents bookings from being unnecessarily marked as requests when enough total capacity is still available.
Original PR description
ISSUE ===== Introduced in bce7e94650c337a9046958a7689c81db5b2a4c73, We now handle capacity when booking users. They have each a max capacity of user_capacity for each slot. However, when it comes to…
ISSUE ===== Introduced in bce7e94650c337a9046958a7689c81db5b2a4c73, We now handle capacity when booking users. They have each a max capacity of user_capacity for each slot. However, when it comes to the manual confirmation treshold, we do not account for the total capacity of all users combined, but consider the maximum to be user_capacity! This can lead to a lot of 'request' meetings as we reach the manual confirmation percentage very quickly. STEPS TO REPRODUCE ================== 1. Create an appointment type based on users, with 'manage capacities' enabled, 'manual confirmation' enabled and 'when over' 50% total capacity. Set 2 users and 3 'seats max'. This way, the total capacity of your appointment is 2 * 3 = 6 per slot. 2. As a public user, take an appointment for 2 capacity in the front end 3. The meeting will end up as a 'request', even though the capacity booked is 2/6 < 50%, and should be 'booked' FIX === We now multiply the number of users on the appointment type by the user_capacity when computing the total capacity and comparing it to the asked capacity on booking an appointment. A test is included Task-4930778 Forward-Port-Of: odoo/enterprise#94446 Forward-Port-Of: odoo/enterprise#89876
Publishing and sending planning slots now respects the filters users selected in the planning view, such as role or team filters. This prevents unintended shifts from being published when users change the date range before publishing.
Original PR description
To reproduce: ============= -Reset all planning.slot to draft -Search "Dev" role -In weekly Gantt view, click on publish & send -Change date to match the current month (or any other period) -Publish Problem: ========= We filter only by datetime and ignore domain from context : https://github.com/odoo/enterprise/blob/20b45f6c65c78a572a3f26b78f6ed458accf7c9f/planning/wizard/planning_send.py#L31-L33 Solution: ========= - Get active domain from context and override only it's date_time since it changed. opw-5017014 Forward-Port-Of: odoo/enterprise#96207 Forward-Port-Of: odoo/enterprise#93295
This fixes cases where certain tax returns did not get marked as completed after reaching their final review or submission step. It also prevents the system from trying to finalize payments for returns that do not support a paid state, avoiding submission errors for affected localizations.
Original PR description
First. Returns that are generic_state_review and generic_state_review_submit weren't marked as completed once they reached their last state. Second, When submitting tax returns, we tried to automatically try to finalize the payment if there was nothing to pay. But some tax returns dont have a paid state since they use the generic_state_review_submit state_worfklow. This makes sure we are not trying to pay any returns that cannot be paid. Steps to reproduce: - Create a return with generic_state_review_submit or use a return with it, like l10n_lt_reports.vat_return_type - Validate every checks - Try to submit the return - 💥 Traceback 💥 Forward-Port-Of: odoo/enterprise#95655
Internal agents can now translate WhatsApp messages even when they are only viewing a conversation and are not listed as members. This removes an unnecessary limitation and helps support staff understand customer messages consistently.
Original PR description
Before this commit, when an agent that is not member of whatsapp but is peeking the conversation, the agent could not translate the message. This happens because the translation feature is limited to internal users, but this was determined based on the self member relational field. This works when the agent is a member but when not a member this was arbitrarily disabling the feature. This commit fixes the issue by looking at whether the user is internal or not, based on self persona independently on whether the agent is member or not of the conversation. Task-5111383 Forward-Port-Of: odoo/enterprise#96205 Forward-Port-Of: odoo/enterprise#95474
UPS shipping rate checks during ecommerce express checkout now work when shoppers provide only the minimal delivery details required at that stage. This prevents checkout failures caused by unnecessary street and phone validation before the full address is collected.
Original PR description
Express checkout in ecommerce does an initial rate check with shipping connectors that does not require all of the fields normally required by that shipping connector. For UPS, this meant express checkout was failing due to an unnecessary `street` and `phone` field check since the only required delivery fields for express checkout are: (city, zip, country_code, state_code) For more info, see: https://github.com/odoo/odoo/blob/b403d5d74dd545f926a38a6aa6d18118d34e83b7/addons/website_sale/controllers/delivery.py#L181-L188 opw-[4447700](https://www.odoo.com/web#id=4447700&view_type=form&model=project.task) Forward-Port-Of: odoo/enterprise#96572 Forward-Port-Of: odoo/enterprise#78788
This fixes Brazilian Avalara tax calculations for service invoices with discounts. Discounts are now handled consistently with Avalara's service tax data, preventing understated taxable amounts and incorrect tax totals.
Original PR description
Confusingly, Avalara's service API already accounts for the discount in lineNetFigure, whereas their goods API does not. In <saas-18.4 this was handled by _l10n_br_get_line_total(), but it got lost in the big refactor in saas-18.4 [1]. [1] https://github.com/odoo/enterprise/pull/82623 opw-5147143 Forward-Port-Of: odoo/enterprise#96585
Features or functions removed from Odoo
Odoo removes an older analytic filter from financial reports and relies on the newer analytic grouping filter instead. This should make analytic reporting more consistent because the remaining filter better handles analytic distributions across accounting reports.
Original PR description
Removing `filter_analytic`, as `filter_analytic_groupby` does the job better and considers the analytic distribution. Community PR: https://github.com/odoo/odoo/pull/223331 task-4819486
20 changes
Enhancements to existing features
Mexican payroll now uses payslip issue checks to warn users when required information is missing for CFDI generation. This helps payroll teams identify and resolve data problems earlier, reducing failed or delayed electronic payslip processing.
Original PR description
We now have a "issues" system on the payslips. Let's use it to signal what is missing for the correct generation of the CFDI. Task: 5068311
Resolved issues and error corrections
The New User Invite email template now generates website and email links correctly. This prevents recipients from receiving malformed links, making onboarding invitations work as expected.
Original PR description
Website and email links were malformed on the New User Invite email template. Later versions also have this issue on the other templates will change those in forward ports. Renderer was treating the string formatting as a string itself when using the double curly braces on variables. Removed the curly braces so the variable was properly evaluated and inserted into the string. opw-4977756 Forward-Port-Of: odoo/odoo#221487
This fix prevents an IoT device from immediately losing its server configuration after being paired again in a specific recovery scenario. It helps avoid failed setup loops and reduces manual reconfiguration for users managing IoT boxes.
Original PR description
Steps to reproduce: 1. Pair your IoT 2. From the IoT homepage, clear the server configuration 3. From the DB, delete the IoT box record 4. Pair your IoT again EXPECTED BEHAVIOUR: - IoT pairs succesfully ACTUAL BEHAVIOUR: - IoT pairs but then immediately clears the server configuration This commit introduces a simply sanity check to workaround the issue, by simply ignoring a `server_clear` message if it was received less than 5 seconds after connecting to the websocket. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230244
Credit notes created after a sales order down payment now correctly reverse the cost of goods sold. This keeps inventory and expense accounting accurate when customers are refunded after partial upfront payment.
Original PR description
**Problem:** When we do a downpayment on an invoice then pay the rest and do a credit note, the credit note does not reverse the cogs **Steps to reproduce:** - create a storable product invoiced on…
**Problem:** When we do a downpayment on an invoice then pay the rest and do a credit note, the credit note does not reverse the cogs **Steps to reproduce:** - create a storable product invoiced on ordered quantity - set the category of the product as avco and "inventory valuation" of the category as automated - set an onhand quantity and a positive cost - create a SO for 1 quantity of this product and confirm - click on create invoice, select downpayment percentage and 25% - click on create draft and confirm it - click on create invoice, select regular, create draft - confirm and select credit note - write something in the reason field and click on reserve - confirm it **Current behavior:** if you open the "Journal Items" page of the credit note you'll see that there is no line revresing the cogs (there would be if we didn't do a downpayment but invoiced all at once) **Expected behavior:** There should be: - A line crediting "600000 Expenses" (or the account that was debited for the cogs on the original invoice) with the amount being the cost of your product. - A line debiting "110300 stock interim (delivered)"(or the account that was credited for the cogs on the original invoice) with the amount being the cost of your product. **Cause of the issue:** Since this commit https://github.com/odoo/odoo/pull/163251/commits/d7b0510908d341c205461ca18b1730c93b88e445 (slightly modfified for efficieny reasons by this commit https://github.com/odoo/odoo/commit/4f9c52c03c65a497937053530e8d6c775d305e35), when _stock_account_prepare_anglo_saxon_out_lines_vals is called on the account move (the credit note) it calls _get_anglo_saxon_price_ctx. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/stock_account/models/account_move.py#L114 One of the invoice lines of the account move is linked via sale_line_ids attribute to a sale order line that is a downpayment. As a consequence, inside _get_anglo_saxon_price_ctx, move_is_downpayment will be populated with this line. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/sale_stock/models/account_move.py#L136-L139 Then _stock_account_prepare_anglo_saxon_out_lines_vals calls _stock_account_get_anglo_saxon_price_unit. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/stock_account/models/account_move.py#L131 Inside this method, because move_is_downpayment is populated, is_line_reversing will stay false https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/sale_stock/models/account_move.py#L163-L164 As a consequence, - qty_to_invoice will become - qty_to_invoice - account_move will be populated - therefore posted_cogs will be populated https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/sale_stock/models/account_move.py#L166-L174 So _compute average price will be called with a qty_invoiced of 1 instead of 0 and a qty_to_invoice of -1 instead of 1. So it will return 0 instead of the cost of the product because "missing" will be negative. https://github.com/odoo/odoo/blob/76a8d6bc28eb5998bd976b3c41bf9772d325c8bf/addons/stock_account/models/product.py#L915 **fix** The use case of this commit https://github.com/odoo/odoo/pull/163251/commits/d7b0510908d341c205461ca18b1730c93b88e445 is this one : - SO for qty of 10 (product invoiced on delivered qty). - 100% downpayment. - deliver 6. - invoice. In that case the invoice is actually a credit note but it still has to include the cogs (not reversed), so move_is_downpayment needs to be populated However in our use case the cogs has to be reversed (so move_is_downpayment has to be None). One difference between those two use case is that in our use case the account move has a reversed_entry_id. opw-5041783 Forward-Port-Of: odoo/odoo#229774 Forward-Port-Of: odoo/odoo#226809
This fixes ISO 20022 payment files for Danish banks by allowing the required local clearing instruction to be added when configured. Businesses using Danish bank payments can avoid rejected payment files by setting the appropriate clearing option, while behavior stays unchanged if no option is set.
Original PR description
The denmark banks were refusing ISO20022 documents because there was a missing field: "//PmtInf/PmtTpInf/LclInstrm/Cd" or "//PmtInf/CdtTrfTxInf/PmtTpInf/LclInstrm/Cd". One of those field should be filled by either 'ONCL' or 'SDCL' which means 'Over Night Clearing' or 'Same Day Clearing'. To fix this we added a config parameter with a key: account_iso20022.local_instrument_code where we can set OCNL or SDCL to add the required field to the iso document. If nothing is set, the field will not be added. opw-5073076 Forward-Port-Of: odoo/enterprise#96190 Forward-Port-Of: odoo/enterprise#95903
This update brings the spreadsheet engine up to its latest version with fixes for chart animations, dashboard chart menus, formatting conversion, sheet renaming, mobile formula access, headers, and pivot measures. Users should see smoother spreadsheet dashboards and fewer small interruptions when editing or presenting spreadsheet content.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/86fc4428f8 [REL] 19.0.5 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/86fc4428f8 [REL] 19.0.5 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/47bb54fc70 [FIX] chart: zoomable chart should be animated [Task: 5079057](https://www.odoo.com/odoo/2328/tasks/5079057) https://github.com/odoo/o-spreadsheet/commit/301b2ca0ec [IMP] carousel: allow full screen toggle in carousel [Task: 5078831](https://www.odoo.com/odoo/2328/tasks/5078831) https://github.com/odoo/o-spreadsheet/commit/975b3487fe [MOV] figures: rename `fullScreenChart` to `fullScreenFigure` [Task: 5078831](https://www.odoo.com/odoo/2328/tasks/5078831) https://github.com/odoo/o-spreadsheet/commit/0cea053f34 [FIX] format: wrong internal format conversion [Task: 5126306](https://www.odoo.com/odoo/2328/tasks/5126306) https://github.com/odoo/o-spreadsheet/commit/a2df5684dd [FIX] spreadsheet: prevent sheet name edit from losing focus [Task: 5109129](https://www.odoo.com/odoo/2328/tasks/5109129) https://github.com/odoo/o-spreadsheet/commit/0c0386b3ec [FIX] Evaluation: remove spread relations [Task: 5105030](https://www.odoo.com/odoo/2328/tasks/5105030) https://github.com/odoo/o-spreadsheet/commit/297ca4a894 [FIX] headers: can add lots of headers [Task: 5092626](https://www.odoo.com/odoo/2328/tasks/5092626) https://github.com/odoo/o-spreadsheet/commit/030841ec5e [FIX] composer: show FX icon in inactive mobile composer [Task: 5092659](https://www.odoo.com/odoo/2328/tasks/5092659) https://github.com/odoo/o-spreadsheet/commit/23f44838cb [FIX] chart: fix button hover background in dashboard menu [Task: 5082189](https://www.odoo.com/odoo/2328/tasks/5082189) https://github.com/odoo/o-spreadsheet/commit/242c9a7966 [FIX] pivot: add deferred calculated measure [Task: 5096156](https://www.odoo.com/odoo/2328/tasks/5096156) Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya <rmbh@odoo.com> Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
Live chat visitors can no longer start calls or invite guests from chat threads. This prevents unsupported visitor actions and keeps live chat interactions aligned with intended permissions.
Original PR description
This commit removes the possibility for live chat visitors to start a call and invite guests. task-4849019 Forward-Port-Of: odoo/odoo#229924 Forward-Port-Of: odoo/odoo#228531
This fix prevents Chilean electronic invoice XMLs received by email from failing when they contain accented characters such as Ó. Businesses can process these vendor documents more reliably without manual intervention caused by import errors.
Original PR description
### Issue:
The invoice XMLs having special characters like "Ó" received in DTE emails will trigger a traceback.
### Cause:
`.decode('utf-8')` will try decoding the bytes in utf-8 but Ó is not UTF-8, so there is a traceback:
```
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcd in position 1734: invalid continuation byte
```
In any case, it crashes at the next line: `xml_content = etree.fromstring(xml_dte)` because the XML specifies the encoding (i.e. unicode) but the true encoding is `utf-8` so an error is raised:
```
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.
```
### Solution:
Remove `.decode('utf-8')` when decoding. The method `fromstring` accepts bytes and will use the encoding specified in the XML.
opw-5124661
Forward-Port-Of: odoo/enterprise#96410This fixes an inventory valuation issue where FIFO product costs could be updated from the manually set cost instead of the actual valuation average. After revaluation, product cost now stays aligned with inventory value, improving accuracy for stock accounting and reporting.
Original PR description
**Steps to reproduce:** - create a storable product with fifo category - update the cost to 200 - click on the on hand smart button and add a quant of 1 quantity - update the cost to 300 - click on…
**Steps to reproduce:** - create a storable product with fifo category - update the cost to 200 - click on the on hand smart button and add a quant of 1 quantity - update the cost to 300 - click on the on hand smart button and update the quantity to 2 - the value should be 500, which makes a 250 value per product - open Inventory/valuation and search your product - group by product, select your product and click on "+" icon to open the revaluation widget - add 200 (so +100 per unit) - go back to the product form **Current behavior:** the cost is now at 400 **Expected behavior:** the cost should be at 350 (250 + 100) If we change the standard_price we should change it in accordance with the valuation **Cause of the issue:** In action_validate_revaluation, during the update of the standard_price, the current standard_price (set by the user and disconnected from the valuation) is used in the computation. https://github.com/odoo/odoo/blob/5118f7cb80744f901d7028dc75c29aba9591b83b/addons/stock_account/wizard/stock_valuation_layer_revaluation.py#L127 opw-5028848 Forward-Port-Of: odoo/odoo#229977 Forward-Port-Of: odoo/odoo#228457
Fixes an issue where automatic replenishment could create purchase orders with slightly inflated quantities when product packaging used different unit multiples. This helps businesses avoid unnecessary over-ordering and keeps inventory purchases aligned with actual demand.
Original PR description
**Steps to reproduce:** - enable "units of measure & packagings" settings - navigate to "units and packagings" and create a new one called "pack of 2" - set a quantity of 2 and the reference unit as…
**Steps to reproduce:** - enable "units of measure & packagings" settings - navigate to "units and packagings" and create a new one called "pack of 2" - set a quantity of 2 and the reference unit as "units" - create a new storable product - next to "sale price" change the unit to "pack of 6" - in the sales tab add "pack of 2" in the packagings - in the purchase tab add a vendor - click on the reordering rule smart button and create a new one - set the min and max to 0 and set the replenishment multiple to "pack of 2" (you might have to make this column visible using the filters) - create and confirm a quotation for 1 pack of 6 **Current behavior:** a new Purchase Order is created for a quantity of 1.02 **Expected behavior:** it should be a quantity of 1 **Cause of the issue:** qty_multiple is rounded (in _compute_quantity) before the computation of remainder. https://github.com/odoo/odoo/blob/7a0a246016d50ae80e49f3502a97e82d414ab0b0/addons/stock/models/stock_orderpoint.py#L373-L376 In cases of repeating decimal numbers (like 0.3333333 in our example), this leads to the remainder not being 0 even though it should be 0. opw-5040144 Forward-Port-Of: odoo/odoo#230013 Forward-Port-Of: odoo/odoo#228014
Appointment bookings with multiple staff members now calculate manual confirmation thresholds using the combined capacity of all assigned users. This prevents bookings from being unnecessarily marked as requests when enough total capacity is still available, and adds test coverage for this behavior.
Original PR description
While the fix has been already implemented in 19.0 in [1], this commit forwards-port the test of the original commit, as it differs from the one included (modified) in [1] and treats the case of…
While the fix has been already implemented in 19.0 in [1], this commit forwards-port the test of the original commit, as it differs from the one included (modified) in [1] and treats the case of managing capacity, and some other use cases not covered by the test in [1]. A small error is also corrected in a separate commit, as the appointment used to get the phone question was wrong in a test related to the original issue. ORIGINAL ISSUE ============== Introduced in https://github.com/odoo/enterprise/commit/bce7e94650c337a9046958a7689c81db5b2a4c73, We now handle capacity when booking users. They have each a max capacity of user_capacity for each slot. However, when it comes to the manual confirmation treshold, we do not account for the total capacity of all users combined, but consider the maximum to be user_capacity! This can lead to a lot of 'request' meetings as we reach the manual confirmation percentage very quickly. STEPS TO REPRODUCE ================== 1. Create an appointment type based on users, with 'manage capacities' enabled, 'manual confirmation' enabled and 'when over' 50% total capacity. Set 2 users and 3 'seats max'. This way, the total capacity of your appointment is 2 * 3 = 6 per slot. 2. As a public user, take an appointment for 2 capacity in the front end 3. The meeting will end up as a 'request', even though the capacity booked is 2/6 < 50%, and should be 'booked' FIX === We now multiply the number of users on the appointment type by the user_capacity when computing the total capacity and comparing it to the asked capacity on booking an appointment. 1 : https://github.com/odoo/enterprise/commit/b19e26b0333180ba7a487e14e06385693cf7ab16 Task-4930778 Forward-Port-Of: odoo/enterprise#89876
UPS shipping rate checks during ecommerce express checkout no longer fail when shoppers have only provided the limited address details required at that stage. This helps customers continue checkout smoothly before entering full street and phone information later.
Original PR description
Express checkout in ecommerce does an initial rate check with shipping connectors that does not require all of the fields normally required by that shipping connector. For UPS, this meant express checkout was failing due to an unnecessary `street` and `phone` field check since the only required delivery fields for express checkout are: (city, zip, country_code, state_code) For more info, see: https://github.com/odoo/odoo/blob/b403d5d74dd545f926a38a6aa6d18118d34e83b7/addons/website_sale/controllers/delivery.py#L181-L188 opw-[4447700](https://www.odoo.com/web#id=4447700&view_type=form&model=project.task) Forward-Port-Of: odoo/enterprise#78788
Fixes an error that could stop users from validating payments in Point of Sale when using Kenya OSCU electronic invoicing. This ensures sales can be completed normally for Kenyan companies without the checkout process failing.
Original PR description
**Steps to reproduce:** 1. Install `l10n_ke_edi_oscu_pos`. 2. Set company to a Kenya (KE) company. 3. Open POS → Clothes shop → add a product → go to Payment → try to Validate → traceback occurs.…
**Steps to reproduce:**
1. Install `l10n_ke_edi_oscu_pos`.
2. Set company to a Kenya (KE) company.
3. Open POS → Clothes shop → add a product → go to Payment
→ try to Validate → traceback occurs.
**Issue:**
- A traceback is raised when validating a payment in the POS screen.
`undefined
TypeError: Cannot read properties of undefined (reading 'services')
at OrderPaymentValidation.beforePostPushOrderResolve`
**Cause:**
- ` this.env` and `this.orm` is not directly accessible in `OrderPaymentValidation`.
https://github.com/odoo/enterprise/blob/8ca771eb28a1fac13037c0d45e8d716d3dfc6ed2/l10n_ke_edi_oscu_pos/static/src/app/utils/order_payment_validation.js#L7-L24
**Solution:**
- Use `this.pos.env` instead of `this.env`, and `this.pos.data.call` instead of
`this.orm.call` to correctly access the environment and execute data calls
during payment validation.
> Reference:
https://github.com/odoo/enterprise/blob/5a794a6e69ba884862b4a3f399143d1392caa6f0/pos_barcodelookup/static/src/overrides/components/product_screen/product_screen.js#L8-L10
[Related Community PR](https://github.com/odoo/odoo/pull/230069)
**opw - 5137557**Opening the Quality Points button from a product in Point of Sale no longer causes an error. The system now opens the correct quality control view, preventing disruption for users reviewing product quality rules.
Original PR description
**Step to Reproduce** 1- Install point_of_sale and quality_control. 2- Open POS -> Product -> Product 3- Open any product and click the Quality Points smart button → traceback occurs **Issue**…
**Step to Reproduce** 1- Install point_of_sale and quality_control. 2- Open POS -> Product -> Product 3- Open any product and click the Quality Points smart button → traceback occurs **Issue** `UncaughtPromiseError > OwlError Uncaught Promise > The following error occurred in onWillStart: ""quality.point"."product_variant_count" field is undefined."` **Root Cause** https://github.com/odoo/odoo/blob/a729578afb7fed79aac2d622aae4da4c0917f8e5/addons/point_of_sale/views/product_view.xml#L23-L25 - View reference is passed in the context. - When this context is propagated to `action_see_quality_control_point`, https://github.com/odoo/enterprise/blob/7b777bffbebfb6503bb348005e9ce076825926e4/quality_control/models/quality.py#L579-L584 https://github.com/odoo/enterprise/blob/2e08282ca275bf1e66c58e28391f11f8bd7884d2/quality_control/views/quality_views.xml#L859-L868 - Than traceback occurs because the action does not pass a `view_id`. - When the context contains `list_view_ref`, it attempts to load the product template list view with the `quality.point` model. - This leads to a traceback since the fields defined in that view do not exist on the `quality.point` model. **Solution** - Pass a proper `view_id` from the Python side to ensure the correct view is loaded, preventing `list_view_ref` from forcing to load an invalid template. **opw-** **5090505** Forward-Port-Of: odoo/enterprise#95040
Point of Sale now handles unusually large payment amounts without crashing during order validation. The fix also ensures the confirmation prompt closes correctly after approval, helping cashiers complete sales smoothly.
Original PR description
**Steps to reproduce:** 1. Install the POS module. 2. Open POS and add a product. 3. Proceed to the payment page. 4. Make a payment greater than (total cost of order * 1000). 5. Try to validate the…
**Steps to reproduce:**
1. Install the POS module.
2. Open POS and add a product.
3. Proceed to the payment page.
4. Make a payment greater than (total cost of order * 1000).
5. Try to validate the payment → traceback occurs.
**Issue:**
- A traceback is raised when validating a payment in the POS screen.
`undefined
TypeError: Cannot read properties of undefined (reading 'utils')
at OrderPaymentValidation.isOrderValid `
**Cause:**
- ` this.env` is not directly accessible in `OrderPaymentValidation`.
> Reference:
https://github.com/odoo/odoo/blob/33c789eeed3b307e40c0f7ab2c6bc07c33867498/addons/pos_online_payment/static/src/app/utils/order_payment_validation.js#L25-L28
**Solution:**.
- Use `this.pos.env` instead of `this.env` to correctly access the environment
during payment validation,
> NOTE
- After fixing the traceback, the 'Large Payment Amount' confirmation dialog
appears correctly. However, when clicking 'OK', the dialog was not closing
because the callback function `validateOrder` returned `False` even for valid
orders. This caused the dialog to reopen in an infinite loop.
https://github.com/odoo/odoo/blob/d309b52e5b19727b3e91ed91afd44e392a3b851a/addons/web/static/src/core/confirmation_dialog/confirmation_dialog.js#L71-L91
- Add return `True` in `validateOrder`, because even when the order was valid,
it returned `False`, causing the `ConfirmationDialog` to reopen repeatedly
when clicking "OK". Returning `True` ensures the dialog closes properly after
successful validation.
> Reference:
https://github.com/odoo/odoo/blob/4cd1ad3aa46ad4645fc7b5e530b79d53382de6d5/addons/point_of_sale/static/src/app/utils/order_payment_validation.js#L108-L138
[Related Enterprise PR](https://github.com/odoo/enterprise/pull/96284)
opw-5137557This fixes Indian HR leave calculations so sandwich leave counts all applicable non-working days around a leave period, not just the nearest day. It also ensures half-day leave is recorded as 0.5 days instead of a full day, improving payroll and absence accuracy.
Original PR description
**Steps to reproduce:** - Install l10n_in and l10n_in_hr_holidays module - Time off > configuration > Public holidays - Create a public holiday for Independence Day (15/08/2025) - Go to Time off >…
**Steps to reproduce:** - Install l10n_in and l10n_in_hr_holidays module - Time off > configuration > Public holidays - Create a public holiday for Independence Day (15/08/2025) - Go to Time off > configuration > 'Time off Types', - Create a Time off type with - 'Sandwich leave' ticked and `Take Time Off in` to half a day - Go to Time off > Management > Time off - Case 1: Create a paid time off leave for the employee from 13/08 to 17//08/2025 - Case 2: Create a paid time off with any date and mark it as a half-day **Observation:** - Case 1: You will see Duration 3 days with the sandwich leave policy. - Case 2: Half-day leave shows 1 day instead of 0.5 **Root Cause:** - Case 1: For the sandwich leave rule, here we checked only one day after and before, leave start and leave end, respectively. It will cause an issue if an employee applies leave that starts or ends with 3 non-working days. https://github.com/odoo/odoo/blob/5d2f1510c08d5570fc2c6c8de0cb4042bacf12d6/addons/l10n_in_hr_holidays/models/hr_leave.py#L39-L46 - Case 2: We forcefully added a 1-day leave, without checking if the leave is half day or not. https://github.com/odoo/odoo/blob/5d2f1510c08d5570fc2c6c8de0cb4042bacf12d6/addons/l10n_in_hr_holidays/models/hr_leave.py#L19 **Solution:** - Case 1: Extend the sandwich leave logic to check every day before and after until a working day is found. - Case 2: Fixed duration calculation to add 0.5 for half-day leaves. opw-5025766 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226883
Point of Sale now correctly shows and allows selection of product variant options that use the Image display type. This prevents sales staff from being blocked when selling products configured with these newer variant options.
Original PR description
**Steps to reproduce:** - Make a variant category, make it an Image - Add it to a product, go to PoS and order the product - The product variants will not be shown and can't be selected **Why the fix:** Since 19.0, there is a new kind of variant, Image, but it was not taken in the conditional statement for the product popup for the variants. As it didn't fall into any category, nothing was shown. At the moment this is basically the same as the Color option, but with an extra label below to provide more information. This it will be IMP later on with images like in the Sales module. opw-5099123
Duplicated leads without an assigned salesperson now remain eligible for rule-based assignment. This prevents sales opportunities from being missed when teams rely on automated assignment rules.
Original PR description
Currently, leads are not automatically assigned via rule-based assignment when duplicating an existing lead, even if the duplicated lead matches the assignment criteria. **Pre-requisites:** 1) Set up…
Currently, leads are not automatically assigned via rule-based assignment
when duplicating an existing lead, even if the duplicated lead matches
the assignment criteria.
**Pre-requisites:**
1) Set up rule-based lead assignment in the CRM settings.
2) Configure the sales team's assignment domain:
`[("user_id", "=", False)]`
3) Configure the sales team members' domain:
`[("probability", ">=", 10)]`
**Steps to Reproduce:**
1) Create a lead that matches the above assignment rules.
2) Remove the salesperson (user_id) and sales team from the lead.
3) Duplicate the lead.
4) Update the probability to a valid value (e.g., ≥ 10).
5) Manually trigger the `Rule-Based Assignment`.
**Issue:**
The original lead gets assigned, but the duplicated one does not.
**Cause:**
When duplicating, the system sets date_open to the current date by default,
even if the duplicated and original leads have no assigned users.
https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_lead.py#L929-L931
However, `rule-based assignment` only considers leads where `date_open` is False https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_team_member.py#L136-L141
**Solution:**
Set `date_open` to False during duplication if the original lead has no `user_id`.
This ensures the new lead remains eligible for assignment.
opw-5003529
Forward-Port-Of: odoo/odoo#229512
Forward-Port-Of: odoo/odoo#227387This fixes Razorpay payment failures that could occur when a provider was configured with both standard credentials and OAuth. The payment flow now uses the correct authentication method, helping customers complete payments on mobile without 403 errors.
Original PR description
In a specific context, Razorpay rejects connections using both Key ID/Secret and an access token simultaneously. To reproduce, it's require a real production Razorpay account since Oauth is not available in test mode. Step to reproduce: - Configure Key ID/Secret and connect via OAuth on the Razorpay payment provider. - On iOS/Android, making a payment on the website triggers a "403 Forbidden" error because Razorpay redirect to /payment/razorpay/return and the signature from Razorpay not correspond to the expected signature computed with the Key Secret. This fix prioritizes call with Key ID/Secret over token authentication. opw-5100194 opw-4989944 opw-5039880 opw-5099580 Forward-Port-Of: odoo/odoo#229468
Invoices using the Saudi Arabia localization can now be printed or sent without triggering an error. The report date formatting was corrected so PDF generation works as expected for customer invoices.
Original PR description
Steps to Reproduce: - Open any customer invoice for l10n_sa localisation. - Click the Send or Print button. - The system shows a traceback instead of generating the PDF report. Issue: - The problem was caused by a wrong date format setting in the report template. Fix: - Updated the date field setup in the report so it formats correctly when printing or sending invoices https://drive.google.com/file/d/1eY3F78YVQzutLikTigXAR0I0_2DwWILs
13 changes
Resolved issues and error corrections
UPS shipping rates can now be checked during express checkout using only the limited delivery details available at that step. This prevents shoppers from being blocked unnecessarily when street address or phone number information has not yet been collected.
Original PR description
Express checkout in ecommerce does an initial rate check with shipping connectors that does not require all of the fields normally required by that shipping connector. For UPS, this meant express checkout was failing due to an unnecessary `street` and `phone` field check since the only required delivery fields for express checkout are: (city, zip, country_code, state_code) For more info, see: https://github.com/odoo/odoo/blob/b403d5d74dd545f926a38a6aa6d18118d34e83b7/addons/website_sale/controllers/delivery.py#L181-L188 opw-[4447700](https://www.odoo.com/web#id=4447700&view_type=form&model=project.task) Forward-Port-Of: odoo/enterprise#78788
Shop floor users without HR app access can now see and add employees as operators in the shop floor app. This keeps production workflows moving without requiring broader HR permissions.
Original PR description
**PROBLEM** If a user doesn't have access to the hr.employee, they can't add any operators to the shop floor app, even if they are a shop floor user. **STEP TO REPRODUCE** 1. On a fresh db, install the mrp module. 2. Restrict Marc Demo's access to the hr app. 3. Switch to Marc Demo, and go to the shop floor app. 4. Click the + Add Operator button, and notice the pop up view doesn't show employee. **FIX** Switch the model shown by the view to hr.employee.public. opw-4887229
Portal and public users can now print or export public Knowledge articles with the correct content and formatting. This avoids blank pages caused by print styling conflicts and missing print layouts, improving reliability for shared documentation.
Original PR description
### Reproduction Steps 1. Install `knowledge`, `spreadsheet`, and `planning` modules 2. In the knowledge app on an admin account, ensure an article is publicly available and invite a portal user 3.…
### Reproduction Steps 1. Install `knowledge`, `spreadsheet`, and `planning` modules 2. In the knowledge app on an admin account, ensure an article is publicly available and invite a portal user 3. Log in as the portal user and attempt to print/export the article 4. Also attempt to print/export the same article from the public (unauthenticated) view **Result**: * As a portal user: a blank page is displayed instead of the article. * As a public user: a blank page is also displayed instead of the article. ### Root Cause The blank print issue comes from multiple problems with CSS asset loading in print mode: 1. **Spreadsheet Conflict (Portal View)** The spreadsheet module’s print styles were incorrectly included in the `web.assets_backend` bundle, causing conflicts. These styles are already properly loaded through `spreadsheet.assets_print` and shouldn’t be duplicated in the backend. 2. **Missing Print Assets (Portal View)** The knowledge portal template was missing the `web.assets_web_print` bundle, which contains the core print styles needed for proper article formatting. 3. **Planning Conflict (Public View)** The planning module’s print styles in the `web.assets_frontend` bundle were globally hiding elements, conflicting with the display of knowledge articles. 4. **Missing CSS rules (Public View)** The public knowledge templates were also missing specific CSS rules required for proper article rendering in print mode. ### Fix This PR fixes problems 2, 3 and 4 by: * Removing the unused/irrelevant planning print styles * Ensuring `web.assets_web_print` is loaded in portal * Creating a new print bundle for the frontend view * Hiding the knowledge header in the public view when printing (to improve layout) The first issue is tackled in odoo/odoo#223434 opw-4816241
This fix prevents online job application forms from failing when submitted by users who are already signed in. It ensures applicants can complete recruitment forms reliably, reducing lost applications and support issues.
Original PR description
In [1], `email_from` was made mandatory when submitting a form as a logged in user. In [2], `email_from` was removed from the form parameters once consumed by the job application form. Because of these, the job application form fails when submitted while being logged in. This commit avoids this error by not consuming the `email_from` field in the job application handling when the user is logged in. [1]: https://github.com/odoo/odoo/commit/1aa5cbb06be85e94c01f8f55ef57b9415b9bb50f [2]: https://github.com/odoo/odoo/commit/05f9f43b93e10745b130a7ee185261e9a259ef2a task-4280924
This fixes a styling conflict that could cause Knowledge articles to print or export as blank pages for portal or public users. Spreadsheet print styles are now kept out of the general backend assets, reducing conflicts while preserving spreadsheet print functionality.
Original PR description
### Reproduction Steps 1. Install `knowledge`, `spreadsheet`, and `planning` modules 2. In the knowledge app on an admin account, ensure an article is publicly available and invite a portal user 3.…
### Reproduction Steps 1. Install `knowledge`, `spreadsheet`, and `planning` modules 2. In the knowledge app on an admin account, ensure an article is publicly available and invite a portal user 3. Log in as the portal user and attempt to print/export the article 4. Also attempt to print/export the same article from the public (unauthenticated) view **Result**: * As a portal user: a blank page is displayed instead of the article. * As a public user: a blank page is also displayed instead of the article. ### Root Cause The blank print issue comes from multiple problems with CSS asset loading in print mode: 1. **Spreadsheet Conflict (Portal View)** The spreadsheet module’s print styles were incorrectly included in the `web.assets_backend` bundle, causing conflicts. These styles are already properly loaded through `spreadsheet.assets_print` and shouldn’t be duplicated in the backend. 2. **Missing Print Assets (Portal View)** The knowledge portal template was missing the `web.assets_web_print` bundle, which contains the core print styles needed for proper article formatting. 3. **Planning Conflict (Public View)** The planning module’s print styles in the `web.assets_frontend` bundle were globally hiding elements, conflicting with the display of knowledge articles. 4. **Missing Print Assets (Public View)** The knowledge public templates were also missing the `web.assets_web_print` bundle, preventing proper article rendering in print mode. ### Fix This PR addresses the first issue by removing spreadsheet print assets from the `web.assets_backend` bundle, since they're already available through their dedicated `spreadsheet.assets_print` bundle. The remaining issues are tackled in odoo/enterprise#92665 opw-4816241
Prevents users from unbuilding manufacturing orders created through subcontracting, because that workflow produced incomplete accounting entries. This avoids incorrect stock valuation and journal entry imbalances for subcontracted production.
Original PR description
**Problem:** unbuilding a Manufactring order created through a subcontracting process gives the wrong account move lines **Steps to reproduce:** - create a storable product (the comp) and set a cost…
**Problem:** unbuilding a Manufactring order created through a subcontracting process gives the wrong account move lines **Steps to reproduce:** - create a storable product (the comp) and set a cost - create a storable product (the final product), set a cost and set a vendor - for the final product set the category as avco and automated - for the final product create a bill of materials subcontracted and set the same vendor - for the components add the comp for a quantity of 1 - create a Purchase order for the final product and the same vendor and confirm - validate the receipt - From the receipt click on the valuation smart button and click on the book widget of the line of the final product - notice how there is 3 journal items line including one crediting "stock interim (Received)" - unarchive the operation type "subcontracting" - open Manufacturing/Manufacturing Orders, delete the "to do" filter and search for a Manufacturing order with your final product - unbuild it - Open accounting/journal entries and select the journal entry for the unbuild **Current behavior:** There is only two account lines. There is no line balancing the "Stock Interim" line of the manufacturing order. **Cause of the issue:** The override of _generate_valuation_lines_data in mrp_subcontracted_account adds the stock interim line on the manufacturing order. However when unbuilding, the qty is negative so we exit the function https://github.com/odoo/odoo/blob/1358f93a4c73de5a28cda72ec78769625c863efd/addons/mrp_subcontracting_account/models/stock_move.py#L20 **fix** Because subcontracted Manufacturing orders are not meant to be unbuilt, we prevent it opw-4998137
Belgian POS sessions using Blackbox fiscal settings no longer fail when users have multiple companies selected. This prevents an error during POS opening by correctly handling tax checks across more than one company.
Original PR description
When opening a POS session with multiple companies selected, an error is raised due to direct access to `taxes_id.amount`, which assumes a single tax record. Steps to reproduce: 1. Create two Belgian companies and configure Blackbox (= `iface_fiscal_data_module` = True on POS config) 2. Select both companies in the UI 3. Try to open the POS 4. Error: ValueError: Expected singleton: account.tax(12, 83) This fix uses `any()` to check if all taxes are 0% instead of accessing the `amount` attribute directly, avoiding singleton errors when multiple taxes exist across companies. opw-4962923 Forward-Port-Of: odoo/enterprise#96603 Forward-Port-Of: odoo/enterprise#91984
This fix prevents payroll work entry generation from crashing when a fully flexible employee has overlapping time off and public holidays. It helps payroll teams process these employees reliably without manual workarounds or blocked payroll runs.
Original PR description
**Issue:** Multiple errors occur when processing payroll for "Fully Flexible" employees and overlapping leave scenarios: 1. ValueError "Expected singleton: hr.work.entry.type(7, 8)" during work entry…
**Issue:** Multiple errors occur when processing payroll for "Fully Flexible" employees and overlapping leave scenarios: 1. ValueError "Expected singleton: hr.work.entry.type(7, 8)" during work entry generation when sick leave overlaps with public holiday **Steps to Reproduce:** 1. Go to the **Employees** app and create a new employee. * Set the working hours to **empty (fully flexible)**. 2. Go to **Contracts** and create a new contract. * Set the **Work Entry Source** to *Attendance*. * Save and make the contract **Running**. 3. Go to **Time Off** → **New**, and create a sick time off for the employee. * Example: from **25th to 29th**. * Approve the time off. 4. Go to **Configuration** → **Public Holidays**, and create a new public holiday. * Example: **27th**, which overlaps with the sick time off. * Work Entry Type = **Paid Time Off**. 5. Go to **Payroll** → **Work Entries**. * A **traceback** occurs. **Root Causes:** - In `_get_interval_leave_work_entry_type()`: Direct access to `interval[2].work_entry_type_id.code` causes singleton violation when overlapping leaves create intervals containing multiple work entry types. **Fix:** - Replace direct access to `interval[2].work_entry_type_id.code` with safe recordset slicing `interval[2].work_entry_type_id[:1].code` to prevent singleton violation when interval contains multiple work entry types This resolves payroll blocking issue for deployments using the Fully Flexible employee feature, where employees may have overlapping leave types and no assigned working calendar. Test : [PR](https://github.com/odoo/enterprise/pull/93902) opw-4979974
This fixes an issue where time off spanning two allocations could be incorrectly counted as exceeding the available balance when a public holiday fell at the start of the second allocation. Public holidays are now included properly during recalculation, helping employees and HR teams see accurate leave usage.
Original PR description
### Steps to reproduce: - Install Time off apps - Create two consecutive allocations (e.g. one for 2025 and one for 2026) - Create a leave that overlap with the two allocation (e.g. from 8th Dec to…
### Steps to reproduce: - Install Time off apps - Create two consecutive allocations (e.g. one for 2025 and one for 2026) - Create a leave that overlap with the two allocation (e.g. from 8th Dec to 3rd Jan) - Create a public holiday at the beginning of the second allocation (e.g. on 1st Jan 2026) ### Cause: When we are checking the leave duration after having a public holiday the will return the attendance without the public holidays duration so when subtracting the attendance duration from the leave duration we will have a remaining amout equals to the public holiday duration and it will be considered as excess days. https://github.com/odoo/odoo/blob/06e47d8601ba56b1650eeaeef71ebd7a4af39b8b/addons/hr_holidays/models/hr_employee_base.py#L228-L230 https://github.com/odoo/odoo/blob/06e47d8601ba56b1650eeaeef71ebd7a4af39b8b/addons/hr_holidays/models/hr_employee_base.py#L246-L254 ### Fix: We check for public holidays in the interval we are fetching its attendance to avoid assuming it is an excess days in the leave opw-5006119
This fixes an error that could block users from saving a manufacturing order after starting one operation and editing another. Manufacturing order dates now only use operations that are actually scheduled, avoiding crashes and keeping production timing accurate.
Original PR description
**Steps to reproduce:** 1. In Settings, enable "Work Orders". 2. Create a product with a BOM that has 2 operations: op1 and op2. 3. Create and confirm an MO for 1 unit. 4. Start op1 and change the…
**Steps to reproduce:** 1. In Settings, enable "Work Orders". 2. Create a product with a BOM that has 2 operations: op1 and op2. 3. Create and confirm an MO for 1 unit. 4. Start op1 and change the Real Duration of op2. 5. Try to save. **Issue:** - Traceback : `'<' not supported between instances of 'datetime.datetime' and 'bool'` **Cause of the issue:** Starting the first operation launches a call of the `button_start` method creating a `resource.calendar.leaves` to set on the `leave_id` of this first operation: https://github.com/odoo/odoo/blob/97a70e71c32ea6183f87fd5eb558b32bcbd2d231/addons/mrp/models/mrp_workorder.py#L630-L641 Then, setting the duration of the second operation from the form view of the MO and saving triggers a call of the write of the MO containing the `[Command.update(op_2.id, new_duration)]` as vals.This, in turn, calls `_plan_workorders`: https://github.com/odoo/odoo/blob/97a70e71c32ea6183f87fd5eb558b32bcbd2d231/addons/mrp/models/mrp_production.py#L939-L942 while the first operation has a set `leave_id` but the second do not However, the `min` operator will be applied to both the set and the unset values, comparing a `boolean` with a `datetime`: https://github.com/odoo/odoo/blob/97a70e71c32ea6183f87fd5eb558b32bcbd2d231/addons/mrp/models/mrp_production.py#L1581-L1588 **Solution:** Only workorders with a `leave_id` (i.e., those planned in work-center schedule) should be considered when computing MO `date_start` and `date_finished`. Workorders without a `leave_id` are not yet scheduled and therefore should not influence MO start and end dates. As both `date_start` and `date_finished` of a workorder are related to the `leave_id` record. As per `mrp_workorder._compute_dates`, these dates reflect the work-center scheduling (`leave_id.date_from` and `leave_id.date_to`). https://github.com/odoo/odoo/blob/6a075fa3c090920499ccbd5fe673819da7e3f95e/addons/mrp/models/mrp_workorder.py#L250-L260 Therefore, when computing MO dates, it logically follows that only workorders with an assigned `leave_id` should be used. This avoids mixing unscheduled operations (`leave_id = False`) with scheduled ones, preventing invalid comparisons and ensuring accurate production timing. **opw-5068080**
Product tax fields now make it clear which company each sale or purchase tax belongs to when users work with multiple companies. This helps accounting users choose the correct tax and avoid confusion in multi-company environments.
Original PR description
Backport of some changes included here https://github.com/odoo/odoo/commit/2cf73ba8fe50288a0ea9d0ad4b8aeb51bc345740 The goal of this pr is to see for which company belongs each sale/purchase tax in a…
Backport of some changes included here https://github.com/odoo/odoo/commit/2cf73ba8fe50288a0ea9d0ad4b8aeb51bc345740 The goal of this pr is to see for which company belongs each sale/purchase tax in a product when more than one company is selected. This pr solves odoo task #4829985 and this issue https://github.com/odoo/odoo/issues/147673 Steps to reproduce: 1) Go to runbot odoo enterprise 18 instance and select companies "My Belgian Company" and "My Company (San Francisco)" taking position in "My Belgian Company". 2) Go to "Accounting / Customers / Products" and get into product with name "Bolt" and internal reference "CONS_89957". There is shown two taxes in "Sale Taxes" and "Purchase Taxes" fields but is not possible to distinguish for which company belongs each tax. Current behavior: It can not be distinguished whenever for which company belongs each customer tax in a product if more than one company is selected. Expected behavior: It can be distinguished whenever for which company belongs each customer tax in a product if more than one company is selected. Task Adhoc side: 52262 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
Odoo now handles attached email files containing accented or other non-English characters correctly. This prevents email sending failures when users attach saved email messages in the chatter, improving reliability for international communication.
Original PR description
The previous fix for `message/rfc822` attachments forced binary encoding (`cte='binary'`) to comply with RFC 2046. However it also introduced a new issue: emails containing `.eml` attachments with…
The previous fix for `message/rfc822` attachments forced binary encoding (`cte='binary'`) to comply with RFC 2046. However it also introduced a new issue: emails containing `.eml` attachments with non-ASCII characters could not be serialized ### Steps to reproduce 1. Send an email via the chatter with a `.eml` file attached containing non-ASCII characters (e.g., "é") in its body. The sending of that email will fail with a `UnicodeEncodeError` error ### Cause Commit 6197233ef1611ddd974cfdb06ae2568e4af369de attempted to fix an issue where `.eml` (`message/rfc822`) attachments were not RFC-compliant. It did this by forcing the `Content-Transfer-Encoding` to `binary` for the raw byte content of the attachment. While this worked for simple ASCII attachments, it failed for attachments containing non-ASCII characters. When Python's `email` library later tried to serialize the entire message, it treated the attachment's content as an opaque binary blob. It did not understand the character encoding within that blob, leading to a `UnicodeEncodeError` during the final serialization process. ### Fix Instead of attaching the raw bytes, we now: * Parse `.eml` contents using `email.parser.BytesParser`, producing a proper `Message` object. * Attach the parsed message directly, letting the email library handle correct encoding and transfer settings automatically. opw-4655868 Forward-Port-Of: odoo/odoo#223790
This fix updates Spanish VAT handling so certain non-EU service sales are reported in the correct VAT category instead of being treated as exports. It also corrects the refund sign for the related non-subject VAT service tax, improving accuracy in Modelo 303 tax filings.
Original PR description
The s_iva_e tax (IVA 0% Extracomunitaria (Servicios)) is configured as no_sujeto_loc, but is reported as "Exportacion" in modelo 303. There might have been the idea that we need a tax for services that are just a complement to some goods, but this tax is not used that way in practice. So, it is better to treat it as a duplicate of the s_iva_ns tax (Not Subject To VAT (services)) where we also see that the refund sign was wrong. opw-5079297 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229752
10 changes
Resolved issues and error corrections
New user invitation emails now generate website and email links correctly. This prevents recipients from receiving malformed links and helps invited users access Odoo without confusion.
Original PR description
Website and email links were malformed on the New User Invite email template. Later versions also have this issue on the other templates will change those in forward ports. Renderer was treating the string formatting as a string itself when using the double curly braces on variables. Removed the curly braces so the variable was properly evaluated and inserted into the string. opw-4977756 Forward-Port-Of: odoo/odoo#221487
This fixes a rounding issue that could make fully prepaid Saudi invoices show a negative zero amount, causing the invoice data and QR code to disagree. Businesses using Saudi e-invoicing can now submit these affected invoices to ZATCA successfully instead of receiving a rejection.
Original PR description
Issue: Doing down payment up to 100% can create a -0.00 PayableAmount that won't match the QR Code value, as it's set to absolute. Step to reproduce: 1 Install l10n_sa_edi 2 Navigate to Accounting >…
Issue: Doing down payment up to 100% can create a -0.00 PayableAmount that won't match the QR Code value, as it's set to absolute. Step to reproduce: 1 Install l10n_sa_edi 2 Navigate to Accounting > Configuration > Taxes. 3 Select the 15% tax and copy it. 4 In the Advanced Configuration tab, select the "Included in Price" option. 5 Navigate to Sales. 6 Select NEW 7 Add ARAMCO (default customer in l10n_sa) as a customer 8 Click into ARAMCO and change contact type to an Individual. 9 Navigate back to Sale Order. 10 Add the following products: - a Booking Fees. 1 quantity. Unit price 225.4 15% tax (price included) - b Burger Menu Combo. 1 quantity. Unit price 180 15% tax (price included) - c Booking Fees. 1 quantity. Unit price 300 15% tax (price included) - d Burger Menu Combo. 1 quantity. Unit price -101.43 15% tax (price included) 11 Select Confirm. 12 Select Create Invoice, then Down payment of 100%. 13 Confirm the invoice. 14 Navigate back to Sale order. 15 Select Create Invoice, then Regular Invoice. 16 Confirm the invoice. 17 Select "Process now" in the blue banner. 18 Receive error. Current behavior: - Message: "Invoice was rejected by ZATCA" - ZATCA return an error 400 and states the QR Code is invalid as the BT-115 in the invoice (XML) and QRCode doesn't match Expected behavior: - Message: "Invoice Successfully Submitted to ZATCA" Cause of the issue: - Some issues with floating point operations create a difference in value between a 100% down payment and the value of the invoice it covers. This results in a -1e-13 `payable_amount` that ends up being a -0.00 PayableAmount after going through `float_rounding`. Solution: - By rounding the `payable_amount` as per currency limit, the `payable_amount` fall back to -0.00. Then it goes through `float_rounding` which return 0.00. opw-5059795 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes incorrect tax mappings in the Maltese localization for EU and non-EU partner fiscal positions. Businesses using Maltese accounting will now have sales and purchase taxes mapped to the correct tax type and rate, reducing the risk of wrong tax treatment on transactions.
Original PR description
### Steps to reproduce: - Install "l10n_mt" and switch to a Maltese company - Check the fiscal position "EU Partner", it maps Sales taxes to Purchase ones - "Partner outside the EU" maps Purchase taxes to Sales ones ### Solution: Fix the CSV. We map the taxes respecting Sales/Purchase and with the same percentage. opw-5065298
This fix sends the extra payment details required by some Adyen payment methods, such as customer country and order line information. It helps transactions using services like Klarna complete successfully instead of being blocked by missing required data.
Original PR description
Some payment methods eg. Klarna require 'country code' and 'line items' in order to process the transaction. opw-5077617
This fix prevents Chrome on iOS from automatically changing parts of page text in a way that could disrupt Odoo screens. It helps keep the web interface stable for affected mobile users, especially on Chrome iOS versions where this browser behavior reappeared.
Original PR description
Chrome iOS wraps some text nodes (like measures, email...) with a `<chrome_annotation>` tag, which breaks OWL rendering. This commit works around it by adding the (undocumented) `<meta name="chrome"…
Chrome iOS wraps some text nodes (like measures, email...) with a `<chrome_annotation>` tag, which breaks OWL rendering. This commit works around it by adding the (undocumented) `<meta name="chrome" content="nointentdetection">` tag to disable this Chrome behavior. The tag has to be set before the onDOMContentLoaded event to be taken into account. Note: Looks like this behavior was present in Chrome iOS 127 and disabled afterward (because it already had issues) but it appeared again in version 140-141. References: - https://issues.chromium.org/issues/353650041 - https://issues.chromium.org/issues/388718411 - https://stackoverflow.com/questions/78207646/how-do-i-disable-chrome-annotation-tags - https://stackoverflow.com/questions/78575970/prevent-auto-detection-of-phone-numbers-in-chrome-mobile - https://stackoverflow.com/questions/78725191/stop-chrome-ios-auto-detecting-numbers-followed-by-letter-m-as-metre-units-an - https://github.com/solidjs/solid/issues/2235 opw-4969197
Odoo Studio now creates edited views based on the nearest main view instead of accidentally basing them on an extension view. This helps prevent customization issues and keeps Studio changes attached to the correct underlying screen structure.
Original PR description
…ry view Accidentally pass an inheriting view id to edit view. Before this commit, the studio view thus created inherited from the extension view After this commit, it inherits from the closest primary view. opw-4930800
Belgian POS sessions using the fiscal Blackbox can now open correctly when users have multiple companies selected. The change prevents a tax-check error that blocked session startup in multi-company setups.
Original PR description
When opening a POS session with multiple companies selected, an error is raised due to direct access to `taxes_id.amount`, which assumes a single tax record. Steps to reproduce: 1. Create two Belgian companies and configure Blackbox (= `iface_fiscal_data_module` = True on POS config) 2. Select both companies in the UI 3. Try to open the POS 4. Error: ValueError: Expected singleton: account.tax(12, 83) This fix uses `any()` to check if all taxes are 0% instead of accessing the `amount` attribute directly, avoiding singleton errors when multiple taxes exist across companies. opw-4962923 Forward-Port-Of: odoo/enterprise#91984
Fixed an issue in Time Off where mandatory day markers could appear on the wrong calendar date when users viewed Odoo in Hebrew. This helps ensure employees and managers see accurate time-off calendar information regardless of language settings.
Original PR description
Steps to reproduce: 1. Install Time Off (hr_holidays). 2. Go to Time Off → Configuration → Mandatory Days. 3. Create a mandatory day. 4. Open the user profile (top right corner) and change the…
Steps to reproduce: 1. Install Time Off (hr_holidays). 2. Go to Time Off → Configuration → Mandatory Days. 3. Create a mandatory day. 4. Open the user profile (top right corner) and change the language to Hebrew. 5. Open Time Off and view the calendar. Issue: The mandatory day marker is displayed on the incorrect date when the interface is in Hebrew. Cause: https://github.com/odoo/odoo/blob/ea9cd8357e148654458e3505963ae847d181776e/addons/hr_holidays/static/src/views/hooks.js#L18-L32 This is because the code was using 'info.el.dataset.date' directly which is based on the rendered DOM element and can be influenced by locale formatting, instead of the canonical ISO date, leading to incorrect selectors when trying to add the hr_mandatory_day CSS classes to the date. solution: Use the correct date value derived from info.date via Luxon’s toISODate() method Replaced info.el.dataset.date in the DOM selectors with the normalized ISO date to ensure that the correct element is targeted regardless of the current language or locale. opw-4979274
This fixes French localization time-off calculations so leave-related timesheet entries use the employee's actual work schedule, even when it starts earlier or ends later than the company schedule. It prevents incorrect worked-hour totals, helping payroll and timesheet records reflect the correct absence duration.
Original PR description
This bug is in France localization. In some cases employee schedule seems ignored in timesheet entry (`account.analytic.line`) creation, and the duration field is created using the company schedule.…
This bug is in France localization. In some cases employee schedule seems ignored in timesheet entry (`account.analytic.line`) creation, and the duration field is created using the company schedule. The reason is the case which the employee schedule starts before company scheudle or ends after it. To reproduce the bug: 1- Make a db with fr company (install l10n_fr) 2- Make two working schedule: - Company schedule with working day on Monday from 8:00-12:00 13:00-17:00 - Employee schedule with working day on Monday from 8:30-12:25 13:30-17:15 3- Assign company schedule to company in `Company Working Hours` in Setting and apply employee schedule to an employee from `Payroll` tab of employee 4- Allocate some time off to the employee and take a time off on Monday 5- Check the work entries for the day you took the day off on timesheet app 6- 7:24 `Worked Hour` is shown instead of 7:40 The bug occurs because in calling `adjust_date_range`, the case which employee's schedule ends after company schedule is not considered. opw-4868643 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The hierarchy view now handles circular reporting relationships, such as an employee being set as their own manager, without crashing or getting stuck. This improves reliability for users viewing organization charts and other hierarchy-based screens.
Original PR description
This commit fixes some traceback errors in the web_hierarchy module by refining the cycle detection of records in hierarchies. Infinite loops in case of a cycle's presence in the `removeChildNodes` and `processNode` methods are now prevented. Additionally, tree re-rooting in case of the presence of two nodes in the same tree, which implies a cycle's existence, is now avoided. There was an edge case where an employee could be their own manager, creating two child nodes of that employee. The case is now handled by making sure that records are unique for each parent ID in the `recordsPerParentId` object. task-5022670 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr