Daily updates from Odoo
Tuesday, October 7, 2025
86 changes
15 changes
Resolved issues and error corrections
This fix prevents the HTML editor from getting stuck and showing an error when users remove formatting from colored table cells. It makes table color handling more consistent, so formatting can be cleared safely without interrupting editing work.
Original PR description
Problem: When having a `table` with `color` and selecting a cell to remove format, we get a traceback: "Infinite Loop in removeAllColor()." Cause: The color is applied on `table`, but we only process `td` for color removal. As the color remains on `table`, each attempt to remove it keeps reapplying, leading to an infinite loop. Solution: When removing color, also remove it from the `table`. Then apply the color to all child `td`. This ensures `td` colors are later removed automatically if selected, avoiding the loop. Steps to reproduce: 1. Add a `color` property to a `table` and `td`. 2. Select the `td`. 3. Click "remove format" from the toolbar. 4. Observe traceback. opw-5112088 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229878
Live chat visitors are now prevented from starting calls or inviting additional guests from chat threads. This keeps visitor capabilities aligned with intended support workflows and reduces unwanted or confusing actions during live chat sessions.
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#229796 Forward-Port-Of: odoo/odoo#228531
Reordering rules now calculate purchase quantities correctly when product packaging uses multiples that create repeating decimals. This prevents Odoo from generating purchase orders with slightly inflated quantities, such as 1.02 instead of 1, helping keep purchasing accurate.
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#228014
This fix keeps a cashier’s manually selected tax setup when validating a Spanish point-of-sale order. It prevents incorrect tax amounts from appearing as change on receipts, improving accuracy for shops using Spanish simplified invoicing.
Original PR description
Currently, when you use a default fiscal position in the pos, if you switch to no fiscal position, upon order validation the tax amount is counted as change. Steps to reproduce: ------------------- *…
Currently, when you use a default fiscal position in the pos, if you switch to no fiscal position, upon order validation the tax amount is counted as change. Steps to reproduce: ------------------- * Install l10n_es_pos, switch to es company * In the config of a shop, use fiscal position, set some as available, one as default * Open shop session * Add a product that has taxes * Switch fiscal position to one that has 0% taxes * There should not be taxes in the cart at this point * Go to pay the order (cash or bank) > Observation: On the receipt the previous tax value is counted as change Why the fix: ------------ The issue happens because of the simplified invoice mechanism present in the ES localization. When you validate an order and that order can apply for simplified invoice, if there is no customer on the order the partner is set with the simplified partner. When setting a partner on the order we update the fiscal position and pricelist. https://github.com/odoo/odoo/blob/1358f93a4c73de5a28cda72ec78769625c863efd/addons/point_of_sale/static/src/app/models/pos_order.js#L929 The fiscal position is updated with the partner's fiscal position or the default one if none on the partner. https://github.com/odoo/odoo/blob/1358f93a4c73de5a28cda72ec78769625c863efd/addons/point_of_sale/static/src/app/models/pos_order.js#L986-L995 Instead of the fallback on the default fiscal position in the case it is not set on a partner we fallback on the order current fiscal position. If it is different than the default one is means that it was changed intentionally and there's a high chance we want to keep it, otherwise it will already be the default fp. opw-5051231 Forward-Port-Of: odoo/odoo#229237
Self-order customers will no longer see or select time slots that have already reached their allowed capacity. This prevents overbooking and fixes time zone handling so availability is calculated against the correct slot time.
Original PR description
**Steps to reproduce:** - Have a preset that requires time slots - Make the slots_per_interval 1 and the interval_time long enough - Go to the self order, make a purchase and select a slot - Make…
**Steps to reproduce:** - Have a preset that requires time slots - Make the slots_per_interval 1 and the interval_time long enough - Go to the self order, make a purchase and select a slot - Make another purchase - The slot we chose before is still showing and available **Why the fix:** Once the capacity of a time slot has been reached, we should not allow customer to chose it. This behavior occured for 2 reasons: - In the xml file where we declare this select, we did not take the fact that a slot could be full into account, leading to it always being showed. This is now done using the isFull attribute, like it is done in the regular PoS. - This same isFull was not correctly set, as there was a mismatch in slots timezone and format. When we retrieved them from the server, they were in UTC timezone, but the current slot we were working with was in the locale timezone. It is now converted to UTC to check if we already hit max capacity. Before this, selecting a timezone was actually selecting the one that was two hours earlier (for Belgium). With this commit, the values that reached max capacity will not be displayed on the select for the time slots anymore. opw-5092888 Forward-Port-Of: odoo/odoo#228441
The Unrealized Currency Gains/Losses report now correctly creates draft adjustment entries even when users customize how report lines are grouped. This prevents a misleading “No adjustment needed” error and helps finance teams complete currency revaluation workflows 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
Users who can print and send SEPA direct debit mandates can now generate and access the related PDF attachments. This removes a permission mismatch that could block sending mandate emails or prevent users from opening attachments they had created.
Original PR description
Removing the groups restriction from the `mandate_pdf_file` field in model `sdd.mandate` because it was causing issues when using the `sdd.mandate.send` wizard. Any user who has access to the `sdd.mandate` model can use this wizard to print and send the record. During this process, the system generates a PDF and stores it in the `mandate_pdf_file` binary field, linking the resulting attachment to the record. The previous group restriction prevented users who were not part of the `account.group_account_readonly` group from sending the email with the attachment. Even if the email was somehow sent, those users still couldn’t access the attachments they themselves had generated and sent. With this change, any user who is allowed to send and print `sdd.mandate` records will also be able to generate and later access the corresponding attachments. Forward-Port-Of: odoo/enterprise#96119
This fixes an issue where an IoT device could pair successfully but then immediately lose its server configuration because an old clear message was processed. The system now ignores stale clear requests right after reconnecting, making re-pairing more reliable for users.
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
Recruitment users can now add applicants to a talent pool without being blocked by employee access restrictions. This prevents an unexpected error in the hiring workflow for users who have Recruitment permissions but limited HR employee access.
Original PR description
Steps to reproduce: ==================== 1. Grant admin access for Recruitment to demo user. 2. Go to the Recruitment app. 3. Open Applications > Talent Pool. 4. Select a talent pool. 5. Click "Add to pool". Problem: ========= If the user lacks read access on Employees, an access error occurs. This happens because `_add_applicants_to_pool` tries to access `proposed_contracts`, https://github.com/odoo/enterprise/blob/95b9942316c962950ace6b899faa6f1e6c8fee9a/hr_contract_salary/models/hr_applicant.py#L17 which triggers a read on `hr.version`. Since `hr.version` uses `_order`, https://github.com/odoo/odoo/blob/f0eb0c792b77fbaf0ef3738ea88d9c2bae880a85/addons/hr/models/hr_version.py#L28 it tries to sort the result, leading to a access rights error. Fix: ==== Use `sudo` when calling _add_applicants_to_pool. opw-5074018
This fix prevents the emoji picker from crashing when Odoo is used in non-English languages. Users can now open and use the emoji picker in Discuss even when translations contain special line breaks or emoji data is unavailable.
Original PR description
**Description of the issue this PR addresses:** ------------------------------------------------ In some non-English translations, emoji strings include `\n`, which breaks JSON parsing in `emoji_data.js`. This causes `emojis.length === 0`, so the empty state is displayed instead of the main emoji picker UI. Some UI logic still executes on missing DOM elements, which triggers errors. **Current behavior before PR:** --------------------------------- - Switch to a non-English language - Open the emoji picker in Discuss - Errors are triggered due to missing DOM elements **Desired behavior after PR is merged:** ----------------------------------------- - Emoji JSON parses correctly - The emoji picker opens without errors in non-English languages - The emoji picker still opens when `emojis.length === 0` **Task:** 4978824 Forward-Port-Of: odoo/odoo#229795 Forward-Port-Of: odoo/odoo#223564
This update refreshes Odoo's spreadsheet component with several bug fixes that make spreadsheet editing more reliable. Users should see fewer issues with format handling, sheet renaming, header creation, mobile formula editing, and pivot table calculations.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/d4df70e06e [REL] 18.4.13 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/d4df70e06e [REL] 18.4.13 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/5952c992b5 [FIX] format: wrong internal format conversion [Task: 5126306](https://www.odoo.com/odoo/2328/tasks/5126306) https://github.com/odoo/o-spreadsheet/commit/cf2dc7fd11 [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/5d90de9d07 [FIX] Evaluation: remove spread relations [Task: 5105030](https://www.odoo.com/odoo/2328/tasks/5105030) https://github.com/odoo/o-spreadsheet/commit/4b990f1c47 [FIX] headers: can add lots of headers [Task: 5092626](https://www.odoo.com/odoo/2328/tasks/5092626) https://github.com/odoo/o-spreadsheet/commit/32118777ef [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/697ee86139 [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>
Incoming Chilean electronic invoice emails with accented characters could fail to process and show an error. This fix allows those XML invoices to be read correctly, reducing manual follow-up for affected documents.
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-5124661This update prevents UK tax report submissions from reusing invalid saved device identifiers when contacting HMRC. If an incorrect value is found in the browser, Odoo clears it so a valid identifier can be used and requests are less likely to be rejected.
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 drivers correctly prepare information before sending it to the Odoo database. It prevents failures when using connected payment terminal libraries, helping devices continue to communicate reliably after recent platform changes.
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 v19 -> master: https://github.com/odoo/enterprise/pull/96537 opw-5129596
The German Datev export now handles sales and purchase receipts even when no customer or vendor is entered. This prevents export failures and helps businesses keep accounting data flowing correctly for receipt-based transactions.
Original PR description
Since 18.4, there are purchase receipts as a function for vendor bills, where you can choose to put no vendor in the vendor field, the same is true for invoices with sale receipts. Making sure that partners are not Null task-5114562
14 changes
Resolved issues and error corrections
This fix resolves an issue where users could be blocked from validating a backordered delivery in warehouses using a two-step delivery flow. It ensures stock reservations are adjusted correctly when lot-tracked products are split across packages and backorders, helping deliveries proceed without manual workarounds.
Original PR description
# Problem Unreserve issue preventing users from validating a delivery order with 2-step delivery warehouse configuration. Introduced in the following commit:…
# Problem Unreserve issue preventing users from validating a delivery order with 2-step delivery warehouse configuration. Introduced in the following commit: https://github.com/odoo/odoo/commit/13567aa27250f5798bbe42648eeac82241dbb780 # Steps to reproduce on the runbot: - Activate packages - Edit the warehouse to deliver in 2-steps - Create a product tracked by lot - Create two lots with 5 qty each - Create a sale order with 10 qty and confirm - Check the delivery order and assign: => 2 units to lot1 and create a pkg for it => 1 units to lot1 without pkg => 3 to lot2 without package - Validate the delivery and create a backorder - go to pick backorder and try to validate - Unreserve issue pops up - For further details, check: [#225948](https://github.com/odoo/odoo/issues/225948) # Solution: Conditional subtracting limited to new lines only. Task ID: opw-5086289 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229994 Forward-Port-Of: odoo/odoo#229420
Removing formatting from a selected table cell no longer triggers an error when color formatting was applied to the whole table. This makes the HTML editor more reliable for users editing styled tables.
Original PR description
Problem: When having a `table` with `color` and selecting a cell to remove format, we get a traceback: "Infinite Loop in removeAllColor()." Cause: The color is applied on `table`, but we only process `td` for color removal. As the color remains on `table`, each attempt to remove it keeps reapplying, leading to an infinite loop. Solution: When removing color, also remove it from the `table`. Then apply the color to all child `td`. This ensures `td` colors are later removed automatically if selected, avoiding the loop. Steps to reproduce: 1. Add a `color` property to a `table` and `td`. 2. Select the `td`. 3. Click "remove format" from the toolbar. 4. Observe traceback. opw-5112088 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229878
Credit notes created after a sales down payment now correctly reverse the cost of goods sold. This keeps inventory and accounting entries accurate when customers are refunded after partial invoicing.
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#229156 Forward-Port-Of: odoo/odoo#226809
This fixes an inventory valuation issue where FIFO product costs could be updated from the wrong starting value after a manual revaluation. Product costs now stay aligned with the actual stock valuation, improving inventory and accounting accuracy.
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#228457
Spanish Point of Sale orders now keep the fiscal position selected by the cashier when the order is validated. This prevents incorrect receipt totals where a previous tax amount could appear as change after switching to a no-tax fiscal position.
Original PR description
Currently, when you use a default fiscal position in the pos, if you switch to no fiscal position, upon order validation the tax amount is counted as change. Steps to reproduce: ------------------- *…
Currently, when you use a default fiscal position in the pos, if you switch to no fiscal position, upon order validation the tax amount is counted as change. Steps to reproduce: ------------------- * Install l10n_es_pos, switch to es company * In the config of a shop, use fiscal position, set some as available, one as default * Open shop session * Add a product that has taxes * Switch fiscal position to one that has 0% taxes * There should not be taxes in the cart at this point * Go to pay the order (cash or bank) > Observation: On the receipt the previous tax value is counted as change Why the fix: ------------ The issue happens because of the simplified invoice mechanism present in the ES localization. When you validate an order and that order can apply for simplified invoice, if there is no customer on the order the partner is set with the simplified partner. When setting a partner on the order we update the fiscal position and pricelist. https://github.com/odoo/odoo/blob/1358f93a4c73de5a28cda72ec78769625c863efd/addons/point_of_sale/static/src/app/models/pos_order.js#L929 The fiscal position is updated with the partner's fiscal position or the default one if none on the partner. https://github.com/odoo/odoo/blob/1358f93a4c73de5a28cda72ec78769625c863efd/addons/point_of_sale/static/src/app/models/pos_order.js#L986-L995 Instead of the fallback on the default fiscal position in the case it is not set on a partner we fallback on the order current fiscal position. If it is different than the default one is means that it was changed intentionally and there's a high chance we want to keep it, otherwise it will already be the default fp. opw-5051231 Forward-Port-Of: odoo/odoo#229237
Reconciled bank statement lines that were marked for checking are now automatically marked as checked, preventing them from getting stuck in a pending review state. When automatic checking is disabled, users can now act directly from the dropdown instead of relying on less convenient activity reminders.
Original PR description
When reconciling a statement line that needs to be checked, the statement line will automatically be checked. We do that because the buttons in the dropdown are not accessible by the user anymore, so to avoid the case where a statement line will stay as to check forever, we just set is as checked. Also when auto-check on post was set to false, we created an activity but it wasn't really easy to use for users. Now they can use the button in the drop down. task-5022806 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The bank reconciliation dropdown now includes options to mark statement lines as checked or requiring review. This helps accounting users keep reconciliation status accurate even when lines are reconciled and the dropdown is no longer available.
Original PR description
This commit will add buttons in the dropdown to allow users to set the statement line as checked or to check. Also, the community pr will allow that when reconciled the statement line is automatically set as checked since the dropdown is not there anymore. (Known issue is that in this case the filter is not refreshed) task-5022806
Razorpay payment processing now avoids using two authentication methods at the same time, which could cause payment failures in some mobile checkout flows. This helps customers complete payments more reliably when the provider has both standard credentials and OAuth configured.
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
The Unrealized Currency Gains/Losses report now correctly creates draft adjustment entries even when users customize report grouping. This prevents a misleading "No adjustment needed" error and supports more flexible report configurations.
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
Users who can print and send SEPA direct debit mandates can now generate, send, and reopen the related PDF attachments without needing an extra accounting read-only role. This removes a permission mismatch that could block mandate emails or make generated attachments inaccessible to the users who created them.
Original PR description
Removing the groups restriction from the `mandate_pdf_file` field in model `sdd.mandate` because it was causing issues when using the `sdd.mandate.send` wizard. Any user who has access to the `sdd.mandate` model can use this wizard to print and send the record. During this process, the system generates a PDF and stores it in the `mandate_pdf_file` binary field, linking the resulting attachment to the record. The previous group restriction prevented users who were not part of the `account.group_account_readonly` group from sending the email with the attachment. Even if the email was somehow sent, those users still couldn’t access the attachments they themselves had generated and sent. With this change, any user who is allowed to send and print `sdd.mandate` records will also be able to generate and later access the corresponding attachments. Forward-Port-Of: odoo/enterprise#96119
Point of Sale now saves large local data sets in smaller steps instead of trying to process everything at once. This reduces the chance of failed or slow data saves, improving reliability when handling high volumes of sales data.
Original PR description
When saving large datasets to IndexedDB, all batches were started in parallel. This could cause excessive open transactions, long execution times, and premature transaction aborts due to the timeout. With this commit, batches are now processed one at a time, ensuring that each batch completes before starting the next. This improves stability and prevents transaction overload when handling high volumes of data. opw-5052956 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Updates the spreadsheet component to a newer version with several fixes that make spreadsheets more reliable. Users should see fewer issues with formatting, pivot calculations, sheet renaming, and spreadsheet headers.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/b4764cba65 [REL] 18.3.23 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/b4764cba65 [REL] 18.3.23 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/01de174f41 [FIX] format: wrong internal format conversion [Task: 5126306](https://www.odoo.com/odoo/2328/tasks/5126306) https://github.com/odoo/o-spreadsheet/commit/e53c7f5125 [FIX] Evaluation: remove spread relations [Task: 5105030](https://www.odoo.com/odoo/2328/tasks/5105030) https://github.com/odoo/o-spreadsheet/commit/7a80bf28f1 [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/0b6565e4de [FIX] headers: can add lots of headers [Task: 5092626](https://www.odoo.com/odoo/2328/tasks/5092626) https://github.com/odoo/o-spreadsheet/commit/af28911cdb [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>
Unmarking a completed package in Inventory now correctly clears the related picked status, so delivery orders no longer get stuck waiting and can check availability again. The fix also preserves picked status when users manually enter done quantities after starting from zero stock, avoiding a new workflow regression.
Original PR description
### Issue: To reproduce the bug: 1. Activate `Packages` settings in Inventory: 2. Activate `Move entire packages` on picking type `delivery orders` 3. Create new product `Test move package` 4. Update…
### Issue:
To reproduce the bug:
1. Activate `Packages` settings in Inventory:
2. Activate `Move entire packages` on picking type `delivery orders`
3. Create new product `Test move package`
4. Update quantity in `WH/Stock` with a newly created package and a qty (eg 5)
5. Go to the delivery orders and create a new picking with the created product and a quantity of 5
6. Click on `Mark as Todo`, the picking is set as ready and a package level is created automatically to move the quantity we did put in stock in the package.
7. Mark the checkbox `Done` on the package level (this will mark the move line and the move as picked)
8. Unmark the checkbox `Done` on the package level.
The package level is deleted, as well as the stock move line,
but the stock move still has the checkbox picked that is
marked.
The picking is then in waiting state and we cannot check
availability again.
Currently to be able to check the availability, the picked
check should be undone manually.
### Cause of issue
Currently, in `_compute_picked` in `stock_move`, we don't
update value of move.picked if there is `no move_line_ids`
present which is wrong.
### Fix:
In the fix, picked is set to False when there no
`move_line_ids`
### Issue 2
This fix cause another issue, in which the move loses its `picked` status after manually setting the done quantity when no stock was initially available,
### Cause of issue 2
To be more specific this fix on `_compute_picked`
```diff
- elif move.move_line_ids:
move.picked = False
+ else:
move.picked = False
```
has the following side effect:
- On a confirmed picking, pick a move with a quantity of 0 then change the quantity to 10 the move is unpicked -> undesirable.
After you picked the move, when you set the quantity, you will set `move_line_ids` on your move to match the quantity increase here:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move.py#L2157-L2165
However,`self._set_quantity_done_prepare_vals(qty)` does not return a `stock.move.line` record set but a `Command.create` whose values do not contain any info on the picked value of the move *line*:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move.py#L1497-L1507
The fact that the `move_line_ids` is set on the move to this command.create, flags the `picked` field of the stock move to dirty and adds it to the field to recompute because of the dependency `move_line_ids.state`:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move.py#L208-L209
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/odoo/api.py#L795-L800
THEN, the creation of the move.line happends and since the value of the picked was not set in the command.create, we populate it based on the picked value of the move:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move_line.py#L347-L348
However, at this point since the picked value of the move has been flagged as dirty it is recomputed using the `compute_method` modified in our fix.
And since the move does not have any move line at this stage, it is computed to be picked = False resetting the picked value.
### Fix of Issue 2:
We should set the picked values in the vals here:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move.py#L1497-L1507
opw-4964561
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#222034This fix clears invalid saved device identifiers before sending UK HMRC requests. It helps prevent rejected submissions caused by outdated or corrupted browser data, improving reliability for UK tax reporting users.
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
5 changes
Resolved issues and error corrections
SEPA Direct Debit payments now correctly validate whether a customer's mandate is still active. This prevents valid future-dated mandates from being rejected incorrectly, reducing avoidable payment failures.
Original PR description
The check to ensure that the mandate used in a token payment is still valid had two issues: - It was comparing a date (the mandate's end date) with a datetime. - It was incorrectly rejecting mandates expiring in the future, while it should have done the opposite. Forward-Port-Of: odoo/enterprise#96263 Forward-Port-Of: odoo/enterprise#96143
The Unrealized Currency Gains/Losses report now correctly creates draft adjustment entries even when users customize how report lines are grouped. This prevents an incorrect “No adjustment needed” error and helps accounting teams complete currency revaluation workflows 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
Danish banks were rejecting some ISO20022 payment files because a required clearing instruction was missing. This fix lets businesses configure the needed clearing code so payment files can be accepted while leaving files unchanged when no code 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#95903
This fix ensures Chilean and Peruvian point-of-sale sessions keep their required local compliance fields when multiple devices are synchronized. It prevents those fields from disappearing after real-time notifications, reducing disruption in multi-device PoS setups.
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
UK tax report submissions to HMRC now discard invalid saved device identifiers before sending requests. This prevents repeated rejection of submissions caused by corrupted browser-stored data, improving reliability for affected users.
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
1 change
Resolved issues and error corrections
The partner ledger now includes reconciled entries that do not have a partner when calculating opening balances for a new reporting period. This prevents mismatches between initial balances and totals, giving finance teams more accurate year-to-year reporting.
Original PR description
### Issue: The partner ledger does consider lines without partners when calculating the initial balance. ### Steps to reproduce: - Create an invoice in 2025 - Create an entry in 2025 without partner…
### Issue: The partner ledger does consider lines without partners when calculating the initial balance. ### Steps to reproduce: - Create an invoice in 2025 - Create an entry in 2025 without partner for the same amount - Reconcile the two - Open the partner ledger for 2025, everything is correct - Change the dates to 2026, the amount of the initial balance ignores the entry but not the totals ### Cause: The method `_get_sums_without_partner` is called for the totals, but not for the initial balance. Its purpose is to add the amounts of the lines without partners that were reconciled with lines with a partner. ### Solution: Call `_get_sums_without_partner()` in `_get_initial_balance_values()` add the results before returning the initial balances. As this is the same logic as `_query_partners()` we create a new method. This method needs to be called with the dates of the initial balance in the options. So we create a duplicate of the options and input the new dates options. opw-5068790 Forward-Port-Of: odoo/enterprise#96341 Forward-Port-Of: odoo/enterprise#95881
27 changes
Resolved issues and error corrections
This fix prevents crashes when processing incoming emails with XML attachments for Chilean electronic invoicing. It restores stable email handling so users can continue processing documents without interruption after the first message.
Original PR description
Description of the issue/feature this PR addresses: Fixes [#230014](https://github.com/odoo/odoo/issues/230014). Requires #96467 and #96421 under 19.0 approved and merged for a full fix. Please also forward to saas-18.4 along with #96421 , issue is also present there. (DO NOT FORWARD #96467 TO saas-18.4). Current behavior before PR: Crashes after processing first email with XML due to a savepoint implementation which is not working. Desired behavior after PR is merged: No crash. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix stops the HTML editor from getting stuck when users remove formatting from a colored table cell. It makes formatting cleanup more reliable, preventing an error that could interrupt content editing.
Original PR description
Problem: When having a `table` with `color` and selecting a cell to remove format, we get a traceback: "Infinite Loop in removeAllColor()." Cause: The color is applied on `table`, but we only process `td` for color removal. As the color remains on `table`, each attempt to remove it keeps reapplying, leading to an infinite loop. Solution: When removing color, also remove it from the `table`. Then apply the color to all child `td`. This ensures `td` colors are later removed automatically if selected, avoiding the loop. Steps to reproduce: 1. Add a `color` property to a `table` and `td`. 2. Select the `td`. 3. Click "remove format" from the toolbar. 4. Observe traceback. opw-5112088 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229878
Closing a Picture-in-Picture call window now properly shuts down the related call interface. This prevents errors when users leave or disconnect from calls after using the pop-out window.
Original PR description
**Description of the issue this PR addresses:** When closing a Picture-in-Picture (PiP) window, the app mounted on it was not destroyed. As a result, the `Meeting` component remained mounted even…
**Description of the issue this PR addresses:** When closing a Picture-in-Picture (PiP) window, the app mounted on it was not destroyed. As a result, the `Meeting` component remained mounted even though the call was disconnected, leading to errors. The cleanup of the mounted app only occurred when creating a new PiP window, not when closing one. **Current behavior before PR:** * Closing a PiP window does not destroy the mounted app. * `Meeting` component stays mounted after call disconnect. * Errors occur due to leftover state. **Desired behavior after PR is merged:** * The app mounted on the PiP window is properly destroyed as soon as the PiP window is closed. * No errors occur from a lingering `Meeting` component after closing. **Steps to reproduce:** - Join a call - Open the call in PiP - Disconnect the call either via PiP or from the Discuss app -> traceback OR - Close PiP window, then disconnect the call from the Discuss app -> traceback task-[5112773](https://www.odoo.com/odoo/project/1519/tasks/5112773)
This fix prevents the AI assistant from crashing when users ask for sales results in a pivot view. It improves reliability by checking that report measures are valid before using them, so business users can run AI-powered sales analysis more smoothly.
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**
This fixes an error that prevented users of the Spanish accounting localization from opening the VAT Book report. The report now loads as expected while keeping the related chatter or annotation control hidden where needed.
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
This fix prevents customers from encountering an access error when paying for a self-order from a mobile device after a contact was linked to the order messages. It helps keep the mobile ordering and payment flow reliable for restaurant and point-of-sale users.
Original PR description
Before this commit, if a partner was added to the message_partner_ids, as reading the order triggered the compute function and it changed the uid to the public user due to a call to _check_sudo_commands. This caused an access error when trying to pay an order from the mobile. opw-5128747 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Website header menus now automatically move extra items into the dropdown when header content changes size, preventing items from overflowing off-screen. Editing also behaves more reliably by keeping text selection active when a menu is moved and clearing it when a dropdown closes, avoiding lost typing or floating toolbars.
Original PR description
> [VBAL] Supported payment methods inner content (in the header): You can adjust the height, but this moves the elements on the right outside of the screen (can be fixed by zooming/unzooming on the…
> [VBAL] Supported payment methods inner content (in the header): You can adjust the height, but this moves the elements on the right outside of the screen (can be fixed by zooming/unzooming on the screen but not user friendly): https://drive.google.com/file/d/1J0Vp050kDzx_jnPVfWyHxy6GpQ6GvpBX/view?usp=drive_link ### [FIX] website: re-adapt extra menu on size changes of menu and navbar When the size available or needed for the the top menu changes (for other reasons than a window resize), the menus were not auto-hidden. They were auto-hidden only if the window changes size. If the user is editing the website and increase the width of some element in the header, it may overflow. The overflow disappears only once the user changes the size of the window (which causes some menu to be hidden again). This commit fixes that by replacing the listener for a window `resize` event by a `ResizeObserver` that observe the sizes of the navbar, the menu and the menu's siblings. Steps to reproduce: - Open website builder - Add text in the header until it gets too large - Bug: the last menu is not moved to the dropdown to make more space available task-4367641 ### [FIX] website: move selection with menu when auto-hiding menus When some menu are moved to be hidden in the dropdown, if the selection is inside a moved menu, it was lost. This commit fixes that by opening the dropdown and moving the selection if it is in a menu moved to the dropdown Steps to reproduce: - Open website builder - Add text in the label of a menu until it is moved to the dropdown - Bug: the selection is lost, keep writing does not write anywhere task-4367641 ### [FIX] website: remove selection in dropdown when it closes When the user has the selection inside a dropdown that closes, the selection was kept. If the toolbar was shown on the selection, then used to stays floating where the selection used to be. This commits listen for the closing of the dropdown to remove the selection if it was in the dropdown. Steps to reproduce: - Open website builder - Click on the user's name to open the dropdown - Select some text in the dropdown (the toolbar should appear) - Press "esc" (the dropdown should close) - Bug: the toolbar is left hanging where the selection used to be task-4367641 Forward-Port-Of: odoo/odoo#228135
Inventory valuation settings now require both a journal and valuation account before they can be saved. This prevents scheduled inventory valuation closing from failing when required accounting information is missing.
Original PR description
When the journal is not set in the inventory valuation settings, running the cron ``Stock Account: Inventory Valuation Closing`` results in a traceback. Steps to reproduce the error: - Install…
When the journal is not set in the inventory valuation settings, running the cron ``Stock Account: Inventory Valuation Closing`` results in a traceback. Steps to reproduce the error: - Install ``accountant`` and ``stock`` modules - Go to Settings > Inventory Valuation > Periodicity: Daily > Unset the Journal > Save - Run the cron ``Stock Account: Inventory Valuation Closing`` Traceback: ``` NotNullViolation: null value in column "journal_id" of relation "account_move" violates not-null constraint ``` https://github.com/odoo/odoo/blob/4cd1ad3aa46ad4645fc7b5e530b79d53382de6d5/addons/stock_account/models/res_company.py#L57-L63 This occurs because when the journal is unset, ``journal_id`` becomes null, leading to the above error when the cron runs. Error also occurs when the ``Valuation Account`` is unset. Traceback: ``` CheckViolation: new row for relation "account_move_line" violates check constraint "account_move_line_check_accountable_required_fields" ``` Solution: The ``Journal`` and ``Valuation Account`` fields in the Inventory Valuation settings are now marked as required in the view to ensure that valid values are always set, preventing the cron from failing. sentry-6925934391
Self-ordering now prevents customers from selecting time slots that have already reached their capacity. This avoids overbooking and fixes timezone handling so slot availability is checked against the correct time.
Original PR description
**Steps to reproduce:** - Have a preset that requires time slots - Make the slots_per_interval 1 and the interval_time long enough - Go to the self order, make a purchase and select a slot - Make…
**Steps to reproduce:** - Have a preset that requires time slots - Make the slots_per_interval 1 and the interval_time long enough - Go to the self order, make a purchase and select a slot - Make another purchase - The slot we chose before is still showing and available **Why the fix:** Once the capacity of a time slot has been reached, we should not allow customer to chose it. This behavior occured for 2 reasons: - In the xml file where we declare this select, we did not take the fact that a slot could be full into account, leading to it always being showed. This is now done using the isFull attribute, like it is done in the regular PoS. - This same isFull was not correctly set, as there was a mismatch in slots timezone and format. When we retrieved them from the server, they were in UTC timezone, but the current slot we were working with was in the locale timezone. It is now converted to UTC to check if we already hit max capacity. Before this, selecting a timezone was actually selecting the one that was two hours earlier (for Belgium). With this commit, the values that reached max capacity will not be displayed on the select for the time slots anymore. opw-5092888 Forward-Port-Of: odoo/odoo#228441
Project timesheet forecast date filters now handle local dates consistently instead of shifting them through UTC. This prevents records from being incorrectly included or excluded by one day for users in time zones far from UTC, improving report accuracy.
Original PR description
This commit fixes the timezone issues with the Date filters, in which we were comparing a UTC DateTime value to a local timezone's Date. In certain timezones, this leads to off-by-one errors in the records fetched from the DB, depending on how far ahead or behind UTC that timezone is. Specifically, we remove the UTC conversion within the filter domains. opw-5068870 Forward-Port-Of: odoo/enterprise#94032
Status receipts with QR codes now close the printer connection properly after printing. This prevents the IoT printer from timing out and blocking later status receipt prints, improving reliability for point-of-sale or hardware status checks.
Original PR description
Steps to reproduce: 1. Print a status receipt (that includes a QR code) 2. Wait a few minutes 3. Print another status receipt EXPECTED: - Receipt prints succesfully ACTUAL: - No receipt printed - Error logged by IoT: `ConnectionResetError: [Errno 104] Connection reset by peer` - Any further attempts to print status will fail In odoo/odoo#229731, a QR code was added to the status receipt by using the `escpos` library. However, the code is never closing the connection to the printer, and after some time the connection will timeout and attempting to print the status will throw an exception. We fix this by wrapping the commands in the `EscposIO` context, which will automatically close the printer connection after the context ends. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents errors when users create records or upload files before the system has fully saved the related attachment. File data is now handled consistently, so AI features can read the record context without crashing.
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
The Unrealized Currency Gains/Losses report now correctly creates draft adjustment entries even when users customize how report lines are grouped. This prevents a misleading “No adjustment needed” error and helps finance teams complete currency revaluation workflows 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 update fixes rental checkout behavior so products added from the shop page use the correct default rental dates instead of falling back to a 24-hour period. It also prevents overnight rental periods from being incorrectly combined with other rental durations, reducing pricing and booking errors.
Original PR description
task-5065762
Fixes tax returns that use review-based workflows so they are correctly marked complete when they reach their final state. It also prevents the system from trying to process a payment 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 💥
Point of Sale now shows a clear message if the company country is not set, instead of letting the session open and then fail to load. This helps users understand and fix the setup issue quickly, reducing confusion and support needs.
Original PR description
Before this commit, if the fiscal country was not set on the company, it was still possible to open the PoS session, but the interface would fail to load due to an error in the round_base_lines_tax_details function, which requires the country. With this commit, a clear error message is displayed when the country is not set, preventing the session from opening and avoiding the silent loading failure. opw-5135750 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Purchase order deadlines now stay aligned when planned receipt dates are moved to a specific weekday, helping teams avoid misleading order dates. Manufacturing orders created through reception reporting are also linked back to the related sales order, making sales information easier to track.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents the emoji picker from breaking when users work in non-English languages where translated emoji labels contain special line breaks. It ensures the picker opens reliably in Discuss and avoids confusing empty screens or errors.
Original PR description
**Description of the issue this PR addresses:** ------------------------------------------------ In some non-English translations, emoji strings include `\n`, which breaks JSON parsing in `emoji_data.js`. This causes `emojis.length === 0`, so the empty state is displayed instead of the main emoji picker UI. Some UI logic still executes on missing DOM elements, which triggers errors. **Current behavior before PR:** --------------------------------- - Switch to a non-English language - Open the emoji picker in Discuss - Errors are triggered due to missing DOM elements **Desired behavior after PR is merged:** ----------------------------------------- - Emoji JSON parses correctly - The emoji picker opens without errors in non-English languages - The emoji picker still opens when `emojis.length === 0` **Task:** 4978824 Forward-Port-Of: odoo/odoo#229795 Forward-Port-Of: odoo/odoo#223564
Publishing and sending planning schedules now respects the filters users selected in the planning view, such as a specific role. This prevents unrelated shifts from being included when users change the date period 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#93295
This fix prevents duplicate manufacturing component entries from appearing in the Shop Floor view after a BoM component is removed. It helps manufacturing users continue work without encountering an error, and adds test coverage to keep the issue from returning.
Original PR description
### Steps to reproduce: 1. Create a BoM with two components to be consumed in an operation 2. Create a Manufacturing Order with this BoM and confirm it 3. On the BoM, remove one of the products and save 4. Go to the Shop Floor 5. Select the workcenter used in step 1 6. Got duplicate key in t-foreach ### Before this commit: Stock moves without quality checks, that are linked to a workorder but not linked to a BoM line, are included twice in the view, resulting into a traceback. ### After this commit: Include only once the stock moves, removing duplicates from the view. opw-5029970 Forward-Port-Of: odoo/enterprise#93482
Mobile users now get a cleaner, more usable spreadsheet dashboard control panel. The update fixes dropdown display issues, improves the search and filter layout, and adds an easier way to show or hide navigation.
Original PR description
The control panel of a dashboard (search bar + navigation buttons) was really ugly on mobile. This commit fixes most issues: - the global fitler values dropdown is now correctly rendered - there is now a button to hide/show the navbar - the layout of the share/search bar/date filter is now responsive - the search bar facets are now correctly truncated - the button to open the list of dashboard is now at the same level as the sahre button Task: [4996784](https://www.odoo.com/odoo/2328/tasks/4996784) Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update ensures IoT-connected payment drivers send data in a format the database now accepts. It helps prevent communication failures for affected payment terminals 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
This update prevents UK HMRC submissions from repeatedly failing when a user's browser has stored an invalid device identifier. Odoo now clears the bad saved value so a valid identifier can be used for future requests.
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 fixes a problem where using the browser back button from an invalid form could make Odoo stop responding. Users can now continue interacting with the web client instead of being stuck on a locked screen.
Original PR description
Be in an invalid form view and do browser back. The form view can't be saved as it is invalid, so it can't be left. Before this commit, the body was `pointer-events: none`, i.e. the user couldn't…
Be in an invalid form view and do browser back. The form view can't be saved as it is invalid, so it can't be left. Before this commit, the body was `pointer-events: none`, i.e. the user couldn't interact with the webclient anymore. This is due to a code in webclient.js, which listens to the `ROUTE_CHANGE` event and calls `loadState`. PR [1] prevented the user to interact with the UI during the state loading, as it could lead to weird side-effects. To achieve this, it set the `point-events: none` rule on the body, and reset it once the promise returned by loadState was fullfilled. Unfortunately, in the above mentionned case, loadState returned a promise that was left pending forever, leading to a fully locked webclient. This commit fixes the issue by returning nothing, like we already do in other similar cases in the action service, when the requested action can't be executed. [1] https://github.com/odoo/odoo/pull/205290 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes how inventory value is calculated when there is not enough FIFO stock history and stock temporarily goes negative. The system now uses the last known unit cost instead of the full previous move value, helping keep inventory and accounting valuations accurate.
Original PR description
Before this commit: If there are not enough FIFO in valuations, (i.e. going -ve) the extra value comes from the last known move. But we should not use the whole move value - just the unit value from it. After this commit: The move value is made a unit before multiplying. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The mail app now keeps blur settings adjustable in real time during call previews and active calls. This fixes an issue where users could not change background or edge blur once the blur effect was applied, improving the video call experience.
Original PR description
**Current behavior before PR:** - Before this commit, `applyBlurEffect` returned a partial object with only `stream` and `close` properties, preventing access to properties like `edgeBlur` and `backgroundBlur` needed for real-time adjustments during calls. **Desired behavior after PR is merged:** - This commit returns the `BlurManager` instance from `applyBlurEffect` and adds an `onChange` listener in `CallPreview`, enabling users to adjust blur characteristics in real-time during both preview and active calls. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where users could be blocked from validating a backordered delivery in warehouses using a two-step delivery process with packaged and lot-tracked products. The correction ensures stock reservations are adjusted only where appropriate, reducing interruptions during order fulfillment.
Original PR description
# Problem Unreserve issue preventing users from validating a delivery order with 2-step delivery warehouse configuration. Introduced in the following commit:…
# Problem Unreserve issue preventing users from validating a delivery order with 2-step delivery warehouse configuration. Introduced in the following commit: https://github.com/odoo/odoo/commit/13567aa27250f5798bbe42648eeac82241dbb780 # Steps to reproduce on the runbot: - Activate packages - Edit the warehouse to deliver in 2-steps - Create a product tracked by lot - Create two lots with 5 qty each - Create a sale order with 10 qty and confirm - Check the delivery order and assign: => 2 units to lot1 and create a pkg for it => 1 units to lot1 without pkg => 3 to lot2 without package - Validate the delivery and create a backorder - go to pick backorder and try to validate - Unreserve issue pops up - For further details, check: [#225948](https://github.com/odoo/odoo/issues/225948) # Solution: Conditional subtracting limited to new lines only. Task ID: opw-5086289 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229994 Forward-Port-Of: odoo/odoo#229420
14 changes
Resolved issues and error corrections
Barcode package scanning now follows the same “Allow Extra Products” setting as individual product scans. This prevents unintended products from being added to internal transfers and shows users a warning when package contents are skipped.
Original PR description
**Steps to reproduce:** 1. Install *Inventory* and *Barcode* modules. 2. Disable *Allow Extra Products*: - *Configuration* → *Operation Types* → *Internal Transfer*(unarchive if needed) → *Barcode…
**Steps to reproduce:** 1. Install *Inventory* and *Barcode* modules. 2. Disable *Allow Extra Products*: - *Configuration* → *Operation Types* → *Internal Transfer*(unarchive if needed) → *Barcode App* tab → uncheck *Allow Extra Products*. 3. In *Settings*, enable *Packages* and *Storage Locations*. 4. Create two storable products, e.g.: - Product A → put 10 units in Package PKG-A. - Product B → put 15 units in Package PKG-B. 5. Create an *Internal Transfer*: - Add Product A manually. - From the column dropdown, enable *View Buttons*. click on `view` on line and create a stock move. 6. Open the *Barcode* app → *Operations* → *Internal Transfer* → select the transfer created. 7. From the gear icon, in *Enter Barcode*, input PKG-B (the package name of Product B) and click *Apply*. **Observed behavior:** - The products inside the scanned package are added to the transfer, even though *Allow Extra Products* is disabled. - Regular (non-packaged) products are correctly blocked. **Root cause:** - The check for extra products was only applied when scanning individual products. - When scanning a package, its contents bypassed the restriction and created new lines for each product. **Solution:** - Apply the *Allow Extra Products* restriction also when processing package contents in the barcode picking model. - Skip the creation of lines for disallowed products and notify the user with a warning message listing the skipped products. opw-4863621
UK tax report submissions now check the saved HMRC device identifier before sending it. If the stored value is invalid, Odoo clears it so requests are not rejected by HMRC for using a malformed device ID.
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#87335
This fixes an inventory issue where undoing a completed package move could leave the delivery marked as picked, blocking availability checks and requiring manual correction. It also preserves the picked status when users manually enter done quantities after stock was initially unavailable, keeping warehouse workflows consistent.
Original PR description
### Issue: To reproduce the bug: 1. Activate `Packages` settings in Inventory: 2. Activate `Move entire packages` on picking type `delivery orders` 3. Create new product `Test move package` 4. Update…
### Issue:
To reproduce the bug:
1. Activate `Packages` settings in Inventory:
2. Activate `Move entire packages` on picking type `delivery orders`
3. Create new product `Test move package`
4. Update quantity in `WH/Stock` with a newly created package and a qty (eg 5)
5. Go to the delivery orders and create a new picking with the created product and a quantity of 5
6. Click on `Mark as Todo`, the picking is set as ready and a package level is created automatically to move the quantity we did put in stock in the package.
7. Mark the checkbox `Done` on the package level (this will mark the move line and the move as picked)
8. Unmark the checkbox `Done` on the package level.
The package level is deleted, as well as the stock move line,
but the stock move still has the checkbox picked that is
marked.
The picking is then in waiting state and we cannot check
availability again.
Currently to be able to check the availability, the picked
check should be undone manually.
### Cause of issue
Currently, in `_compute_picked` in `stock_move`, we don't
update value of move.picked if there is `no move_line_ids`
present which is wrong.
### Fix:
In the fix, picked is set to False when there no
`move_line_ids`
### Issue 2
This fix cause another issue, in which the move loses its `picked` status after manually setting the done quantity when no stock was initially available,
### Cause of issue 2
To be more specific this fix on `_compute_picked`
```diff
- elif move.move_line_ids:
move.picked = False
+ else:
move.picked = False
```
has the following side effect:
- On a confirmed picking, pick a move with a quantity of 0 then change the quantity to 10 the move is unpicked -> undesirable.
After you picked the move, when you set the quantity, you will set `move_line_ids` on your move to match the quantity increase here:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move.py#L2157-L2165
However,`self._set_quantity_done_prepare_vals(qty)` does not return a `stock.move.line` record set but a `Command.create` whose values do not contain any info on the picked value of the move *line*:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move.py#L1497-L1507
The fact that the `move_line_ids` is set on the move to this command.create, flags the `picked` field of the stock move to dirty and adds it to the field to recompute because of the dependency `move_line_ids.state`:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move.py#L208-L209
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/odoo/api.py#L795-L800
THEN, the creation of the move.line happends and since the value of the picked was not set in the command.create, we populate it based on the picked value of the move:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move_line.py#L347-L348
However, at this point since the picked value of the move has been flagged as dirty it is recomputed using the `compute_method` modified in our fix.
And since the move does not have any move line at this stage, it is computed to be picked = False resetting the picked value.
### Fix of Issue 2:
We should set the picked values in the vals here:
https://github.com/odoo/odoo/blob/57c0ce5f0af9b46c037759d85205bc3e88890af7/addons/stock/models/stock_move.py#L1497-L1507
opw-4964561
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prCustomers who are required to sign in before using the online store are now sent back to their cart, shop, or product page after logging in. This prevents interrupted appointment or purchase flows and helps reduce checkout abandonment.
Original PR description
**Steps to reproduce:** - Install eCommerce and Appointment - Set `Ecommerce Access` to `Logged in users` in Settings > Website - Go to the website without logging in - Create an appointment - Proceed to make the payment - You will get redirected to the sign-in page due to the setting - After logging-in the system doesn't redirect back to the checkout form **Issue:** When the user is not logged and the setting is applied, the user is directly sent to the login page without further redirection. **Fix:** Added redirect param to the original url target. opw-4965735 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Unrealized Currency Gains/Losses report now creates adjustment entries correctly even when users customize how report lines are grouped. This prevents an incorrect “No adjustment needed” message and helps accounting teams complete currency revaluation workflows 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
Duplicated CRM leads without an assigned salesperson now remain eligible for rule-based assignment. This prevents sales teams from missing duplicated leads that should be automatically assigned based on their 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#227387This fix makes Indian time off calculations more accurate when sandwich leave spans multiple non-working days and when employees request half-day leave. It helps payroll and HR records reflect the correct leave duration instead of over- or under-counting days.
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
This fix ensures separator lines in the email marketing showcase template remain visible when emails are sent. It improves the visual consistency of marketing emails, especially on desktop layouts, and corrects styling that could previously be lost.
Original PR description
Problem: When adding the `s_showcase` template in email marketing and saving, the separator is not properly rendered in the received email. Cause: The separator is implemented as an empty `<div>` with `display: inline-block` and `height: 100%`. In emails, this can collapse to 0px, making the separator invisible. Additionally, `border-<position>-color` was not applied correctly in some cases. Solution: - Lock the computed height of empty separator elements so they remain visible. - Restrict visibility of separators to desktop screen sizes where columns are stacked horizontally. - Fix rendering of `border-<position>-color`. Steps to reproduce: 1. Open a new email marketing. 2. Add the `s_showcase` template. 3. Test-send the email. 4. Observe that the separator is not visible. opw-5077992 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The website blog now keeps selected tag filters when users add, change, or clear archive date filters. It also corrects a small visual alignment issue so dates, tags, and post previews line up properly in list card layouts.
Original PR description
This PR addresses the following issues: **Issue 1: Date Misalignment** **Steps to Reproduce:** 1. Navigate to website → Blog Page → Edit. 2. Change the layout from Grid to List. 3. Toggle the Cards…
This PR addresses the following issues:
**Issue 1: Date Misalignment**
**Steps to Reproduce:**
1. Navigate to website → Blog Page → Edit.
2. Change the layout from Grid to List.
3. Toggle the Cards button on.
4. The date and tags will appear slightly misaligned.
**Solution:**
Adding `#{` code in the `t-attf-class` attribute will align the date with the blog post content and tags.
**Expected Behavior:**
The date should align with the blog post content and tags preview.
**Issue 2: Some Tag Filters Getting Removed**
**Steps to Reproduce:**
1. Add a date filter from the sidebar of the blog.
2. Remove this filter by clicking the X button.
3. If multiple tags are present in the filter section, only the first tag remains while the rest are removed when the date filter is added or removed.
**Solution:**
Sending a POST request whenever the date filter is selected or removed. To achieve this, we introduced the `post_link` class to the `<select>` and `<a>` elements. When a date option is chosen, the click event triggers the `_onClickPost` handler
function, which extracts the URL from the `value` attribute of the `<option>` tag.
**Expected Behavior:**
All previously added tags should remain after adding or removing the date filter.
**Issue 3: All Tag Filters Getting Removed**
**Steps to Reproduce:**
1. Navigate to website → Blog Page → Turn On the Sidebar.
2. Select any tag from the tags section in the sidebar.
3. Ensure no blog is selected.
4. Select a date from the archives in the sidebar.
5. Change the date to '-- All Dates' in the archives dropdown.
6. All tags in the filter are removed along with the date.
**Solution:**
Removing the condition for navigation based on whether a blog is present or not will ensure tags remain in the filter section after selecting the '-- All Dates' option.
**Expected Behavior:**
Tags present in the filter section should remain after selecting the '-- All Dates' option.
task-3937884
Forward-Port-Of: odoo/odoo#225845This update brings the spreadsheet component up to its latest stable version and fixes several user-facing issues. Users should see more reliable formatting, header handling, calculation behavior, and sheet renaming without losing focus.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/67a1b4af88 [REL] 18.0.46 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/67a1b4af88 [REL] 18.0.46 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/0aa0e39c13 [FIX] format: wrong internal format conversion [Task: 5126306](https://www.odoo.com/odoo/2328/tasks/5126306) https://github.com/odoo/o-spreadsheet/commit/3b48d98c00 [FIX] Evaluation: remove spread relations [Task: 5105030](https://www.odoo.com/odoo/2328/tasks/5105030) https://github.com/odoo/o-spreadsheet/commit/141465db49 [FIX] headers: can add lots of headers [Task: 5092626](https://www.odoo.com/odoo/2328/tasks/5092626) https://github.com/odoo/o-spreadsheet/commit/d958b25af8 [FIX] spreadsheet: prevent sheet name edit from losing focus [Task: 5109129](https://www.odoo.com/odoo/2328/tasks/5109129) 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>
Vendor credit notes created through purchase order matching now show refund quantities with the correct sign. This prevents confusing negative quantities and helps keep purchase billing and refunds aligned with received goods.
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. *** Backport of https://github.com/odoo/odoo/commit/8bcc501a47bbd9df3f7d2a7d2bacd63b0127a087 *** task-4975200
This fixes an inventory workflow issue where a stock move could remain marked as picked after a package was unmarked as done and its related move lines were removed. Businesses get more accurate warehouse status tracking and avoid misleading picked quantities during package operations.
Original PR description
To reproduce: - Use a picking type to 'move entire packs' - Have a qty in stock in a package - Create a picking to move the package and confirm - Mark the package level as done - Unmark the package level as done When the package level is marked as done, the related stock move line will be marked as picked, which will in turn set the stock move as picked. When the done checkbox is removed from the package level, the stock move line will be deleted, and said package level will be deleted, but the move did remain as picked. OPW-4964561 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
Pasted tables from tools like Google Docs now keep the expected formatting and structure in Odoo's HTML editor. This prevents tables from appearing incorrectly or with empty cells, making copied content more reliable for users.
Original PR description
### Purpose of this PR: - Ensure that pasted table elements get the standard classes: `table, table-bordered, and o_table.` - When content is pasted from other source (e.g., Google Docs inside iframe), attribute nodes coming from another JavaScript context do not match the `Attr` prototype of the current context. Use `item.nodeType === Node.ATTRIBUTE_NODE` instead of `instanceof Attr` to detect attribute nodes. - Insert a base container into empty `<td>` elements when pasting tables from external sources. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Public-facing mail page text now uses the proper translation system instead of always showing the original source language. This helps visitors see page components in their selected language, improving localization consistency.
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#230129
10 changes
Resolved issues and error corrections
Invoices can no longer be set up with SEPA direct debit payments when the related mandate is closed. This prevents businesses from accidentally collecting payments using inactive customer authorizations.
Original PR description
**The issue:** It's currently possible to create select SEPA payment for an invoice when the mandate is "closed" instead of "revoked". **Cause:** The search for usable mandates, is not taking into consideration the "closed" state and looking for non draft/revoked. **Fix:** Changed the query to look specifically for "active" mandate. opw-5048748
UPS shipping rates can now be checked during express checkout using only the limited address details available at that stage. This prevents shoppers from being blocked by unnecessary street and phone requirements, making checkout smoother.
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)
Public mail-related pages now correctly show translated text instead of falling back to the original source language. This improves the experience for visitors and portal users who use Odoo 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
Changing the scheduled date for one stock move no longer unintentionally updates other moves on the same receipt. This helps warehouse users keep individual item schedules accurate and avoids accidental rescheduling when saving a receipt.
Original PR description
Issue Before This Commit: ---------------------------------- Updating the scheduled date of a single move would unintentionally update the dates of all other moves, particularly if the new date was…
Issue Before This Commit: ---------------------------------- Updating the scheduled date of a single move would unintentionally update the dates of all other moves, particularly if the new date was earlier than the picking’s scheduled date. Steps to produce: ---------------------------------- - Install the `stock_delivery` module. - Create a receipt with two moves. - Change the scheduled date of one move to a value earlier than the picking date. - Save the receipt, the date of both moves will be updated. Cause of the issue: ---------------------------------- Changing a move’s date also updated the picking’s scheduled date. When the picking was saved, its inverse method propagated the new date to all associated moves. Fix: ---------------------------------- The override of the `onchange` method to prevent the picking’s `scheduled_date` from being updated when a move's date is modified, as it is recomputed when the form view is saved. This ensures only the intended move date is changed, preventing unintended side effects and giving users more precise control over scheduling. Task ID: [4653516](https://www.odoo.com/odoo/project/966/tasks/4653516)
The spreadsheet component has been updated to the latest version for Odoo 17. This fixes an issue that could limit users when adding many headers, making spreadsheet work more reliable for larger or more detailed sheets.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/c8f112036d [REL] 17.0.75 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/22c5e4325f [FIX] headers: can add lots of headers [Task: 5092626](https://www.odoo.com/odoo/2328/tasks/5092626) 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>
Confirmed sales orders now keep coupon point balances accurate when a customer switches from one reward to another. This prevents customers from being charged the wrong number of loyalty points and keeps loyalty balances reliable.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10…
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10 points; 5. use coupon code on a confirmed order; 6. select 10% discount reward; 7. change to a 50% discount reward; 8. check coupon point total. Issue ----- Even though the 5 point reward was used, only 4 out of 10 points remain. Cause ----- When updating the reward line of a confirmed order, it keeps track of point cost changes before & after a write. Its purpose is to restore back the point difference on the coupon record. The issue is that while point changes are stored, coupon changes are not. When updating reward lines, `_reset_loyalty` is used, which removes the `coupon_id` from the lines. As a consequence, attempting to restore the point difference on `line.coupon_id` after an update, it writes to an empty record. Solution -------- Store both coupons & their used points before write. After write, restore the previous points to the previous coupon, and subtract the current point cost from the current coupon. This way, any combination of coupon/point changes should have the points updated as expected. opw-4910922
The barcode app no longer crashes when scanning a picking order for a kit product variant that has its own packaging. This keeps warehouse scanning flows working reliably for businesses using product variants and packaging.
Original PR description
In the barcode application, scanning a picking order containing a kit product variant with packaging will raise a Traceback. * Steps to reproduce: 1. Enable packagings on inventory configuration. 2.…
In the barcode application, scanning a picking order containing a kit product variant with packaging will raise a Traceback. * Steps to reproduce: 1. Enable packagings on inventory configuration. 2. Create a product, that as a least 2 variants. 3. Add a packaging to one of the variants. 4. Create a BoM for created product (kit type). 5. Create a picking order for the variant with packaging. 6. Print the picking operation to scan the code through barcode. 7. Go to barcode and try to scan it, this will trigger the traceback. * Cause of the issue: Scaning a barcode will call get_barcode_data during this call it will retrieve the information about the picking order and call _get_stock_barcode_data: https://github.com/odoo/enterprise/blob/f2dd6326c2084ed467c3e4c3e9d931f41309ad79/stock_barcode/controllers/stock_barcode.py#L91 _get_stock_barcode_data will obtain the packaging methode for the products. https://github.com/odoo/enterprise/blob/f2dd6326c2084ed467c3e4c3e9d931f41309ad79/stock_barcode_mrp/models/stock_picking.py#L13-L16 since in our use case the product has variant the packaging information is not inside product_tmpl_id.packaging_ids and thereof it will not retrieve the packaging information. * Fix We don't need to use product_tmpl_id.packaging_ids because of its compute and set methods (and the fact that the product_variant_ids field is required), the product_tmpl_id.packaging_ids will always be included in the product_tmpl_id.product_variant_ids.packaging_ids: https://github.com/odoo/odoo/blob/0f4fc2b1ba65eb9fab3faa24deb2849caf7b9057/addons/product/models/product_template.py#L409-L419 our fix will allow for packaging in the variant to be considered when there is more than only one variant. opw-4852875 opw-4969241 opw-4952818
Point of Sale now reads quantity information included in GS1 barcodes when products are scanned. This helps cashiers add the correct amount automatically, reducing manual adjustments and checkout errors.
Original PR description
Before this commit, the quantity encoded in a GS1 barcode was ignored when scanning. After this commit, the product will be added with the correct quantity extracted from the GS1 barcode. opw-5126522 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes how certain Spanish service sales taxes are classified in VAT reporting so they are treated as not subject to VAT instead of exports. It also corrects the refund sign for the related tax, helping businesses produce more accurate Modelo 303 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
Emails sent from Odoo could fail when they included attached email files containing accented or other non-English characters. This fix ensures those attachments are handled correctly, improving reliability for users who exchange multilingual email content.
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