Daily updates from Odoo
Friday, November 14, 2025
235 changes
2 changes
Resolved issues and error corrections
This change fixes an issue that could block users from adding attachments after saving an invoice email as a template. It keeps the email wizard linked to the correct document, preventing an error and making the sending flow work as expected.
Original PR description
Currently, an error occurs when trying to add an attachment after saving an invoice email as a template in the `Send wizard`. **Steps to produce:** - Install the `account` module. - Create a new…
Currently, an error occurs when trying to add an attachment after saving an invoice email as a template in the `Send wizard`. **Steps to produce:** - Install the `account` module. - Create a new invoice, fill in all required details, then `confirm` and click `Send`. - Click the `three-dot (⋮)` menu and select `Save as Template`, enter a name, and save the template. - Try to add an attachment. **Error:** `AttributeError: 'account.move.send.wizard' object has no attribute '_mail_post_access'` `AttributeError: 'account.move.send.wizard' object has no attribute '_get_thread_with_access'` Root **cause:** At [1], the code sets a new `template_id` when the template is saved. This triggers `_compute_model()` at [2], which updates the model field to `account.move.send.wizard` instead of `account.move`, using the `active_model` context, causing the `error`. **Fix:** This commit ensures that after saving a mail template, the wizard retains the correct model, same as [3], and prevents the attachment upload error. [1]: https://github.com/odoo/odoo/blob/5c6afcbffb49803a03e3a384ed60de68093dca04/addons/account/wizard/account_move_send_wizard.py#L296 [2]: https://github.com/odoo/odoo/blob/5c6afcbffb49803a03e3a384ed60de68093dca04/addons/account/wizard/account_move_send_wizard.py#L244-L248 [3]: https://github.com/odoo/odoo/blob/5c6afcbffb49803a03e3a384ed60de68093dca04/addons/mail/wizard/mail_compose_message.py#L380-L389 sentry-6987172677 Forward-Port-Of: odoo/odoo#234268
Follow-up payment reminder emails now send any attachments and dynamic reports that were configured on the email template. This ensures customers receive the full intended reminder message instead of only the basic email content.
Original PR description
### Issue: We can add attachments and dynamic report to the email templates, but they are not sent with follow-ups. ### Steps to reproduce: - Go to the "Payment reminder" email template - Under the…
### Issue: We can add attachments and dynamic report to the email templates, but they are not sent with follow-ups. ### Steps to reproduce: - Go to the "Payment reminder" email template - Under the page "Content", add an attachment by clicking the "Attachments" button - Under the page "Settings", add a dynamic report - Create an overdue invoice for a partner - Go on the form view of the partner, "Accounting" page - Click "Send", make sure the template used is the one with the attachments - Send - The attachments on the template and the dynamic report are not sent ### Cause: The mail template to send the follow-ups is only used to prefill the wizard. ### Solution: Add the template in `_get_wizard_options()` to add the template in the option and later use it to add/generate its attachments. This commit also refactors how the attachments are computed: The previous code was adding the invoices PDFs then removing them. The whole process was confusing. Now `options['attachment_ids']` is appended in `_get_followup_attachments()` with the desired attachments depending on the options. opw-5147736 Forward-Port-Of: odoo/enterprise#99458 Forward-Port-Of: odoo/enterprise#98454
2 changes
Resolved issues and error corrections
When returning to a Kanban view after removing a grouping, the system now correctly restores the record limit. This prevents the view from trying to load an excessive number of records, which could slow down the page or cause a crash.
Original PR description
Steps to reproduce ================== - Add a group by in the kanban product view - Switch to the list view - Remove the group by - Switch back to the kanban view -> No limit is applied, and the webclient can crash if too many records are returned. Cause of the issue ================== The groupsLimit is set as MAX_SAFE_INTEGER in the kanban view https://github.com/odoo/odoo/blob/df959e05ac9cf3136d1724bc80b7597a70932225/addons/web/static/src/views/kanban/kanban_controller.js#L168 Which is then reused as the limit https://github.com/odoo/odoo/blob/df959e05ac9cf3136d1724bc80b7597a70932225/addons/web/static/src/model/relational_model/relational_model.js#L368 Solution ======== There is already a code path to reset the limit when switching from grouped to ungrouped, but is wasn't called on the first load (when this.root isn't set yet) opw-5167769 Forward-Port-Of: odoo/odoo#235598 Forward-Port-Of: odoo/odoo#235232
Event registration emails will no longer show a price when the attendee’s ticket is fully discounted and the total is zero. This avoids confusing customers with an amount that is not actually due.
Original PR description
Steps to reproduce: 1. Create a new sale order with an event ticket line 2. Apply a 100% discount on the ticket line 3. Confirm the sale order 4. Check on the new attendee created, the mail sent to the attendee. Current behavior: The email shows the unit price without the discount applied which can be confusing for the customer as it might look like they need to pay that amount. After this commit: The email will just show the confirmation of the registration to the event withouth mentioning the price when the total price is 0. opw-5122776 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235482
1 change
Resolved issues and error corrections
Users without full administration rights can now revoke SEPA direct debit mandates even when those mandates were used for customer portal payments. This prevents an access error and ensures the related saved payment methods are archived automatically.
Original PR description
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** -…
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** - Enable SEPA Direct Debit payment provider in Test Mode - Create a mandate for a customer w/ valid IBAN - Create an invoice for that customer and post it - Action > Generate a Payment Link, open this in an incognito window - Pay using SEPA Direct Debit - Call `_set_done()` on the payment.transaction - Try to revoke the mandate as a non-admin with "Accounting / Billing" -> Access Error, can't modify payment.token **Cause:** - When SEPA Mandate is revoked, we check for all associated payment tokens (saved payment methods from SEPA Direct Debit payment provider) and deactivate them. - The check in code isn't called with sudo, so it uses the current user access rights, but only admins can modify the payment tokens in any way. **Solution:** - Write to the `linked_tokens` with sudo so we can archive the tokens regardless of user access opw-5136221 Forward-Port-Of: odoo/enterprise#99447 Forward-Port-Of: odoo/enterprise#99232
27 changes
Resolved issues and error corrections
This fix makes sure sales orders are no longer shown as fully invoiced when their linked invoice has been canceled. It keeps the invoice status accurate, which helps teams trust the order and billing information they see.
Original PR description
Since 81f25bc, _compute_qty_invoiced would not reset the field to zero when the linked invoice was canceled, meaning that sale orders would be still be flagged as 'Fully Invoiced'. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When a helpdesk refund is created from a sales order, the credit note now keeps only the product that was actually selected for refund. This also narrows the product suggestions in the refund wizard to the products linked to the original sales order, avoiding confusion and incorrect refunds.
Original PR description
_ ## Short functional explanation of the error Let's say a customer buys 2 products. An SO is created. This customer wants to refund only one of the 2 products. He sends a ticket to helpdesk and we…
_ ## Short functional explanation of the error Let's say a customer buys 2 products. An SO is created. This customer wants to refund only one of the 2 products. He sends a ticket to helpdesk and we click on refund. Even if we specify the product to refund, this action creates a credit note containing both products (previously present on the SO) instead of only the one to refund. Additionally, when selecting the product, we could see in the dropdown of suggestions all the existing products, instead of only the ones related to the SO. ## Reproduction Steps 1. Create a SO containing 2 different products and confirm it. 2. Create a regular invoice and confirm. 3. Go to Helpdesk. Click on the configuration tab, and helpdesk teams. 4. Click on your helpdesk team, scroll down. In After-Sales, check "Refunds". 5. Create a ticket and specify the customer who wants to refund. Make sure the correct helpdesk team is assigned. 6. Click on refund. It opens the wizard. Specify the product to refund and the Invoices to Refund. 7. Click on reverse. ### Expected behavior A credit note containing only the specified product to refund should be created. ### Unexpected behavior The created credit note contains both products originally present on the SO. ## Origin of the issue When issuing a refund from helpdesk_stock_account, this piece of code is called: https://github.com/odoo/enterprise/blob/2051e84c55618c64179c4b9f3e99f4e795bacd32/helpdesk_stock_account/wizard/account_move_reversal.py#L16-L17 which calls the ```reverse_moves``` method in the helpdesk_account.py file, which itself calls the ```reverse_moves``` method in the account_move_reversal.py file, in the account module, and so on. Finally, we arrive in the account_move.py file. In the ```_reverse_moves``` of this file, we can see the code: https://github.com/odoo/odoo/blob/bee7fc1f955c52a88b527ad9a2ddf0021529bbc7/addons/account/models/account_move.py#L4937-L4947 where we simply copy all the lines of the move in the SO without filtering them. As a result, we get the lines of the product we don't want to refund __ opw-5148789 Forward-Port-Of: odoo/enterprise#98771
This fix ensures user presence updates are handled correctly whether they arrive through the web interface or via the websocket connection. It helps keep online status tracking reliable and prevents missed presence updates.
Original PR description
update_presence can both be called in http and with websocket as explained here: https://github.com/odoo/odoo/commit/de6de48deb983be910876c6133c2869907c142f7 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change fixes a barcode scanning issue in batch picking so the system correctly waits for the previous processing step to finish. It helps prevent intermittent scan errors and makes the picking workflow more reliable.
Original PR description
Commit bc9247d46225c696842bc7b0e3c883320231ab1b has introduced an override of the `processBarcode` method. However, it does not return nor await the super call. In particular, in the case where the super call should be done the overrides returns "undefine" rather than a promess to await and hence that call is not awaited anymore. Note: This error has been noticed from the fact that the test `test_barcode_batch_scan_lots` sometimes fails on step 29/31. runbot-233631 Forward-Port-Of: odoo/enterprise#99303
This fix ensures purchase orders no longer stay marked as invoiced when the related vendor bill is canceled. The invoice quantity is now recalculated properly, so the order status reflects the real billing situation.
Original PR description
Since 81f25bc57b8433a65bf33950c64dc7582240a229, `_compute_qty_invoiced` was not resetting the field to zero when the linked invoice was canceled, resulting in purchase orders remaining in status `invoiced` even if there was no invoice any more. With this commit, we always write the qty_invoiced on the purchase order line, and the status is recomputed accordingly. Source: post odoo.com migration feedback
Opening the chat icon from an employee’s profile now works correctly instead of showing an error. This fixes a broken user action and ensures employees with linked user accounts can be contacted directly from their form view.
Original PR description
Before this commit, when opening a chat with an employee from the form view it would result in a traceback. Steps to reproduce: 1. Open the form view of an employee that has a user associated 2. Click the "chat" icon next to their name -> traceback This happens because the `getChat` method would insert a Persona record in the Store with a displayName field which has been changed to a setter in [1]. This commit fixes the issue by setting the `name` field instead. [1] https://github.com/odoo/odoo/pull/234702 Forward-Port-Of: odoo/odoo#235279
This fix lets vendor bills and invoices with deferred amounts be reset to draft multiple times, even when audit trail controls are enabled. It removes a restriction that could block users from correcting or reprocessing these documents after an initial reset.
Original PR description
Resetting a vendor bill or invoice with deferred amounts will unlink or reset all existing deferred entries. If the audit trail is enabled, some of these entries must be cancelled instead. [AccountMove.button_draft()](https://github.com/odoo/enterprise/blob/a3f461040cb3443fbcb190c28fddae7044bbd1e7/account_accountant/models/account_move.py#L80-L88) If a protected entry is already cancelled, `AccountMove._unlink_or_reverse()` will still attempt to cancel it. This prevents entries from being Reset to Draft more than once. The current commit removes this restriction. opw-5187737 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235223
This change prevents an access error that could appear when opening the Documents app after a company was archived. It ensures folders are only fetched for companies the user can still access, so the app opens reliably without unexpected permission issues.
Original PR description
**Steps to reproduce:** - Add some folders - Create a new company - Assign some folders to the new company - Archive the company - Click on Documents app - AccessError is raised when opening it…
**Steps to reproduce:** - Add some folders - Create a new company - Assign some folders to the new company - Archive the company - Click on Documents app - AccessError is raised when opening it **Issue:** The issue seems to be related to caching issue on the field `type` when fetching the documents with `search_panel_select_range` and going through `_compute_display_name`: `folders = accessible_records.filtered(lambda d: d.type == 'folder')` This error was quite inconsistent and might be related to the cache missing some prefetched data on a record it shouldn't have been able to read. There is a need to ensure only the folders available to the user are able to be fetched. **Fix:** Added the `type` field in the `search_panel_fields` but this might not be needed if the issue comes from elsewhere. For now the issue was mitigated by explicitly checking for the user companies in the domain of the searchs, but it needs to be checked as this behavior might break other flows. opw-4931278 Forward-Port-Of: odoo/enterprise#99043 Forward-Port-Of: odoo/enterprise#96817
Message attachments that are images now display in their full size instead of being cropped into a square preview. This makes it easier for users to understand shared images at a glance without opening them in a separate viewer.
Original PR description
Before this commit, images attached to a message had their preview cropped and forced people to view with file viewer. This square and cropped visual looks good in contexts other than message, e.g. chatter attachment list. In message, however, most of the time people want to share images and be able to see whole content just from preview. This commit fixes the issue by making image preview of message see whole content. Task-5259604 Before <img width="1360" height="788" alt="Screenshot 2025-11-13 at 17 49 30" src="https://github.com/user-attachments/assets/d84c245e-2501-4e5b-9e32-10f0ae882b7e" /> After <img width="1366" height="831" alt="Screenshot 2025-11-13 at 17 49 39" src="https://github.com/user-attachments/assets/ce27f9eb-1f9a-4802-9590-fa69e8c40140" />
The call settings dropdown in the Mail app has been adjusted so its options, icons, and toggles are clearly visible in light mode. This also removes an unwanted border on click and corrects spacing, making the call settings easier and more reliable to use.
Original PR description
**Current behavior before PR:** When opening the dropdown to select input/output devices during calls in light mode, the following issues were observed: - select options had white text on white…
**Current behavior before PR:** When opening the dropdown to select input/output devices during calls in light mode, the following issues were observed: - select options had white text on white background, making them unreadable. - The select's down arrow icon was invisible. - The toggle thumb was barely visible when unchecked. - A border appeared unnecessarily when the dropdown was clicked (in both light and dark mode). - The blur background toggle spacing was incorrect. **Desired behavior after PR is merged:** - select options now have a dark gray background ($gray-700), ensuring proper contrast and readability in light mode. - The select's down arrow icon and toggle elements have consistent visibility. - The extra border on dropdown click is removed. - The toggle spacing is visually corrected. task-5163527 > **Note:** Spotted in Chrome Browser **Before:** <img width="945" height="438" alt="image" src="https://github.com/user-attachments/assets/fdfa24a4-c089-428c-b20d-0cdd4a7fb945" /> <img width="189" height="40" alt="image" src="https://github.com/user-attachments/assets/88a3372e-7ee6-4be5-b224-51c1c998a5e0" /> **After:** <img width="743" height="319" alt="image" src="https://github.com/user-attachments/assets/a06eb60c-88e2-4c75-852b-6e04a06a6336" /> <img width="212" height="51" alt="image" src="https://github.com/user-attachments/assets/602ea08f-edaa-472f-884f-81c36afe1429" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Website SEO dialog no longer opens too early while the page preview is still loading. This prevents a crash on slow connections and makes the editing experience more reliable for users.
Original PR description
Steps to reproduce: - Open Website app and enter edit mode on any page. - Reload the page with a slow connection. - Immediately open "Optimize SEO" from the navbar menu. Before this commit, the dialog accessed the preview document while the iframe was reloading, so reading location.origin raised a TypeError. After this commit, the dialog waits for the iframe to finish loading or returns immediately when it is already complete, preventing crashes. task-5104033 Forward-Port-Of: odoo/odoo#235231 Forward-Port-Of: odoo/odoo#230820
The point of sale receipt now displays the cashier or server name even when a preset like "Eat in" is used. This ensures customers always see who handled the order, improving clarity and accountability at checkout.
Original PR description
Currently cashier name is only shown if no preset is shown or if the present identification is set on name. Steps tot reproduce: -------------------- * Open restaurant * Make sure you use the Eat in preset * Place an order and pay it > Observation: On the receipt the "Served by:" indication is not shown. Why the fix: ------------ The cashier/server information should not depend on the preset used. opw-5154347 Forward-Port-Of: odoo/odoo#234767 Forward-Port-Of: odoo/odoo#231930
This change restores employee lookup results in forms for users who do not have access to the Employees app, including on mobile. It ensures employee records can still be selected when they are used as a related field, so users no longer see an empty result list.
Original PR description
**Steps to reproduce** - With Studio, create a many2one field in relation to the Employee model. - Have a user with no "Employees" rights. - With this user and in mobile view, click on the field to…
**Steps to reproduce** - With Studio, create a many2one field in relation to the Employee model. - Have a user with no "Employees" rights. - With this user and in mobile view, click on the field to select an employee. -> No records found. Note: the many2one_avatar_employee widget used in HR apps avoid this problem. **Cause** Issue since https://github.com/odoo/odoo/commit/e962860c6f0d8ec9e50bb376e1faab5c7bc69374 The `web_search_read` on the private employee model returns no records when an `image_*` or `avatar_*` field is part of the requested fields. This is because we try to fetch these fields https://github.com/odoo/odoo/blob/188a3fe45fb41463ff86d1fa5e930ab43fb70d0e/addons/hr/models/hr_employee.py#L240 but they are not stored on the public employee model, and will not be put in cache. When performing a read after that, these fields are missing from cache. We try to fetch them from the db https://github.com/odoo/odoo/blob/e962860c6f0d8ec9e50bb376e1faab5c7bc69374/odoo/models.py#L3185 but this fetch is again done using the public employee. This results in missing values and is interpreted as an access error, no data is returned in `web_search_read`. **Solution** Read the problematic fields to make them present in cache when the cache of the public employee is copied to the one of the private employee. opw-4297115 Forward-Port-Of: odoo/odoo#234806 Forward-Port-Of: odoo/odoo#197575
This update prevents an error that could appear when users clicked the Edit Configuration button on a quotation line after the product name had been removed. It makes the button only available when a configurable product is actually selected, avoiding a broken user experience.
Original PR description
Currently, when a user adds a configurable product to an order line, and remove the name of product and click on `Edit Configuration` (pencil icon) error is encountered. **Steps to Reproduce:** -…
Currently, when a user adds a configurable product to an order line, and remove the name of product and click on `Edit Configuration` (pencil icon) error is encountered. **Steps to Reproduce:** - Install Sales module - Create a Quotation - Add a product(e.g Acoustic Bloc Screen), then only remove the name from the orderline and click on **edit button(pencil Icon)**. **Error:** `TypeError: SaleProductConfiguratorController.sale_product_configurator_get_values()` `missing 1 required positional argument: 'product_template_id'` **Root Cause:** When a user clicks on Edit configuration, the client-side JavaScript makes an RPC call to the server, targeting the `sale_product_configurator_get_values`. which expects product_template_id at [1] and since it is removed from order line the error is encountered. [1]- https://github.com/odoo/odoo/blob/1b657cf1e1ce43874a3ede307b2f8ad68216aa56/addons/sale/controllers/product_configurator.py#L11-L13 **Solution:** This commit prevents the error by correcting `depends` on the field `is_configurable_product`, which will ensure that edit button will be only present if the configurable product is selected. Sentry-5741581459, 6925770690 Forward-Port-Of: odoo/odoo#217464
This change makes interval processing more reliable by ensuring interval data is normalized before it is merged. It prevents inconsistencies and occasional errors that could appear when different interval types were combined, especially in planning-related operations.
Original PR description
## The issue Prior to this commit, the `other` parameter in the `_merge` method could belong to a different class, not necessarily an instance of `Intervals`.…
## The issue Prior to this commit, the `other` parameter in the `_merge` method could belong to a different class, not necessarily an instance of `Intervals`. https://github.com/odoo/odoo/blob/8c737601327acec1d83e1e5e3c6e66c9fd226339/addons/resource/models/utils.py#L158-L165 The comment indicates that normalization should be enforced; however, there is no corresponding reference to it within the `_boundaries` method. https://github.com/odoo/odoo/blob/8c737601327acec1d83e1e5e3c6e66c9fd226339/addons/resource/models/utils.py#L48-L53 That normalization just happens in the `__init__`. https://github.com/odoo/odoo/blob/8c737601327acec1d83e1e5e3c6e66c9fd226339/addons/resource/models/utils.py#L117-L132 ## Example For example, in Planning module, we perform operations between `Intervals` and `WorkIntervals`. The `WorkIntervals` class behaves differently from `Intervals`: while `Intervals` uses disjoint closed intervals, `WorkIntervals` uses disjoint semi-closed intervals. ## Side effects During these operations, the `_merge` method was not normalizing the `_items`, which caused inconsistencies and errors (when we are merging two unormalized intervals `([0, 10], [10, 20])` with an empty `others`). ## The fix This commit ensures that the `other` parameter is normalized before processing the `_merge` operation. The fix ensures that normalized intervals are always produced after `_merge`, even when unnormalized intervals are provided as input. ## Real case That issue has been found in that ticket: 5184291 Forward-Port-Of: odoo/odoo#235233 Forward-Port-Of: odoo/odoo#234352
This update ensures duplicated spreadsheets always load the latest version instead of sometimes reusing an outdated browser cache. It helps users avoid seeing missing or stale changes after copying a spreadsheet tab.
Original PR description
It happens that browser may use a cache if there's no explicit cache control/expiration time: https://httpwg.org/specs/rfc9111.html#heuristic.freshness Steps to reproduce (non-deterministic): - create a new spreadsheet - do some changes, edit a few cells - right click on the tab and hit "Duplicate" => the spreadsheet is not up-to-date on the duplicated tab. The browser loaded the response from "disk cache" instead of fetching the latest data from the server. I'm using Chrom Version 142.0.7444.162 (Official Build) (64-bit) We add an explicit cache control. Forward-Port-Of: odoo/enterprise#99426
The website now only shows the language selector when there is actually more than one language available. This prevents an empty list item from appearing in the header, which could create an unnecessary border or blank space.
Original PR description
This PR calls the language selector placeholder only when multiple languages exist, avoiding an empty header list item that creates an unnecessary border or empty space. task-5150808 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234345 Forward-Port-Of: odoo/odoo#231256
The website now correctly updates the displayed price without national taxes when a quantity-based fixed price starts to apply. This ensures shoppers in Argentina see the right tax-free price as they change quantities, avoiding confusing mismatches on product pages.
Original PR description
Versions -------- - saas-18.4+ Steps ----- 1. Have a company with Argentinian localization; 2. in Website settings, enable "Display Price without National Taxes"; 3. add a quantity-based fixed price on the website's pricelist; 4. go to a product page where the fixed price can be applied; 5. increase quantity so the fixed price should apply. Issue ----- The price without national taxes isn't getting updated. Cause ----- In the `_get_additional_combination_info` override, the given `quantity` gets ignored, as well as the pricelist price for product variants, instead defaulting to their `lst_price`. Solution -------- Pass the quantity to `_compute_price_rule`, and use the result for both templates & variants. opw-5040056 Forward-Port-Of: odoo/odoo#232480
Follow-up reminder emails now correctly send any files attached to the email template, including dynamic reports. This ensures customers receive all intended documents with their payment reminders, instead of only seeing them prefilled in the sending wizard.
Original PR description
### Issue: We can add attachments and dynamic report to the email templates, but they are not sent with follow-ups. ### Steps to reproduce: - Go to the "Payment reminder" email template - Under the…
### Issue: We can add attachments and dynamic report to the email templates, but they are not sent with follow-ups. ### Steps to reproduce: - Go to the "Payment reminder" email template - Under the page "Content", add an attachment by clicking the "Attachments" button - Under the page "Settings", add a dynamic report - Create an overdue invoice for a partner - Go on the form view of the partner, "Accounting" page - Click "Send", make sure the template used is the one with the attachments - Send - The attachments on the template and the dynamic report are not sent ### Cause: The mail template to send the follow-ups is only used to prefill the wizard. ### Solution: Add the template in `_get_wizard_options()` to add the template in the option and later use it to add/generate its attachments. This commit also refactors how the attachments are computed: The previous code was adding the invoices PDFs then removing them. The whole process was confusing. Now `options['attachment_ids']` is appended in `_get_followup_attachments()` with the desired attachments depending on the options. opw-5147736 Forward-Port-Of: odoo/enterprise#99458 Forward-Port-Of: odoo/enterprise#98454
This change ensures invoices sent to ZATCA use the right submission path when the customer belongs to a parent company. Instead of treating these cases as simplified invoices, Odoo now checks the customer’s main commercial entity so company-related invoices are sent through the clearance process as expected.
Original PR description
…earance or reporting api When sending an invoice to ZATCA, if the contact is an individual, the invoice is sent through the reporting API, and if the contact is a company, the invoice is sent through the clearance API. As of now, if the contact has a parent company, the invoice is sent through the report api. However, we need to make sure that in this case, the invoice goes through the clearance api. The fix introduced simply checks the partner_id.commercial_partner_id to decide whether the invoice is a simplified invoice (i.e. through the reporting api) or not. Task-5085142 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#234691
The OEE smart button on workcenter screens now shows the same value as the detailed OEE report. This fixes a rounding mismatch so users see a more accurate and consistent efficiency measure.
Original PR description
**Current behavior:** The form view for a workcenter has an OEE smart button which can display a different value from the real OEE displayed by the `mrp_workcenter_productivity_report_oee` displayed…
**Current behavior:** The form view for a workcenter has an OEE smart button which can display a different value from the real OEE displayed by the `mrp_workcenter_productivity_report_oee` displayed when actually clicking the button and looking at the report. **Expected behavior:** Same values **Steps to reproduce:** 1. Make a workcenter and a BoM with an operation performed at the workcenter 2. Use the BoM in an MO such that there is some un-productive time (e.g., recorded production duration takes longer than expected duration) * example: 0:20 expected, 1:01 actual 3. Go to the workcenter list view -> click on the created workcenter -> look at OEE smart button display value -> click on it to see report -> report values are different **Cause of the issue:** the `oee` field on the workcenter is computed with rounded intermediary `blocked_time` and `productive_time` values, the actual report uses the raw values. **Fix:** Don't use the rounded intermediary values in computing `oee`. Post-this-diff, we actually do one less `_read_group` (along with computing a more accurate field value). opw-4795463 Forward-Port-Of: odoo/odoo#232730 Forward-Port-Of: odoo/odoo#218310
This change prevents users from cancelling purchase orders that have been locked. If someone needs to cancel a locked order, they must unlock it first, which helps protect confirmed orders from accidental changes and keeps records consistent.
Original PR description
Issue before this commit: ========================== Locked purchase orders could still be cancelled, which defeats the purpose of locking them. Steps to reproduce: ========================== 1. Install the `purchase` module. 2. Enable "Lock Confirmed Orders" in the configuration. 3. Create and confirm a purchase order. 4. Lock the purchase order. 5. Try to cancel it → the PO still gets cancelled despite being locked. After this commit: =========================== Cancelling a locked purchase order is no longer allowed. If a user tries to cancel a locked PO, a UserError will be raised instructing them to unlock it first. Locking a purchase order is intended to prevent accidental changes, including edits and cancellations, once the order is confirmed. With this change, users must explicitly unlock a purchase order before cancelling it, ensuring better control and data integrity. TaskId: 4760864 Forward-Port-Of: odoo/odoo#208716
This change makes website image editing tests more reliable by ensuring image-related data and editor resources are loaded before the test continues. It removes timing-related failures, which helps the test suite run consistently and reduces false failures in development and CI.
Original PR description
The goal of this commit is to fix the indeterminate tests related to image editing in the website builder. Problem: ===== Some tests related to image editing on the website fail in an indeterminate…
The goal of this commit is to fix the indeterminate tests related to image editing in the website builder. Problem: ===== Some tests related to image editing on the website fail in an indeterminate manner. This test failure is related to the sidebar's async. When selecting an image, the Image options need to fetch certain data (the original image, etc.). The “html_editor.assets_image_cropper” bundle is also loaded. This loading time can exceed 200 ms, causing the test to fail unpredictably. Solution: ====== 1.Preload the “html_editor.assets_image_cropper” bundle and store it in the cache. 2. Use `waitSidebarUpdated` when selecting an image. `waitSidebarUpdated`` will wait until all the data is loaded and the sidebar is updated. This solution is not optimal, but it will make all the tests deterministic. The best solution: ========= We should mock or preload all the data needed for the tests. This change requires adapting the current production code to make it easily patchable to mock, for example, “.text()” on a response to an image fetch. Error: https://runbot.odoo.com/odoo/error/232956 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234312
This change prevents the partner fiscal country list from showing the same country code twice in some cases. It avoids a form display issue and keeps the data cleaner without changing the intended business behavior.
Original PR description
Recently we started considering `country_code` as part of the `fiscal_country_codes` [1]. Because of this, the field can now contain duplicates. If your active company is a US one, and you set United States as the country on the partner you end up with `US,US`. It breaks some (admittedly fragile) invisible conditions on the `res.partner` form view [2]. Although we could fix those conditions, it would require everyone to update the module, and having duplicate country codes in `fiscal_country_codes` field doesn't serve any purpose anyway. [1] https://github.com/odoo/odoo/pull/229584 [2] https://github.com/odoo/enterprise/pull/62615 opw-5248844 opw-5241556 Forward-Port-Of: odoo/odoo#235652
This change fixes an error that could happen when users saved an invoice email as a template and then tried to add an attachment. The send wizard now keeps the correct document context, so attachment uploads continue to work normally.
Original PR description
Currently, an error occurs when trying to add an attachment after saving an invoice email as a template in the `Send wizard`. **Steps to produce:** - Install the `account` module. - Create a new…
Currently, an error occurs when trying to add an attachment after saving an invoice email as a template in the `Send wizard`. **Steps to produce:** - Install the `account` module. - Create a new invoice, fill in all required details, then `confirm` and click `Send`. - Click the `three-dot (⋮)` menu and select `Save as Template`, enter a name, and save the template. - Try to add an attachment. **Error:** `AttributeError: 'account.move.send.wizard' object has no attribute '_mail_post_access'` `AttributeError: 'account.move.send.wizard' object has no attribute '_get_thread_with_access'` Root **cause:** At [1], the code sets a new `template_id` when the template is saved. This triggers `_compute_model()` at [2], which updates the model field to `account.move.send.wizard` instead of `account.move`, using the `active_model` context, causing the `error`. **Fix:** This commit ensures that after saving a mail template, the wizard retains the correct model, same as [3], and prevents the attachment upload error. [1]: https://github.com/odoo/odoo/blob/5c6afcbffb49803a03e3a384ed60de68093dca04/addons/account/wizard/account_move_send_wizard.py#L296 [2]: https://github.com/odoo/odoo/blob/5c6afcbffb49803a03e3a384ed60de68093dca04/addons/account/wizard/account_move_send_wizard.py#L244-L248 [3]: https://github.com/odoo/odoo/blob/5c6afcbffb49803a03e3a384ed60de68093dca04/addons/mail/wizard/mail_compose_message.py#L380-L389 sentry-6987172677 Forward-Port-Of: odoo/odoo#234268
This change corrects where rounding is applied in accounting tests and related logic, so amounts are handled more consistently. It also updates outdated test comments and adjusts sample values to better verify the behavior, reducing the risk of small calculation errors.
Original PR description
Also fixes the comments that were wrong. Change some values to better test things 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#235557 Forward-Port-Of: odoo/odoo#234213
When an attendee is created from a free or fully discounted ticket, the confirmation email will no longer display a misleading unit price. This makes the message clearer for customers and avoids confusion about whether payment is still due.
Original PR description
Steps to reproduce: 1. Create a new sale order with an event ticket line 2. Apply a 100% discount on the ticket line 3. Confirm the sale order 4. Check on the new attendee created, the mail sent to the attendee. Current behavior: The email shows the unit price without the discount applied which can be confusing for the customer as it might look like they need to pay that amount. After this commit: The email will just show the confirmation of the registration to the event withouth mentioning the price when the total price is 0. opw-5122776 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235482
2 changes
Resolved issues and error corrections
This fix prevents an error that could appear when paying a Point of Sale order with change using a black box setup. It allows the system to complete the necessary internal updates without blocking the payment flow, improving reliability at checkout.
Original PR description
When paying an order with change with blackbox, the backend would raise an error telling "Modifying a registered order is not allowed". This is due because of some backend recomputation. To avoid this, we add a context key to bypass blackbox checks during backend recomputation. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Odoo’s email processing has been updated to recognize the CP-850 character encoding alias. This prevents certain incoming emails from failing to be read and helps ensure messages from external systems are processed without errors.
Original PR description
While investigating a few support tickets related to how the l10n_cl override the fetch mail methods, we noticed a more general issue: As of now, the payload parsing business logic of Odoo can't…
While investigating a few support tickets related to how the l10n_cl override the fetch mail methods, we noticed a more general issue:
As of now, the payload parsing business logic of Odoo can't handle emails encoding parts with `charset=cp-850`.
This is due to the fact that `cp-850` is not a accepted/standard encoding alias for cp850 charsets in python's `encoding` library.
Whether or not a mail stack should generate mail using `charset=cp-850` or not, we this fix aims at pro-actively declaring `cp-850` as a valid alias for cp850, so that implicitly the email CPython library can correctly decode the payloads in emails.
### Before this bug:
Sending a mail using `charset=cp-850` would generate a traceback.
Example:
```
From: Sender Name <sender@example.com>
To: Recipient Name <odooalias@example.com>
Subject: Test Email with CP-850 Encoding
Date: Thu, 13 Nov 2025 12:00:00 +0100
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----------=_4987654321-00000000"
This is a multi-part message in MIME format.
------------=_4987654321-00000000
Content-Type: text/plain; charset=cp-850
Content-Transfer-Encoding: quoted-printable
Hallo, dit is een test met een =82 speciale letter.
=
------------=_4987654321-00000000--
```
Would generate:
```
File "/home/odoo/src/odoo/addons/mail/models/mail_thread.py", line 1398, in message_process
msg_dict = self.message_parse(message, save_original=save_original)
File "/home/odoo/src/odoo/addons/mail/models/mail_thread.py", line 1792, in message_parse
msg_dict.update(self._message_parse_extract_payload(message, msg_dict, save_original=save_original))
File "/home/odoo/src/odoo/addons/mail/models/mail_thread.py", line 1592, in _message_parse_extract_payload
content = part.get_content()
File "/home/odoo/miniconda3/lib/python3.10/email/message.py", line 1096, in get_content
return content_manager.get_content(self, *args, **kw)
File "/home/odoo/miniconda3/lib/python3.10/email/contentmanager.py", line 22, in get_content
return self.get_handlers[maintype](msg, *args, **kw)
File "/home/odoo/miniconda3/lib/python3.10/email/contentmanager.py", line 67, in get_text_content
return content.decode(charset, errors=errors)
LookupError: unknown encoding: cp-850
```
### After fix:
`content = part.get_content()` correctly handles the `cp-850` alias
OPW-5171501
OPW-5247486
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#2355291 change
Resolved issues and error corrections
This fix removes hidden newline characters from fields used in Swiss QR codes. It helps ensure the codes are formatted correctly and accepted by banks or payment systems without rejection.
Original PR description
Swiss QR codes have required information for each line of the QR code. Newline characters present in a field's content shift the content to a different line than intended, causing the QR code to be rejected. This commit removes newline characters from the field elements and alters a unit test to check if this issue occurs again. opw-5095997 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr