Daily updates from Odoo
Friday, August 14, 2026
45 changes · saas-19.2
Resolved issues and error corrections
This fix adjusts an internal Belgian payroll test so it uses a normal working day instead of a Sunday. It prevents false test failures during leave validation, helping keep payroll maintenance and releases reliable without changing user-facing behavior.
Original PR description
The test `test_float_holiday_attest` fails with a ValidationError: "The following employees are not supposed to work during that period". The previous patch (cf. PR odoo/enterprise#107490) froze time to "2026-02-01 08:00:00", which was a Sunday. When validating the leave created for `today`, check of the employee's calendar fails because zero working hours are scheduled on weekends. This commit updates `@freeze_time` to "2026-02-02 08:00:00" (Monday) so the leave validation runs against a valid working day. runbot-240132 runbot-241193 Forward-Port-Of: odoo/enterprise#126391
French VAT reimbursement declarations now include the bank account holder's name in the account details section. This helps ensure declaration 3519 contains all required account information and reduces the risk of rejected or incomplete refund submissions.
Original PR description
For reimbursement declarations, the name of the holder of the account is required This commits adds holder's name to the account data zone no-task-id Forward-Port-Of: odoo/enterprise#127631 Forward-Port-Of: odoo/enterprise#127554
Barcode receipts now keep the putaway destination when users scan multiple lots for the same product. This prevents items from being split between the intended shelf and the default stock location, reducing warehouse confusion and manual corrections.
Original PR description
Steps to reproduce --- 1. Enable Storage Locations and Lots & Serial Numbers. 2. Add a putaway rule sending a lot-tracked product from WH/Stock to WH/Stock/Shelf 1. 3. Confirm a receipt reserving 2…
Steps to reproduce --- 1. Enable Storage Locations and Lots & Serial Numbers. 2. Add a putaway rule sending a lot-tracked product from WH/Stock to WH/Stock/Shelf 1. 3. Confirm a receipt reserving 2 units of that product; putaway sets the reserved move line destination to WH/Stock/Shelf 1. 4. In the Barcode app, scan a first lot, then a second lot. The second lot lands on a separate line at WH/Stock instead of WH/Stock/Shelf 1. Issue --- The first lot reuses the reserved line and keeps its Shelf 1 destination. The second lot cannot reuse it because its tracking number differs, so `_findLine` returns nothing and `_getNewLineDefaultValues` builds a new line with `location_dest_id` set to `_defaultDestLocation()`, the picking's default destination (WH/Stock). https://github.com/odoo/enterprise/blob/314a79b774f30dc9377b2971492576c4b84483e1/stock_barcode/static/src/models/barcode_picking_model.js#L1591-L1601 Putaway relocates the destination on the move line at reservation, never on the picking, so only the reserved line carries Shelf 1. Since `groupKey` includes `location_dest_id`, the new line does not group with the first lot and shows separately at WH/Stock. This is not a regression: new lines have always defaulted to the operation destination. https://github.com/odoo/enterprise/blob/314a79b774f30dc9377b2971492576c4b84483e1/stock_barcode/static/src/models/barcode_picking_model.js#L239-L241 The new line now inherits the selected line's `location_dest_id`, already relocated by putaway, instead of the default. opw-6317077 Forward-Port-Of: odoo/enterprise#125309
The Helpdesk Stock ticket screen now shows the Replace button even when no customer is selected. This keeps the action available in the same way as related buttons, reducing confusion for support teams handling stock-related helpdesk cases.
Original PR description
Adjust the `invisible` condition to make the button visible even if no customer is selected, for consistency with other buttons --- task-6103996 Forward-Port-Of: odoo/enterprise#124467
This fixes an issue where financial reports could show incorrect date ranges after switching between companies with different fiscal year setups. The report now selects the correct fiscal year based on the chosen end date, helping keep period-based reporting accurate.
Original PR description
Fix year-mode date filter when switching between companies with different fiscal years With two companies configured: one using a standard fiscal year and one using an offset fiscal year, switching between them could produce incorrect date ranges. This happened because the previous company’s `date_to` value was reused to compute the current period for the newly selected company, and vice versa. The fix is to use the `date_to` year instead and select the latest fiscal year ending in that same year.
Invoices in Peru that include lines without taxes now fail with a clear, handled message during batch sending instead of causing a generic system error. This prevents the background sending process from getting blocked and allows other invoices to continue being processed.
Original PR description
In l10n_pe_edi, invoices containing lines without tax can't be submitted to SUNAT.
When sending a single invoice, an error message is displayed. However, sending multiple invoices processes them in the background by a cron job. In this case, EDI document creation fails without error handling, raising a generic parsing error and blocking the cron from processing other invoices.
Steps to reproduce:
1. Create and post two invoices with no tax on some lines.
2. From the list view, select both invoices and click "Send" and mark "SUNAT".
3. An exception is raised: `ValueError: XMLSyntaxError("Start tag expected, '<' not found, line 1, column 1")`.
opw-6390480An automated accounting test was adjusted to match a related platform change in how grouped data is read. This keeps the accounting test suite aligned with the updated behavior and helps prevent false test failures during releases.
Original PR description
The fix at https://github.com/odoo/odoo/pull/281911 adds bin_size: tru in the web_read_group. This commit adpats an accounting test as a consequence Forward-Port-Of: odoo/enterprise#127638
The timesheet assistant layout now keeps duration values on one line, adds spacing, and allows long titles to wrap cleanly. This prevents overlapping text in chronological views, making timesheet entries easier to read and review.
Original PR description
- enforce duration in one line - add a gap between the title and duration - wrap title if so long - adapt flex direction of chronological view to avoid overlapping of title and start time --- task-6432434
This fix corrects how certain Swiss payroll tax mutation values are listed in declarations. It helps ensure submitted payroll information uses the expected official format, reducing the risk of reporting errors or follow-up corrections.
Original PR description
task-6116327 Forward-Port-Of: odoo/enterprise#127745
The timesheet assistant now preserves a project chosen by the user when switching between suggestions. This prevents accidental replacement of an unsaved project selection, reducing data entry mistakes and rework.
Original PR description
Steps to reproduce: - Select an unmatched suggestion. - Select Project A on the timesheet form (do not save it yet). - Select another suggestion matched to Project B. Observed behavior: Project A is overridden by Project B. Expected behavior: Project A remains selected on the timesheet. By initializing `project_id` with the current record's data, we prevent the suggestion loop from overwriting the user's manual selection. task-6410844 Forward-Port-Of: odoo/enterprise#126450
Fixed an issue that caused Deferred Revenue Report exports to fail when the report included annotations. Business users can now export annotated accounting reports to Excel without encountering a server error.
Original PR description
**Steps to reproduce:** * Install the **Accounting** module. * Unhide the **Start Date** and **End Date** fields on invoice lines. * Create and post a customer invoice with deferred dates. * Go to…
**Steps to reproduce:** * Install the **Accounting** module. * Unhide the **Start Date** and **End Date** fields on invoice lines. * Create and post a customer invoice with deferred dates. * Go to **Accounting → Reports → Deferred Revenue Report**. * Add an annotation to a deferred revenue line by clicking the **annotate** from three dots next to the account. * Export the report in **XLSX** format. **Observed behavior:** * The export fails with a server error: `UnboundLocalError: cannot access local variable 'annotations_x_offset' where it is not associated with a value` **Cause:** * The variable `annotations_x_offset` is assigned inside the `for header_level_index, header_level in enumerate(options['column_headers'])` loop, which writes the "Annotations" column header for each header level. * The Deferred Revenue Report produces an empty `column_headers` list, so the loop body never executes and `annotations_x_offset` is never assigned. * When the code later tries to write annotation data for each report line, it references the unassigned variable, causing Python to raise `UnboundLocalError`. **Fix:** * Introduce a boolean flag `annotations_header_written = False` before the header loop to explicitly track whether the "Annotations" column header has already been written. * Inside the header loop, set `annotations_header_written = True` after writing the header. * After writing all individual column headers (where `x_offset` already points to the first free column after all data columns), add a fallback: if `report_annotations` is set but `annotations_header_written` is still `False`, assign `annotations_x_offset` from the current `x_offset` and write the "Annotations" header. opw-6354473 Forward-Port-Of: odoo/enterprise#127726 Forward-Port-Of: odoo/enterprise#122768
Accounting users can now export Spanish VAT record books even when the report includes Point of Sale transactions. The report safely reads the needed POS data internally, preventing access errors while keeping normal user permissions unchanged.
Original PR description
Steps to reproduce:
- With an ES Company
- Open a POS session, add product with tax and pay
- As a user with only accounting access
- Go to Accouting > Reporting > Tax report
- Select Generic Tax report
- Print "VAT record Books"
Issue:
An AccessError will raise
```
Access Error
You are not allowed to access 'Point of Sale Session' (pos.session) records.
This operation is allowed for the following groups:
- Point of Sale/User
Contact your administrator to request access if necessary.
```
Analysis:
Vat Record Books handler for POS needs to read pos.session and pos.order records. Currently, the action is performed with the rights of the user running the report, so accounting-only user face an error.
As POS records are only read internally to build the report, we add sudo call to get the data.
opw-5862529
Forward-Port-Of: odoo/enterprise#126590
Forward-Port-Of: odoo/enterprise#125980Rejection notification emails now show the name of the person who declined to sign, rather than the email recipient's name. This prevents confusion for other parties involved in the signing process and makes document status updates more accurate.
Original PR description
**Description of the issue/feature this PR addresses:** When a document is rejected by a signer, the notification email sent to other involved parties incorrectly displays the recipient's name in the…
**Description of the issue/feature this PR addresses:** When a document is rejected by a signer, the notification email sent to other involved parties incorrectly displays the recipient's name in the subject line instead of the person who actually refused to sign. This occurs because the subject string was using `partner.name` (the current email recipient) instead of `refuser.name`. This commit updates the string to reference the refuser, ensuring the subject accurately identifies the individual who rejected the document. **Steps to reproduce:** - Sign > upload any PDF > add signature request for 2 different signers > Send > choose signers, e.g. Abigail Carter and Marc Demo > Send - Settings > Technical > Emails > Emails - Select one of the sent emails > Sign document > sign > Validate & Send Completed Document - Select the other email > Sign document > top-right dropdown arrow > Decline to sign > Decline - Settings > Technical > Emails > Emails - Observe that all emails sent state that the recipient of the email rejected the signing **Current behavior before PR:** - Rejection email subject states that the recipient refused to sign **Desired behavior after PR is merged:** - Rejection email subject states that the refuser refused to sign opw-6421188 Forward-Port-Of: odoo/enterprise#126412
Australian payroll submissions now check that required payslip or employee information exists before sending data to the ATO. Instead of an unexpected system error, users receive a clear validation message, helping payroll teams correct incomplete STP records more easily.
Original PR description
When submitting payroll data to the ATO from an STP record without any payslips or employees, a traceback is raised. Steps to reproduce the error: - Install ``l10n_au_hr_payroll_account`` module -…
When submitting payroll data to the ATO from an STP record without any payslips or employees, a traceback is raised. Steps to reproduce the error: - Install ``l10n_au_hr_payroll_account`` module - Switch to ``My australian Company`` - Go to Payroll > Configuration > Settings > In Australian Localization, Set BMS ID > Set STP Responsible and his date of birth - Go to Payroll > Reporting > Single Touch Payroll > Create a new record > Set Payment Date > Submit to ATO > Sign & Submit to ATO Traceback: ```py IndexError: tuple index out of range ``` https://github.com/odoo/enterprise/blob/b0e48baaf99bdc4faefd2ffdd3bd5637fb548593/l10n_au_hr_payroll_account/models/l10n_au_stp.py#L228-L233 The traceback occurs because ``_get_fiscal_year_start()`` assumes that the STP record always contains at least one payslip or one employee. When these recordsets are empty, indexing the first element raises an IndexError. Solution: This commit validates that the required payslips or employees are present before the submission and raises a validation error instead of a traceback. Forward-Port-Of: odoo/enterprise#127733 Forward-Port-Of: odoo/enterprise#124096
Steps to reproduce: 1. Refund an order using a Glory Cash payment method 2. The machine refunds the cash correctly **Expected behaviour:** Odoo validates the refund **Actual behaviour:** Odoo sets the line amount to zero, refund incomplete The fix is to correctly remove the money dispensed from the payment total, resulting in a negative payment amount rather than zero. In addition, we remove similar logic for Cashdro machines that was also broken as the code path was never executed.
Original PR description
Steps to reproduce: 1. Refund an order using a Glory Cash payment method 2. The machine refunds the cash correctly **Expected behaviour:** Odoo validates the refund **Actual behaviour:** Odoo sets the line amount to zero, refund incomplete The fix is to correctly remove the money dispensed from the payment total, resulting in a negative payment amount rather than zero. In addition, we remove similar logic for Cashdro machines that was also broken as the code path was never executed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281938
Before this commit, marking several manufacturing orders as done at once crashed or could post labour costs on the wrong account, because the labour posting loop read the product and the company from the whole recordset instead of the manufacturing order being processed. Steps to reproduce: - activate a second company, e.g. My Company (Chicago) - create a manufacturing order in each company and confirm them - in the Manufacturing Orders list view, select both orders and mark them as done
Original PR description
Before this commit, marking several manufacturing orders as done at once crashed or could post labour costs on the wrong account, because the labour posting loop read the product and the company from…
Before this commit, marking several manufacturing orders as done at once crashed or could post labour costs on the wrong account, because the labour posting loop read the product and the company from the whole recordset instead of the manufacturing order being processed. Steps to reproduce: - activate a second company, e.g. My Company (Chicago) - create a manufacturing order in each company and confirm them - in the Manufacturing Orders list view, select both orders and mark them as done A "ValueError: Expected singleton: res.company(...)" traceback is raised and none of the orders can be closed, even though each one can be marked as done individually. With same-company orders of different products, the production location resolved from the union of products, so the labour entry could be posted against another product's WIP account. Use the manufacturing order of the current loop iteration to resolve the production location, as the rest of the loop already does. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276586
In saas-19.1, `purchase_cdnur_regular` was renamed to `purchase_cdnur_overseas`. However, commit https://github.com/odoo/odoo/commit/c4b0911e061ff0619bd3d6a411701fc898dad258 still used the old section name. This commit updates `purchase_cdnur_regular` to `purchase_cdnur_overseas`. Forward-Port-Of: odoo/odoo#281895
Original PR description
In saas-19.1, `purchase_cdnur_regular` was renamed to `purchase_cdnur_overseas`. However, commit https://github.com/odoo/odoo/commit/c4b0911e061ff0619bd3d6a411701fc898dad258 still used the old section name. This commit updates `purchase_cdnur_regular` to `purchase_cdnur_overseas`. Forward-Port-Of: odoo/odoo#281895
Making sure that during the race condition between the save triggered by closing the widget and the one triggered by the ’ NEED_LOCAL_CHANGES’ bus doesn’t lead to the re-opening of the widget itself and subsequently the list mass edit pop up. Forward-Port-Of: odoo/odoo#281013
Original PR description
Making sure that during the race condition between the save triggered by closing the widget and the one triggered by the ’ NEED_LOCAL_CHANGES’ bus doesn’t lead to the re-opening of the widget itself and subsequently the list mass edit pop up. Forward-Port-Of: odoo/odoo#281013
Steps to reproduce the bug: - As an administrator, create a user with the "Manufacturing / Administrator" right but without the "Administration / Settings" right - Log in as that user - Create and confirm a manufacturing order - Click "Plan" -> works fine - Click "Unplan" Problem: Clicking "Unplan" raises: "You do not have enough rights to access the field 'tracking_value_ids' on Message (mail.message)." This regression was introduced by commit: https://github.com/odoo/odoo/commit/
Original PR description
Steps to reproduce the bug: - As an administrator, create a user with the "Manufacturing / Administrator" right but without the "Administration / Settings" right - Log in as that user - Create and…
Steps to reproduce the bug: - As an administrator, create a user with the "Manufacturing / Administrator" right but without the "Administration / Settings" right - Log in as that user - Create and confirm a manufacturing order - Click "Plan" -> works fine - Click "Unplan" Problem: Clicking "Unplan" raises: "You do not have enough rights to access the field 'tracking_value_ids' on Message (mail.message)." This regression was introduced by commit: https://github.com/odoo/odoo/commit/76be1f20098d62a35b08a58ce9be1c380388ac01 which made button_unplan() walk order.message_ids looking for the tracking value of the previous date_start, so it can be restored: https://github.com/odoo/odoo/blob/320d3422345a4bd792a07652490a9869d79ae716/addons/mrp/models/mrp_production.py#L1750-L1752 mail.message.tracking_value_ids is restricted with groups="base.group_system", so reading it as the current (non-Settings-admin) user raises an AccessError. button_plan() never hits this code path since it only calls message_post(), which is why the same user can plan but not unplan. Solution: Read message_ids in sudo(), since this is only internal bookkeeping to recover the previous date_start and not something that should require Settings/Administration access. opw-6455333
Before this commit: = - When a slot reached its maximum capacity for a given time frame, it was hidden from the POS slot selection dialog. - In Self Order, slots at maximum capacity were still displayed as available. After this commit: = - When a slot reaches its maximum capacity for a given time frame, it remains visible with a red background in the POS slot selection dialog. - In Self Order, slots at maximum capacity are hidden. - Removed tour `test_slot_limit_orders` and added equiv
Original PR description
Before this commit: = - When a slot reached its maximum capacity for a given time frame, it was hidden from the POS slot selection dialog. - In Self Order, slots at maximum capacity were still displayed as available. After this commit: = - When a slot reaches its maximum capacity for a given time frame, it remains visible with a red background in the POS slot selection dialog. - In Self Order, slots at maximum capacity are hidden. - Removed tour `test_slot_limit_orders` and added equivalent hoot test. task-6340956
Issue: --- On the product page, when the image layout is set to grid and only one image is there, the image doesn't take the full width of its container on mobile devices. A empty space appears next to it. Steps to reproduce: 1- Go to a product page with mlutiple images. 2- Switch the image layout from carousel to grid. 3- Remove extra images and keep only one image. 4- Open the page using mobile view in chrome. This can be fixed by forcing `width: 100%` explicitly on the image wrapp
Original PR description
Issue: --- On the product page, when the image layout is set to grid and only one image is there, the image doesn't take the full width of its container on mobile devices. A empty space appears next to it. Steps to reproduce: 1- Go to a product page with mlutiple images. 2- Switch the image layout from carousel to grid. 3- Remove extra images and keep only one image. 4- Open the page using mobile view in chrome. This can be fixed by forcing `width: 100%` explicitly on the image wrapper for `o_grid_solo`. opw-6265732
An old refactor left some data around that are in conflict with other records for the same model. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281710 Forward-Port-Of: odoo/odoo#281276
Original PR description
An old refactor left some data around that are in conflict with other records for the same model. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281710 Forward-Port-Of: odoo/odoo#281276
Steps to reproduce the bug: - Install a localization that overrides invoice_policy defaults for storable products without an explicit company_id (e.g. l10n_ke_edi_oscu_stock, which forces 'delivery' in that case) - Run TestSaleMRPAngloSaxonValuation.test_sale_mrp_kit_bom_cogs (sale_mrp) or TestAngloSaxonValuation.test_anglo_saxon_cogs_partial_down_payment_credit_note (sale_stock) Problem: These tests create their products without setting invoice_policy explicitly, relying on the field's im
Original PR description
Steps to reproduce the bug: - Install a localization that overrides invoice_policy defaults for storable products without an explicit company_id (e.g. l10n_ke_edi_oscu_stock, which forces 'delivery'…
Steps to reproduce the bug: - Install a localization that overrides invoice_policy defaults for storable products without an explicit company_id (e.g. l10n_ke_edi_oscu_stock, which forces 'delivery' in that case) - Run TestSaleMRPAngloSaxonValuation.test_sale_mrp_kit_bom_cogs (sale_mrp) or TestAngloSaxonValuation.test_anglo_saxon_cogs_partial_down_payment_credit_note (sale_stock) Problem: These tests create their products without setting invoice_policy explicitly, relying on the field's implicit default. l10n_ke_edi_oscu_stock's _compute_invoice_policy (https://github.com/odoo/enterprise/blob/4e459417dac809caafea34aa2e487fc3c1f0ce1a/l10n_ke_edi_oscu_stock/models/product.py#L16-L21) forces invoice_policy to 'delivery' for any storable product whose company_id is not set, which is the case for products created in these test fixtures. Once invoice_policy becomes 'delivery', invoiced quantities are driven by qty_delivered instead of the ordered quantity, which the affected tests never account for (some deliver an arbitrary quantity instead of the exact BoM demand, others never validate a delivery at all), causing wrong COGS amounts or wrongly invoiced quantities as soon as such a localization is installed alongside these modules. Solution: Pin invoice_policy to 'order' explicitly wherever these test fixtures create their products, so the test outcome no longer depends on which other modules happen to be installed. runbot-243633 Forward-Port-Of: odoo/odoo#279277 Forward-Port-Of: odoo/odoo#278346
`test_orderpoint_activity_portal_context_leak` assumes that running the orderpoint will trigger a procurement exception. However, depending on which modules are installed (e.g., when `purchase_stock` is absent), standard stock rules for the test warehouse destination location can succeed in generating stock moves rather than raising an error. Deactivate all matching destination stock rules on the test warehouse prior to running procurement so the orderpoint is guaranteed to fail. runbot-94
Original PR description
`test_orderpoint_activity_portal_context_leak` assumes that running the orderpoint will trigger a procurement exception. However, depending on which modules are installed (e.g., when `purchase_stock` is absent), standard stock rules for the test warehouse destination location can succeed in generating stock moves rather than raising an error. Deactivate all matching destination stock rules on the test warehouse prior to running procurement so the orderpoint is guaranteed to fail. runbot-941316 Forward-Port-Of: odoo/odoo#279781
Before this commit and since the new read_group (which fetches records from open groups server side), images were loaded as base64, overloading the return payload and potentially triggering overload errors (MemoryError) This was because the bin_size = true context key was forgotten. After this commit, images are not loaded as base64 thanks to that context key Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged:
Original PR description
Before this commit and since the new read_group (which fetches records from open groups server side), images were loaded as base64, overloading the return payload and potentially triggering overload errors (MemoryError) This was because the bin_size = true context key was forgotten. After this commit, images are not loaded as base64 thanks to that context key Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281911
Before this commit, the html composer variant of "Opening thread with needaction messages should mark all messages of thread as read" failed at random on runbot: 11. [verifySteps] expected the following steps > Expected: [ "mark-all-messages-as-read", ] > Received: [] This happens because the channel of that variant holds no message, so the test goes to the inbox before the channel is loaded and it keeps scrollUnread set. Opening the channel again then loads its m
Original PR description
Before this commit, the html composer variant of "Opening thread with needaction messages should mark all messages of thread as read" failed at random on runbot: 11. [verifySteps] expected the…
Before this commit, the html composer variant of "Opening thread with needaction messages should mark all messages of thread as read" failed at random on runbot:
11. [verifySteps] expected the following steps
> Expected: [
"mark-all-messages-as-read",
]
> Received: []
This happens because the channel of that variant holds no message, so the test goes to the inbox before the channel is loaded and it keeps scrollUnread set. Opening the channel again then loads its messages around the 0 separator, and that fetch calls set_message_done, which marks the needaction message as read and leaves nothing for mark_all_as_read to mark.
This commit fixes the issue by giving the channel two messages, pointing the separator at the first one and waiting for their display: loading messages around the separator is skipped when that message is already loaded, so opening the channel again fetches nothing, which the closing assertion checks as well.
The text composer variant gets the same fixture, so that both variants read as master does, from commit 8cd330e3e2d5b1d857d3effb80aa8176d60b38f9. It does not fail: it already waits for a message of its own, and a fetch around its non-zero separator leaves the messages alone in the mock.
https://runbot.odoo.com/odoo/error/945744
Forward-Port-Of: odoo/odoo#282038
Forward-Port-Of: odoo/odoo#281714Before this commit, the Chat action of the meeting view could keep its unread dot instead of showing "1" after "Mark as Unread": FAILED: [14/21] Tour discuss.meeting_view_tour Step .o-mail-Meeting [title='Chat']:has(.badge:contains(1)). Element (.o-mail-Meeting [title='Chat']:has(.badge:contains(1))) has not been found. TIMEOUT step failed to complete within 10000 ms. This happens because a mark as read carries the id of the newest message the client knew when it re
Original PR description
Before this commit, the Chat action of the meeting view could keep its unread dot instead of showing "1" after "Mark as Unread": FAILED: [14/21] Tour discuss.meeting_view_tour Step .o-mail-Meeting…
Before this commit, the Chat action of the meeting view could keep its unread dot instead of showing "1" after "Mark as Unread":
FAILED: [14/21] Tour discuss.meeting_view_tour
Step .o-mail-Meeting [title='Chat']:has(.badge:contains(1)).
Element (.o-mail-Meeting [title='Chat']:has(.badge:contains(1)))
has not been found.
TIMEOUT step failed to complete within 10000 ms.
This happens because a mark as read carries the id of the newest message the client knew when it requested it, and under load it can reach the server after a newer message was posted. The new message separator then moves back before that message, which makes it unread before the user even asks for it. The click on "Mark as Unread" writes the separator the counter is already computed from, so the counter does not change, and the client, which holds the counter it displays while the user reads the thread, never refreshes it.
This commit moves the new message separator forward only, so reading messages never makes another one unread.
https://runbot.odoo.com/odoo/error/945958
Forward-Port-Of: odoo/odoo#281988Before this commit, the test "Shows warning badge on mic/camera on non-granted permission in meeting conversations" failed on runbot, on 19.0: Failed to find 1 of "button[title='Turn camera on']" (Timeout of 10 seconds). Found 0 instead. This happens because the mock server numbers a new record with the highest id of the model plus one, so a record created right after the last one is deleted takes its id back. Joining another call leaves the meeting call first, and the session of the new c
Original PR description
Before this commit, the test "Shows warning badge on mic/camera on non-granted permission in meeting conversations" failed on runbot, on 19.0: Failed to find 1 of "button[title='Turn camera on']"…
Before this commit, the test "Shows warning badge on mic/camera on non-granted permission in meeting conversations" failed on runbot, on 19.0: Failed to find 1 of "button[title='Turn camera on']" (Timeout of 10 seconds). Found 0 instead. This happens because the mock server numbers a new record with the highest id of the model plus one, so a record created right after the last one is deleted takes its id back. Joining another call leaves the meeting call first, and the session of the new call carries the id of the one just left. Leaving broadcasts "discuss.channel.rtc.session/ended" for that id, and under load it lands after the join: the client reads it as its own session being closed and ends the call it has just joined. This commit numbers the records of a model with a counter, started above the ids its definition gives, as a database sequence does, so a notification about a deleted record can no longer name a live one. https://runbot.odoo.com/odoo/error/945965 Forward-Port-Of: odoo/odoo#282244
Before this commit, the hoot test "keep banner for messages received while scrolled up" failed at random on runbot: ``` Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))" (Timeout of 10 seconds). Found 0 instead. ``` This happens because the test waits for the scroll position it sets in the DOM only, while the thread copies that position to the record on the scroll event, one animation frame later. Bob's message can arrive in between, when the record still says "bot
Original PR description
Before this commit, the hoot test "keep banner for messages received while scrolled up" failed at random on runbot:
```
Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))"
(Timeout of 10 seconds). Found 0 instead.
```
This happens because the test waits for the scroll position it sets in the DOM only, while the thread copies that position to the record on the scroll event, one animation frame later. Bob's message can arrive in between, when the record still says "bottom": the counter the banner reads stays frozen at 0 and the message is marked as read on arrival, so the banner never shows.
This commit waits until the record holds that position before posting.
https://runbot.odoo.com/odoo/error/945967
Forward-Port-Of: odoo/odoo#282333
Forward-Port-Of: odoo/odoo#282218Backport of commit 0b7118e10010. Since 19.2 the receipt can also be generated on the server (emailed receipt, receipt from the backend order) by going to "Point of Sale > Orders > Order#N > Download Receipt", where the QR was still that of the phase 1, so the ZATCA app rejected it when scanning it, because it's not a valid phase 2 QR code. We now use the invoice phase 2 QR when the invoice is legal. opw-6399766 Before (not accepted when scanning) <img width="449" height="504" alt="i
Original PR description
Backport of commit 0b7118e10010. Since 19.2 the receipt can also be generated on the server (emailed receipt, receipt from the backend order) by going to "Point of Sale > Orders > Order#N > Download Receipt", where the QR was still that of the phase 1, so the ZATCA app rejected it when scanning it, because it's not a valid phase 2 QR code. We now use the invoice phase 2 QR when the invoice is legal. opw-6399766 Before (not accepted when scanning) <img width="449" height="504" alt="image" src="https://github.com/user-attachments/assets/fb56daf9-a825-4df8-9123-14b25c13bde4" /> After (accepted when scanning) <img width="481" height="491" alt="image" src="https://github.com/user-attachments/assets/f41b582c-24f2-4976-8379-43af63845481" />
### Steps to reproduce: - Enable "Lots & Serial Numbers" in the Inventory settings - Create a storable product tracked by lots - Create a lot for that product and leave it without any quantity - Open the lot form > cog menu > Scrap #### > ValueError: Expected singleton: stock.location() ### Cause of the issue: A lot is only given a `location_id` when all its positive quants lay in a single location, so a lot with no quant at all has none: https://github.com/odoo/odoo/blob/8b8852f1c3
Original PR description
### Steps to reproduce: - Enable "Lots & Serial Numbers" in the Inventory settings - Create a storable product tracked by lots - Create a lot for that product and leave it without any quantity - Open…
### Steps to reproduce: - Enable "Lots & Serial Numbers" in the Inventory settings - Create a storable product tracked by lots - Create a lot for that product and leave it without any quantity - Open the lot form > cog menu > Scrap #### > ValueError: Expected singleton: stock.location() ### Cause of the issue: A lot is only given a `location_id` when all its positive quants lay in a single location, so a lot with no quant at all has none: https://github.com/odoo/odoo/blob/8b8852f1c3ae5b78a4a3e99c99eacab83f0be5c9/addons/stock/models/stock_lot.py#L169-L172 The `action_scrap` nevertheless always forwards that value to the scrap move, so the form is opened with `default_location_id` set to `False`: https://github.com/odoo/odoo/blob/8b8852f1c3ae5b78a4a3e99c99eacab83f0be5c9/addons/stock/models/stock_lot.py#L415-L426 Now, the issue is that the `_onchange_lot_ids` of the new stock move then evaluates the reservation of a move whose source location is still empty which raises the traceback because of a `self.ensure_one` required on the location to determine if the move `should_bypass_reservation`: https://github.com/odoo/odoo/blob/8b8852f1c3ae5b78a4a3e99c99eacab83f0be5c9/addons/stock/models/stock_move.py#L1515 https://github.com/odoo/odoo/blob/8b8852f1c3ae5b78a4a3e99c99eacab83f0be5c9/addons/stock/models/stock_move.py#L1989-L1992 https://github.com/odoo/odoo/blob/8b8852f1c3ae5b78a4a3e99c99eacab83f0be5c9/addons/stock/models/stock_location.py#L414-L416 Note that if the default key was not present, the traceback would not be triggered and the scrap would be performed from the `default_stock_location` of the company: https://github.com/odoo/odoo/blob/4c4219a7d9d51f703b15e83ab755faf1f2c8a71d/addons/stock/models/res_company.py#L21-L22 Indeed the issue is that the `default_get` looks the context key up by *membership*, so that a falsy `default_location_id` is still returned as a default value for the field if provided: https://github.com/odoo/odoo/blob/8b8852f1c3ae5b78a4a3e99c99eacab83f0be5c9/odoo/orm/models.py#L1313-L1317 And therefore will not be computed in the first onchange: https://github.com/odoo/odoo/blob/8b8852f1c3ae5b78a4a3e99c99eacab83f0be5c9/addons/web/models/models.py#L1974-L1988 Note: The `stock.lot.action_scrap`, and this `default_location_id` line with it, were introduced by 1c7d80a10b5d, which replaced the `stock.scrap` model by scrap `stock.move` records. That commit is only present from saas-19.2 onwards, so earlier versions are not affected. opw-6441937 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Issue: Consumption Warnings were appearing for services in manufacturing orders, but services are not consumed therefore the warning makes no sense. Steps to reproduce: Create a bill of materials with at least 1 service type component line Create a manufacturing order for that product Validate the manufacturing order Why: Consumption warning was appearing because we have no amount of quantity of products of type service / combo. Since these types are not supposed to have a quantit
Original PR description
Issue: Consumption Warnings were appearing for services in manufacturing orders, but services are not consumed therefore the warning makes no sense. Steps to reproduce: Create a bill of materials with at least 1 service type component line Create a manufacturing order for that product Validate the manufacturing order Why: Consumption warning was appearing because we have no amount of quantity of products of type service / combo. Since these types are not supposed to have a quantity in the same way goods do, this check does not make sense for products other than goods and therefore we should remove the check for products other than `'consu'` opw-6420932
Steps: - Install `account_peppol` module. - Set `Peppol` compatible country and related details - Go to my/account page. Issue: - Peppol related details always displayed on `my/account` page even though user select different invoice sending method like: `By Email`. Casue: - selector to manage visibility of Peppol related details in `my/account` is wrong and because of that those fields always display. Probably because https://github.com/odoo/odoo/pull/195764 and backport of this https
Original PR description
Steps: - Install `account_peppol` module. - Set `Peppol` compatible country and related details - Go to my/account page. Issue: - Peppol related details always displayed on `my/account` page even…
Steps: - Install `account_peppol` module. - Set `Peppol` compatible country and related details - Go to my/account page. Issue: - Peppol related details always displayed on `my/account` page even though user select different invoice sending method like: `By Email`. Casue: - selector to manage visibility of Peppol related details in `my/account` is wrong and because of that those fields always display. Probably because https://github.com/odoo/odoo/pull/195764 and backport of this https://github.com/odoo/odoo/pull/198327 merged at same time. Fix: - Update selector to fix this ### [FIX] account_peppol: fix error when setting wrong endpoint Steps: - Install `account_peppol` module. - Set `Peppol` compatible country and related details. - Go to my/account page. - Set some wrong Peppol value for `Peppol e-Address (EAS)` or `Peppol Endpoint` or `Electronic format`. Issue: - Not able to save those details without any error message on address page and getting error on console `Cannot read properties of undefined (reading 'classList')`. Casue: - In this PR https://github.com/odoo/odoo/pull/190312 when adapting portal page we set not existing fields in `invalid_fields` details and because of that it can't find related fields on address page and don't allow to save details without raising proper error message. Fix: - Updated `invalid_fields` values to properly target them ### [FIX] account_peppol: fix display issue for peppol related fields in address Forward-Port-Of: odoo/odoo#281718
Before this commit, the two steps posting "Hello everyone!" were spliced into the meeting view tour at the index of the step clicking on the Chat action, looked up with `steps.find`. That returns the step itself, so `splice` coerced it to NaN and inserted at 0: the message was posted as the very first thing the tour did, and the marker it searched for served no purpose. Reminder that the index it aimed for does not work: the meeting view is fullscreen with the invite panel open there, and the
Original PR description
Before this commit, the two steps posting "Hello everyone!" were spliced into the meeting view tour at the index of the step clicking on the Chat action, looked up with `steps.find`. That returns the step itself, so `splice` coerced it to NaN and inserted at 0: the message was posted as the very first thing the tour did, and the marker it searched for served no purpose. Reminder that the index it aimed for does not work: the meeting view is fullscreen with the invite panel open there, and the only composer belongs to the chat panel, which opens one step later. This commit writes the two steps at the head of the list and drops the marker, so the tour runs in the order it reads. Forward-Port-Of: odoo/odoo#282060
Steps to reproduce: - 1. In the website editor, open the portal "My Account" page and, in the Customize panel, disable the "Timesheets" option. 2. As a portal user, open My Account > Tasks for a project whose tasks have allocated time and logged timesheets. 3. Look at the task list, then open one of those tasks. Issue: - The task list still shows the per-group "Total: spent / allocated", and the task detail page still shows "Allocated Time", even though timesheets are hidden in the port
Original PR description
Steps to reproduce: - 1. In the website editor, open the portal "My Account" page and, in the Customize panel, disable the "Timesheets" option. 2. As a portal user, open My Account > Tasks for a project whose tasks have allocated time and logged timesheets. 3. Look at the task list, then open one of those tasks. Issue: - The task list still shows the per-group "Total: spent / allocated", and the task detail page still shows "Allocated Time", even though timesheets are hidden in the portal. Fix: - - Add `_show_portal_timesheets()` to the condition of the list "Total" column. - Gate the `portal_my_task_allocated_hours` block on `_show_portal_timesheets()` in the task detail page. task-6140807 Forward-Port-Of: odoo/odoo#272043
Steps to Reproduce: ------------------------ - Install the Point of Sale module & create an order with a customer (partner). - Scan the QR code on the receipt to retrieve the invoice. Issue: ------- When clicking `Get My Invoice`, the invoice was not being generated. Cause: --------- - The correct partner was not being set. POS customer scanning the QR code is not logged into Odoo, so no partner is associated with the request. We were incorrectly using the logged-in user’s partner,
Original PR description
Steps to Reproduce: ------------------------ - Install the Point of Sale module & create an order with a customer (partner). - Scan the QR code on the receipt to retrieve the invoice. Issue: -------…
Steps to Reproduce: ------------------------ - Install the Point of Sale module & create an order with a customer (partner). - Scan the QR code on the receipt to retrieve the invoice. Issue: ------- When clicking `Get My Invoice`, the invoice was not being generated. Cause: --------- - The correct partner was not being set. POS customer scanning the QR code is not logged into Odoo, so no partner is associated with the request. We were incorrectly using the logged-in user’s partner, which resulted in an empty partner and therefore an empty VAT value. - The customer's country was also incorrect because the partner’s country was fetched but then overwritten by the order’s country due to improper value assignment. Fix: ---- - In most POS scenarios, the customer associated with the order is the one requesting the invoice. Therefore, if no logged-in user is found, we now correctly use the order’s partner to retrieve VAT and other required information. - The partner's country was corrected by ensuring the values are assigned in the proper order and no longer overridden incorrectly. task: 5406951 Forward-Port-Of: odoo/odoo#239811
Before this commit, `waitStoreFetch` returns before the answer is in the store: right after `waitStoreFetch("channels_as_member")`, the store holds no record for a channel that answer carries, on a hundred runs out of a hundred. A test that then asserts on the fetched data depends on timing. This happens because `listenStoreFetch` steps from the `onRpc` callback, which runs before the route is served. The `microTick` at the end of `waitStoreFetch` is meant to cover the rest of the round trip,
Original PR description
Before this commit, `waitStoreFetch` returns before the answer is in the store: right after `waitStoreFetch("channels_as_member")`, the store holds no record for a channel that answer carries, on a hundred runs out of a hundred. A test that then asserts on the fetched data depends on timing.
This happens because `listenStoreFetch` steps from the `onRpc` callback, which runs before the route is served. The `microTick` at the end of `waitStoreFetch` is meant to cover the rest of the round trip, but the answer only reaches the store six microtasks later.
This commit steps from `Store.fetchStoreData` instead, whose promise resolves once the answer is in the store, and drops the tick. The `onRpc` option keeps its route hooks, as tests use it to delay a request.
Forward-Port-Of: odoo/odoo#282155
Forward-Port-Of: odoo/odoo#281499**ISSUE** When running` _cron_migrate_local_to_cloud_storage` manually,` cron._trigger` is called, which schedules the cron to be triggered later by a worker. To check whether the cron is being run manually or not, we check if there is a request. In SaaS, staging, and duplicate databases, the request is only truthy when the cron is run manually and falsy when run by a worker. In a SH production database, however, the request is truthy both when run manually and when run by a worker due to a spe
Original PR description
**ISSUE** When running` _cron_migrate_local_to_cloud_storage` manually,` cron._trigger` is called, which schedules the cron to be triggered later by a worker. To check whether the cron is being run manually or not, we check if there is a request. In SaaS, staging, and duplicate databases, the request is only truthy when the cron is run manually and falsy when run by a worker. In a SH production database, however, the request is truthy both when run manually and when run by a worker due to a specific cron worker configuration in that environment. As a result,` cron._trigger `is called infinitely and nothing gets uploaded to the cloud. **FIX** Instead of calling `cron._trigger()` to reschedule the job, `limit_time_real` is used when `request` is truthy, and `limit_time_real_cron` otherwise. opw-6330674 Forward-Port-Of: odoo/odoo#279581
Description of the issue/feature this PR addresses: Odoo supports WebP image fields, but `base_import` validates remote images with `PIL.Image.open()`. Odoo intentionally leaves Pillow's WebP decoder unloaded, so a valid WebP URL is rejected as an unidentified image. Current behavior before PR: Importing a valid WebP image URL fails with `cannot identify image file`. Oversized and unsupported WebP files are also rejected by Pillow before the import-specific size policy can be applied. Desire
Original PR description
Description of the issue/feature this PR addresses: Odoo supports WebP image fields, but `base_import` validates remote images with `PIL.Image.open()`. Odoo intentionally leaves Pillow's WebP decoder…
Description of the issue/feature this PR addresses: Odoo supports WebP image fields, but `base_import` validates remote images with `PIL.Image.open()`. Odoo intentionally leaves Pillow's WebP decoder unloaded, so a valid WebP URL is rejected as an unidentified image. Current behavior before PR: Importing a valid WebP image URL fails with `cannot identify image file`. Oversized and unsupported WebP files are also rejected by Pillow before the import-specific size policy can be applied. Desired behavior after PR is merged: Use Odoo's existing WebP header parser for dimension validation. Valid WebP URLs import unchanged, unsupported WebP remains rejected, and the existing 42-million-pixel import limit remains enforced. Tests cover valid, unsupported, and oversized WebP URL payloads. The complete `test_base_import` suite passes (56 tests, 0 failures/errors). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282133 Forward-Port-Of: odoo/odoo#276648
Currently, returning a product via the PoS does not populate the `origin_returned_move_id` on the generated incoming stock move. For products using AVCO or FIFO valuation, this causes the stock valuation engine to fall back to the product's current standard price instead of using the historical cost of the original sale, resulting in stock valuation errors and accounting imbalances. This commit fixes the issue by updating `_prepare_stock_move_vals` to evaluate the `refunded_orderline_id`. It
Original PR description
Currently, returning a product via the PoS does not populate the `origin_returned_move_id` on the generated incoming stock move. For products using AVCO or FIFO valuation, this causes the stock valuation engine to fall back to the product's current standard price instead of using the historical cost of the original sale, resulting in stock valuation errors and accounting imbalances. This commit fixes the issue by updating `_prepare_stock_move_vals` to evaluate the `refunded_orderline_id`. It traces the refund back to the original PoS order and dynamically links the original completed outgoing stock move. This ensures the valuation waterfall correctly intercepts the return and applies the original historical cost. opw-6216531 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273847
Steps to reproduce: 1. Install CRM 2. Activate the Arabic language with English 3. Create a lead with a new email, a new company name, and the Arabic language 4. Save and try to send a message from the chatter Issue: - After the message is sent, the language of Lead is changed to EN from Arabic - Contacts created with the English language Cause: - When we send a message from the chatter of a Lead that has an email_from, a partner_name, and the Arabic language, this forces the creati
Original PR description
Steps to reproduce: 1. Install CRM 2. Activate the Arabic language with English 3. Create a lead with a new email, a new company name, and the Arabic language 4. Save and try to send a message from…
Steps to reproduce: 1. Install CRM 2. Activate the Arabic language with English 3. Create a lead with a new email, a new company name, and the Arabic language 4. Save and try to send a message from the chatter Issue: - After the message is sent, the language of Lead is changed to EN from Arabic - Contacts created with the English language Cause: - When we send a message from the chatter of a Lead that has an email_from, a partner_name, and the Arabic language, this forces the creation of a new contact First child contact is created with arabic language, but `parent_name` is present in the creation dictionary, so this triggers `_create_parent_from_name` that builds a dictionary to create the parent company, but it does not pass the language. As a result, the parent company is created with the English language. then `_create_parent_from_name` links the child to this new parent and this linking triggers the `_compute_lang` on the child and overwrites the child's language with the parent's language At last, Lead's own computed field `_compute_lang_id` triggers and sets the language to English Solution: - pass the language in the dictionary to create the parent company opw-6449407 Forward-Port-Of: odoo/odoo#281747
Steps to reproduce: - make a few sales in the PoS and refund one of them - close the session - select all those orders, including the refund, and create a consolidated invoice Issue: The invoice is refused with "You cannot validate an invoice with a negative total amount. You should create a credit note instead.", while the total of the selected orders is positive. If a cash rounding method is set on the PoS config, no error is raised but the posted document is a credit note carrying a r
Original PR description
Steps to reproduce: - make a few sales in the PoS and refund one of them - close the session - select all those orders, including the refund, and create a consolidated invoice Issue: The invoice is…
Steps to reproduce: - make a few sales in the PoS and refund one of them - close the session - select all those orders, including the refund, and create a consolidated invoice Issue: The invoice is refused with "You cannot validate an invoice with a negative total amount. You should create a credit note instead.", while the total of the selected orders is positive. If a cash rounding method is set on the PoS config, no error is raised but the posted document is a credit note carrying a rounding line equal to twice the order total (a credit note of 20.00 with a 40.00 "Rounding" line for sales of 10.00 + 20.00 and a refund of 10.00). Cause: _prepare_invoice_vals picked the move type from the presence of a refund in the group instead of its net amount: any group holding an order with is_refund set, or a negative amount_total, became an 'out_refund'. _get_invoice_lines_values then negates the quantities of every order whose direction differs from the move type, so the sales end up as negative lines of a credit note and the document totals -20.00 instead of +20.00. account.move refuses to post it. When invoice_cash_rounding_id is set, the cash rounding line is computed to bring the document back to a total valid for its type, so it absorbs the whole sign error and the wrong credit note is posted silently. Fix: Choose the move type from the net amount_total of the group, as was done up to saas-18.3, and keep is_refund only as the tie-break when that net is zero so a lone zero-total refund still gives a credit note. The sign handling of the lines is unchanged: it already keys on each order's own direction, which is what makes a sale a negative line of a credit note and a refund a negative line of an invoice. opw-6452996 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281703
Steps to reproduce: - Create a "Buy 2 Get 1 free" program whose rule and reward cover three products having the same price - In the PoS, add one unit of each of the three products -> one free product is given - Add three more units of the second product, 6 units in total Issue: Only one free product is given instead of two, the order total is 50 instead of 40. Cause: `_updateRewardLines` deletes the reward lines and re-applies each claimed reward. Beforehand it merges the claims havin
Original PR description
Steps to reproduce: - Create a "Buy 2 Get 1 free" program whose rule and reward cover three products having the same price - In the PoS, add one unit of each of the three products -> one free product…
Steps to reproduce: - Create a "Buy 2 Get 1 free" program whose rule and reward cover three products having the same price - In the PoS, add one unit of each of the three products -> one free product is given - Add three more units of the second product, 6 units in total Issue: Only one free product is given instead of two, the order total is 50 instead of 40. Cause: `_updateRewardLines` deletes the reward lines and re-applies each claimed reward. Beforehand it merges the claims having the same reward and the same price, which is the case for two free products of the same price even when they were claimed for two different products. The merged claim keeps the `_reward_product_id` of the first line only, with a quantity of two. On re-application, `_computeUnclaimedFreeProductQty` only counts in `available` the quantity of that single product, since the other lines are counted only while a reward line is still in the order and they have all just been deleted. It therefore returns 1 and the second free product is lost. Fix: Only merge claims that were made for the same free product. Gift card/ewallet claims have no `_reward_product_id` and claims of a reward having a single reward product all share the same one, so both keep being merged as before. opw-6430385 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282052
As the `requirements.txt` file path changed from `addons/iot_box_image` to `setup/iot_box_builder` the checkout from 19 to saas-19.4 can't find the file (looking at the former path instead of the new one). As a workaround, we add `sentry_sdk` requirement in v19.0. Forward-Port-Of: odoo/odoo#282122 Forward-Port-Of: odoo/odoo#282001
Original PR description
As the `requirements.txt` file path changed from `addons/iot_box_image` to `setup/iot_box_builder` the checkout from 19 to saas-19.4 can't find the file (looking at the former path instead of the new one). As a workaround, we add `sentry_sdk` requirement in v19.0. Forward-Port-Of: odoo/odoo#282122 Forward-Port-Of: odoo/odoo#282001
When creating a MO For a product with no variant, it will add an on apply on variant component, even if only one of it's attribute has a values that match with the product on the mo. Steps to reproduce: ------------------- * Create a Product with two never attributes (att1 and att2) * Add values to both attributes * Create a BOM with components with apply on variant for every possibility: - component att1 val1, att2 val1, apply on variant: att1 value 1 att2 value1 - component att1 v
Original PR description
When creating a MO For a product with no variant, it will add an on apply on variant component, even if only one of it's attribute has a values that match with the product on the mo. Steps to…
When creating a MO For a product with no variant, it will add an on apply on variant component, even if only one of it's attribute has a values that match with the product on the mo. Steps to reproduce: ------------------- * Create a Product with two never attributes (att1 and att2) * Add values to both attributes * Create a BOM with components with apply on variant for every possibility: - component att1 val1, att2 val1, apply on variant: att1 value 1 att2 value1 - component att1 val1, att2 val2, apply on variant: att1 value 1 att2 value2 - component att1 val2, att2 val1, apply on variant: att1 value 2 att2 value1 - ... * Add mto and manufacture to the product * Create and confirm a SO for the product variant att1 value 1 and att value 2 -> On the MO every component that as at least one of the values will be present. Observation: ------------- When confirming the SO it will call action_confirm. Since we are in mto, it will create a procurement order of the manufacture type and will create a MO. When creating the workorder, it will call explote on the bom to know all the components: https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/mrp/models/mrp_production.py#L626 Each line that does not respect the apply on variant condition will be ignored: https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/mrp/models/mrp_bom.py#L450-L451 it will retrieve the line if at least one value from any attribute match: https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/mrp/models/mrp_bom.py#L623-L626 opw-6293259 Forward-Port-Of: odoo/odoo#271351