Monday, January 20, 2025
12 changes · 18.0
Enhancements to existing features
Odoo notification emails are now more compact by hiding headers and footers unless they contain important access actions or are needed for key business documents. This reduces clutter in email threads, improves readability, and removes extra details such as the internal-email ribbon and sales order expiration date.
Original PR description
Email notifications typically include: 1) A header with elements such as an access button, title, or subtitle. 2) A footer with sender information and a "Powered by Odoo" link. While these elements…
Email notifications typically include: 1) A header with elements such as an access button, title, or subtitle. 2) A footer with sender information and a "Powered by Odoo" link. While these elements provide valuable context, they can clutter email threads, especially in interleaved responses. This commit introduces a dynamic mechanism to streamline email notifications by conditionally hiding the header and footer based on predefined criteria: By default, - The header will be displayed only if it contains an access button. - The footer will be displayed if it contains an access button and the email is sent from an internal user and if the email is a notification about an invoice, a Purchase order (PO) or a Sales order (SO). To ensure flexibility, new context variables are introduced: - `email_notification_allow_header`, `email_notification_allow_footer`: Enable or disable the conditional hiding mechanism. - `email_notification_force_header`, `email_notification_force_footer`: Force the display of the header and footer regardless of conditions. Additionally, the ribbon indicating that an email is internal has been removed to further simplify the layout. These updates reduce email size, improve readability in threaded conversations, and ensure that critical information is highlighted without unnecessary clutter. Task-4128966
Resolved issues and error corrections
This fixes an issue where opening a Point of Sale linked to a special product from another company could make all products disappear. The POS now filters those special products by company and keeps the product list usable while showing the right error when needed.
Original PR description
**Current behavior:** When a user opens a POS with any special product - such as a tip product - assigned to a different company, no products are displayed in the POS interface. **Expected…
**Current behavior:** When a user opens a POS with any special product - such as a tip product - assigned to a different company, no products are displayed in the POS interface. **Expected behavior:** The user should receive an error message indicating that the assigned special product is reserved for another company. If the default special product is associated with a different company, products should still be listed in the POS. **Steps to reproduce:** 1. Create a POS for a company C<sub>**1**</sub>. 2. Create a Tip product, reserved for company C<sub>**2**</sub>. 3. Set the Tip product for the POS of company C<sub>**1**</sub>. 4. Open the POS for company C<sub>**1**</sub>. 5. No products are listed in the POS. **Cause of the issue:** The `get_special_products()` method returns the default tip product without verifying the company assignment, leading to incorrect behavior. Additional inheriting models add more products to this method, still without checking the company assignment. **Fix:** - Modified the `_get_limited_products_loading` function to filter the special products according to the session company. - Modified the `_get_default_tip_product` function to bypass the company check if the default tip product is assigned to a different company. opw-4396020 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Portal users with shared access can now load chatter messages even when someone has reacted with an emoji. This prevents message-loading errors in shared projects while only exposing the reacting person's name.
Original PR description
Before this commit, when accessing a shared chatter from a portal user that has edit access, chatter messages could not be loaded when a partner added at least one emoji reaction on a message. Steps…
Before this commit, when accessing a shared chatter from a portal user that has edit access, chatter messages could not be loaded when a partner added at least one emoji reaction on a message. Steps to reproduce: - Share a project with Joel Willis with edit access - Create a task with Joel Willis on this project - Post a message as Joel Willis on the new task - Let Mitchell Admin add a reaction on the new message => Joel Willis cannot load messages: ``` An error occurred while fetching messages. ``` This happens because the custom mail message formatter of portal chatter messages was crafting the reaction data of the messages to return. When providing people that have reacted to the message, Access to reacted partners was denied due to ACL. This commit fixes the issue by sudo() the partners of message reaction to retrieve their data to the portal user. This is ok because the portal has access to the message, therefore access to the reaction and related data are fine. Note that data of partner that have reacted is very limited: only the name is returned. opw-4454427
This fixes an issue where changing an account code for a company could leave related branch companies using outdated cached values, causing validation errors. Businesses with shared accounts across a parent company and branches can now update account codes more reliably and keep records consistent.
Original PR description
When we implemented shared accounts, a design decision was that all the branches of a root company should have the same code for an account. However, updating the code for a company doesn't update it…
When we implemented shared accounts, a design decision was that all the branches of a root company should have the same code for an account. However, updating the code for a company doesn't update it for the other companies with the same root. #### Steps to reproduce: - Create a company and a branch. - With both companies active, try to modify the code of an account. - Notice the ValidationError that pops up. #### Analysis: When writing on `code`, `_inverse_code` writes on `code_store`, which is a dependency of `code`. However, because `code` is protected at that point, it isn't invalidated + recomputed for the other companies. As a result, the old, incorrect value persists in cache. #### Solution: I don't think there is a nice neat solution to this. Ideally, we would like to remove the cache values for all the companies other than the active company. However, there isn't a cache function for doing that on context-dependent fields. We try to simulate that by first invalidating, then eagerly recomputing the code again just for the active company. task-none
Cross-dock deliveries now follow the intended route when started from a sales order, without disrupting normal purchase receipts. This prevents products from being incorrectly moved to outbound areas during regular purchasing and makes cross-docking usable as a targeted exception.
Original PR description
## General Issue: Cross-dock rules cannot function as the main rule without disrupting unrelated flows (e.g., regular purchases). They also fail as exceptions, as they are not triggered in such…
## General Issue:
Cross-dock rules cannot function as the main rule without disrupting unrelated flows (e.g., regular purchases). They also fail as exceptions, as they are not triggered in such cases.
## Cause:
Push and pull rules have been refactored in saas-17.2 (see commit 11e69870db1c49d9a6af79ffd263e4e162b34b6b). Previously, most flows relied solely on pull rules, generating the entire picking chain at inventory need confirmation. With the refactoring, push rules are now prioritized, generating pickings step-by-step upon validation. While this increases route flexibility, it introduces issues for flows expected to be entirely triggered by sales order (SO) validations, such as cross-docking.
In version 18.0, cross-dock rules were refactored to rely only on push rules (see commit af5479dfdbed0959c02bd862c8184fe141b51788), but this created significant issues.
### Steps to Reproduce:
- In the settings, Enable multi-step routes.
- Configure the warehouse for 2-step receipt and delivery
> automatically unarchives the cross-dock route and updates its rules:
- Push rule: Input → Output
- Buy rule: → Partner/Customer
#### Scenario 1: Cross-dock set on the product
#### Issue: Cannot receipt in 2 steps → cross dock can not be the rule.
- Create an inventory-tracked product with the buy and cross-dock routes.
- Create and confirm a purchase order for 1 unit of the product.
- Validate the receipt from Vendor → Input.
Result:
Instead of generating a picking Input → Stock, the cross-dock push rule triggers, generating a picking Input → Output.
### Cause:
Rules are prioritized by product-specific rules, followed by warehouse rules:
https://github.com/odoo/odoo/blob/e3d54695862f73d9be6c35121def57ed641a1a45/addons/stock/models/stock_rule.py#L535-L539 The cross-dock push rule therefore overrides regular 2-step receipt rules, even though cross-dock routes only make sense for flows initiated by an SO.
#### Scenario 2: Cross-dock not set on the product
#### Issue: Cannot trigger cross-docking by any means → cross dock can not be the exception.
- Create an inventory-tracked product with only the buy route.
- Create an SO for 1 unit of the product and set the cross-dock route on the Sales Order Line (SOL). Confirm the SO.
> A purchase order (PO) is created.
- Confirm the PO.
> A regular receipt is generated.
- Confirm the receipt.
Result:
The flow proceeds as a regular 2-step delivery; the cross-dock route is not applied.
### Cause:
The SO uses the cross-dock route only for the buy rule to generate a PO. Once the PO is generated is role in this world is done. There is no way to provide a route on the PO, it will just generate a regular receipt: https://github.com/odoo/odoo/blob/e3d54695862f73d9be6c35121def57ed641a1a45/addons/purchase_stock/models/purchase_order_line.py#L343-L350 Once it is confirmed, the flow defaults to regular 2-step delivery rules, as the cross-dock route is neither a default nor set on the product.
### Fix:
We add the possibility of transmitting the route_id from the pol. As such, we make it possible to use the crossdock route by setting it on the sol, to generate a PO that will pursue with the crossdock route. Furthermore, we discourage to use the crossdock route on products/product categories by setting the default setable values to False.
opw-4380375
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThe Point of Sale now handles cases where a cashier selects an order that has already been deleted. Instead of showing an error, the system switches to another draft order or creates a new one, keeping checkout workflows moving smoothly.
Original PR description
Resolved an issue where selecting a deleted order behaves correctly on the product screen but fails on the payment screen. **Steps to reproduce:** 1. create an order (order 1) 2. add product 3. go to payment screen 4. create another draft order (order 2) 5. go to Orders in the dropdown of the navbar (TicketScreen) 6. delete order 1 7. select the order you deleted from the navbar draft orders This will result in a traceback A fix was introduced in 18.1: https://github.com/odoo/odoo/commit/acb11c422ebf2b4811804a14ae12f849817f229a That commit in 18.1 can't just be backported because it changes the API of some related_models methods. This PR redirects you to Order 2 because order 1 is already Deleted If there isn't any other draft orders created, it redirects you to a new draft order. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Automation rules now correctly detect which fields should trigger them when a saved default filter is used. This prevents rules from losing their trigger settings and fixes navigation from Documents to Automation Rules.
Original PR description
Before this commit, 'trigger_field_ids' were already computed from the filter_domain, but using a default_filter_domain didn't work due to the '_onchange_trigger' method emptying 'trigger_field_ids' in the case of on_create_or_write. After this commit, we made '_onchange_trigger' take into account the filter_domain for this case. This addition fixes a window action from Documents to Automation Rules. see odoo/odoo#193206 see odoo/enterprise#75719 task-4481308 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users can now open Chart of Accounts entries after a company has been archived. The fix prevents inactive companies from being included in account mapping checks, avoiding an access error that interrupted accounting work.
Original PR description
After archiving a company users encounter an error when accessing any account in the CoA Steps to reproduce: - Create a second company - Archive it - Go to the Chart of Accounts - Open an account Issue: "Access to unauthorized or invalid companies" error will block the action. It occurs because the mapping is dynamically computed from the user companies, without filtering the actually active records opw-4270320 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
This fixes an access error that could block users from adding timesheets to tasks when projects are shared across multiple companies. The change helps multi-company teams record time reliably without removing sales links from tasks.
Original PR description
Steps to reproduce: ---------------------------------- 1) Create two companies and two users with employees. 2) Create a sale order with Company A. 3) Confirm the sale order. 4) Remove the company_id…
Steps to reproduce: ---------------------------------- 1) Create two companies and two users with employees. 2) Create a sale order with Company A. 3) Confirm the sale order. 4) Remove the company_id from the project. 5) Select the default company B and remove Company A. 6) Add a timesheet to the task. Issue: ------------------------ - When we try to add the timesheet for company 2 an access error will appears Cause: ------------------ - Currently, when we remove the company from the project, the project and task become accessible to all companies.The sale line item reference is not removed from the task, so when creating the timesheet, the sale item reference is passed. The user can access the sale order, but the analytic distribution is not accessible, causing an access error. If we remove the sale item from the task, there will be no access error. However, doing so is not preferable, which is why we applied sudo. Fix: ------------------------- - In this commit to resolved access error by adding `sudo()` to bypass record rules when retrieving `analytic_distribution` from `sale.order.line`. task-4206915
Paying part of a split restaurant order no longer creates duplicate preparation cards in the preparation display. This keeps kitchen and service teams working from a clean, accurate order queue and avoids confusion during table service.
Original PR description
- Avoid duplicating ticket in preparation display when paying a split order. - Don't call `this.pos.sendOrderInPreparation` after paying an order if this order is splitted or is a split from an other order. - Inside `pos_preparation_display.sync_from_ui` only call `process_order` if it the order is not splitted/splitting. Steps to Reproduce: - Add items to the cart and confirm an order. - A preparation is created in the PD (correct behavior). - Go back to the table, split the order, and pay for some lines. - Previously, a duplicate preparation card was created for split lines in the PD (incorrect behavior). enterprise PR: https://github.com/odoo/enterprise/pull/77150 task-id: 4476871 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
Quotations created from a billable project now correctly use that existing project when service lines generate tasks. This prevents Odoo from creating an extra duplicate project, keeping customer work organized in the intended place.
Original PR description
### Steps to reproduce: - Create a project and make it billable - Add a customer and add the first quotation from smart button on the project - On the quotation, add a service product that creates Project and Task and save - Notice another project has been created with a task inside ### Cause: This is happening because when creating an order that has an SO line that creates a project and a task we only check if the so_line has a project or not but we should fallback on order.project_id too. https://github.com/odoo/odoo/blob/saas-17.4/addons/sale_project/models/sale_order_line.py#L323 ### Fix: We fallback on the project of the order if we didn't find a project for the SO line. opw-4409810
This fix prevents duplicate preparation display tickets from appearing when restaurant staff split an order and pay for only some items. It keeps kitchen or preparation screens accurate, reducing confusion and avoiding unnecessary duplicate work.
Original PR description
- Avoid duplicating ticket in preparation display when paying a split order. - Inside `pos_preparation_display.sync_from_ui` only call `process_order` if `pos_restaurant` is not installed in the config. Steps to Reproduce: - Add items to the cart and confirm an order. - A preparation is created in the PD (correct behavior). - Go back to the table, split the order, and pay for some lines. - Previously, a duplicate preparation card was created for split lines in the PD (incorrect behavior). community PR: https://github.com/odoo/odoo/pull/193692 task-id: 4476871