Tuesday, August 11, 2026
38 changes · saas-19.4
Resolved issues and error corrections
The payroll off-cycle action now works when users select several payslips at once from the list view. This prevents an error screen and lets payroll teams process multiple payslips more smoothly.
Original PR description
Steps to reproduce: - Open payslip list view - Select multiple payslips - Select "Send to Off-cycle" action Issue: A traceback occurs with ValueError: Expected singleton when the action is executed on multiple payslips. Reason: - 'action_move_to_off_cycle()' assumes a singleton and directly accesses self.version_id.id - When multiple payslips are selected from list view then self contains several payslips and self.version_id returns multiple versions, causing the singleton error. Solution: - Iterate over each payslip individually when processing the off-cycle action and use the corresponding version for each record, allowing the action to work correctly in multi-record mode task-6320059
Users who have both Partner Commissions access and Purchase user rights can now create and view purchase orders as expected. The fix keeps normal purchasing access available for mixed-role users while preserving commission-only restrictions.
Original PR description
## Current behavior: The user Partner Commissions access rights as All Documents or Own Documents and Purchase access rights as User. With this configuration, the user is unable to create new…
## Current behavior: The user Partner Commissions access rights as All Documents or Own Documents and Purchase access rights as User. With this configuration, the user is unable to create new Purchase Orders, and existing Purchase Orders are also not visible in the Purchase module. ## Expected behavior: The expected behavior is that the user should be able to create and view Purchase Orders with these access rights. Additionally, clarification is required regarding the purpose of the new Partner Commissions access group. ## Steps to reproduce: - Go to user and assign Partner Commission rights as All or own document. - On Purchase, select group as User. ## Cause of the issue: partner_commission adds commission-specific purchase order record rules, but purchase users have no matching purchase-order rule in that module. For mixed-role users, the commission rule ends up restricting standard purchase orders as well. ## Fix: Apply the module's explicit all-purchase rule to purchase users so mixed users keep base procurement access while commission-only users remain restricted by the commission rules. opw-6366074 Forward-Port-Of: odoo/enterprise#126003
Large accounting reports could get stuck in a browser rendering loop, especially when moving from Profit and Loss to General Ledger with multiple companies or localizations. This fix changes how report line status information is prepared so the report opens reliably even with many lines.
Original PR description
## Description Opening an accounting report containing many lines can trigger Owl's maximum render iteration error, leading to an infinite rendering loop. This could notably occur when navigating…
## Description Opening an accounting report containing many lines can trigger Owl's maximum render iteration error, leading to an infinite rendering loop. This could notably occur when navigating from a Profit and Loss report to a General Ledger in multi-company setting or with a few l10n. `AccountReportLineName` used `asyncComputed` to create the audit status record, although its computation contained no asynchronous operation. Each line therefore published its result after the initial render and scheduled another render. With enough lines, the report exceeded Owl's limit of 1000 render iterations before the DOM could be updated. This commit uses `computed` instead, allowing the status record to be calculated and cached synchronously. Keep the record construction untracked so its internal reactive state does not become a dependency. opw-6432000 ## Steps to reproduce - Go on a runbot instance saas-19.4, enterprise build, select all companies, make sure some localications are installed (since we need quite a few lines). - P&L, select date range the whole year 2026, unfold the Expense account, kebab button -> General Ledger. If you have enough lines, you will enter an infinite loop in the front-end. Not always obvious to reproduce it. The test provided is deterministic in term of reproduction.
Bank statement matching now uses an existing optimized database index when looking for unreconciled accounting entries. This should improve performance for related accounting workflows without changing user-facing behavior.
Original PR description
We have a very efficient index for searching unreconciled lines on known accounts. Let's use it.
```python
_unreconciled_index = models.Index("(account_id, partner_id) WHERE reconciled IS NOT TRUE")
```
Before this change, the query planner didn't recognize the index because of its definition being slightly different wrt the null values.
Forward-Port-Of: odoo/enterprise#127093This fix prevents occasional errors when an UrbanPiper delivery order acceptance is processed twice at nearly the same time. It makes the preparation-ticket marking step safely ignore already processed orders, reducing intermittent failures in point-of-sale order flows.
Original PR description
mark_urbanpiper_prep_order_as_printed() raised ValueError when the 'urbanpiper_printed' flag was already set, to stop the same order from printing its preparation ticket twice…
mark_urbanpiper_prep_order_as_printed() raised ValueError when the 'urbanpiper_printed' flag was already set, to stop the same order from printing its preparation ticket twice (https://github.com/odoo/enterprise/pull/103894, Task-5353283). Accepting an UrbanPiper order fires this RPC from two places for the same order: synchronously from TicketScreen, and again via the DELIVERY_ORDER_COUNT bus notification the accept flow itself broadcasts. Under load, both requests race for the row lock; Odoo's retrying() replays the loser on lock contention, and by the time it replays the winner has already committed, so the loser hits the already-printed branch and raises. The raise is an unhandled ValueError, so it surfaces as a 500 and fails any tour that accepts an order (test_frontend.py, test_order_receipt.py), intermittently and CI-timing-dependent only. The only caller (pos_store.js: _sendDeliveryOrderForPreparation) already wraps the RPC in try/catch and treats a caught exception exactly like a falsy return value: either way it just skips sending the ticket to preparation. No other code reads or writes urbanpiper_printed, and no webhook path calls this method, so returning False is behaviorally identical for every real caller and safe to make the default. This also removes the mark_urbanpiper_prep_order_as_printed_patch monkeypatch added alongside the original raise in test_01_order_flow: it existed solely to swallow this exact ValueError for that one tour, which is no longer needed now that the method itself is idempotent. runbot error: 941514 Forward-Port-Of: odoo/enterprise#127467 Forward-Port-Of: odoo/enterprise#125840
A restaurant appointment test now properly closes an edited form before finishing. This prevents random test failures and helps keep future updates to the restaurant appointment feature stable.
Original PR description
The `test_appointment_kanban_view` tour test was randomly failing with the following error: `AssertionError: Tour finished with a dirty form view being open.` This occurred because the tour ended right after clearing a date field on a form, leaving the form in a "dirty" (unsaved changes) state. This commit fixes the issue by adding a final step to the tour that clicks the cancel/discard button. Forward-Port-Of: odoo/enterprise#109633
Fixed an issue where opening Bank Matching from a return could fail when no bank journal was selected. This prevents an error screen and lets users continue reconciliation from the working file flow.
Original PR description
When accessing the reconciliation widget from the working file check, there is no journal to be selected, hence no journal in the context. This was tracebacking since we were trying to send a read query to the server with an undefined id. To reproduce: * create a bank statement line without reconciling * set up the return on the misc journal * open the return, then "Bank Matching" Forward-Port-Of: odoo/enterprise#127421
This update fixes several issues in the Timesheets Assistant so users see a clearer default timeline, avoid duplicate loading, and no longer have dismissed suggestions reappear. It also improves visual selection behavior and better recognizes Discord browser activity, making assisted timesheet creation more trustworthy and easier to use.
Original PR description
## [FIX] timesheet_grid: remove duplicate rpc call Before this commit, the `loadTimesheets` method is called 2 times in a row, that method does a rpc call to load the existing timesheets and so, it…
## [FIX] timesheet_grid: remove duplicate rpc call Before this commit, the `loadTimesheets` method is called 2 times in a row, that method does a rpc call to load the existing timesheets and so, it is not needed to call it 2 times since the rpc will return the exact same result. This commit removes the rpc call when we compute the suggestions to only load the timesheets when we load all the data. ## [FIX] timesheet_grid: show chronological view instead of project view Before this commit, the `by project` view were loaded first in the timesheet assistant action, to group the suggestion by project, the problem is at the beginning the view will not really show a perfect matching and so the user could think the feature does not work and he will not understand how to correctly match the suggestions shown in the view. This commit changes the view loaded by default in Timesheets Assistant to first show the chronological view, that view is more logical for the current user to rethink what he did in the past to correctly map the events to a project and a task when he generates his timesheets thanks to those events. The by project view is still useful afterwards when the system has learned the choices made by the current user. ## [FIX] timesheet_grid: ensure events are consumed forever Before this commit, the suggestions removed by the current user comes back when he changes the date and come back to the day he removes the suggestions. The reason is because a shallow copy of events consumed is made and that copy alters the duration of the initial object. This commit avoids copying the consumed events object to make sure the initial object is not altered when processing the events to remove them if they are removed before by the user. ### Steps to reproduce the issue: 1. install timesheet_grid and Activity watch, makes sure Activity watch collects some activities on your computer. 2. Go to Assistant menu in timesheets app. 3. Remove some suggestions displayed in the right panel. 4. Go to next date. 5. Come back to previous date. ### Expected Behavior: The suggestions removed should not appear again. ### Actual Behavior: The suggestions removed come back in the view. ## [FIX] timesheet_grid: fix flicker when suggestion selected Before this commit, when the user selects a suggestion in timesheet assistant, there is a small flicker appears because the height of the row grows because of the border added to highlight the suggestion selected. This commit reviews a bit the style to make sure the border bottom in the previous element is removed if the element is not selected or if the 2 consecutives suggestions are selected. ## [FIX] timesheet_grid: fix discord rules to handle discord in web Before this commit, when the user uses discord in its browser instead of the app on his computer, the discord rules don't catch the activity watch events because the tab title is different than the windows name in the app. This commit adapts the regex of Discord rules to handle the both use cases. task-[6385639](https://www.odoo.com/odoo/project.task/6385639) Forward-Port-Of: odoo/enterprise#125599 Forward-Port-Of: odoo/enterprise#124855
The “My Team” default filter now appears only on the Time Off Overview Gantt page where it is intended. This prevents employees and managers from seeing an unexpected default filter on other HR Gantt views, reducing confusion and keeping each view’s results accurate.
Original PR description
A default filter would sometimes appear on all the HR Gantt views. That is not supposed to happen as this filter is only supposed to appear on the Time Off > Overview gantt page (`hr.leave.report.calendar`) This was because the SearchModel that was supposed to be applied only for `hr.leave.report.calendar` was used for the `hrHolidaysGanttView` and `time_off_report_calendar`. This PR makes it so that the SearchModel is only applied to the required gantt view and not all of them. task-5502544
Fixed an error that could occur when users turned the No Follow-Up option on or off for invoices paid in multiple installments. This prevents server crashes in the Follow-Up Report when some installments are already settled, helping accounting teams manage customer follow-ups reliably.
Original PR description
Steps to Reproduce: 1. Configure Payment Term (Accounting > Configuration > Payment Terms) containing multiple installments. 2. Create a Customer Invoice with this Payment Term. 3. Post the invoice.…
Steps to Reproduce:
1. Configure Payment Term (Accounting > Configuration > Payment Terms) containing multiple installments.
2. Create a Customer Invoice with this Payment Term.
3. Post the invoice.
4. Register a payment and fully reconcile one of the installments.
5. Navigate to the customer's Follow-Up Report (Accounting > Reporting > Partner Ledger > Report: Follow-Up Report).
6. Navigate to remaining open installment/account move line for that invoice.
7. Turn On or Off the No Follow-Up toggle for the invoice.
An error occurs when enabling or disabling the No Follow-Up toggle.
Issue:
Enabling or disabling the No Follow-Up toggle on a remaining open installment in the Follow-Up Report raises a server error when the invoice contains multiple installments and one or more installments are already fully reconciled.
Root Cause:
The Follow-Up Report only loads and sends non-fully reconciled account move lines from the JavaScript side through all_line_ids. In action_toggle_no_followup(), when the selected line belongs to an invoice, the code retrieves all receivable/payable lines of the invoice, including fully reconciled installments:
```
move.line_ids.filtered(
lambda line: line.account_type in ('asset_receivable', 'liability_payable'),
)
```
The method then attempts to map every receivable/payable line to a report line ID using aml_id_to_line_id. Since fully reconciled installments are not present in all_line_ids, they are missing from the mapping dictionary, causing a KeyError when accessing:
`aml_id_to_line_id[line.id]
`
Fix:
Restricted the impacted lines to those present in the report by adding a check that the account move line exists in aml_id_to_line_id before performing the mapping:
```
lambda line: line.account_type in ('asset_receivable', 'liability_payable')
and line.id in aml_id_to_line_id
```
opw-6245448
Forward-Port-Of: odoo/enterprise#126785
Forward-Port-Of: odoo/enterprise#126156Planning reports now include shifts for employees with flexible schedules even when no specific start and end hours are set. This keeps the Schedule views and Planning / Timesheets Analysis report consistent, giving managers more reliable planned time data.
Original PR description
## Behavior Before the PR When an employee did not have explicit `hours_from` and `hours_to` values defined, their shift was in the **Schedule by X** pivot view but was not included in the **Planning…
## Behavior Before the PR When an employee did not have explicit `hours_from` and `hours_to` values defined, their shift was in the **Schedule by X** pivot view but was not included in the **Planning / Timesheets Analysis** report. ## Steps to Reproduce 1. Create an employee with a Flexible Working Schedule in the Employee form, or configure working hours where both `Hour from` and `Hour to` are left unset. 2. Add a shift for this employee linked to a project and a task. 3. Publish the shift. 4. Navigate to **Planning → Schedule → By Project**, switch to the pivot view, and observe that the shift created in step 2 appears and is counted. 5. Navigate to **Planning → Reporting → Planning / Timesheets Analysis**, switch to the pivot view, and observe that the same shift does not appear. ## Behavior After the PR When an employee does not have explicit `hours_from` and `hours_to` values, their shift is now considered valid in both the **Schedule by X** views and the **Planning / Timesheets Analysis** report. ## Additional Notes - In earlier versions of Odoo, the `Work From` and `Work To` fields were mandatory. With a change to flexible working schedules and the option to define only the total number of hours per day, these fields may now be left empty. This change exposed the underlying issue addressed by this fix. task-[5969788](https://www.odoo.com/odoo/project/4105/tasks/5969788) Forward-Port-Of: odoo/enterprise#110606
This fixes an internal automated test so it correctly accounts for archived call activity records before removing activity types. The change helps prevent false test failures and improves confidence in the mail activity and VoIP-related test suite without changing customer-facing behavior.
Original PR description
test_create_call_activity attempts to delete any 'phonecall' activity types. This is so it can test the functionality of create_call_activity when there is no existing 'phonecall' activity type. However, demo data inside voip creates an archived activity with the type mail_activity_data_call. https://github.com/odoo/enterprise/blob/cc4456ac16aeee59830db08505a27877e149f3a7/voip/demo/voip_call.xml#L4-L13 When searching for phonecall_activities the test only gets active activities. We need to alter this to fetch all. Otherwise, the test will then try to delete the activity type when there are still records using the type. opw-6443475 runbot-242850 Forward-Port-Of: odoo/enterprise#126540
This commit fixes the verification JSON. For OSS taxes no_sujeto_loc and no_sujeto, CuotaTotal and ImporteTotal must Only include the base amount, not the tax amount. See the chatter in the task for AEAT guidelines. Also removed the validation error blocking no_sujeto_loc taxes with a non-zero amount, since OSS taxes legitimately have one in Odoo accounting (e.g. 22% IT VAT) even though it is excluded from the Veri*Factu json. upgrade :- https://github.com/odoo/upgrade/pull/10799 tas
Original PR description
This commit fixes the verification JSON. For OSS taxes no_sujeto_loc and no_sujeto, CuotaTotal and ImporteTotal must Only include the base amount, not the tax amount. See the chatter in the task for AEAT guidelines. Also removed the validation error blocking no_sujeto_loc taxes with a non-zero amount, since OSS taxes legitimately have one in Odoo accounting (e.g. 22% IT VAT) even though it is excluded from the Veri*Factu json. upgrade :- https://github.com/odoo/upgrade/pull/10799 task-5411766 Forward-Port-Of: odoo/odoo#281384 Forward-Port-Of: odoo/odoo#272068
When unsetting the Available in Self Order field on a product, a traceback occurs. Steps to reproduce the error: - Install ``pos_self_order`` module with demo data - Open any Product that is available in pos > In Point of sale Tab, Unset Available in Self Order field > Save Traceback: ```py ValueError: Expected singleton: pos.config() ``` When the ``self_order_available`` field is updated, ``write()`` calls ``_send_availability_status()`` at [1]. Previously, this method only pr
Original PR description
When unsetting the Available in Self Order field on a product, a traceback occurs. Steps to reproduce the error: - Install ``pos_self_order`` module with demo data - Open any Product that is…
When unsetting the Available in Self Order field on a product, a traceback occurs. Steps to reproduce the error: - Install ``pos_self_order`` module with demo data - Open any Product that is available in pos > In Point of sale Tab, Unset Available in Self Order field > Save Traceback: ```py ValueError: Expected singleton: pos.config() ``` When the ``self_order_available`` field is updated, ``write()`` calls ``_send_availability_status()`` at [1]. Previously, this method only processed POS configurations with a ``current_session_id``, but that condition was removed in commit https://github.com/odoo/odoo/commit/22e075987cf05c5891120b86694b5312936d4def at [2]. As a result, ``_send_availability_status()`` may now call ``load_product_from_pos()`` with a POS configuration that has no current session. This eventually calls ``_get_available_pricelists()`` on an empty ``pos.config`` recordset, triggering the singleton error. [1]-https://github.com/odoo/odoo/blob/8e7732045bd465cd1a763329e4e8448de45960ad/addons/pos_self_order/models/product_product.py#L118-L120 [2]-https://github.com/odoo/odoo/blob/8e7732045bd465cd1a763329e4e8448de45960ad/addons/pos_self_order/models/product_product.py#L126 sentry-7614402869 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Steps: - Install l10n_co module. - Set `CO company` on user. - Go to address page on portal address. - Set `Company Name`, `ID Type` and `ID Number` on the address page. Issue: - Not able to save address without any error message on the address page and in logger it raise validation error. Cause: - In address we actually do vat validation before creation/updation and if there is any issue with vat number then add it into invalid_fields instead raising any validation error, so here wh
Original PR description
Steps: - Install l10n_co module. - Set `CO company` on user. - Go to address page on portal address. - Set `Company Name`, `ID Type` and `ID Number` on the address page. Issue: - Not able to save…
Steps: - Install l10n_co module. - Set `CO company` on user. - Go to address page on portal address. - Set `Company Name`, `ID Type` and `ID Number` on the address page. Issue: - Not able to save address without any error message on the address page and in logger it raise validation error. Cause: - In address we actually do vat validation before creation/updation and if there is any issue with vat number then add it into invalid_fields instead raising any validation error, so here when user set `Company name` on address it try to create parent company and again do vat validation and it raise validation error because `ID Type` on customer is not propagated to parent when creating parent company from portal. Fix: - Skip vat validation on parent company creation from address. To-do: We also need to pass `ID type` and other accounting related values when creating parent company from customer or make them dependent like `Vat`. Issued PR: https://github.com/odoo/odoo/pull/264356 opw-6434127 Forward-Port-Of: odoo/odoo#281441 Forward-Port-Of: odoo/odoo#280859
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/5c667fedc1 [REL] 19.4.6 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/48df9225db [IMP] composer: writing an number value should override date formats [Task: 6353692](https://www.odoo.com/odoo/2328/tasks/6353692) https://github.com/odoo/o-spreadsheet/commit/48e2180e31 [FIX] index: export `CarouselFigure` [Task: 6449019](https://www.odoo.com/odoo/2328/tasks/6449019) ht
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/5c667fedc1 [REL] 19.4.6 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/5c667fedc1 [REL] 19.4.6 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/48df9225db [IMP] composer: writing an number value should override date formats [Task: 6353692](https://www.odoo.com/odoo/2328/tasks/6353692) https://github.com/odoo/o-spreadsheet/commit/48e2180e31 [FIX] index: export `CarouselFigure` [Task: 6449019](https://www.odoo.com/odoo/2328/tasks/6449019) https://github.com/odoo/o-spreadsheet/commit/1a6144752d [FIX] chart: geoChart uses same d3 projection for main and full screen chart [Task: 6395379](https://www.odoo.com/odoo/2328/tasks/6395379) https://github.com/odoo/o-spreadsheet/commit/60d40c1514 [FIX] carousel: crash on multiuser when deleting chart [Task: 6445004](https://www.odoo.com/odoo/2328/tasks/6445004) https://github.com/odoo/o-spreadsheet/commit/4e9affe04f [FIX] figures: fix movement issue with arrow keys [Task: 6374091](https://www.odoo.com/odoo/2328/tasks/6374091) https://github.com/odoo/o-spreadsheet/commit/01acbcaa9d [IMP] package: update owl to 45 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
### Problem: Background videos on `website` were not looping correctly for 3 reasons - Not all `video_providers` implemented the loop `optionsConfig`. - The `loop` optionsConfig was not enabled automatically when adding background videos - YouTube requires a `playlist` url param with the same value as the `videoID` in order to loop correctly ### Steps to reproduce: - Go to website. - Add a Snippet. - In the snippet builder options, add a background video like [1]. - Save the web
Original PR description
### Problem: Background videos on `website` were not looping correctly for 3 reasons - Not all `video_providers` implemented the loop `optionsConfig`. - The `loop` optionsConfig was not enabled…
### Problem: Background videos on `website` were not looping correctly for 3 reasons - Not all `video_providers` implemented the loop `optionsConfig`. - The `loop` optionsConfig was not enabled automatically when adding background videos - YouTube requires a `playlist` url param with the same value as the `videoID` in order to loop correctly ### Steps to reproduce: - Go to website. - Add a Snippet. - In the snippet builder options, add a background video like [1]. - Save the website. - The background video does not loop. ### Solution: This PR, - Implements the `loop` optionsConfig for more supported video providers. - Enables the `loop` optionsConfig for background videos by default - Adds the `playlist` param for YouTube video provider when `loop` optionsConfig is enabled. ### Unsupported video providers: - Loom [2] - Twitch [3] - Facebook [4] - Instagram - GoogleDrive - Dailymotion [7] ### Supported Players: - YouTube [5] - Vimeo [6] ##### Note on Dailymotion: Dailymotion supports the loop parameter on iFrame embedded videos but the behavior of playback goes against expectations set by other providers. Instead of looping through the requested video, Dailymotion will loop through an automatic "playlist" that it then goes through. This behavior is also not consistent with all videos, some videos don't seem to adhere to this norm. Since playing random videos is worse than not looping, the loop param addition is not handled by this PR. [1]: https://www.youtube.com/watch?v=sEH3pOhj0xs [2]: https://support.atlassian.com/loom/docs/embed-your-video-into-a-webpage/ [3]: https://dev.twitch.tv/docs/embed/video-and-clips/ [4]: https://developers.facebook.com/docs/plugins/embedded-video-player [5]: https://developers.google.com/youtube/player_parameters [6]: https://help.vimeo.com/hc/en-us/articles/12426486963857-How-to-add-autoplay-and-loop-parameters-to-my-video-s-embed-code [7]: https://developers.dailymotion.com/docs/add-runtime-player-parameters-web task-6431769
**Steps to reproduce:** 1. Install eCommerce, l10n_be, payment_stripe and switch to belgian company 2. Switch the admin user's company to the belgian one, and update their contact address to be in Belgium 3. Create a website for the belgian company and enable stripe payment provider 4. Add SEPA payment method in stripe configuration 5. Open the website, add any product to cart, go to checkout and make a payment using SEPA **Issue:** - Check the transaction in Stripe dashboard: the order
Original PR description
**Steps to reproduce:** 1. Install eCommerce, l10n_be, payment_stripe and switch to belgian company 2. Switch the admin user's company to the belgian one, and update their contact address to be in…
**Steps to reproduce:** 1. Install eCommerce, l10n_be, payment_stripe and switch to belgian company 2. Switch the admin user's company to the belgian one, and update their contact address to be in Belgium 3. Create a website for the belgian company and enable stripe payment provider 4. Add SEPA payment method in stripe configuration 5. Open the website, add any product to cart, go to checkout and make a payment using SEPA **Issue:** - Check the transaction in Stripe dashboard: the order reference is currently sent only in the `Description` field which is for internal information and is not shown to customers on their bank statements. Customers only see "MACKNET", so they cannot identify which order the payment relates to. **Expected behavior:** - Should also send the order reference to Stripe's `statement_descriptor` field, which is the field used for the customer-facing bank statement reference. - The `statement_descriptor` value must comply with Stripe's requirements: Must not contain <, >, \, ', ", or * Must contain at least one letter Maximum 22 characters **Fix:** - Pass the order reference, which should already satisfy the first two requirements based on Odoo order/invoice naming conventions opw-6424994 Forward-Port-Of: odoo/odoo#281417 Forward-Port-Of: odoo/odoo#280985
Clearing the cache in the `write` of `ir.module` caused issues when installing `website`. Having it in `create` was enough for the original use case that prompted the PR. So we remove the `write` in this commit. Reproduce: 1. Create a new empty db 2. Set language to German 3. Install Website 4. The install gets stuck and you can't access the db anymore. task-None Forward-Port-Of: odoo/odoo#281465
Original PR description
Clearing the cache in the `write` of `ir.module` caused issues when installing `website`. Having it in `create` was enough for the original use case that prompted the PR. So we remove the `write` in this commit. Reproduce: 1. Create a new empty db 2. Set language to German 3. Install Website 4. The install gets stuck and you can't access the db anymore. task-None Forward-Port-Of: odoo/odoo#281465
Currently, when the user receives a product with an expiry date whose removal date is before the current date, creating a backorder for the corresponding subcontracting operation causes the system to crash. ## Steps to produce: - Install Manufacturing - Go to settings and enable: - Subcontracting - Lots & Serial Numbers - Expiration dates - Create a product named Vegetable Salad and set Tracking to By Unique Serial Number. - In the inventory section, enable Expiration date and
Original PR description
Currently, when the user receives a product with an expiry date whose removal date is before the current date, creating a backorder for the corresponding subcontracting operation causes the system to…
Currently, when the user receives a product with an expiry date whose removal date is before the current date, creating a backorder for the corresponding subcontracting operation causes the system to crash. ## Steps to produce: - Install Manufacturing - Go to settings and enable: - Subcontracting - Lots & Serial Numbers - Expiration dates - Create a product named Vegetable Salad and set Tracking to By Unique Serial Number. - In the inventory section, enable Expiration date and configure: - Expiration Date: 10 days after receipt - Removal Date: 8 days before expiration date - Create a BoM for Vegetable salad - BoM Type: Subcontracting - Subcontractor: Chef - Component: Vegetable - Create a receipt for 2 units of Vegetable Salad from Chef - Mark it as Todo > Details > Assign serial to both lines - Set the Removal Date of the second serial number to a date earlier than today, then Save and Validate the receipt. - In the expiry warning wizard, click Proceed Except Expired and create backorder ## Observed Behavior: Creating a backorder after proceeding with the expiry warning wizard fails with the following error: `ValueError: Expected singleton: stock.move(12, 13)` ## Root cause: This issue occurs because, when the user confirms the backorder, the current picking is validated at [1]. This calls `_action_done` at [2], which in turn calls `_action_done` on the todo moves at [3]. As part of this process, `todo_moves` creates backorders at [4] and then confirms those backorder moves at [5]. During confirmation, the subcontracting manufacturing order (MO) with a serial number that has expired is split at [6], creating a new MO. This new MO then creates two backorder moves at [7]: one for the finished product and one for the component. The problem arises because `default_lot_ids` are added to the context at [8] for the expiry wizard. That same context is unintentionally propagated to the backorder wizard during backorder confirmation. As a result, the ORM assigns those lot IDs to both the component and finished product moves. This triggers the `_set_lot_ids` inverse method, which calls `_prepare_move_line_vals` at [9]. However, `_prepare_move_line_vals` is an `ensure_one` method, while `self` now contains two moves (the component move and the finished product move). Because the method expects a single record but receives two, it raises a singleton error. [1]: https://github.com/odoo/odoo/blob/c744f123ae4c7a4969e9885ee1efa99be7775340/addons/stock/wizard/stock_backorder_confirmation.py#L64 [2]: https://github.com/odoo/odoo/blob/c744f123ae4c7a4969e9885ee1efa99be7775340/addons/stock/models/stock_picking.py#L1428-L1429 [3]: https://github.com/odoo/odoo/blob/c744f123ae4c7a4969e9885ee1efa99be7775340/addons/stock/models/stock_picking.py#L1273 [4]: https://github.com/odoo/odoo/blob/c744f123ae4c7a4969e9885ee1efa99be7775340/addons/stock/models/stock_move.py#L2267-L2268 [5]: https://github.com/odoo/odoo/blob/c744f123ae4c7a4969e9885ee1efa99be7775340/addons/stock/models/stock_move.py#L2332 [6]: https://github.com/odoo/odoo/blob/c744f123ae4c7a4969e9885ee1efa99be7775340/addons/mrp_subcontracting/models/stock_picking.py#L158 [7]: https://github.com/odoo/odoo/blob/c744f123ae4c7a4969e9885ee1efa99be7775340/addons/mrp/models/mrp_production.py#L2055-L2075 [8]: https://github.com/odoo/odoo/blob/c744f123ae4c7a4969e9885ee1efa99be7775340/addons/product_expiry/models/stock_picking.py#L33-L38 [9]: https://github.com/odoo/odoo/blob/c744f123ae4c7a4969e9885ee1efa99be7775340/addons/stock/models/stock_move.py#L679 ## Solution: Sanitize the context before opening the backorder wizard so that `default_lot_ids` from the expiry wizard are not propagated. This prevents the ORM from incorrectly assigning lot IDs to the component and finished product backorder moves, avoiding the singleton error in `_prepare_move_line_vals`. With this change, users can successfully create backorder pickings and subcontracting manufacturing orders for products that are being removed without encountering any errors opw-6390571 Forward-Port-Of: odoo/odoo#278262
Steps to reproduce: - Set a Saudi company with a long legal name (e.g. "Golden Oasis Trading and Contracting Company Limited") - Make a POS order and look at the receipt QR code Issue: The QR code is drawn visibly smaller and denser than for a company with a short name, even though the image it sits in is the same 150px box: 90px of code at a 2px module pitch, against 111px at 3px. Cause: The ZATCA payload embeds the seller name, so a longer name needs a higher QR version, i.e. more mo
Original PR description
Steps to reproduce: - Set a Saudi company with a long legal name (e.g. "Golden Oasis Trading and Contracting Company Limited") - Make a POS order and look at the receipt QR code Issue: The QR code is…
Steps to reproduce: - Set a Saudi company with a long legal name (e.g. "Golden Oasis Trading and Contracting Company Limited") - Make a POS order and look at the receipt QR code Issue: The QR code is drawn visibly smaller and denser than for a company with a short name, even though the image it sits in is the same 150px box: 90px of code at a 2px module pitch, against 111px at 3px. Cause: The ZATCA payload embeds the seller name, so a longer name needs a higher QR version, i.e. more modules. ZXing's BrowserQRCodeSvgWriter draws each module at a whole number of pixels of the canvas it is given (multiple = floor(canvas / (modules + 8))), so asking it for a fixed 150x150 or 200x200 canvas leaves a leftover margin that varies with the module count. The code shrinks as soon as the module count crosses a multiple of the canvas size. opw-6399878 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281036 Forward-Port-Of: odoo/odoo#280000
With demo data, the default event TZ was not UTC. Now the test event tz is set to UTC and the test works with or without demo data. Runbot-945450 Task-6429727 Forward-Port-Of: odoo/odoo#281445
Original PR description
With demo data, the default event TZ was not UTC. Now the test event tz is set to UTC and the test works with or without demo data. Runbot-945450 Task-6429727 Forward-Port-Of: odoo/odoo#281445
Steps to reproduce: - Go to Edit mode - Go to the Theme tab - Open a color preset to customize it - Change the "Headings" color => The color of "Title" did not change in the preview By changing the tag from "h3" to "h1", the color in the preview is now correctly updated in the theme tab. "fs-4" is added to keep the previous size. task-6299680 Forward-Port-Of: odoo/odoo#279324 Forward-Port-Of: odoo/odoo#278056
Original PR description
Steps to reproduce: - Go to Edit mode - Go to the Theme tab - Open a color preset to customize it - Change the "Headings" color => The color of "Title" did not change in the preview By changing the tag from "h3" to "h1", the color in the preview is now correctly updated in the theme tab. "fs-4" is added to keep the previous size. task-6299680 Forward-Port-Of: odoo/odoo#279324 Forward-Port-Of: odoo/odoo#278056
Description ----------------- This fix ensures the allocation button appears consistently and that the parent-child relationships link correctly. Issue -------- The allocation smart button failed to appear when needed. Additionally, even when visible, creating an allocation did not properly generate the smartbuttons linking parent and child manufacturing orders together. Use Case ------------- 1. Create and confirm a manufacturing order that has a semi finished product 2. Cancel th
Original PR description
Description ----------------- This fix ensures the allocation button appears consistently and that the parent-child relationships link correctly. Issue -------- The allocation smart button failed to appear when needed. Additionally, even when visible, creating an allocation did not properly generate the smartbuttons linking parent and child manufacturing orders together. Use Case ------------- 1. Create and confirm a manufacturing order that has a semi finished product 2. Cancel the MO for the semi finished product 3. Create a new MO for the semi finished product manually 4. Go to the allocation smartbutton of the new MO and link the new MO to the final product **Task-id**: 6280980 Forward-Port-Of: odoo/odoo#269221
Steps to produce: --- - Install the Sales module. - Create a new product. - Click the edit icon on the product image. - Search for `apple`. - Select any image from the results. Issue: --- - Selecting an image raises the following JavaScript error: `TypeError: Cannot read properties of undefined (reading 'activeTab')` Root cause: --- - In [commit], `this.state.activeTab` was passed as the `activeTab` value. - [commit1] replaced `this.state.activeTab` with `this.activeTab()`, but
Original PR description
Steps to produce: --- - Install the Sales module. - Create a new product. - Click the edit icon on the product image. - Search for `apple`. - Select any image from the results. Issue: --- - Selecting an image raises the following JavaScript error: `TypeError: Cannot read properties of undefined (reading 'activeTab')` Root cause: --- - In [commit], `this.state.activeTab` was passed as the `activeTab` value. - [commit1] replaced `this.state.activeTab` with `this.activeTab()`, but this call site was not updated, causing `this.state.activeTab` to be `undefined`. Solution: --- - Replace `this.state.activeTab` with `this.activeTab()` to match the current implementation. [commit]: https://github.com/odoo/odoo/commit/7427089969ab445dc86e37d628c9c59e7c73c632 [commit1]: https://github.com/odoo/odoo/commit/2788aa7f47c2fc869f63e25d9b052d1b04f535b3 opw-6428459 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr