Friday, June 26, 2026
168 changes
9 changes
Resolved issues and error corrections
This change prevents a crash that could happen when loading accounting charts for Spanish templates in certain setup flows. It makes the loading process more robust by avoiding a missing-data lookup, so chart setup and tests complete reliably.
Original PR description
Description of the issue this commit addresses: In single-app and patched chart-template flows, template_data can be provided without a parent key. l10n_es accessed template_data['parent'] in _post_load_data, raising KeyError during chart loading and test setup. --- Desired behavior after this commit is merged: This commit checks ES template ancestry from template_code instead of reading parent from template_data, avoiding KeyError when that key is absent while keeping the post-load logic scoped to ES template chains. --- runbot-[242586](https://runbot.odoo.com/odoo/error/242586) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix removes an unnecessary block that stopped Gemini 3 from being used with tools and structured responses. As a result, AI features can work again for website SEO optimization and for retrying failed AI actions when another provider is unavailable.
Original PR description
Purpose: -------- Gemini models since gemini-3 support requests with tools and structured outputs. The exception in the code is now raised only for gemini-2.5 models. This exception was preventing to use an agent with gemini 3 to optimize SEO in ai_website, or to retry failed ai fields or ai server actions on the saas when the request to openAI failed. Task-6335595
This change lets Odoo keep very small base unit counts without rounding them away, so product reference prices are calculated correctly for large-pack items. It improves pricing accuracy for cases like selling screws in boxes of 10,000 or similar bulk packaging.
Original PR description
**Description of the issue/feature this PR addresses:** The `Product Reference Price` feature in `website_sale` cannot correctly handle products sold in large packs when the reference quantity…
**Description of the issue/feature this PR addresses:** The `Product Reference Price` feature in `website_sale` cannot correctly handle products sold in large packs when the reference quantity requires a very small `base_unit_count`. For example, a product sold as a `box of 10000` screws should be able to use `0.0001` as its `Base Unit Count`, so the reference price can be computed against the box quantity correctly. **Current behavior before PR:** `base_unit_count` uses the default float precision, so values with more than two decimal places are rounded in the product form. When trying to set `Base Unit Count` to `0.0001`, the value is rounded to `0.00` / `0.01`, which makes the Product Reference Price computation incorrect. Steps to reproduce: 1. Go to Settings > Website and enable Product Reference Price. 2. Create or open a product named `Screws`. 3. Set Sales Price to `$ 1.00`. 4. On the product form, set Base Unit Count to `0.0001`. 5. In Custom Unit of Measure, type `box of 10000` and press Create. <img width="1374" height="740" alt="1" src="https://github.com/user-attachments/assets/2d4f7863-b2cd-4c7c-87e1-11526dc50551" /> **Desired behavior after PR is merged:** `base_unit_count` keeps high-precision values such as `0.0001`. This allows `Product Reference Price` to correctly support large-pack scenarios, such as selling screws in a `box of 10000`, by storing `base_unit_count` with unlimited numeric precision. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262579
This update stops popup snippets from being added in places where they should not be available, such as inside other popups. It also ensures the available snippets are refreshed correctly after changes, helping avoid errors and keeping the website editor more reliable.
Original PR description
*: website, website_mass_mailing __Problem__ In some cases, popup snippets can be dropped inside another popup. This shouldn't be possible. Moreover, it produces the following error: `TypeError:…
*: website, website_mass_mailing __Problem__ In some cases, popup snippets can be dropped inside another popup. This shouldn't be possible. Moreover, it produces the following error: `TypeError: Cannot read properties of undefined (reading 'after')`. This can happen in multiple scenarios: - After saving a custom snippet, the snippets are reloaded but `disableUndroppableSnippets` is not called again, although the snippets should be filtered again. - `NewsletterPopupPlugin` registers `.o_newsletter_popup` in the `so_snippet_addition_selector` resource, bypassing the more restrictive `dropzone_selector` of `PopupOptionPlugin`. - Popups are not disabled when the cookie bar is open because we don't take `excludeAncestor` into account in `DisableSnippetsPlugin`. __Fix__ - Trigger an event whenever the snippets are loaded and call `disableUndroppableSnippets` when it is. - Remove the redundant `NewsletterPopupPlugin`. - Filter `dropAreaEls` with `excludeAncestor` in `DisableSnippetsPlugin`. Forward-Port-Of: odoo/odoo#271635 Forward-Port-Of: odoo/odoo#269864
The Shopee connector now handles customer identifiers that are larger than the older supported range. This prevents errors when creating new contacts and ensures Shopee orders can still be matched to the correct customer.
Original PR description
When the Shopee connector was introduced, Shopee documented `buyer_user_id` as an int32. We therefore store it in an `Integer` field, which maps to a PostgreSQL int32 column. However, feedback showed that Shopee can send ids exceeding the int32 bounds, leading to a traceback when creating new contacts. Shopee has since updated their documentation to confirm the field is actually an int64. Since we are in stable and cannot change the column type, this commit falls back to the `ref` field of the `res.partner` model to store and match Shopee contacts whose identifier doesn't fit within an int32. opw-6325948 See also: - master: https://github.com/odoo/enterprise/pull/121507 - upgrade: https://github.com/odoo/upgrade/pull/10578 Forward-Port-Of: odoo/enterprise#121498
This fix prevents POS down payments from being counted twice when calculating how much is still left to invoice on a sales order. It ensures the final invoice shows the correct remaining amount and avoids negative invoice balances.
Original PR description
Steps to reproduce --- 1. Create and confirm a sale order 2. In the POS, settle it with a down payment and invoice the down payment 3. From the sale order, create and post the final invoice Issue --- The order ends up with a negative amount to invoice. The pos_sale override https://github.com/odoo/odoo/blob/a1bcd917846493d08dd02b63e6110078ff5156a3/addons/pos_sale/models/sale_order.py#L83-L88 always subtracts the amount paid in the POS, which is required before the final invoice because the down payment sits on a separate line the base computation ignores; but once the final invoice is posted that down payment is already deducted through its negated line, so subtracting it again counts it twice and pushes amount to invoice below zero. opw-6261272 Forward-Port-Of: odoo/odoo#269323
This change fixes the Apps > Industries page so filters can be applied again. It improves the way industry listings are prepared in the background, allowing users to narrow down results more easily when browsing apps by industry.
Original PR description
Before this commit, no filter could be applied on Apps > Industries menu, because the module list returned by the appstore was difficult to filter as is. This commit uses the `new` command to create temporary ir.module.module such that any filtering domain can be applied, providing that the filter condition is available from the appstore controller. task-6067092 Forward-Port-Of: odoo/odoo#270005
This update prevents the Point of Sale from crashing when a Pine Labs payment is force-cancelled after the terminal has already timed out or been cancelled. It improves the cancellation flow so staff can safely close the payment without seeing an error screen.
Original PR description
**Step to Reproduce:** 1. Open the POS. 2. Add any product to the order. 3. Proceed to the payment screen and select `Pine Labs` as the payment method. 4. Observe that the Pine Labs terminal does not…
**Step to Reproduce:** 1. Open the POS. 2. Add any product to the order. 3. Proceed to the payment screen and select `Pine Labs` as the payment method. 4. Observe that the Pine Labs terminal does not respond and no payment popup appears on the device. 5. Wait until the payment request is cancelled (either manually or due to timeout). 6. Click the `Force Cancel` button. 7. Observe that the POS throws a traceback. **Video:** https://drive.google.com/file/d/1A3QPdby-J12IWgOX_SfCLrauQ_QnbqvG/view **Issue:** When a Pine Labs payment request is cancelled (either through a cancel request or by timeout), clicking the `Force Cancel` button results in a traceback in the POS. **Reason:** During the cancellation flow, the payment line status is updated to `retry` so that the transaction can be marked as cancelled and retried if necessary. Later, when the user clicks `Force Cancel`, `_paymentCancelRequestHandler()` attempts to retrieve the pending Pine Labs payment line using: ```javascript const line = this.pendingPineLabsPaymentLine(); ``` However, `pendingPineLabsPaymentLine()` only returns payment lines whose status is not `retry`, as defined here: https://github.com/odoo/odoo/blob/19.0/addons/point_of_sale/static/src/app/services/pos_store.js#L1820 Since the payment line was already transitioned to the `retry` state during the cancellation flow, no `payment line` is found and `line` becomes `undefined`. The handler subsequently attempts to update the status of this `undefined` `payment line`, resulting in the traceback when `Force Cancel` is executed. **Solution:** Add a condition in `_paymentCancelRequestHandler()` to verify that a payment line is available before attempting to update its status. If no payment line is found, it indicates that the payment line has already been moved to the `retry` state during a previous cancellation attempt. In such cases we clear `pollingTimeout`, `inactivityTimeout` and reset `this.payment_stopped` to `false`. This prevents the traceback while ensuring that the `Force Cancel` flow properly cleans up the pending payment state. opw-6297135 Forward-Port-Of: odoo/odoo#271397 Forward-Port-Of: odoo/odoo#271241
When sending invoices with a custom report attached, the attachment will now keep its own configured filename instead of inheriting the standard invoice’s localized name. This prevents duplicate-looking attachments and makes emailed invoices easier to identify for customers and accounting teams.
Original PR description
Steps to reproduce: * Install `l10n_mx_edi` (or `l10n_sa_edi`). * Go to **Accounting → Customers → Invoices**. * Open **Studio** and, from the top bar, go to **Reports**. * Duplicate the standard…
Steps to reproduce: * Install `l10n_mx_edi` (or `l10n_sa_edi`). * Go to **Accounting → Customers → Invoices**. * Open **Studio** and, from the top bar, go to **Reports**. * Duplicate the standard **Invoice PDF** report. * Open the duplicated report and make any modification to it. * Enable **Developer Mode**. * Go to **Settings → Technical → Actions → Reports** and update the custom report's **Printed Report Name**. * Go to **Settings → Technical → Email → Templates** and create a new invoice email template. * Add the custom report to the template's **Dynamic Reports**. * Create and confirm an invoice for a **Mexican company**. * Click **Send** and select the newly created email template. Observed behavior: * The custom report attachment uses the CFDI-based filename instead of its own report name, making it appear as a duplicate of the standard invoice attachment. Cause: * `_get_placeholder_mail_template_dynamic_attachments_data` relied on the `invoice_report` context key to pass the extra report into `_get_invoice_report_filename`. However, localization overrides (e.g. `l10n_mx_edi`, `l10n_sa_edi`) unconditionally return their own filename without checking the context, so the extra report's `print_report_name` was never evaluated. Fix: * Introduce `_get_invoice_mail_template_dynamic_report_filename` on `account.move` that directly evaluates a given report's `print_report_name`, bypassing the localization override chain. * Call this new method in `_get_placeholder_mail_template_dynamic_attachments_data` instead of the context-based `_get_invoice_report_filename` call. This avoids the need to patch every localization override and cleanly separates the concern of naming dynamic report attachments from the main invoice report filename logic. opw-6228268 Forward-Port-Of: odoo/odoo#271489
5 changes
Resolved issues and error corrections
This update corrects several emoji-related issues in the editor, including removing leftover search text when an emoji is selected and improving backspace behavior on mobile devices. It helps ensure emoji replacement works more reliably and that the cursor stays in the right place for users typing on phones and tablets.
Original PR description
2 changes
Resolved issues and error corrections
This update ensures the company SIA code used for Italian Ri.Ba. exports is exactly 5 characters long. It prevents batch payment validation from failing with an error when the code is too long, making the payment export process more reliable.
Original PR description
Currently, the sia_code field on res.company lacks length validation. For Italian Ri.Ba (CBI) exports, this field MUST be exactly 5 characters. If a user enters more (e.g., during initial setup), the Batch Payment validation (specifically the XML file generation) crashes with a traceback. Steps to Reproduce: - Set Company SIA Code to 6+ characters - Create multiple payments with Ri.Ba. method - Create a Ri.Ba Batch Payment - Click 'Validate' Ticket [link](https://www.odoo.com/odoo/project.task/6031062) opw-6031062 Forward-Port-Of: odoo/enterprise#121610
2 changes
Resolved issues and error corrections
This update makes Odoo correctly find invoice XML files whether they are directly in the ZIP or inside nested ZIP files. It prevents errors when sending invoices to Viettel S-Invoice, so invoice delivery completes more reliably.
Original PR description
Description of the issue/feature this PR addresses: The actual XML extraction hardcoded the double-zipped case by reading only the first entry of the outer zip (`zip_file.infolist()[0]`), assuming it…
3 changes
Enhancements to existing features
The softphone contact list is now cleaner and easier to use, with better search results and no unnecessary grouping by first letter. Users can also search contacts by email correctly, and the keypad’s extended search view now matches the main address book experience, including highlighted matches and editable searches. This makes finding the right contact faster and less confusing.
4 changes
Resolved issues and error corrections
When a customer adds an online payment option to an order that was already synchronized, the system now sends the updated order information again. This ensures the customer is charged the correct, latest amount after changes like increasing the order total.
Original PR description
When an online payment line is added, the order is synced to the server so the customer can pay it online. This sync was only performed when the order did not yet exist on the server (string id). As a result, once an order had already been synced, modifying it (e.g. increasing the amount) and adding the online payment line again did not push the new amount to the server. opw-6314690 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
**Issue 1:** Step to reproduce: - Type ':wave' to open suggestion list - Now click on any emoji from the suggestion list Description of the issue: - The selected emoji gets inserted, but the…
**Issue 1:** Step to reproduce: - Type ':wave' to open suggestion list - Now click on any emoji from the suggestion list Description of the issue: - The selected emoji gets inserted, but the `searchNode` `:wave` does not get removed and remains beside the inserted emoji Cause: - When the user clicks an emoji from the suggestion list, focus shifts to the suggestion list item. As a result, `selection.extend()` is unable to properly select the searchNode in the editable area. Because the `searchNode` is not selected, `deleteSelection()` fails to remove it before inserting the emoji. Solution: - Added the `user-select-none` class to the suggestion list to prevent selection/focus shift on emoji click, ensuring the searchNode is properly selected and replaced by the selected emoji **Issue 2:** Steps to reproduce: - Open a To-do on a mobile device. - Type `:p` to create an emoji. - Press Backspace. Issue: - When using the SwiftKey keyboard, pressing Backspace after an emoji can result in an incorrect cursor position. Cause: - When Backspace is pressed, a selection snapshot is cached during the `keydown` event. - Later, `deleteBackward` converts the emoji back to its corresponding expression (:p) by triggering an undo operation, but the cached selection does not get updated. As a result, the previously cached selection is reused, causing the cursor to be placed incorrectly. Solution: - After performing the undo, update the cached selection to match the new cursor position. - This ensures that the latest selection is used instead of the outdated selection captured during `keydown`. **Issue 3:** Steps to reproduce: - Open a To-do on a mobile device. - Type `:p` to create an emoji. - Press Backspace. Issue: - Pressing Backspace on an emoji does not revert it to its matching expression (`:p`). Cause: - On mobile devices, `event.key` can be undefined in keydown. As a result, `deleteBackward` is triggered through the `beforeinput` event, which correctly reverts the emoji to its matching expression. However, after that, the `input` event is triggered and converts the expression back into the emoji again, making it appear as if the emoji was not reverted. Solution: - When the event type is `deleteContentBackward`, skip converting the expression back into an emoji and return early. task-6201173
This fix makes website popups respond correctly even when the show/hide toggle is clicked very quickly. It prevents the popup from getting stuck in the wrong visible state, which also avoids related errors when creating nested popups.
Original PR description
__To reproduce__ 1. Drop a popup on the website. 2. Click twice rapidly on the popup show/hide toggle in the sidebar. => The popup visibility will be in an inconsistent state compared to the toggle's…
__To reproduce__ 1. Drop a popup on the website. 2. Click twice rapidly on the popup show/hide toggle in the sidebar. => The popup visibility will be in an inconsistent state compared to the toggle's eye icon. __Reason__ Bootstrap ignores any call to show/hide if the popup is still transitioning. __Fix__ - Set `_isTransitioning` to `false` to trick Bootstrap into firing the event regardless of its current state. - When hide/show are triggered in quick succession, the modal can enter an inconsistent state with `.show` class but `display: none` style (hide removes `.show` immediately, show restores it with `display: block`, then hide applies `display: none` after animation). Dispatching `transitionend` event before resetting `_isTransitioning` ensures Bootstrap completes its state transitions. __Note__ This commit also fixes `custom_popup_snippet`, which fails non-deterministically with the following error: `TypeError: Cannot read properties of undefined (reading 'after')` This error occurs when trying to add a popup inside another popup that never closes due to this bug. runbot-939039
This update corrects how Philippine tax reports identify transactions when grouped taxes are used. It ensures lines are included under the right tax tags, so report totals are more accurate and fewer transactions are missed.
Original PR description
When using group taxes, the base invoice lines only store the parent tax in the `account_move_line_account_tax_rel` table. Because of this, if a child tax within the group contains a specific tax report tag, the generic report query would previously fail to pick up those base lines. This commit updates the SQL join conditions in `l10n_ph_generic_report.py` to also match `account_tax.id` against the child taxes of the linked parent tax using the `account_tax_filiation_rel` table. This ensures that base lines are correctly reported under the tags of their respective child taxes. Task-6278098 Forward-Port-Of: odoo/enterprise#121876 Forward-Port-Of: odoo/enterprise#121596
This update fixes an issue where messages in chat threads could sometimes fail to appear after a reload. It improves reliability so users consistently see the latest conversation content without needing to refresh again.
Original PR description
The Thread component mirrors `thread.isLoaded` into the `state.mountedAndLoaded` flag that gates whether the real messages (as opposed to the empty phantom placeholder) are rendered. The mirroring…
The Thread component mirrors `thread.isLoaded` into the `state.mountedAndLoaded` flag that gates whether the real messages (as opposed to the empty phantom placeholder) are rendered. The mirroring effect both read `mountedAndLoaded` as a dependency and wrote it. `useEffect` records its dependency array before running the body, so right after the effect sets `mountedAndLoaded` to true the recorded dependencies still hold the pre-write pair `[isLoaded=true, mountedAndLoaded=false]`; that update only settles on a later, microtask-deferred patch. When a second reload runs `reset()` in that window, it drives `mountedAndLoaded` back to false while `isLoaded` stays true. The settling patch then computes the very `[true, false]` pair that was already recorded, so the effect never re-runs: `mountedAndLoaded` is stranded at false and no message is ever rendered. Depend on a monotonic `resetCount` bumped by `reset()` instead of on `mountedAndLoaded` itself. It is never written by the effect, so the recorded dependencies can no longer match the current ones after a reset and the effect always re-runs to re-sync `mountedAndLoaded` with `isLoaded`. `reset()` keeps clearing `mountedAndLoaded` as before (the false dip is needed for the reload scroll handshake), so the behaviour is otherwise unchanged. https://runbot.odoo.com/odoo/error/940032 Forward-Port-Of: odoo/odoo#272281
The Italian Ri.Ba. setup now enforces that the company SIA code is exactly 5 digits. This prevents batch payment validation from failing later when generating the export file, avoiding disruptive errors for users during payment processing.
Original PR description
Currently, the sia_code field on res.company lacks length validation. For Italian Ri.Ba (CBI) exports, this field MUST be exactly 5 characters. If a user enters more (e.g., during initial setup), the Batch Payment validation (specifically the XML file generation) crashes with a traceback. Steps to Reproduce: - Set Company SIA Code to 6+ characters - Create multiple payments with Ri.Ba. method - Create a Ri.Ba Batch Payment - Click 'Validate' Ticket [link](https://www.odoo.com/odoo/project.task/6031062) opw-6031062 Forward-Port-Of: odoo/enterprise#121610
This change fixes an error that could appear when opening a billing target in the Timesheets app. It ensures the required employee leave information is available, so users can view billing targets without the page failing.
Original PR description
Prerequisites to reproduce: - Enable `Billing Rate Indicators` in timesheets. - Change timesheet access of user to `User: all timesheets` - Remove Employee access Steps to Reproduce: - In Timesheets app, from configuration go to `Billing Time Targets` - Click on view button on any row Issue: - A traceback breaking the flow. Reason: - We use `hr_presence_status` widget which requires `leave_date_to` and `current_leave_id` field, change made from odoo/odoo@0496ed1 and https://github.com/odoo/odoo/commit/4b5089694436aa00254666e10cd2106b21adfe2b - Thus unavailability of field causing the traceback. Fix: - Add a related field for leave_date_to from which we get the value. Forward-Port-Of: odoo/enterprise#121571
Description of the issue/feature this PR addresses: The actual XML extraction hardcoded the double-zipped case by reading only the first entry of the outer zip (`zip_file.infolist()[0]`), assuming it was always a nested zip containing the XML. This made it fail when: - The XML was directly in the outer zip (single-zipped). - The zip contained multiple files and the first nested zip didn't hold the XML. Current behavior before PR: After sending an Invoice to Viettel S-Invoice, the e-Invoicing platform would return a ZIP containing one XML file. The XML File being double-unzipped, a traceback is raised. Desired behavior after PR is merged: The fix rewrites _recursive_zip_xml_file_data to actually be recursive. Invoices can be sent to Viettel S-Invoice without raising a traceback. opw-[6249929](https://www.odoo.com/odoo/project.task/6249929?debug=1) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272121 Forward-Port-Of: odoo/odoo#268482
When a new file is uploaded in Documents, it is now shown with its available actions right away. This avoids the extra step of deselecting and reselecting the file just to access those actions, making the workflow smoother and faster.
Original PR description
Bug === When uploading a new file in documents, it's selected, but the actions are not visible (we need to unselect - select the record to see the actions). Task-5408471
Original PR description
[IMP] voip: remove grouping by initial in softphone contacts listing This commit keeps the alphabetical / phone sort, but no useless groups anymore. Idea: it was only to have a "pretty" listing but…
[IMP] voip: remove grouping by initial in softphone contacts listing
This commit keeps the alphabetical / phone sort, but no useless groups
anymore. Idea: it was only to have a "pretty" listing but it will
prevent more advanced sorting to make sense in the future (e.g. showing
most called contacts first). This also simply improves Owl performance
as a bonus.
[IMP] voip: use AddressBook for keypad "more" searches
Before this commit, the keypad component was implementing its own
contact searches, with unsorted results. Indeed, with the demo data,
search "m" would for example have "Mitchell Admin" first, because it
was loaded first by discuss for the presence status, then the rest of
the contacts having "m" in their name.
The "more" keypad search view now uses the AddressBook component,
sharing the UI and its features.
The keypad "more" view had 2 extra differences though:
- Search match highlighting
- T9 searches
Those 2 features are now added in the AddressBook component.
Bonus: while in the "more" keypad view, you can now edit the search.
[IMP] voip: (really) allow contact search by email
Before this commit, when a contact was searched in the softphone,
contacts were loaded in the store based on their name, phone... and
email. But then the softphone filtered the store contacts by name and
phone... but not email. This lead to this weird behavior:
- Have a contact zzz with email yyy@example.com
- Have 50 contacts alphabetically before zzz
- Search "y" => You don't see zzz
- Remove the "y" search
=> You see 13 contacts + zzz (because it was loaded before)... if you
scroll, contacts will appears between the 13 contacts and zzz.
Now, you will at least see zzz during the "y" search making the last
step less confusing, and allowing to actually take profit of the search
by email that is already done loading-wise.
Note that this is also a first step towards fixing problems introduced
by [1] a long time ago, when the softphone used the Store to gather the
loaded contacts, while before the tab components themselves were in
charge of loading and displaying the loaded contacts.
[1]: https://github.com/odoo/enterprise/commit/bbdb033031720365c448c6f3de40906ee0c4243e
task-5871346Resolved issues and error corrections
Reporting menu items that were previously visible with only the Invoicing app are now available only when the Accounting app is installed. This keeps the Invoicing experience simpler and ensures users see only the reports relevant to their setup.
Original PR description
The invoicing app provides access to many reports which are not needed for the purposes related to invoicing. These reports have been moved to only be accessible if the accounting app is installed instead of being available by default with just the invoicing app. task-6298711
This fix corrects an incorrect data key used in the Belgian payroll reporting process. It helps ensure payroll information is sent and interpreted properly, reducing the risk of reporting errors.
Original PR description
Task#6333132
This update prevents an error that could appear when a user clears the currency field while registering a payment for Argentine withholding. It makes the payment process more reliable and avoids an unexpected traceback in this workflow.
Original PR description
When the user removes the currency from the payment register, a traceback is raised. Steps to reproduce the error: - Install ``l10n_ar_withholding`` module - Switch to ``(AR) Exento`` company - Create a new invoice > Confirm > Pay > Unset the currency Traceback: ```py ValueError: Expected singleton: res.currency() ``` https://github.com/odoo/odoo/blob/d98afdc08b46bf458eaa287ea882cc7663286a59/addons/l10n_ar_withholding/wizards/account_payment_register.py#L27 This line causes a traceback with an empty currency when the user removes the currency from the payment register. sentry-7362499567 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Mailing campaigns now correctly count email bounces for contacts, even when the bounce notice comes from a different sender address. This improves the accuracy of campaign reports and helps teams better identify invalid or unreachable email addresses.
Original PR description
Previously, when a mailing campaign sent out an email to a mailing.contact, and that email bounced, the bounce would not increment the contact's bounce count. This commit makes it so that the bounce count is correctly updated when a mailing campaign sends an email that bounces. task-4893615
This change prevents the Repair app from failing during installation in certain database setups. It matters because it restores successful automated builds and avoids a blocking error when the app is installed without optional add-ons being loaded first.
Original PR description
Runbot builds on version 17.0 and 18.0 fail due to the lines below. These lines reference `move.sale_line_id` as the previous dependencies did not add `sale_line_id` to the `stock.move` model when using --skip-auto-install. https://github.com/odoo/odoo/blob/51824f462402d3d141bda2717402d1fdcf2e118b/addons/repair/models/stock_move.py#L97-L100 To reproduced the issue: 1. New blank database 2. ./odoo-bin -d [database-name] -i repair --skip-auto-install 3. See error in console Looking ahead to verison 18.1+ we see the dependencies change here: https://github.com/odoo/odoo/commit/f7dbdec11b74f8c7d969763d8c5cf09542a47f86 **Affects 17.0 and 18.0** Ticket [link](https://www.odoo.com/odoo/project/27948/tasks/6306099) This can also close this very, very old PR https://github.com/odoo/odoo/pull/189584 Forward-Port-Of: odoo/odoo#271901