Daily updates from Odoo
Friday, August 29, 2025
36 changes · saas-18.4
Resolved issues and error corrections
This fix prevents open dialog windows from getting out of sync when one dialog is closed more than once. Users can now continue and close remaining dialogs normally, avoiding stuck windows and potential crashes during employee holiday attest workflows.
Original PR description
Have two dialogs opened, call twice `close` on one of them. From that point, the `stack` in dialog_service is empty (because the second time, the dialog can't be found in `stack`, so its index is -1,…
Have two dialogs opened, call twice `close` on one of them. From that point, the `stack` in dialog_service is empty (because the second time, the dialog can't be found in `stack`, so its index is -1, and calling `splice` with -1 removes from the end of the array), even though one of the 2 dialogs is still displayed. From that point, calling closeAll does not close the remaining dialog. In practice, this can be reproduced in Employees > Laurie Poiret (must be in BE company). In the cog menu, click on "Departure: Holiday Attest". In the dialog, click on the external button of the many2one. Close the second dialog by clicking on the X. At this point, `close` has been called twice for that dialog (once by the click on the cross, and once by an override of `dialogData.dismiss` in FormViewDialog), and `stack` is thus empty. Clicking on an action button in the first dialog (e.g. "Validate & Compute holiday attests") then no longer closes the remaining dialog as it should (as `closeAll` is called by the action service). Then, a crash can occur when manually trying to close that dialog, as the view in the background no longer exists, and closing the dialog calls its `onClose` callback, which tries to reload the view, thus leading to the "Component is destroyed" error. Issue introduced by https://github.com/odoo/odoo/pull/203169 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#224792
This fixes a visual issue where elements meant to have rounded corners only on one side could also change corners that should have stayed unchanged. It helps notifications, card layouts, and similar website elements display with the intended shape again.
Original PR description
Commit [1] (which was patched by multiple other commits since then already) needs yet another patch: the `rounded-start`, `rounded-end`, `rounded-top`, `rounded-bottom` and all their size variants…
Commit [1] (which was patched by multiple other commits since then already) needs yet another patch: the `rounded-start`, `rounded-end`, `rounded-top`, `rounded-bottom` and all their size variants were not working anymore: the direction they were not supposed to control were forced to the default border-radius value. E.g. the class rounded-end-4 was forcing `border-radius: default big big default` instead of just forcing "big" on the top-right and bottom-right.
This could be fixed while keeping the improvement added by [1] (which is allowing the value to use CSS variable, allowing to auto-adapt children with the right border-radius when needed) but it is fact better/simpler to just revert the improvement just for those classes (while keeping it for the base `rounded` and `rounded-{SIZE}` classes). Indeed, this is not necessary at the moment. They can be used in layouts but we do not allow edition of their radius via the builder: when we do, we normally should always prefer to give the user full control over the 4 directions, by switching to the `rounded` or a `rounded-{SIZE}` class.
This bug could be visible in different standard ways:
- Notifications
- Cards Grid snippet
- ...
Note: this also actually revealed that [1] re-introduced the 4 and 5 sizes which were actually disabled by the /web/.../utilities_custom.scss file. This commit re-disable them for those partial classes... but they probably should be restored to respect Bootstrap's default. The 1-2-3 sizes are also not using CSS variable of Bootstrap. This commit adds a FIXME comment about this.
[1]: https://github.com/odoo/odoo/commit/d0daf3990079477ef7552d769b944b55d9be4366
Related to task-3358501Fixes color selector issues in the HTML editor so floating color menus close properly when the toolbar is hidden. It also makes color changes more reliable for text using gradients, preventing confusing or broken color picker behavior.
Original PR description
**Current behavior before PR:** **Issue 1:** - Have a long text content in editable, making the container scrollable. - Select first line of the text, in toolbar open color selector. - Scroll down…
**Current behavior before PR:** **Issue 1:** - Have a long text content in editable, making the container scrollable. - Select first line of the text, in toolbar open color selector. - Scroll down until the toolbar overflows and becomes hidden. - Notice that the toolbar disappears when it overflows its container while color picker remains open, floating at the top of container. **Issue 2:** - Select a text having gradient text color. - Open text color selector, switch to custom color picker. - Notice that hex and rgba fields are empty and user is not able to apply color through it. In colorpicker.js, the convertCSSColorToRgba method fails when attempting to convert a gradient color to RGBA. As a result, colorComponents does not receive valid values and colorpicker doesn't work as expected. **Issue 3:** After merging commit [1], text color can be applied without removing or affecting the existing gradient color. In result, if gradient is fully selected then applying text color creates a new font tag inside gradient instead of replacing the gradient. **Desired behavior after PR:** **Issue 1:** Now, when the toolbar overflows and gets hidden, the color selector becomes hidden along with toolbar. **Issue 2:** Now, if `convertCSSColorToRgba` fails to convert selected color to rgba color then default color `#FF0000`is assigned to color components. This ensures that the colorpicker functions correctly. **Issue 3:** Now, if gradient is fully selected then, - Applying text color removes existing text gradient. - Applying background color removes existing background gradient. - Applying text color doen't remove the existing background gradient. - Applying background color doesn't remove the existing text gradient. [1]: https://github.com/odoo/odoo/commit/938995744b15f345958a2d78a6c844dd5bf1ae6c Enterprise PR: https://github.com/odoo/enterprise/pull/84579 task-4581884 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221381 Forward-Port-Of: odoo/odoo#202889
This fixes an internal mistake in how user group names are searched. It helps ensure group lookup results are accurate and avoids confusion when administrators search for access groups.
Original PR description
Followup of #223210 .
Google Merchant Center shipping price calculations now avoid overusing external carrier quote requests. This helps prevent hitting daily carrier rate limits, such as DHL limits, while keeping product shipping information available for online sales channels.
Original PR description
### Issue: The `Google Merchant Center` calls the method `_prepare_gmc_shipping_info` in order to compute the best shipping price for each published product in each possible country: https://github.com/odoo/odoo/blob/1ac89eb71aab48fa8d50fbae01d96bec23d88418/addons/website_sale/models/product_product.py#L352-L361 To achieve this, the method will request the shipping rate for each possible carrier, product, country. However, for external carriers, each such combination will require a request to the external api via the `rate_shipment`: https://github.com/odoo/odoo/blob/1ac89eb71aab48fa8d50fbae01d96bec23d88418/addons/website_sale/models/delivery_carrier.py#L44-L53 This is problematic as external carriers have a standard rate limit (maximal amount of rate requests allowed per day). For instance DHL standard rate limit is 250 requests per day. opw-5048969 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224649
The website link editing test has been updated to work with the new website builder layout and turned back on. This helps ensure link editing continues to work reliably, with links now defaulting to HTTPS when no protocol is entered.
Original PR description
The link_tools tour was previously broken due to DOM structure changes introduced by the new website builder and was consequently disabled. This commit updates the tour steps to align with the new DOM and re-enables the associated test. Note: Previously, HTTP was the default protocol. Now, HTTPS is used as the default if none is specified.
This fix makes an automated sales timesheet test wait until the needed kanban column is ready before continuing. It reduces random test failures, helping keep releases and updates more dependable without changing user-facing behavior.
Original PR description
In this commit, we fix the undeterministic behavior by adding a step to ensure kanban column is created before continue scenario. runbot-error-id~181916 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#224447
This fixes exchange returns so serial-tracked products are treated as new incoming items instead of reusing existing serial numbers. It also corrects stock quantity calculations after exchanges and only shows the exchange return option where it is relevant.
Original PR description
When returning tracked-by-serial products from an incoming picking for an exchange, the exchange move will have selected existing serial numbers for the new incoming picking. This happens because…
When returning tracked-by-serial products from an incoming picking for an exchange, the exchange move will have selected existing serial numbers for the new incoming picking. This happens because `move_orig_ids` is set on the exchange move(s), then `_action_assign()` happens. If there's a `move_orig_ids`, it will use the available move lines from the move_orig_ids and so assign the corresponding serial number. Additionally, the buttons to generate/import serials/lots are invisible because `origin_returned_move_id` is set on the same exchange move(s). Again, the exchange move(s) should be considered 'new' move thus having no origin. task 4893860: Additionally (again), it fixes an issue where on-hand quantities and forecasted quantities of the exchanged product were incorrect after validating the exchange. task 4778066: Finally, this PR also hides the 'Return for Exchange' button for pickings that are neither `incoming` nor `outgoing`. tasks 4748294 (& 4778066 & 4893860) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224696 Forward-Port-Of: odoo/odoo#216111
This fix prevents the Point of Sale from accidentally deleting two order lines when reducing an unsaved line with the barcode box flow. Cashiers can correct quantities more reliably without losing an extra item from the current order.
Original PR description
- Fix issue in `handleDecreaseUnsavedLine` which was leading to removing two orderlines instead of one in the current order. This issue appeared since this commit (8e964000474125ca2db4ee4e5883be8424d9fca1). Since we already set the line qty to 0 (or remove it) inside `updateSelectedOrderline` after calling `_showDecreaseQuantityPopup`, we don't need to call `removeOrderLine` inside `handleDecreaseUnsavedLine`. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224230
The payroll leave handling now avoids changing work entries that have already been validated. This prevents installation or payroll setup failures when overlapping leave entries are processed, helping keep approved payroll-related records stable.
Original PR description
This logic of solving the overlapping between leave work entries has been adjusted to prevent editing the entries marked as validated. This error appears in the installation in task #4921300. You can refer to the error here: https://runbot.odoo.com/runbot/build/87127472 To reproduce: -Fake time a date in the future, for example :"2025-09-05 UTC". -Install the needed modules with demo data: -i "hr_payroll,project_timesheet_holidays" --with-demo.
This fix ensures the Turkish Nilvera e-dispatch integration sends the exact true or false values required by Nilvera instead of translated text. This prevents potential dispatch submission issues caused by localized wording in exported data.
Original PR description
Before this commit, since we hardcoded the value, the value was present in the pot and po file. Except that nilvera want a precise value which is 'false' or 'true' and not something translated. task-5009049 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222669
Fixed an issue that could block importing user groups whose names contain a slash when no privilege identifier is set. This prevents false “multiple matches” errors and makes group data imports more reliable.
Original PR description
If a group does not have privilege id and contains a /, the group search can return a list of group instead of the group itself. The import display an error message "Found multiple matches for..." opw-4885648
This fixes an issue where a customer’s selected pricelist could change incorrectly when an individual contact was linked to a company. Sales quotations now keep pricing consistent between the individual and their company, reducing pricing mistakes and manual corrections.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Create an individual partner; 2. assign them a pricelist A; 3. create a new company partner for them; 4. create a new pricelist A & sort it on top; 5. open a…
Versions
--------
- 18.0+
Steps
-----
1. Create an individual partner;
2. assign them a pricelist A;
3. create a new company partner for them;
4. create a new pricelist A & sort it on top;
5. open a new quotation;
6. set new company as customer;
7. change customer to the individual partner.
Issue
-----
The quotation's pricelist changed from B to A. The pricelist used for the individual should be identical to the one used for their company.
Cause
-----
Commit de302c2d36305 added the `specific_property_product_pricelist` field to `res.partner`, as the way company-dependent fields are managed was changed on the database-level.
Commit 67cf577cd0a0 added the `_company_dependent_commercial_fields` method to enable syncing company-dependent commercial fields. The base method fetches all fields retrieved via `_commercial_fields`, and selects those whose `company_dependent` attribute is `True`.
In previous versions, the `_company_dependent_commercial_fields` override in `product` adds `property_product_pricelist`, as this field does not have the `company_dependent` attribute set, but it behaves as a company-dependent field. Starting from 18.0, the override adds `specific_property_product_pricelist` instead, which does have the `company_dependent` property set.
As a consequence, when `_company_dependent_commercial_sync` gets called, it does not sync the `specific_property_product_pricelist` as it's not included in the `_commercial_fields` override, nor does it sync when retrieving it from `_company_dependent_commercial_fields`, as it skips the current company, assuming the field was already handled by `_commercial_sync_from_company`: https://github.com/odoo/odoo/blob/c40760244d128cb57e11a233e89a93dd92b8fb56/odoo/addons/base/models/res_partner.py#L667-L668
Solution
--------
- Move `specific_property_product_pricelist` to `_commercial_fields`
- This enables it to sync in `_commercial_sync_from_company`
- Remove the `_company_dependent_commercial_fields` override
- `property_product_pricelist` shouldn't get synced by itself
- `specific_property_product_pricelist` is already included by the base method
opw-4988736
Forward-Port-Of: odoo/odoo#224133
Forward-Port-Of: odoo/odoo#222223This fixes an issue where archiving a loyalty program that was still applied to a Point of Sale order could cause errors when the POS interface was reloaded. Businesses can now archive old loyalty programs without interrupting checkout operations or affecting existing active orders.
Original PR description
Before this commit, archiving a loyalty program while it was actively applied to an order could lead to errors. Specifically, if a PoS order had an active loyalty program applied, and that program was subsequently archived from the backend, reloading the PoS interface would cause issues or prevent proper functionality due to the program's sudden unavailability. opw-4941044 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218814
Early payment discounts are now applied based on the discount deadline saved on the posted invoice, not on later changes to the payment terms. This ensures customers keep the discount eligibility that was communicated to them when the invoice was issued, improving consistency in payment registration and reconciliation.
Original PR description
When a payment term with early payment discount is used on invoice the discount date is set on the payment term line based on the actual configuration of the payment term. When the invoice is posted,…
When a payment term with early payment discount is used on invoice the discount date is set on the payment term line based on the actual configuration of the payment term. When the invoice is posted, this date must not change anymore as it usually is what is communicated to the partner in order to apply EPD. However, if the payment term's delay for discount is modified, the discount date from the move line was not taken into account by the payment register wizard or by the reconciliation widget, as it was instead recalculating a discount limit date, based on the configuration of the payment term at the time the payment is registered on Odoo. Make sure it is the discount date that is stored on payment terms' account move line that is used to define if an early payment discount has to be applied. OPW-4895365 Description of the issue/feature this PR addresses: On runbot, create a new payment term with an early payment discount (eg 10% at 15 days, balance at 30 days). Create a customer invoice with a invoice line (eg 100 USD) for any customer with this payment term and set the date to 10 days before today. Post the invoice, you can see on the payment term line that the discount is valid until 5 days after today. Modify the payment term to set 10% at 5 days. If you go back to the invoice, you'll notice the discount date is still 5 days after today which is fine since this is what was communicated to the customer Current behavior before PR: Register a payment on this invoice and you'll notice the EPD is not applied because it gets the date from the actual configuration of the payment term instead of the date stored on the invoice's payment term line. Desired behavior after PR is merged: Register a payment on this invoice must apply the EPD as it is still valid based on the invoice's payment term line. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224044 Forward-Port-Of: odoo/odoo#215615
This fix prevents draft point-of-sale orders from being synchronized when a cashier validates another order after selecting a customer. It helps avoid unwanted draft orders appearing in the system and keeps sales data cleaner.
Original PR description
Before this commit, in a non-restaurant PoS, when selecting a partner in a draft order, validating an order would also sync the draft order. opw-5037759 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224041
This fixes an issue in Email Marketing where templates saved from a mailing were not shown as choices when creating a new mailing. Users can now reuse saved email content as expected, reducing duplicate work and confusion.
Original PR description
Step to reproduce: - install email marketing and open it - create a new record, add name and add something in email body - click on "Add to Templates" - click on new Observation: - The newly created template is not shown as option for new record. Cause: - https://github.com/odoo/odoo/pull/205486 convert arrays value to object, [exact change](https://github.com/odoo/odoo/commit/f79b2edb614fd08b19b18beeb16be38743f637b2#diff-0b4e81825324dc36e89543232f3f8f8704acddc4ec21031c6ccea78ee93b00eeR368-R379) but in this case, we actually return values_list, i.e. a tuple for m2o fields https://github.com/odoo/odoo/blob/ea1767e3a016f501d5bc4012cc5e964fc05955a3/addons/mass_mailing/models/mailing.py#L816-L834 - Hence, using a key evaluates to `undefined` - so, the values return by `action_fetch_favorites` are not rendered Fix: - use index instead of keys opw-4960103 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents errors when SEO tools receive missing page descriptions or when Google suggestion requests fail. Website editors get a more reliable SEO preview experience instead of unexpected crashes or broken responses.
Original PR description
Ensure the Google suggest fallback always returns a JSON list, even on IOError, instead of raising a serialization traceback. JS (SEOPreview): guard against undefined/empty descriptions with optional chaining and default empty string to avoid runtime errors. opw-4963552 Forward-Port-Of: odoo/odoo#224637 Forward-Port-Of: odoo/odoo#224424
Changing a customer's VAT number on Indian invoices no longer causes the fiscal position to be recalculated unexpectedly. This keeps invoice tax settings stable and aligned with standard behavior, reducing the risk of unintended tax changes after partner details are updated.
Original PR description
The field fiscal_position_id in l10n_in was dependent on l10n_in_gst_treatment, which itself depended on partner.vat, partner.country_id, and partner.l10n_in_gst_treatment. As a result, any change to the partner’s VAT triggered a recomputation of fiscal_position_id. This contradicts the generic behavior, since VAT changes should not affect fiscal position. This fix removes the unnecessary dependency chain. reference - https://github.com/odoo/odoo/pull/224511 Forward-Port-Of: odoo/odoo#224639
Point of Sale now shows a clear Access Denied popup when a user lacks permission to load sample POS category data, instead of failing with a technical error. This helps store administrators understand the permission issue and avoid confusing crashes when opening a POS session.
Original PR description
Currently, an error occurs when a new user with the Member role and Administrator rights for the Point of Sale app attempts to open POS Category. Steps to reproduce: --- - Install the `point_of_sale`…
Currently, an error occurs when a new user with the Member role and Administrator rights for the Point of Sale app attempts to open POS Category.
Steps to reproduce:
---
- Install the `point_of_sale` module (without demo data).
- Create a new User and give Administrator rights for POS & Accounting
- Now log in with a new user in a different browser
- Open the pos session(Clothes or bar)
Traceback:
---
```py
AccessError: You are not allowed to modify 'Product Category' (product.category) records.
This operation is allowed for the following groups:
- Products/Admin en Products / Create
Contact your administrator to request access if necessary.
ParseError:while parsing /home/odoo/src/odoo/saas-18.3/addons/point_of_sale/data/scenarios/clothes_category_data.xml:5, somewhere inside <record id="product_category_clothes" model="product.category">
<field name="name">Clothes</field>
</record>
```
This commit prevents the error by displaying an "Access Denied" pop-up when a user with the "Member" role and Administrator rights attempts to open the POS Category.
sentry-6683335275, 6679363278, 6823710988
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#215429This fixes an issue where changes to a company’s Peppol email address were not being sent to the external Peppol service. Businesses can now rely on email updates made in the configuration wizard being properly applied, helping keep electronic invoicing contact details accurate.
Original PR description
Due to the config wizard email address field being a related field, and the control flow triggering actual API update only on gets hit when the wizard's email is different from company's email, this control flow never triggered. The email field in peppol config wizard is a related field to companies peppol email, so the API update ran only if the wizard's email differed from the company's email. Since both were always the same by definition, the update never triggered. Depends on https://github.com/odoo/iap-apps/pull/1167 no-task Forward-Port-Of: odoo/odoo#224615
This fix restores the ability for shoppers to add products to the cart or buy them directly when a product page uses full-width or zero-width images. It prevents checkout-blocking errors caused by the page layout change, improving reliability for affected eCommerce product pages.
Original PR description
Recent design changes from this PR: https://github.com/odoo/odoo/pull/201019 caused the `Add to Cart`, `Buy Now` buttons, and quantity selector to be moved outside the main `<form>` element on the…
Recent design changes from this PR: https://github.com/odoo/odoo/pull/201019 caused the `Add to Cart`, `Buy Now` buttons, and quantity selector to be moved outside the main `<form>` element on the product page — specifically when the product image is full width or has zero size. Steps to reproduce: - Install eCommerce - Edit a product page and set the product image to full width or zero width - Try to add the product to the cart or use Buy Now Issue: - Clicking `Add to Cart` or `Buy Now` throws a traceback - The product cannot be ordered when using full-width images Root cause: - The buttons and quantity selector are no longer inside the expected `<form>`, so the selector used in the JS widget fails to find the right form data. Fix: - Update the selector to correctly target the intended `<form>` so the widget can fetch the correct product details when a button is clicked. opw-4934557 Affected version: saas~18.4 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Stopping a timesheet timer now matches the entry to the user's local calendar date instead of the UTC date. This prevents time from being added to the previous or next day for users working across time zones, improving accuracy in timesheet records.
Original PR description
Before this commit, if you were to log time on a timesheet using the timer start and stop buttons, you could potentially log time for the previous day's or the upcoming day's timesheet entry. This is because we were searching for previously-created timesheet entries based on the UTC Date of the timer's "stop" time. This fix uses the client's local time to get the Date of the timer stop. With this, we'll only find timesheet entries with the `date` field matching the client's local Date. opw-4967487 Forward-Port-Of: odoo/enterprise#93356 Forward-Port-Of: odoo/enterprise#92569
Payroll advice reports in Indian payroll now use the selected payslips to determine the period instead of relying on the current date. This ensures reports for past payroll runs show the correct period and avoids missing or inaccurate payroll advice details.
Original PR description
Generating a payroll advice would use the current date in order to find other payslips that are for the current period and use this to fill in the period on the advice. However, if you do this for a past payslip, it will either not find any or get the incorrect period. Changed the behavior to use the actual payslips and get the period from those payslips to fill in the period on the report. opw-4582990 Forward-Port-Of: odoo/enterprise#92806 Forward-Port-Of: odoo/enterprise#81625
Swiss payroll sheet calculations no longer unnecessarily recalculate wage-related values after the occupation period is recomputed. This prevents manual payroll adjustments from being overwritten, helping payroll teams keep intentional corrections intact.
Original PR description
Following changes in 18.4, compute sheet introduces a recomputation of occupation period which introduces a recomputation of wages, this recomputation is not necessary as it overrides all introduced manual change.
Subscription invoices created after portal payments now trigger the required electronic document signing process. This restores expected government-compliant invoicing for customers using localized EDI flows, such as Mexican invoice signing.
Original PR description
## Steps to reproduce: - Make sure the Mexican localization is installed and properly set up for signing invoices - Make sure the payment providers are set up (it can be demo, the customer uses…
## Steps to reproduce: - Make sure the Mexican localization is installed and properly set up for signing invoices - Make sure the payment providers are set up (it can be demo, the customer uses Stripe but it can be reproduced with any - Make sure the online payment setting is active - Go to subscription module - Do a new order - In other info, add the online payment checkmark - Confirm the order - Generate the payment link or go into the preview - Make the payment ## Issue: The invoice is generated, but is not signed by the government (no edi is generated), as it used to. ## Cause: The flow works in 17.0 but for the wrong reason. Before this [commit](https://github.com/odoo/enterprise/pull/70562), two mails were sent. And during the chain of triggers of the second email, edi document was generated with `orders._send_success_mail(tx.invoice_ids, tx)`. https://github.com/odoo/enterprise/pull/70562/files#diff-8778c8dce7ca1c24de19f26f11ac0c5410c6c2a4d121c3815682a2323cbb09c2L177 After the removal of the method, it should still work since we still have `payment.transaction._send_invoice` which calls `_generate_and_send_invoices` and should trigger the sub calls necessary for generating the edi stuff. But in `_create_or_link_to_invoice`, we check that the transaction has no invoice_ids linked (make sense with the name of the method). However, at this stage, we already created the invoice in https://github.com/odoo/enterprise/blob/2f3698b250092ad376344e959d46bdc0eebf1a81/sale_subscription/controllers/portal.py#L419-L424 And unfortunately, it will be effectively possible to "let the post process of transaction create" the invoices only in Master (the code is not ready yet). For now it would be too risky for a stable version to make such change. ## Solution: We ensure EDI documents are generated whenever a `subscription_action` is set. To achieve this, modify the `_post_subscription_action` hook to call `_subscription_post_success_payment` for any `subscription_action`, including `assign_token`. From `_subscription_post_success_payment`, we can call `_generate_and_send_invoices` on any invoice that has an EDI associated with it, which sends & signs the required EDI documents. opw-4648189 Forward-Port-Of: odoo/enterprise#93130 Forward-Port-Of: odoo/enterprise#84815
The VoIP CRM app now includes needed permission information when the user session starts. This avoids extra background requests during startup, helping the web client load more efficiently without changing user workflows.
Original PR description
Since the VoIP app use some groups at startup[1], it's made sense to adds it inside the session_info bundle to avoid RPCs at webclient startup. [1]: https://github.com/odoo/enterprise/commit/9d3a13e9adae3a6b1c44b70a52b2fd74ef9dcc1a#diff-e8144e1aa7d3b4933985de5693d78e8c392bce8f7150ad186a04b8c87c7cd32aR14-R16 Forward-Port-Of: odoo/enterprise#93419
This update preserves the intended visibility rules for the 'Return for Exchange' button in rental stock returns. It helps ensure users only see the action when it is appropriate, reducing confusion and avoiding incorrect return workflows.
Original PR description
Adapt the xpath to make sure the invisible condition on the 'Return for Exchange' button is not overriden. tasks 4748294 & 4778066 Forward-Port-Of: odoo/enterprise#93433 Forward-Port-Of: odoo/enterprise#89090
Vendor bills with no taxes are now excluded from GSTR2B reconciliation. This prevents bills that were likely not filed by the vendor from appearing in the matching process, improving the accuracy of Indian GST reporting.
Original PR description
Before this commit- We included the Vendor bills without taxes for GSTR2B reconciliation After this commit- We exclude the Vendor bills without taxes for GSTR2B Because if no tax is there on the bill it means wasn't filed by the Vendor as well task-5023013 Forward-Port-Of: odoo/enterprise#93373 Forward-Port-Of: odoo/enterprise#92866
Fixed an Accounting issue that could block users from deleting a generated bank statement line when a journal entry involved multiple reconciliation models. This helps accounting users correct bank statement entries without encountering an unexpected error.
Original PR description
Currently, an error occurs when trying to remove a move line from a bank statement line if the journal entry contains lines with different reconciliation models. **Steps to Reproduce:** 1. Install…
Currently, an error occurs when trying to remove a move line from a bank statement line if the journal entry contains lines with different reconciliation models. **Steps to Reproduce:** 1. Install the Accounting module. 2. Duplicate the "Internal Transfer" reconciliation model. 3. Accounting dashboard > click on Bank > create new record. 4. Add the invoice, apply "Internal Transfer" reconciliation model. 5. Edit the balance of the line to lower, apply duplicated model(Internal Transfers (copy)). 6. Try deleting the generated Liquidity Transfer line. (Refer [this video](https://drive.google.com/file/d/1cz80Q5325x3rqYUlGahVzFIXH2iqrbRF/view?usp=drive_link) for steps to reproduce.) **Error:** ValueError - Expected singleton: account.reconcile.model(8, 6) **Cause:** In the method `delete_reconciled_line` at [1], the `reco_model_id` is fetched from `self.move_id.line_ids.reconcile_model_id`. If the move contains lines linked to multiple reconcile models, this causes a singleton error during subsequent processing. **Fix:** This commit uses the already computed `move_lines_to_remove` to retrieve `reconcile_model_id` instead of accessing it from `self.move_id.line_ids`, which may result in a multi-recordset. [1] - https://github.com/odoo/enterprise/blob/89aa58029a79928788277489414f8192aa5353e4/account_accountant/models/account_bank_statement.py#L1041-L1049 sentry-6781788260 Forward-Port-Of: odoo/enterprise#91619
The Timesheet Leaderboard now opens reliably even when the current employee is excluded from the billing-rate ranking due to a very low billing rate. This prevents an error screen and keeps managers and employees able to view leaderboard information without interruption.
Original PR description
**Issue:** A traceback occurs when clicking the Timesheet Leaderboard widget. **Cause:** The template `timesheet_leaderboard_dialog.xml` assumes that `state.current_employee` is always defined. However, when the current user's employee has a billing rate ≤ 0.5%, they are filtered out from the leaderboard. As a result, `setCurrentEmployeeIndexFromLeaderboard` returns `undefined`, causing the widget to crash. https://github.com/odoo/enterprise/blob/70ed91ba1ebb94cb1919df49a4d95fad26935d03/sale_timesheet_enterprise/static/src/services/timesheet_leaderboard_service.js#L18-L31 **Steps to reproduce:** 1. Set up a company with 4+ employees having billing targets. 2. Ensure the current user's employee has a billing rate ≤ 0.5% (e.g., 0.3 hours logged / 100 hours target). 3. Switch the leaderboard to "Billing Rate" mode. 4. Click the Timesheet Leaderboard widget. opw-4875410 Forward-Port-Of: odoo/enterprise#93339
Recurring subscriptions based on timesheets were sometimes treated as free when the sales order total or recurring revenue was zero, even though work had already been delivered. This fix ensures delivered timesheet-based services still generate invoices, helping businesses bill correctly for completed work.
Original PR description
### Steps to reproduce: - Install Helpdesk, Sale Subscription apps - Create a service recurring product and set its invoicing policy as 'Based on Timesheets' - Create a SO with the created product…
### Steps to reproduce: - Install Helpdesk, Sale Subscription apps - Create a service recurring product and set its invoicing policy as 'Based on Timesheets' - Create a SO with the created product and set the qty to 0 - Create a Helpdesk ticket and link it to the SO - Record some timesheets in this SO - Run the cron for generating recurring invoices - Notice no invoice will be created for the SO and it will be considered as free renewal ### Cause: When trying to create a recurring invoice we check if the invoice that will get generated is free by checking the MRR and the total amount of the SO and if one of them are 0 we will flag this invoice as free so we won't generate it ### Fix: We check if the order lines to be invoiced is invoiced based on delivery and they have delivered quantity already and if so we create the invoice even if the MRR and the total amount is equal 0 opw-4990478 Forward-Port-Of: odoo/enterprise#93245 Forward-Port-Of: odoo/enterprise#93115
Portal users receiving published planning shift emails now get a link that opens the correct planning view instead of sending them to the portal dashboard. This helps external users access their schedules directly and avoids confusion after clicking the email button.
Original PR description
### Steps to reproduce: - Install Planning app - Create a portal user and an employee for this user - Create a shift for this user and Publish it - Go to the email that has been sent and click on…
### Steps to reproduce: - Install Planning app - Create a portal user and an employee for this user - Create a shift for this user and Publish it - Go to the email that has been sent and click on View Your planning - Notice you are redirected to the portal dashboard home ### Cause: Since this commit diff we removed the check if the user is having planning group https://github.com/odoo-dev/enterprise/commit/72afe1e14703f0a3eafd0cfaec10c67462db73ce#diff-293bc9f44292d19793981abbafbe2a55642d170bda5e3bf17d7654f7bffcbedaL62-L64 When getting the planning url that will be share in the email we don't check if the user is portal or not so we set the url with /odoo path and if a portal user is accessing a /odoo path it will redirect him to /my https://github.com/odoo/odoo/blob/1acf4b2ce2bdad27e7d32d1227698968148a5935/addons/portal/controllers/web.py#L25-L26 ### Fix: We check if the user is portal we set the url with /planning path which will redirect the portal user to the correct planning view opw-5045746 Forward-Port-Of: odoo/enterprise#93359 Forward-Port-Of: odoo/enterprise#93333
The GSTR document summary now ignores invoices that no longer have a valid sequence number. This prevents report generation errors and ensures only properly numbered invoices are included in the summary.
Original PR description
_* = l10n_in_reports_gstr_document_summary Issue: - The GSTR document summary included all invoices that were posted or cancelled with posted_before = True. - If a user manually cleared the invoice sequence (set it to null), such invoices were still picked up. - This caused errors during summary generation since those invoices no longer had valid sequence numbers. Fix: - Adjusted the document summary logic to only include invoices with a valid sequence number. - Ensures that entries without a sequence are ignored, even if they were once posted. Impact: - Prevents errors when generating GSTR document summaries. - Guarantees that only valid, numbered invoices are included in reports. opw-5005048 Forward-Port-Of: odoo/enterprise#93039
The Estonian XML tax report now combines both 22% tax report line balances into a single transaction entry during export. This prevents duplicate transaction22 lines and helps ensure submitted tax reports match the expected format.
Original PR description
Before this pr: - There are two transactions22 entries were introduced because we are having two report lines for 22% tax computation, one with '1' tag, which is valid till 31 June 2025, and another one with '1_2' tag, which is valid from 1 July 2025. After this pr: - The balance computation during export to XML is now adding the balance of both line '1' and '1_2' into line '1' only. - So now we do not need an extra transactions22 entry in the XML tax report. - We are keeping both report lines for now, but the XML report will have only one entry with the total sum of balances in both report lines Related PR: https://github.com/odoo/enterprise/pull/91364 Forward-Port-Of: odoo/enterprise#93197 Forward-Port-Of: odoo/enterprise#92662
The POS IoT integration now selects the printer configured for receipts instead of accidentally using another connected printer, such as a kitchen preparation printer. This prevents receipts from being sent to the wrong device in setups with multiple printers.
Original PR description
Steps to reproduce: 1. Configure a POS with a receipt printer and a preparation printer. 2. Ensure that the preparation printer has a higher ID than the receipt printer (you can force this by deleting it and letting the IoT redetect it.) 3. Try to print a receipt. EXPECTED: The receipt is printed on the configured receipt printer. ACTUAL: The receipt is printed on the prepation printer. This was caused by the hardware proxy code assuming that there will only be 1 printer `iot.device` model loaded, and that it will correspond to the receipt printer. The fix is to ensure the hardware proxy only chooses the printer that is configured as the receipt printer. Forward-Port-Of: odoo/enterprise#93225