Daily updates from Odoo
Monday, July 27, 2026
229 changes
29 changes
Enhancements to existing features
This PR alters the preview record selector pager present in the mass_mailing mobile preview view to allow users to manually select a recipient, instead of rotating through the available recipients. This PR also introduces an alternate-color version of the HTML editor phone_svg image, to be used in the dark theme preview. -- This PR introduces a series of small fixes to the mailing form view, UX and associated views: - When clicking its Discard button, the fullscreen mailing edit
Original PR description
This PR alters the preview record selector pager present in the mass_mailing mobile preview view to allow users to manually select a recipient, instead of rotating through the available recipients.…
This PR alters the preview record selector pager present in the mass_mailing mobile preview view to allow users to manually select a recipient, instead of rotating through the available recipients. This PR also introduces an alternate-color version of the HTML editor phone_svg image, to be used in the dark theme preview. -- This PR introduces a series of small fixes to the mailing form view, UX and associated views: - When clicking its Discard button, the fullscreen mailing editor only discards changes made to the mailing - In the Mailing preview dialog, the "fake" header no longer displays a grab cursor (as it cannot be grabbed) - When sending a test, a toaster is no longer displayed, as information pertaining to its success or failure is already logged in the chatter - The Dynamic list recipient count is no longer displayed for sent mailings, as it may have become outdated since it was sent. This commit also removes the outdated demo in mass_mailing_sale. It was no longer compatible with the editor, and its previous purpose in demonstrating link tracking is now handled by other demo mailings. task-6321624
Resolved issues and error corrections
#### Description of the issue this PR addresses: - Tables containing only a `<caption>` (or a `<thead>` without a `<tbody>`) could reach the editor with no `<tbody>`. - Since table width and margin are moved to the `<tbody>` during setup in 19.0–19.2, such tables caused the editor to fail. - Table operations such as resizing and adding rows or columns also expect a `<tbody>` to exist. #### Desired behavior after PR is merged: - Tables without a `<tbody>` are normalized during editor setup
Original PR description
#### Description of the issue this PR addresses: - Tables containing only a `<caption>` (or a `<thead>` without a `<tbody>`) could reach the editor with no `<tbody>`. - Since table width and margin are moved to the `<tbody>` during setup in 19.0–19.2, such tables caused the editor to fail. - Table operations such as resizing and adding rows or columns also expect a `<tbody>` to exist. #### Desired behavior after PR is merged: - Tables without a `<tbody>` are normalized during editor setup. - `<thead>` is converted or merged into `<tbody>`. - A missing `<tbody>` is created when necessary, preventing the editor from crashing. task-6391354 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278114 Forward-Port-Of: odoo/odoo#276588
Steps to reproduce: ==== - Disable `Group Products in POS` on the product's UoM. - Create a sale order containing that product. - Settle the sale order in POS. Issue: ==== - Order lines are grouped even though grouping is disabled for the product's UoM. Cause: ==== - During the refactoring of `pos_stock`, the order line splitting logic was moved to `pos_sale_stock`. As a result, when `pos_sale_stock` is not installed, sale order lines are no longer split when settling a sale order.
Original PR description
Steps to reproduce: ==== - Disable `Group Products in POS` on the product's UoM. - Create a sale order containing that product. - Settle the sale order in POS. Issue: ==== - Order lines are grouped even though grouping is disabled for the product's UoM. Cause: ==== - During the refactoring of `pos_stock`, the order line splitting logic was moved to `pos_sale_stock`. As a result, when `pos_sale_stock` is not installed, sale order lines are no longer split when settling a sale order. Fix: ==== - Move the shared order line splitting logic to `pos_sale` so it is always applied when settling sale orders, regardless of whether `pos_sale_stock` is installed. task-6401619 Forward-Port-Of: odoo/odoo#277695
Steps to reproduce: - Install Argentina(l10n_ar) localization > Change Company - Accounting > Customers > Invoices > Select an invoice > Click "Pay" - In "Journal" select "Third Party Checks" > In "Payment Method" select "New Third Party Checks" > Fill the rest of the check info (Number, Bank Account, Issuer Vat, Payment Date and Amount) > Click on "Create Payment" - Repeat the payment process for another invoice with same info > Validation Error A change in [PR] caused the check uniquene
Original PR description
Steps to reproduce: - Install Argentina(l10n_ar) localization > Change Company - Accounting > Customers > Invoices > Select an invoice > Click "Pay" - In "Journal" select "Third Party Checks" > In…
Steps to reproduce: - Install Argentina(l10n_ar) localization > Change Company - Accounting > Customers > Invoices > Select an invoice > Click "Pay" - In "Journal" select "Third Party Checks" > In "Payment Method" select "New Third Party Checks" > Fill the rest of the check info (Number, Bank Account, Issuer Vat, Payment Date and Amount) > Click on "Create Payment" - Repeat the payment process for another invoice with same info > Validation Error A change in [PR] caused the check uniqueness constraint apply to all checks. Because of this, using the same check number with the "New Third Party Checks" payment method now raises a validation error. This is not the intended behavior. The uniqueness constraint should only apply to "Own Checks" when using a "Bank" journal for Vendor Bills. It should not apply to "Third Party Checks" with the "New Third Party Checks" payment method in Customer Invoice. Avoid linking `l10n_latam_check_ids` on liquidity lines for outbound "Own Checks" payments so that the uniqueness constraint is enforced only for the "Vendor Bills". [PR]: https://github.com/odoo/odoo/pull/243509/changes opw-6334965 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275261
#### Description of the issue this PR addresses: - Blockquotes currently display their border on the left side. #### Desired behavior after PR is merged: - Update the styling so the border is displayed on the right side for RTL content. task-6296519 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277057 Forward-Port-Of: odoo/odoo#269529
Original PR description
#### Description of the issue this PR addresses: - Blockquotes currently display their border on the left side. #### Desired behavior after PR is merged: - Update the styling so the border is displayed on the right side for RTL content. task-6296519 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277057 Forward-Port-Of: odoo/odoo#269529
When installing the module document_account_peppol, the user has the choice to import his Peppol invoices into the Documents app directly, but also to block the import in Accounting, by removing the Peppol import journal. In that last case, the Peppol application response flow is broken, the document model does not contain the necessary information to handle responses as the imported invoices do. (In stable) We took the decision to remove the ApplicationResponse service from users that bl
Original PR description
When installing the module document_account_peppol, the user has the choice to import his Peppol invoices into the Documents app directly, but also to block the import in Accounting, by removing the Peppol import journal. In that last case, the Peppol application response flow is broken, the document model does not contain the necessary information to handle responses as the imported invoices do. (In stable) We took the decision to remove the ApplicationResponse service from users that block the invoice import flow by removing the import journal. For PDP, the responses are required, but as the block is completely replaced in the view, and reuses the basic account_peppol condition for the required attribute, the account peppol purchase journal will always be required if the company is registered on Peppol/PDP. Nothing to do in 18.0. task-6191644 Forward-Port-Of: odoo/odoo#270096 Forward-Port-Of: odoo/odoo#270091
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's ty
Original PR description
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when…
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's type to a "URL" or "CC" field. - Save the changes. - The "URL/CC" field is prefilled with the user's name. A field is considered repurposed when: - its type is changed (e.g. from "Phone" to "URL"); - a custom field is converted into an existing field. **Fix:** This commit preserves the prefill only when the field keeps the same name and type. Otherwise, it clears the stale prefill so repurposed fields no longer inherit incorrect values. task-[5976747](https://www.odoo.com/odoo/project/974/tasks/5976747) Forward-Port-Of: odoo/odoo#278426 Forward-Port-Of: odoo/odoo#275812
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Configure a multi-company environment with a `Main Company` and a `Secondary Company` - Go to the setting enable Lots & Serial Numbers and switch into `Secondary Company` - Create a warehouse for the Secondary Company - In the Secondary Company, create a lot-tracked storable product - Create and validate a delivery for that product - Open the Traceability Report - Print the report Is
Original PR description
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Configure a multi-company environment with a `Main Company` and a `Secondary Company` - Go to the setting…
Version:
--------
- 18.0+
Steps to reproduce:
-------------------
- Install `stock` module
- Configure a multi-company environment with a `Main Company`
and a `Secondary Company`
- Go to the setting enable Lots & Serial Numbers and switch into
`Secondary Company`
- Create a warehouse for the Secondary Company
- In the Secondary Company, create a lot-tracked storable product
- Create and validate a delivery for that product
- Open the Traceability Report
- Print the report
Issue:
------
The report header always displays the Main Company, even though the
traceability report belongs entirely to the Secondary Company.
Cause:
------
https://github.com/odoo/odoo/blob/2d54db3ac0b6d807e580315e2633f3e2b10a700c/addons/stock/static/src/client_actions/stock_traceability_report_backend.xml#L9
Clicking Print calls onClickPrint(), which builds the PDF URL and
downloads it with download() (a plain XMLHttpRequest POST), landing on
the `type='http'` route `/stock/<output_format>/<report_name>`
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L125-L134
That controller calls stock.traceability.report.get_pdf() without ever setting
`company_id` in the rendering context.
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/stock/controllers/main.py#L23
Inside `get_pdf()`, the report header is rendered by passing an `rcontext`
dict to `web.internal_layout`.
That template resolves the company to display using the following priority:
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/web/views/report_templates.xml#L805-L816
1. `company_id` — an explicit company record in the render context
2. `o.company_id` — the company of the document object `o`
3. `res_company` — the fallback, injected by `_render_template()` as
`self.env.company`
Because `get_pdf()` never sets `company_id` or `o` in `rcontext`, the
template always falls through to `res_company`.
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/odoo/addons/base/models/ir_actions_report.py#L770
This is populated by `ir.actions.report._render_template()`
as `self.env.company`, which resolves to the first company in
the user's `allowed_company_ids` list — typically the main company
regardless of which company owns the lot,
picking, or stock moves being printed.
As a result, the report content belongs to the secondary company while the
header always shows the main company.
Fix:
----
Resolve the company from the record on which the traceability report is
opened (using `active_model` and `active_id`) and pass it explicitly as
`company_id` when rendering the report.
`web.internal_layout` already gives precedence to an explicit
`company_id` over the default `res_company`, ensuring the report header
always displays the company that owns the traced record.
When the record has no company set, the header falls back to
`res_company`. Since the print request is a raw `type='http'` download
that never receives the company switcher's context, `user.context`
(holding `allowed_company_ids`) is now forwarded in the download POST
and merged into the environment by the controller - as done in
`web/controllers/report.py` - so the fallback resolves to the currently
active company instead of the user's default one.
<details>
<summary>Click here to see the results:</summary>
<p><strong>Before:</strong></p>
<div class="image-row">
<img src="https://github.com/user-attachments/assets/7e3a5d65-9114-4bce-9139-a88cff7c261f" />
</div>
<p><strong>After:</strong></p>
<div class="image-row">
<img src="https://github.com/user-attachments/assets/0a105f80-b6ae-400d-a787-fb8706d5f519" />
</div>
</details>
---
opw-6345446
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#273595### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue:
Original PR description
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a…
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue: Writing on the `move_raw_ids` will trigger a call of the `_autoconfirm_production` in order to confirm the newly created move: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L990-L991 https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L1422-L1423 During this confirmation process, one calls the `_merge_moves` method in order to merge this new move (if relevant) to any already existing one. https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/stock/models/stock_move.py#L1575-L1576 Now, the issue is that, `sale_stock_renting` modeule overrides the method `_prepare_merge_moves_distinct_fields` determining the fields relevant to the merge by requiring a read access to the `is_rental_order` compute field of the `sale_order` linked to the MO: https://github.com/odoo/enterprise/blob/b66097122ba3a758734ac6fb2b26579c35cb72c2/sale_stock_renting/models/stock_move.py#L34-L40 However, due to the 'Personal Orders' ir.rule, the user does not have a read access to this record: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/sale/security/ir_rules.xml#L44-L49 Enterprise: https://github.com/odoo/enterprise/pull/121135 opw-6275658 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272256 Forward-Port-Of: odoo/odoo#271017
**Problem:** On a job position whose company is left empty ("Visible to all"), the Recruiter dropdown does not propose any user anymore: only the "Create" option is offered. The same happens on applicants without a company. Only saas-19.2 is affected: 19.0/19.1 still use the res.users-based recruiter field, and on saas-19.3 the company became mandatory on job positions. **Steps to reproduce:** 1. Install Recruitment 2. Open a job position whose Company is "Visible to all" (e.g. any demo jo
Original PR description
**Problem:** On a job position whose company is left empty ("Visible to all"), the Recruiter dropdown does not propose any user anymore: only the "Create" option is offered. The same happens on…
**Problem:**
On a job position whose company is left empty ("Visible to all"), the Recruiter dropdown does not propose any user anymore: only the "Create" option is offered. The same happens on applicants without a company. Only saas-19.2 is affected: 19.0/19.1 still use the res.users-based recruiter field, and on saas-19.3 the company became mandatory on job positions.
**Steps to reproduce:**
1. Install Recruitment
2. Open a job position whose Company is "Visible to all" (e.g. any demo job position)
3. Edit the Recruiter field
**Current behavior:**
The dropdown shows no user, only the "Create" option.
**Expected behavior:**
The dropdown lists the recruiters of all companies, as it does (per company) when a company is set.
**Cause of the issue:**
Commit 05e22346050d replaced the res.users-based `user_id` recruiter field with the hr.employee-based `recruiter_id`, declared with `check_company=True`. For check_company fields, `_description_domain()` sends the client `company_id and [('company_id', 'in', [company_id, False])] or [('company_id', '=', False)]`. When the record has no company, the domain falls back to `[('company_id', '=', False)]`, and since `hr.employee.company_id` is required, no employee can ever match. This reintroduces the issue previously fixed by 5dfe494e62af for the old user_id field: the `allowed_user_ids` mechanism introduced there was dropped by the field replacement.
**Fix:**
`check_company=True` brings nothing to these models server-side (neither `hr.job` nor `hr.applicant` has `_check_company_auto`): its only effect is that client-side domain. Folding the company condition directly into the recruiter domain with `('company_id', '=?', company_id)` keeps the per-company filtering when a company is set and degrades to no filtering when it is not, mirroring what is already done for `interviewer_ids` on the job position. The domains become strings so the client keeps evaluating `company_id` per record.
opw-6290312
Forward-Port-Of: odoo/odoo#276079
Forward-Port-Of: odoo/odoo#270529Problem: When a table (or banner, or columns block) is placed inside a toggle block, deleting the last paragraph in a table cell creates a new block after the toggle block and moves the selection outside the table. Cause: `handleDeleteBackwardContentEnd` assumes the deleted block is always a direct child of the toggle content. However, the deleted block may be nested inside a table, banner, or columns block. Solution: Only create a new block after the toggle block when the selected bloc
Original PR description
Problem: When a table (or banner, or columns block) is placed inside a toggle block, deleting the last paragraph in a table cell creates a new block after the toggle block and moves the selection outside the table. Cause: `handleDeleteBackwardContentEnd` assumes the deleted block is always a direct child of the toggle content. However, the deleted block may be nested inside a table, banner, or columns block. Solution: Only create a new block after the toggle block when the selected block is a direct child of the toggle content. Steps to reproduce: - Add a toggle block. - Insert a table inside its content. - Add two paragraphs to a table cell. - Delete the last paragraph. - Observe that a new block is created after the toggle block and the selection moves outside the table. opw-6382058 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278119 Forward-Port-Of: odoo/odoo#277194
Steps to reproduce: 1. Drop the Website Form snippet. 2. Add a checkbox field. 3. Change the label position to Top. > The Default Value option disappears. Cause: The `applyTo` selector relied on the `.col-sm` wrapper, which is only present for left/right label positions. As a result, it did not match checkbox fields with Top or None labels. This commit fix the applyTo selector so the Default Value option is displayed for checkbox fields regardless of the selected label position.
Original PR description
Steps to reproduce: 1. Drop the Website Form snippet. 2. Add a checkbox field. 3. Change the label position to Top. > The Default Value option disappears. Cause: The `applyTo` selector relied on the `.col-sm` wrapper, which is only present for left/right label positions. As a result, it did not match checkbox fields with Top or None labels. This commit fix the applyTo selector so the Default Value option is displayed for checkbox fields regardless of the selected label position. task-6373796 Forward-Port-Of: odoo/odoo#277754 Forward-Port-Of: odoo/odoo#275823
Steps to reproduce: - activate location - create a tracked product A - create a PO with qty=10 with product A - receive them (8 in WH/Stock, 2 in WH/Stock/Shelf 1) - In Reporting/stock filter with "wh/stock" Issue: On hand value will be 0 Cause: "wh/stock did not match _rec_names = 'name' -> WH location is different than "stock" location (who's parent is "WH"). We need to match it with _rec_names_search (1) to match the right location. We fall back on _rec_names in case _rec_name
Original PR description
Steps to reproduce: - activate location - create a tracked product A - create a PO with qty=10 with product A - receive them (8 in WH/Stock, 2 in WH/Stock/Shelf 1) - In Reporting/stock filter with "wh/stock" Issue: On hand value will be 0 Cause: "wh/stock did not match _rec_names = 'name' -> WH location is different than "stock" location (who's parent is "WH"). We need to match it with _rec_names_search (1) to match the right location. We fall back on _rec_names in case _rec_names_search would not be defined (not really necessary in here but meh why not be conservative) (1) https://github.com/odoo/odoo/blob/2bb7493b72b400ed76cc6460c94867fb86de9f3a/addons/stock/models/stock_location.py#L19 opw-6312702 Forward-Port-Of: odoo/odoo#277059 Forward-Port-Of: odoo/odoo#271552
**Steps to reproduce:** - Enable 2FA - Change user language - Log in in another private window / device - Check the notification email of a login with another device - Email body/subject are not properly adapted to user language **Issue:** View manual rendering doesn't pass the user language. **Fix:** Add it to the context before `_render_template` and subject translation (reapply similar fix [1]). [1] https://github.com/odoo/odoo/commit/4d8d1736ca03a3d6b4e86cbc7463a79a284d1f3c
Original PR description
**Steps to reproduce:** - Enable 2FA - Change user language - Log in in another private window / device - Check the notification email of a login with another device - Email body/subject are not properly adapted to user language **Issue:** View manual rendering doesn't pass the user language. **Fix:** Add it to the context before `_render_template` and subject translation (reapply similar fix [1]). [1] https://github.com/odoo/odoo/commit/4d8d1736ca03a3d6b4e86cbc7463a79a284d1f3c opw-6042550 Forward-Port-Of: odoo/odoo#275705 Forward-Port-Of: odoo/odoo#261468
Steps: - Install sale app. - Create SO for portal user. - Login with portal user. - Vat field is not editable and warning is wrong. Issue: - Before https://github.com/odoo/odoo/pull/211043 and recent fix https://github.com/odoo/odoo/pull/275207 portal user can edit their Vat number even if they have confirmed documents (invoice or SO) if Vat field is not set. Since `is_company` refactoring having set parent_name on address create related company and making `is_commercial_address` False a
Original PR description
Steps: - Install sale app. - Create SO for portal user. - Login with portal user. - Vat field is not editable and warning is wrong. Issue: - Before https://github.com/odoo/odoo/pull/211043 and recent fix https://github.com/odoo/odoo/pull/275207 portal user can edit their Vat number even if they have confirmed documents (invoice or SO) if Vat field is not set. Since `is_company` refactoring having set parent_name on address create related company and making `is_commercial_address` False and because that `Vat` field became reaonly and after recent fix `is_commercial_address` was set from `can_edit_vat` and validation done based on `can_edit_vat` before that `Vat` was editable if they have confirmed documents Fix: - Only make `Vat` readonly if Vat is set and is not individual address Forward-Port-Of: odoo/odoo#278233 Forward-Port-Of: odoo/odoo#277459
# How to reproduce - In Settings, enable Variants & Product Reference Price - Create a published Product with a Sales Price - Add 2 variants to the Product - In the product's variant list, select the first one & set Base Unit Count to 0, - Set the second variant's Base Unit Count to a value > 0 - Go to the Product's page - Select the second variant # The issue The Reference Price is not displayed for the second variant, even though it should since it has a Base Unit Count > 0. Refresh
Original PR description
# How to reproduce - In Settings, enable Variants & Product Reference Price - Create a published Product with a Sales Price - Add 2 variants to the Product - In the product's variant list, select the…
# How to reproduce
- In Settings, enable Variants & Product Reference Price
- Create a published Product with a Sales Price
- Add 2 variants to the Product
- In the product's variant list, select the first one & set Base Unit Count to 0,
- Set the second variant's Base Unit Count to a value > 0
- Go to the Product's page
- Select the second variant
# The issue
The Reference Price is not displayed for the second variant, even though it should since it has a Base Unit Count > 0. Refreshing the page while being on the second variant will prevent the bug from happening.
# Cause
When loading the product's info, we call `_onChangeCombination`. This method is responsible for, among other things, updating the reference price and hiding it if Base Unit Count = 0 :
https://github.com/odoo/odoo/blob/68f258e99f42693131a5309b3606c3b95f93d824/addons/website_sale/static/src/js/variant_mixin.js#L277-L289
To do that, it will search for an html element with the `.o_base_unit_price` css class. If it does not find it, the reference price will not be updated. The issue is that this element is behind a condition in the template :
https://github.com/odoo/odoo/blob/68f258e99f42693131a5309b3606c3b95f93d824/addons/website_sale/views/templates.xml#L2083
When the first time the template is loaded, if
`combination_info.get('base_unit_price')` is False, then the Reference Price will never be added to the view and will never be found by `_onChangeCombination`.
Since our first variant has Base Unit Count = 0, then `base_unit_price` will equal 0, so `combination_info.get('base_unit_price')` will be evaluated to false.
opw-6367289
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#276713
Forward-Port-Of: odoo/odoo#274722**STEP TO REPRODUCE** 1. Install l10n_fr_pdp and select the french company. 2. Go on a contact form, under invoicing, select 'by Approved Platform' for invoice sending. 3. Click on the eInvoice format selection, and notice the format 'France E-invoicing (UBL 2.1)' is not there. Note: with other invoice sending values, it shows up. **CAUSE** In the `_get_ubl_cii_formats_info()` override in `l10n_fr_pdp`, we declare the ubl_21_fr format as not being usable with the peppol invoice sending me
Original PR description
**STEP TO REPRODUCE** 1. Install l10n_fr_pdp and select the french company. 2. Go on a contact form, under invoicing, select 'by Approved Platform' for invoice sending. 3. Click on the eInvoice format selection, and notice the format 'France E-invoicing (UBL 2.1)' is not there. Note: with other invoice sending values, it shows up. **CAUSE** In the `_get_ubl_cii_formats_info()` override in `l10n_fr_pdp`, we declare the ubl_21_fr format as not being usable with the peppol invoice sending method. However, the Approved Platform invoice sending (used to send ubl_21_fr) *is* the peppol invoice sending method in disguise. (we reused the peppol invoice sending method because pdp and peppol are very similar). opw-6387796 Forward-Port-Of: odoo/odoo#276276
This PR fixes the issue of the Cancel button floating on the last row when the buttons wrap and other overflowing issues. Before this PR, we were targetting the screen's orientation and max-height, which worked in general but still let a few layout issues through. On tablets the buttons are large and squarish for better touch usability (which has the double function of leaving plenty of space for translations), this makes fitting them within the modal container without overflowing a bit more c
Original PR description
This PR fixes the issue of the Cancel button floating on the last row when the buttons wrap and other overflowing issues. Before this PR, we were targetting the screen's orientation and max-height,…
This PR fixes the issue of the Cancel button floating on the last row when the buttons wrap and other overflowing issues. Before this PR, we were targetting the screen's orientation and max-height, which worked in general but still let a few layout issues through. On tablets the buttons are large and squarish for better touch usability (which has the double function of leaving plenty of space for translations), this makes fitting them within the modal container without overflowing a bit more complex. Instead, we target ranges of the aspect-ratio of the screen and adjust the buttons squarish aspect-ratio and the number of grid columns accordingly. By controlling the grid's columns we're able to tell the last button (the Cancel button) to stretch to full width when needed as well as having a more balanced layout in both landscape and portrait views. task-6235164 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265711
When inserting nodes, they are run through `node_to_insert_processors` to possibly handle some conversions - e.g. turning paragraphs into further list items within a list. However the `insertedNodes` returned by the `insert` method are actually the nodes that were initially requested to be added. This commit puts the nodes among the `insertedNodes` after they were potentially converted. task-6364282 Forward-Port-Of: odoo/odoo#277789
Original PR description
When inserting nodes, they are run through `node_to_insert_processors` to possibly handle some conversions - e.g. turning paragraphs into further list items within a list. However the `insertedNodes` returned by the `insert` method are actually the nodes that were initially requested to be added. This commit puts the nodes among the `insertedNodes` after they were potentially converted. task-6364282 Forward-Port-Of: odoo/odoo#277789
### Steps to reproduce: - Open the Todo app - In the editor, insert the following content: `<p>a</p><div class="oe_unbreakable"><br></div><p>b</p>` - Double-click the empty unbreakable node - Open the color picker and hover over a color - Toolbar and color picker get closed ### Root cause: - Hovering a color in an empty unbreakable node replaces the `<br>` with a `<font data-oe-zws-empty-inline>` containing a ZWS (`\u200b`). This triggers a selectionchange where `isToolbarVisible()`
Original PR description
### Steps to reproduce: - Open the Todo app - In the editor, insert the following content: `<p>a</p><div class="oe_unbreakable"><br></div><p>b</p>` - Double-click the empty unbreakable node - Open…
### Steps to reproduce: - Open the Todo app - In the editor, insert the following content: `<p>a</p><div class="oe_unbreakable"><br></div><p>b</p>` - Double-click the empty unbreakable node - Open the color picker and hover over a color - Toolbar and color picker get closed ### Root cause: - Hovering a color in an empty unbreakable node replaces the `<br>` with a `<font data-oe-zws-empty-inline>` containing a ZWS (`\u200b`). This triggers a selectionchange where `isToolbarVisible()` finds no `<br>` and no visible text, returns false, and closes the toolbar — which reverts the preview, reopens the toolbar, and causes a flicker loop. ### Solution: - Instead of calling `fillEmpty()` (which inserts a ZWS placeholder) on empty blocks containing `<br>` preserve the `<br>` element by appending it directly inside the `<font>` tag which keeps toolbar open. task-6312933 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276776 Forward-Port-Of: odoo/odoo#271507
Since odoo/odoo@d403c507bf5c6846667fa893f78245a3183e0921, terminal coloring is controlled through `config.colors`, which is initialized by `load_color_options()`. In a fresh spawned `populate` worker process, `config.colors` keeps its default all-false value unless that method is called. As a result, the `ColoredFormatter` is installed in workers, but it emits plain log lines because we didn't load the new coloring options. This commits correctly initializes the config in the workers, and
Original PR description
Since odoo/odoo@d403c507bf5c6846667fa893f78245a3183e0921, terminal coloring is controlled through `config.colors`, which is initialized by `load_color_options()`. In a fresh spawned `populate` worker process, `config.colors` keeps its default all-false value unless that method is called. As a result, the `ColoredFormatter` is installed in workers, but it emits plain log lines because we didn't load the new coloring options. This commits correctly initializes the config in the workers, and removes explicit logger initialization, which is handled by `parse_config(setup_logging=True)`. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
…edit_menus tour Add a step to wait for the DOM to stabilize after nesting 'new_nested_menu' under 'new_menu', fixing a flake on runbot. 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
Original PR description
…edit_menus tour Add a step to wait for the DOM to stabilize after nesting 'new_nested_menu' under 'new_menu', fixing a flake on runbot. 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
### Steps to reproduce: - In the settings enable Multi-Steps route - Unarchive the MTO route and set its production rule in MTSO - Create 3 products: P1, P2 and COMP all using the MTO route - Create 2 BOM's, one for P1 and one for P2: 1 X COMP - Put 2 units of COMP in stock and add an empty bom (to trigger a child MO creation in case the MTSO route is triggered) - Create and confirm a sale order for: 1 x P1 and 1 X P2 #### > An MO was generated for both product but P2 also generated a c
Original PR description
### Steps to reproduce: - In the settings enable Multi-Steps route - Unarchive the MTO route and set its production rule in MTSO - Create 3 products: P1, P2 and COMP all using the MTO route - Create…
### Steps to reproduce: - In the settings enable Multi-Steps route - Unarchive the MTO route and set its production rule in MTSO - Create 3 products: P1, P2 and COMP all using the MTO route - Create 2 BOM's, one for P1 and one for P2: 1 X COMP - Put 2 units of COMP in stock and add an empty bom (to trigger a child MO creation in case the MTSO route is triggered) - Create and confirm a sale order for: 1 x P1 and 1 X P2 #### > An MO was generated for both product but P2 also generated a child MO for 1 unit of COMP instead of using the available unit Cause of the issue: The issue happens in the `_prepare_procurement_qty` which incorrectly assess that 1 unit of COMP will be required. The issue has been introduced by commit https://github.com/odoo/odoo/commit/e30fb722c00805e7226d2ee9e3e587b3c2204840 which introduced a dictionary to keep track of units of products that will be used by the confirmation process of other concurrent mtso moves: https://github.com/odoo/odoo/blob/71f0715bd5e29e976a1e8bfa7c4fa6e04735ebd7/addons/stock/models/stock_move.py#L1683-L1689 https://github.com/odoo/odoo/blob/71f0715bd5e29e976a1e8bfa7c4fa6e04735ebd7/addons/stock/models/stock_move.py#L1712-L1715 https://github.com/odoo/odoo/blob/71f0715bd5e29e976a1e8bfa7c4fa6e04735ebd7/addons/stock/models/stock_move.py#L1810-L1814 While by design this propagates the information used by other mtso moves in a common `_action_confirm` stack, the issue that we encounter is that this quantity is only relevant to be substracted to the free_qty when the unit is not yet reserved and hence already accounted negatively in `free_qty`. However, in the present case, confirming the receipt of P1 and P2 will confirm both moves simultaneously, triggering a common `_run_manufacture` to generate both an MO for P1 and for P2. At this point the dictionary `consumed_from_stock_dict` is shared in both MO's confirmation but since the MO's are confirmed sequentially rather than in batch: https://github.com/odoo/odoo/blob/71f0715bd5e29e976a1e8bfa7c4fa6e04735ebd7/addons/mrp/models/stock_rule.py#L122-L125 The confirmation of the MO of P1 will update the `consumed_from_stock_dict` for 1 unit of COMP and will also reserve 1 unit of COMP before the MO of P2 is confirmed (and calls the `_prepare_procurement_qty`) to determine how many units of COMP are till available. This leads to the incorrect conclusion that 1 - 1 = 0 units are still available to fulfill the demand of P2. opw-6370298 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275539
*: website Commit 8916f6f1fa093e90ad708574afab021bc5e47b84 avoided the temporary switch to the blocks tab. But the de-activation of the target had the desired side-effect of hiding the overlay (which can be confusing/annoying during a drag and drop of a column). This commit explicitly hides the button's overlay and the builder's overlay on drag. Steps to reproduce: - Open website builder - Add the snippet `s_three_columns` - Click on one of the column - Drag the button in the overla
Original PR description
*: website Commit 8916f6f1fa093e90ad708574afab021bc5e47b84 avoided the temporary switch to the blocks tab. But the de-activation of the target had the desired side-effect of hiding the overlay (which can be confusing/annoying during a drag and drop of a column). This commit explicitly hides the button's overlay and the builder's overlay on drag. Steps to reproduce: - Open website builder - Add the snippet `s_three_columns` - Click on one of the column - Drag the button in the overlay "Drag and move" - Bug: the builder's overlay and the button's overlay stay around task-6212783
Description of the issue/feature this PR addresses: report_stock_quantity uses m.quantity instead of the done quantity converted to the product's base UoM when computing the forecast for done inter-warehouse moves. This causes incorrect forecast values when a done stock move uses a UoM with a factor greater than 1. Current behavior before PR: When a done inter-warehouse move uses a UoM with factor > 1 (e.g. a box of 25 units), the forecast only subtracts the raw done quantity (e.g. 2 bo
Original PR description
Description of the issue/feature this PR addresses: report_stock_quantity uses m.quantity instead of the done quantity converted to the product's base UoM when computing the forecast for done…
Description of the issue/feature this PR addresses: report_stock_quantity uses m.quantity instead of the done quantity converted to the product's base UoM when computing the forecast for done inter-warehouse moves. This causes incorrect forecast values when a done stock move uses a UoM with a factor greater than 1. Current behavior before PR: When a done inter-warehouse move uses a UoM with factor > 1 (e.g. a box of 25 units), the forecast only subtracts the raw done quantity (e.g. 2 boxes) instead of the converted quantity in the product's base UoM (e.g. 50 units). This causes the forecast chart to show incorrect negative values before the move date. Steps to reporduce: - Create a storable product with base UoM = Units - Create a UoM "Box of 25" with factor = 25 in the Units category, and add it to the product's allowed UoMs - Create a second warehouse - Do an inventory adjustment of 800 units into warehouse 1 - Create an inter-warehouse transfer of 2 "Box of 25" (= 50 units) from warehouse 1 to warehouse 2 and validate it - Open the forecast chart for the product filtered to warehouse 1 Desired behavior after PR is merged: The forecast report for done inter-warehouse moves correctly converts the done quantity to the product's base UoM using the move's UoM factor, so the forecast chart shows accurate values regardless of the UoM used on the move. opw-6266745 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273797 Forward-Port-Of: odoo/odoo#271766
Currently, sending a simplified invoice (`TD07`) to the Italian Tax Agency fails when an invoice line contains multiple taxes. **Steps to reproduce:** - Install the `l10n_it_edi_withholding` module and switch to an IT Company. - Create a new customer and set only the country to Italy and the Tax ID. - Create a new invoice for that customer. - Add a line with `22%` and `4% INPS` taxes. - Go to the `Electronic Invoicing` tab, set the `Document Type` to `TD07 - Simplified invoice`, and c
Original PR description
Currently, sending a simplified invoice (`TD07`) to the Italian Tax Agency fails when an invoice line contains multiple taxes. **Steps to reproduce:** - Install the `l10n_it_edi_withholding` module…
Currently, sending a simplified invoice (`TD07`) to the Italian Tax Agency fails when an invoice line contains multiple taxes. **Steps to reproduce:** - Install the `l10n_it_edi_withholding` module and switch to an IT Company. - Create a new customer and set only the country to Italy and the Tax ID. - Create a new invoice for that customer. - Add a line with `22%` and `4% INPS` taxes. - Go to the `Electronic Invoicing` tab, set the `Document Type` to `TD07 - Simplified invoice`, and confirm the invoice. - Try to `Send To Tax Agency`. **Error:** `Node: <Natura t-if="line.tax_ids.l10n_it_exempt_reason" t-out="line.tax_ids.l10n_it_exempt_reason"/>` `ValueError: Expected singleton: account.tax(102, 3)` **Root Cause:** At [1], the code accesses `line.tax_ids.l10n_it_exempt_reason`, but when an invoice contains multiple taxes, causing an error. **Fix:** This commit prevents the error and ensures the user can send a simplified invoice by applying a fix similar to [2]. [1]: https://github.com/odoo/odoo/blob/230483ffd7d8674cd6bf98a4ffb6591f755422e0/addons/l10n_it_edi/data/invoice_it_simplified_template.xml#L14 [2]: https://github.com/odoo/odoo/blob/230483ffd7d8674cd6bf98a4ffb6591f755422e0/addons/l10n_it_edi/data/invoice_it_template.xml#L28-L181 Ticket [link](https://www.odoo.com/odoo/project.task/6354138) Ticket [link](https://www.odoo.com/odoo/project.task/6379377) opw-6354138 opw-6379377 Forward-Port-Of: odoo/odoo#278307 Forward-Port-Of: odoo/odoo#273823
**Problem**: When a stock move has no quantity, the computation of the lot cost fails because it tries to divide by zero. **Fix**: Add a check to the ```move._get_valued_qty()``` to make sure it is not zero before performing the division. **Steps to reproduce:** 1. Create a product tracks quantity by lot, and valuation by Lot/Serial. 2. Assign a FIFO costing method category to it. 3. Update on hand quantity to 10 4. Reduce the on hand quantity to 5 and update to 10 again. 5. Go to t
Original PR description
**Problem**: When a stock move has no quantity, the computation of the lot cost fails because it tries to divide by zero. **Fix**: Add a check to the ```move._get_valued_qty()``` to make sure it is not zero before performing the division. **Steps to reproduce:** 1. Create a product tracks quantity by lot, and valuation by Lot/Serial. 2. Assign a FIFO costing method category to it. 3. Update on hand quantity to 10 4. Reduce the on hand quantity to 5 and update to 10 again. 5. Go to the in/out smart button and change the quantity of the most recent sml to 0. 6. Updating the on hand quantity to any larger number raises the error. **Notes**: This issue is created by the recent pr https://github.com/odoo/odoo/pull/273728. If a database has the same workflow before the commit, the error will be raised when checking the on hand quantity or trying to make a stock.picking of that product after checking out the commit. opw-6400941 Forward-Port-Of: odoo/odoo#277878
After [commit](https://github.com/odoo/odoo/commit/b75074f43184a68ebffc2b7833695570966a9bdc) `google_address_autocomplete` fields are readonly true by default. but we need this to readonly=False in preset. we also make the error message more informative for user as the default geolocation service is sometimes inaccurate. So, failing to geolocate can occuer even if you have valid address <img width="1432" height="879" alt="image" src="https://github.com/user-attachments/assets/6e13a
Original PR description
After [commit](https://github.com/odoo/odoo/commit/b75074f43184a68ebffc2b7833695570966a9bdc) `google_address_autocomplete` fields are readonly true by default. but we need this to readonly=False in preset. we also make the error message more informative for user as the default geolocation service is sometimes inaccurate. So, failing to geolocate can occuer even if you have valid address <img width="1432" height="879" alt="image" src="https://github.com/user-attachments/assets/6e13a2fe-6655-436c-8de9-204feba6ee44" /> <img width="737" height="421" alt="image" src="https://github.com/user-attachments/assets/2c3032c2-c3b7-4ab7-8116-7876589a5fa2" /> opw-6377551 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275327
`BuilderRange` supported inverted ranges (`props.min > props.max`) to keep the slider direction consistent across options, which was the case for the `Parallax to Bottom` (`min="-0.15" / max="-3"`) with `get min()`/`get max()` normalizing the bounds and `o_we_inverted_range` flipping the direction whenever `props.min > props.max` was detected. For the Bottom case, any value smaller than `-0.15` (e.g. `-1.5`) satisfied `value < props.min` and was clamped back to `-0.15`, making custom intensit
Original PR description
`BuilderRange` supported inverted ranges (`props.min > props.max`) to keep the slider direction consistent across options, which was the case for the `Parallax to Bottom` (`min="-0.15" / max="-3"`) with `get min()`/`get max()` normalizing the bounds and `o_we_inverted_range` flipping the direction whenever `props.min > props.max` was detected. For the Bottom case, any value smaller than `-0.15` (e.g. `-1.5`) satisfied `value < props.min` and was clamped back to `-0.15`, making custom intensities impossible. Since this is the only inverted `BuilderRange` in the codebase, we restored the right order for the min/max, dropped the getters and replaced them with a prop to apply the `o_we_inverted_range` class in this scenario only. task-6058500 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274818 Forward-Port-Of: odoo/odoo#255252
3 changes
Resolved issues and error corrections
Steps to reproduce: - Install Argentina(l10n_ar) localization > Change Company - Accounting > Customers > Invoices > Select an invoice > Click "Pay" - In "Journal" select "Third Party Checks" > In "Payment Method" select "New Third Party Checks" > Fill the rest of the check info (Number, Bank Account, Issuer Vat, Payment Date and Amount) > Click on "Create Payment" - Repeat the payment process for another invoice with same info > Validation Error A change in [PR] caused the check uniquene
Original PR description
Steps to reproduce: - Install Argentina(l10n_ar) localization > Change Company - Accounting > Customers > Invoices > Select an invoice > Click "Pay" - In "Journal" select "Third Party Checks" > In…
Steps to reproduce: - Install Argentina(l10n_ar) localization > Change Company - Accounting > Customers > Invoices > Select an invoice > Click "Pay" - In "Journal" select "Third Party Checks" > In "Payment Method" select "New Third Party Checks" > Fill the rest of the check info (Number, Bank Account, Issuer Vat, Payment Date and Amount) > Click on "Create Payment" - Repeat the payment process for another invoice with same info > Validation Error A change in [PR] caused the check uniqueness constraint apply to all checks. Because of this, using the same check number with the "New Third Party Checks" payment method now raises a validation error. This is not the intended behavior. The uniqueness constraint should only apply to "Own Checks" when using a "Bank" journal for Vendor Bills. It should not apply to "Third Party Checks" with the "New Third Party Checks" payment method in Customer Invoice. Avoid linking `l10n_latam_check_ids` on liquidity lines for outbound "Own Checks" payments so that the uniqueness constraint is enforced only for the "Vendor Bills". [PR]: https://github.com/odoo/odoo/pull/243509/changes opw-6334965 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275261
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's ty
Original PR description
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when…
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's type to a "URL" or "CC" field. - Save the changes. - The "URL/CC" field is prefilled with the user's name. A field is considered repurposed when: - its type is changed (e.g. from "Phone" to "URL"); - a custom field is converted into an existing field. **Fix:** This commit preserves the prefill only when the field keeps the same name and type. Otherwise, it clears the stale prefill so repurposed fields no longer inherit incorrect values. task-[5976747](https://www.odoo.com/odoo/project/974/tasks/5976747) Forward-Port-Of: odoo/odoo#278426 Forward-Port-Of: odoo/odoo#275812
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue:
Original PR description
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a…
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue: Writing on the `move_raw_ids` will trigger a call of the `_autoconfirm_production` in order to confirm the newly created move: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L990-L991 https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L1422-L1423 During this confirmation process, one calls the `_merge_moves` method in order to merge this new move (if relevant) to any already existing one. https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/stock/models/stock_move.py#L1575-L1576 Now, the issue is that, `sale_stock_renting` modeule overrides the method `_prepare_merge_moves_distinct_fields` determining the fields relevant to the merge by requiring a read access to the `is_rental_order` compute field of the `sale_order` linked to the MO: https://github.com/odoo/enterprise/blob/b66097122ba3a758734ac6fb2b26579c35cb72c2/sale_stock_renting/models/stock_move.py#L34-L40 However, due to the 'Personal Orders' ir.rule, the user does not have a read access to this record: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/sale/security/ir_rules.xml#L44-L49 Enterprise: https://github.com/odoo/enterprise/pull/121135 opw-6275658 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272256 Forward-Port-Of: odoo/odoo#271017
16 changes
Resolved issues and error corrections
[*] = html_builder Steps to reproduce: 1. Go to the Website app and drop any snippet. 2. Apply a background or image shape. 3. If a background shape is applied, click the **Flip Shape** option. 4. Go to the **Theme** tab and change the color palette. Issue: The shape color is not updated after changing the color palette. Reason: In the [commit](https://github.com/odoo/odoo/commit/aec8918018b92cbb5cb3dd761824d4), an edge case was left uncovered where applied background/image shap
Original PR description
[*] = html_builder Steps to reproduce: 1. Go to the Website app and drop any snippet. 2. Apply a background or image shape. 3. If a background shape is applied, click the **Flip Shape** option. 4. Go to the **Theme** tab and change the color palette. Issue: The shape color is not updated after changing the color palette. Reason: In the [commit](https://github.com/odoo/odoo/commit/aec8918018b92cbb5cb3dd761824d4), an edge case was left uncovered where applied background/image shapes were not re-rendered after changing the theme color palette, so its color was not refreshed to match newly selected palette. Forward-Port-Of: odoo/odoo#277860 Forward-Port-Of: odoo/odoo#273337
#### Description of the issue this PR addresses: - Blockquotes currently display their border on the left side. #### Desired behavior after PR is merged: - Update the styling so the border is displayed on the right side for RTL content. task-6296519 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277057 Forward-Port-Of: odoo/odoo#269529
Original PR description
#### Description of the issue this PR addresses: - Blockquotes currently display their border on the left side. #### Desired behavior after PR is merged: - Update the styling so the border is displayed on the right side for RTL content. task-6296519 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277057 Forward-Port-Of: odoo/odoo#269529
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's ty
Original PR description
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when…
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's type to a "URL" or "CC" field. - Save the changes. - The "URL/CC" field is prefilled with the user's name. A field is considered repurposed when: - its type is changed (e.g. from "Phone" to "URL"); - a custom field is converted into an existing field. **Fix:** This commit preserves the prefill only when the field keeps the same name and type. Otherwise, it clears the stale prefill so repurposed fields no longer inherit incorrect values. task-[5976747](https://www.odoo.com/odoo/project/974/tasks/5976747) Forward-Port-Of: odoo/odoo#278426 Forward-Port-Of: odoo/odoo#275812
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Configure a multi-company environment with a `Main Company` and a `Secondary Company` - Go to the setting enable Lots & Serial Numbers and switch into `Secondary Company` - Create a warehouse for the Secondary Company - In the Secondary Company, create a lot-tracked storable product - Create and validate a delivery for that product - Open the Traceability Report - Print the report Is
Original PR description
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Configure a multi-company environment with a `Main Company` and a `Secondary Company` - Go to the setting…
Version:
--------
- 18.0+
Steps to reproduce:
-------------------
- Install `stock` module
- Configure a multi-company environment with a `Main Company`
and a `Secondary Company`
- Go to the setting enable Lots & Serial Numbers and switch into
`Secondary Company`
- Create a warehouse for the Secondary Company
- In the Secondary Company, create a lot-tracked storable product
- Create and validate a delivery for that product
- Open the Traceability Report
- Print the report
Issue:
------
The report header always displays the Main Company, even though the
traceability report belongs entirely to the Secondary Company.
Cause:
------
https://github.com/odoo/odoo/blob/2d54db3ac0b6d807e580315e2633f3e2b10a700c/addons/stock/static/src/client_actions/stock_traceability_report_backend.xml#L9
Clicking Print calls onClickPrint(), which builds the PDF URL and
downloads it with download() (a plain XMLHttpRequest POST), landing on
the `type='http'` route `/stock/<output_format>/<report_name>`
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L125-L134
That controller calls stock.traceability.report.get_pdf() without ever setting
`company_id` in the rendering context.
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/stock/controllers/main.py#L23
Inside `get_pdf()`, the report header is rendered by passing an `rcontext`
dict to `web.internal_layout`.
That template resolves the company to display using the following priority:
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/web/views/report_templates.xml#L805-L816
1. `company_id` — an explicit company record in the render context
2. `o.company_id` — the company of the document object `o`
3. `res_company` — the fallback, injected by `_render_template()` as
`self.env.company`
Because `get_pdf()` never sets `company_id` or `o` in `rcontext`, the
template always falls through to `res_company`.
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/odoo/addons/base/models/ir_actions_report.py#L770
This is populated by `ir.actions.report._render_template()`
as `self.env.company`, which resolves to the first company in
the user's `allowed_company_ids` list — typically the main company
regardless of which company owns the lot,
picking, or stock moves being printed.
As a result, the report content belongs to the secondary company while the
header always shows the main company.
Fix:
----
Resolve the company from the record on which the traceability report is
opened (using `active_model` and `active_id`) and pass it explicitly as
`company_id` when rendering the report.
`web.internal_layout` already gives precedence to an explicit
`company_id` over the default `res_company`, ensuring the report header
always displays the company that owns the traced record.
When the record has no company set, the header falls back to
`res_company`. Since the print request is a raw `type='http'` download
that never receives the company switcher's context, `user.context`
(holding `allowed_company_ids`) is now forwarded in the download POST
and merged into the environment by the controller - as done in
`web/controllers/report.py` - so the fallback resolves to the currently
active company instead of the user's default one.
<details>
<summary>Click here to see the results:</summary>
<p><strong>Before:</strong></p>
<div class="image-row">
<img src="https://github.com/user-attachments/assets/7e3a5d65-9114-4bce-9139-a88cff7c261f" />
</div>
<p><strong>After:</strong></p>
<div class="image-row">
<img src="https://github.com/user-attachments/assets/0a105f80-b6ae-400d-a787-fb8706d5f519" />
</div>
</details>
---
opw-6345446
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#273595### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue:
Original PR description
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a…
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue: Writing on the `move_raw_ids` will trigger a call of the `_autoconfirm_production` in order to confirm the newly created move: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L990-L991 https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L1422-L1423 During this confirmation process, one calls the `_merge_moves` method in order to merge this new move (if relevant) to any already existing one. https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/stock/models/stock_move.py#L1575-L1576 Now, the issue is that, `sale_stock_renting` modeule overrides the method `_prepare_merge_moves_distinct_fields` determining the fields relevant to the merge by requiring a read access to the `is_rental_order` compute field of the `sale_order` linked to the MO: https://github.com/odoo/enterprise/blob/b66097122ba3a758734ac6fb2b26579c35cb72c2/sale_stock_renting/models/stock_move.py#L34-L40 However, due to the 'Personal Orders' ir.rule, the user does not have a read access to this record: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/sale/security/ir_rules.xml#L44-L49 Enterprise: https://github.com/odoo/enterprise/pull/121135 opw-6275658 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272256 Forward-Port-Of: odoo/odoo#271017
Problem: When a table (or banner, or columns block) is placed inside a toggle block, deleting the last paragraph in a table cell creates a new block after the toggle block and moves the selection outside the table. Cause: `handleDeleteBackwardContentEnd` assumes the deleted block is always a direct child of the toggle content. However, the deleted block may be nested inside a table, banner, or columns block. Solution: Only create a new block after the toggle block when the selected bloc
Original PR description
Problem: When a table (or banner, or columns block) is placed inside a toggle block, deleting the last paragraph in a table cell creates a new block after the toggle block and moves the selection outside the table. Cause: `handleDeleteBackwardContentEnd` assumes the deleted block is always a direct child of the toggle content. However, the deleted block may be nested inside a table, banner, or columns block. Solution: Only create a new block after the toggle block when the selected block is a direct child of the toggle content. Steps to reproduce: - Add a toggle block. - Insert a table inside its content. - Add two paragraphs to a table cell. - Delete the last paragraph. - Observe that a new block is created after the toggle block and the selection moves outside the table. opw-6382058 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278119 Forward-Port-Of: odoo/odoo#277194
`t-key` are automatically added to `t-for` elements in templates, but if someone defines `t-key` himself, the converter is supposed to keep it as is. Before this fix: -`t-key` is kept but a closing tag (`>`) is added every iteration. After this fix: -`t-key` is correctly kept, nothing added in addition.
Original PR description
`t-key` are automatically added to `t-for` elements in templates, but if someone defines `t-key` himself, the converter is supposed to keep it as is. Before this fix: -`t-key` is kept but a closing tag (`>`) is added every iteration. After this fix: -`t-key` is correctly kept, nothing added in addition.
Before this PR, the tour could fail non-deterministically because it waited for `o_we_ui_loading` to disappear. However, this class was added with a delay in `operation.js` file, allowing the next tour step to run before the loader was shown. After this PR, the tour waits for `o_loading_screen`, which is added immediately and remains until the operation finishes. This ensures the tour waits correctly before proceeding. runbot-[941508](https://runbot.odoo.com/odoo/error/941508) Forward-Por
Original PR description
Before this PR, the tour could fail non-deterministically because it waited for `o_we_ui_loading` to disappear. However, this class was added with a delay in `operation.js` file, allowing the next tour step to run before the loader was shown. After this PR, the tour waits for `o_loading_screen`, which is added immediately and remains until the operation finishes. This ensures the tour waits correctly before proceeding. runbot-[941508](https://runbot.odoo.com/odoo/error/941508) Forward-Port-Of: odoo/odoo#277651
The daily/monthly Inventory Valuation Closing cron currently skips companies using the Perpetual (real_time) valuation method, so the Periodic Valuation frequency setting has no effect for them. The intent of the feature is to keep the inventory valuation continuously updated (e.g. goods received not yet invoiced) whatever the valuation method, so the cron should also post the closing entries for perpetual companies. Remove the real_time exclusion from the cron domain so the configured frequency
Original PR description
The daily/monthly Inventory Valuation Closing cron currently skips companies using the Perpetual (real_time) valuation method, so the Periodic Valuation frequency setting has no effect for them. The intent of the feature is to keep the inventory valuation continuously updated (e.g. goods received not yet invoiced) whatever the valuation method, so the cron should also post the closing entries for perpetual companies. Remove the real_time exclusion from the cron domain so the configured frequency applies to all companies, and skip companies where the closing raises a UserError (e.g. missing valuation journal or account) so one misconfigured company cannot block the cron. Forward-Port-Of: odoo/odoo#276990
Currently, sending a simplified invoice (`TD07`) to the Italian Tax Agency fails when an invoice line contains multiple taxes. **Steps to reproduce:** - Install the `l10n_it_edi_withholding` module and switch to an IT Company. - Create a new customer and set only the country to Italy and the Tax ID. - Create a new invoice for that customer. - Add a line with `22%` and `4% INPS` taxes. - Go to the `Electronic Invoicing` tab, set the `Document Type` to `TD07 - Simplified invoice`, and c
Original PR description
Currently, sending a simplified invoice (`TD07`) to the Italian Tax Agency fails when an invoice line contains multiple taxes. **Steps to reproduce:** - Install the `l10n_it_edi_withholding` module…
Currently, sending a simplified invoice (`TD07`) to the Italian Tax Agency fails when an invoice line contains multiple taxes. **Steps to reproduce:** - Install the `l10n_it_edi_withholding` module and switch to an IT Company. - Create a new customer and set only the country to Italy and the Tax ID. - Create a new invoice for that customer. - Add a line with `22%` and `4% INPS` taxes. - Go to the `Electronic Invoicing` tab, set the `Document Type` to `TD07 - Simplified invoice`, and confirm the invoice. - Try to `Send To Tax Agency`. **Error:** `Node: <Natura t-if="line.tax_ids.l10n_it_exempt_reason" t-out="line.tax_ids.l10n_it_exempt_reason"/>` `ValueError: Expected singleton: account.tax(102, 3)` **Root Cause:** At [1], the code accesses `line.tax_ids.l10n_it_exempt_reason`, but when an invoice contains multiple taxes, causing an error. **Fix:** This commit prevents the error and ensures the user can send a simplified invoice by applying a fix similar to [2]. [1]: https://github.com/odoo/odoo/blob/230483ffd7d8674cd6bf98a4ffb6591f755422e0/addons/l10n_it_edi/data/invoice_it_simplified_template.xml#L14 [2]: https://github.com/odoo/odoo/blob/230483ffd7d8674cd6bf98a4ffb6591f755422e0/addons/l10n_it_edi/data/invoice_it_template.xml#L28-L181 Ticket [link](https://www.odoo.com/odoo/project.task/6354138) Ticket [link](https://www.odoo.com/odoo/project.task/6379377) opw-6354138 opw-6379377 Forward-Port-Of: odoo/odoo#278307 Forward-Port-Of: odoo/odoo#273823
Issue: The `shape_color_sync_with_theme_color` tour failed randomly at its last step i.e after changing a theme preset color, the image shapes of the saved (custom) snippet sometimes still had the old color. This happened because `updateContent` called its callback without awaiting it, so the re-processing of the custom snippet images ran in the background after the color change operation had already completed. At normal flow this operation finishes before the previews are looked at, but
Original PR description
Issue: The `shape_color_sync_with_theme_color` tour failed randomly at its last step i.e after changing a theme preset color, the image shapes of the saved (custom) snippet sometimes still had the old color. This happened because `updateContent` called its callback without awaiting it, so the re-processing of the custom snippet images ran in the background after the color change operation had already completed. At normal flow this operation finishes before the previews are looked at, but the tour reaches the `Custom` snippets category within milliseconds and could assert the colors before the re-processing was done - making the outcome depend purely on timing. Fix: Awaiting the callback ensures the custom snippets content is fully updated before the operation completes, so by the time the loading indicator disappears the previews are guaranteed to be in sync. runbot-[944175](https://runbot.odoo.com/odoo/error/944175) Forward-Port-Of: odoo/odoo#276862
When inserting nodes, they are run through `node_to_insert_processors` to possibly handle some conversions - e.g. turning paragraphs into further list items within a list. However the `insertedNodes` returned by the `insert` method are actually the nodes that were initially requested to be added. This commit puts the nodes among the `insertedNodes` after they were potentially converted. task-6364282 Forward-Port-Of: odoo/odoo#277789
Original PR description
When inserting nodes, they are run through `node_to_insert_processors` to possibly handle some conversions - e.g. turning paragraphs into further list items within a list. However the `insertedNodes` returned by the `insert` method are actually the nodes that were initially requested to be added. This commit puts the nodes among the `insertedNodes` after they were potentially converted. task-6364282 Forward-Port-Of: odoo/odoo#277789
When searching on the Website site, using the main search on the navbar, it opens a list view with the results (`website.list_hybrid`) which raises the warning on the logs (2 times): "Unknown directives or unused attributes: {'t-key'} in website.list_hybrid"  This happens after the attribute `t-key` was added to the template [\[1\]] because the template is only use
Original PR description
When searching on the Website site, using the main search on the navbar, it opens a list view with the results (`website.list_hybrid`) which raises the warning on the logs (2 times): "Unknown…
When searching on the Website site, using the main search on the navbar, it opens a list view with the results (`website.list_hybrid`) which raises the warning on the logs (2 times):
"Unknown directives or unused attributes: {'t-key'} in website.list_hybrid"

This happens after the attribute `t-key` was added to the template [\[1\]] because the template is only used in QWeb. The validation for them doesn't include the `t-key` [\[2\]] as one of the "iter_directives" nor has a `_compile_directive_*` method to check and remove it from the validation as it's done with the `t-as` and `t-foreach`.
This also causes the raise of the warnings on tours that use the tour method `searchProduct` (of the module `website_sale`) because it uses the first input with the name of search and happens to be the search on the navbar.

[\[1\]]: https://github.com/odoo/odoo/commit/7b1d82aa
[\[2\]]: https://github.com/odoo/odoo/blob/f52cfb09/odoo/addons/base/models/ir_qweb.py#L1400
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#179017**Problem:** For an hour-based time off allocation, changing the employee's working schedule leaves the allocation duration (in days) stale, so the balance shown on the Time Off dashboard becomes wrong. **Steps to reproduce:** 1. Give an employee a working schedule of 8 hours/day. 2. Create an hour-based allocation (time off type with Request Unit = Hours) granting e.g. 8 hours (1 day). 3. Change the employee's working schedule to one with a different Hours per Day (e.g. 4 hours/day). 4.
Original PR description
**Problem:** For an hour-based time off allocation, changing the employee's working schedule leaves the allocation duration (in days) stale, so the balance shown on the Time Off dashboard becomes…
**Problem:** For an hour-based time off allocation, changing the employee's working schedule leaves the allocation duration (in days) stale, so the balance shown on the Time Off dashboard becomes wrong. **Steps to reproduce:** 1. Give an employee a working schedule of 8 hours/day. 2. Create an hour-based allocation (time off type with Request Unit = Hours) granting e.g. 8 hours (1 day). 3. Change the employee's working schedule to one with a different Hours per Day (e.g. 4 hours/day). 4. Check the allocation / the Time Off dashboard balance. **Current behavior:** number_of_days stays at its old value (1), so the balance is recomputed as 1 day x 4 hours = 4 hours instead of the 8 hours actually accrued. **Expected behavior:** The accrued hours stay constant; the duration in days follows the new schedule (8 hours / 4 hours-per-day = 2 days). **Cause of the issue:** `number_of_days` and `number_of_hours_display` compute from each other (`number_of_days = number_of_hours_display / hours_per_day` and `number_of_hours_display = number_of_days * hours_per_day`), forming a dependency cycle, and neither depends on the employee's working schedule. So a schedule change never recomputes either field. Adding the schedule to `_compute_number_of_days`' depends does not help: because of the cycle it recomputes `number_of_hours_display` from the stale `number_of_days` first, which silently destroys the accrued hours. **Fix:** When the employee's working schedule changes, the accrued hours are the quantity that must be preserved, so the duration is recomputed explicitly from the still-stored `number_of_hours_display` (setting `number_of_days` first, exactly as a manual `_compute_number_of_days()` does). Driving the order by hand is necessary because the cyclic compute graph cannot guarantee `number_of_days` is computed before `number_of_hours_display`. opw-6276242 Forward-Port-Of: odoo/odoo#270129
Currently, the property value is not displayed on the Kanban card, even when the `Display in Cards` option is enabled. This PR ensures that if `Display in Cards` option is enabled for a property, its value is displayed on the corresponding equipment Kanban card. **Steps to reproduce:** - Install the Maintenance module. - Open `Equipment`. - Open an existing equipment record or create a new one and save it. - Click the actions (gear) menu from the equipment form view. - Select `Add Prop
Original PR description
Currently, the property value is not displayed on the Kanban card, even when the `Display in Cards` option is enabled. This PR ensures that if `Display in Cards` option is enabled for a property, its value is displayed on the corresponding equipment Kanban card. **Steps to reproduce:** - Install the Maintenance module. - Open `Equipment`. - Open an existing equipment record or create a new one and save it. - Click the actions (gear) menu from the equipment form view. - Select `Add Properties`. - Add a property and enable the `Display in Cards` option. Open the Kanban view. **Expected behavior:** The property value should be displayed on the Kanban card when the `Display in Cards` option is enabled. Issue: [#277479](https://github.com/odoo/odoo/issues/277479) Forward-Port-Of: odoo/odoo#277757
**Issue:** When an employee uses a fully fixed duration based working schedule and each half-day attendance has a decimal duration such as 3.36h, a multi-day half-day time off request can compute a decimal duration such as 5.01 days. This is inconsistent with half-day time off types, which should consume time in half-day increments. **Steps to reproduce:** - Create an employee with a fully fixed duration-based schedule - Set morning and afternoon attendances to 3.36 hours for each weekday
Original PR description
**Issue:** When an employee uses a fully fixed duration based working schedule and each half-day attendance has a decimal duration such as 3.36h, a multi-day half-day time off request can compute a…
**Issue:** When an employee uses a fully fixed duration based working schedule and each half-day attendance has a decimal duration such as 3.36h, a multi-day half-day time off request can compute a decimal duration such as 5.01 days. This is inconsistent with half-day time off types, which should consume time in half-day increments. **Steps to reproduce:** - Create an employee with a fully fixed duration-based schedule - Set morning and afternoon attendances to 3.36 hours for each weekday - Create a time off type with duration type set to half-day - Create a time off request for the employee (e.g. Monday to Friday) - The computed duration is 5.01 days instead of 5 days **Cause:** For half-day time off types, `number_of_days` was taken from generic calendar interval computation. https://github.com/odoo/odoo/blob/19c0e59cc37c7671f13cbda1b2d4850a7731eade/addons/hr_holidays/models/hr_leave.py#L585-L593 On duration-based schedules, this computation returns day values rounded at 0.001 precision, so decimal drift (e.g. 5.01) can appear, Since no final rounding to half-day steps was applied, half-day requests could end with non-half-day values. **Solution:** Round computed durations for half-day time off types to the nearest half-day increment. opw-6215768 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274102 Forward-Port-Of: odoo/odoo#267726
17 changes
Enhancements to existing features
We update the IoT Box version, so that it follow the new saas version (19.4). backport of: odoo/odoo#278588 (as images are still built in 19.1)
Original PR description
We update the IoT Box version, so that it follow the new saas version (19.4). backport of: odoo/odoo#278588 (as images are still built in 19.1)
Resolved issues and error corrections
Issue: The `shape_color_sync_with_theme_color` tour failed randomly at its last step i.e after changing a theme preset color, the image shapes of the saved (custom) snippet sometimes still had the old color. This happened because `updateContent` called its callback without awaiting it, so the re-processing of the custom snippet images ran in the background after the color change operation had already completed. At normal flow this operation finishes before the previews are looked at, but
Original PR description
Issue: The `shape_color_sync_with_theme_color` tour failed randomly at its last step i.e after changing a theme preset color, the image shapes of the saved (custom) snippet sometimes still had the old color. This happened because `updateContent` called its callback without awaiting it, so the re-processing of the custom snippet images ran in the background after the color change operation had already completed. At normal flow this operation finishes before the previews are looked at, but the tour reaches the `Custom` snippets category within milliseconds and could assert the colors before the re-processing was done - making the outcome depend purely on timing. Fix: Awaiting the callback ensures the custom snippets content is fully updated before the operation completes, so by the time the loading indicator disappears the previews are guaranteed to be in sync. runbot-[944175](https://runbot.odoo.com/odoo/error/944175) Forward-Port-Of: odoo/odoo#276862
When installing the module document_account_peppol, the user has the choice to import his Peppol invoices into the Documents app directly, but also to block the import in Accounting, by removing the Peppol import journal. In that last case, the Peppol application response flow is broken, the document model does not contain the necessary information to handle responses as the imported invoices do. (In stable) We took the decision to remove the ApplicationResponse service from users that bl
Original PR description
When installing the module document_account_peppol, the user has the choice to import his Peppol invoices into the Documents app directly, but also to block the import in Accounting, by removing the Peppol import journal. In that last case, the Peppol application response flow is broken, the document model does not contain the necessary information to handle responses as the imported invoices do. (In stable) We took the decision to remove the ApplicationResponse service from users that block the invoice import flow by removing the import journal. For PDP, the responses are required, but as the block is completely replaced in the view, and reuses the basic account_peppol condition for the required attribute, the account peppol purchase journal will always be required if the company is registered on Peppol/PDP. Nothing to do in 18.0. task-6191644 Forward-Port-Of: odoo/odoo#270091
#### Description of the issue this PR addresses: - Blockquotes currently display their border on the left side. #### Desired behavior after PR is merged: - Update the styling so the border is displayed on the right side for RTL content. task-6296519 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277057 Forward-Port-Of: odoo/odoo#269529
Original PR description
#### Description of the issue this PR addresses: - Blockquotes currently display their border on the left side. #### Desired behavior after PR is merged: - Update the styling so the border is displayed on the right side for RTL content. task-6296519 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277057 Forward-Port-Of: odoo/odoo#269529
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's ty
Original PR description
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when…
For a logged-in user, some form fields are automatically prefilled from their profile, such as a "Phone" field with their phone number. **Issue:** The prefill configuration is always preserved when we change options of a field. While this is correct when updating few options, but it also happens after the field is repurposed, causing it to inherit a prefill value intended for a different field. **Steps to reproduce:** - Edit the /contactus page's form. - Change the "Name" field's type to a "URL" or "CC" field. - Save the changes. - The "URL/CC" field is prefilled with the user's name. A field is considered repurposed when: - its type is changed (e.g. from "Phone" to "URL"); - a custom field is converted into an existing field. **Fix:** This commit preserves the prefill only when the field keeps the same name and type. Otherwise, it clears the stale prefill so repurposed fields no longer inherit incorrect values. task-[5976747](https://www.odoo.com/odoo/project/974/tasks/5976747) Forward-Port-Of: odoo/odoo#278426 Forward-Port-Of: odoo/odoo#275812
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Configure a multi-company environment with a `Main Company` and a `Secondary Company` - Go to the setting enable Lots & Serial Numbers and switch into `Secondary Company` - Create a warehouse for the Secondary Company - In the Secondary Company, create a lot-tracked storable product - Create and validate a delivery for that product - Open the Traceability Report - Print the report Is
Original PR description
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Configure a multi-company environment with a `Main Company` and a `Secondary Company` - Go to the setting…
Version:
--------
- 18.0+
Steps to reproduce:
-------------------
- Install `stock` module
- Configure a multi-company environment with a `Main Company`
and a `Secondary Company`
- Go to the setting enable Lots & Serial Numbers and switch into
`Secondary Company`
- Create a warehouse for the Secondary Company
- In the Secondary Company, create a lot-tracked storable product
- Create and validate a delivery for that product
- Open the Traceability Report
- Print the report
Issue:
------
The report header always displays the Main Company, even though the
traceability report belongs entirely to the Secondary Company.
Cause:
------
https://github.com/odoo/odoo/blob/2d54db3ac0b6d807e580315e2633f3e2b10a700c/addons/stock/static/src/client_actions/stock_traceability_report_backend.xml#L9
Clicking Print calls onClickPrint(), which builds the PDF URL and
downloads it with download() (a plain XMLHttpRequest POST), landing on
the `type='http'` route `/stock/<output_format>/<report_name>`
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L125-L134
That controller calls stock.traceability.report.get_pdf() without ever setting
`company_id` in the rendering context.
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/stock/controllers/main.py#L23
Inside `get_pdf()`, the report header is rendered by passing an `rcontext`
dict to `web.internal_layout`.
That template resolves the company to display using the following priority:
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/web/views/report_templates.xml#L805-L816
1. `company_id` — an explicit company record in the render context
2. `o.company_id` — the company of the document object `o`
3. `res_company` — the fallback, injected by `_render_template()` as
`self.env.company`
Because `get_pdf()` never sets `company_id` or `o` in `rcontext`, the
template always falls through to `res_company`.
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/odoo/addons/base/models/ir_actions_report.py#L770
This is populated by `ir.actions.report._render_template()`
as `self.env.company`, which resolves to the first company in
the user's `allowed_company_ids` list — typically the main company
regardless of which company owns the lot,
picking, or stock moves being printed.
As a result, the report content belongs to the secondary company while the
header always shows the main company.
Fix:
----
Resolve the company from the record on which the traceability report is
opened (using `active_model` and `active_id`) and pass it explicitly as
`company_id` when rendering the report.
`web.internal_layout` already gives precedence to an explicit
`company_id` over the default `res_company`, ensuring the report header
always displays the company that owns the traced record.
When the record has no company set, the header falls back to
`res_company`. Since the print request is a raw `type='http'` download
that never receives the company switcher's context, `user.context`
(holding `allowed_company_ids`) is now forwarded in the download POST
and merged into the environment by the controller - as done in
`web/controllers/report.py` - so the fallback resolves to the currently
active company instead of the user's default one.
<details>
<summary>Click here to see the results:</summary>
<p><strong>Before:</strong></p>
<div class="image-row">
<img src="https://github.com/user-attachments/assets/7e3a5d65-9114-4bce-9139-a88cff7c261f" />
</div>
<p><strong>After:</strong></p>
<div class="image-row">
<img src="https://github.com/user-attachments/assets/0a105f80-b6ae-400d-a787-fb8706d5f519" />
</div>
</details>
---
opw-6345446
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#273595### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue:
Original PR description
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a…
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue: Writing on the `move_raw_ids` will trigger a call of the `_autoconfirm_production` in order to confirm the newly created move: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L990-L991 https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L1422-L1423 During this confirmation process, one calls the `_merge_moves` method in order to merge this new move (if relevant) to any already existing one. https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/stock/models/stock_move.py#L1575-L1576 Now, the issue is that, `sale_stock_renting` modeule overrides the method `_prepare_merge_moves_distinct_fields` determining the fields relevant to the merge by requiring a read access to the `is_rental_order` compute field of the `sale_order` linked to the MO: https://github.com/odoo/enterprise/blob/b66097122ba3a758734ac6fb2b26579c35cb72c2/sale_stock_renting/models/stock_move.py#L34-L40 However, due to the 'Personal Orders' ir.rule, the user does not have a read access to this record: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/sale/security/ir_rules.xml#L44-L49 Enterprise: https://github.com/odoo/enterprise/pull/121135 opw-6275658 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272256 Forward-Port-Of: odoo/odoo#271017
The daily/monthly Inventory Valuation Closing cron currently skips companies using the Perpetual (real_time) valuation method, so the Periodic Valuation frequency setting has no effect for them. The intent of the feature is to keep the inventory valuation continuously updated (e.g. goods received not yet invoiced) whatever the valuation method, so the cron should also post the closing entries for perpetual companies. Remove the real_time exclusion from the cron domain so the configured frequency
Original PR description
The daily/monthly Inventory Valuation Closing cron currently skips companies using the Perpetual (real_time) valuation method, so the Periodic Valuation frequency setting has no effect for them. The intent of the feature is to keep the inventory valuation continuously updated (e.g. goods received not yet invoiced) whatever the valuation method, so the cron should also post the closing entries for perpetual companies. Remove the real_time exclusion from the cron domain so the configured frequency applies to all companies, and skip companies where the closing raises a UserError (e.g. missing valuation journal or account) so one misconfigured company cannot block the cron. Forward-Port-Of: odoo/odoo#276990
Problem: When a table (or banner, or columns block) is placed inside a toggle block, deleting the last paragraph in a table cell creates a new block after the toggle block and moves the selection outside the table. Cause: `handleDeleteBackwardContentEnd` assumes the deleted block is always a direct child of the toggle content. However, the deleted block may be nested inside a table, banner, or columns block. Solution: Only create a new block after the toggle block when the selected bloc
Original PR description
Problem: When a table (or banner, or columns block) is placed inside a toggle block, deleting the last paragraph in a table cell creates a new block after the toggle block and moves the selection outside the table. Cause: `handleDeleteBackwardContentEnd` assumes the deleted block is always a direct child of the toggle content. However, the deleted block may be nested inside a table, banner, or columns block. Solution: Only create a new block after the toggle block when the selected block is a direct child of the toggle content. Steps to reproduce: - Add a toggle block. - Insert a table inside its content. - Add two paragraphs to a table cell. - Delete the last paragraph. - Observe that a new block is created after the toggle block and the selection moves outside the table. opw-6382058 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278119 Forward-Port-Of: odoo/odoo#277194
Currently, sending a simplified invoice (`TD07`) to the Italian Tax Agency fails when an invoice line contains multiple taxes. **Steps to reproduce:** - Install the `l10n_it_edi_withholding` module and switch to an IT Company. - Create a new customer and set only the country to Italy and the Tax ID. - Create a new invoice for that customer. - Add a line with `22%` and `4% INPS` taxes. - Go to the `Electronic Invoicing` tab, set the `Document Type` to `TD07 - Simplified invoice`, and c
Original PR description
Currently, sending a simplified invoice (`TD07`) to the Italian Tax Agency fails when an invoice line contains multiple taxes. **Steps to reproduce:** - Install the `l10n_it_edi_withholding` module…
Currently, sending a simplified invoice (`TD07`) to the Italian Tax Agency fails when an invoice line contains multiple taxes. **Steps to reproduce:** - Install the `l10n_it_edi_withholding` module and switch to an IT Company. - Create a new customer and set only the country to Italy and the Tax ID. - Create a new invoice for that customer. - Add a line with `22%` and `4% INPS` taxes. - Go to the `Electronic Invoicing` tab, set the `Document Type` to `TD07 - Simplified invoice`, and confirm the invoice. - Try to `Send To Tax Agency`. **Error:** `Node: <Natura t-if="line.tax_ids.l10n_it_exempt_reason" t-out="line.tax_ids.l10n_it_exempt_reason"/>` `ValueError: Expected singleton: account.tax(102, 3)` **Root Cause:** At [1], the code accesses `line.tax_ids.l10n_it_exempt_reason`, but when an invoice contains multiple taxes, causing an error. **Fix:** This commit prevents the error and ensures the user can send a simplified invoice by applying a fix similar to [2]. [1]: https://github.com/odoo/odoo/blob/230483ffd7d8674cd6bf98a4ffb6591f755422e0/addons/l10n_it_edi/data/invoice_it_simplified_template.xml#L14 [2]: https://github.com/odoo/odoo/blob/230483ffd7d8674cd6bf98a4ffb6591f755422e0/addons/l10n_it_edi/data/invoice_it_template.xml#L28-L181 Ticket [link](https://www.odoo.com/odoo/project.task/6354138) Ticket [link](https://www.odoo.com/odoo/project.task/6379377) opw-6354138 opw-6379377 Forward-Port-Of: odoo/odoo#278307 Forward-Port-Of: odoo/odoo#273823
Before this commit, decreasing the quantity of a move whose move lines are expressed in another unit of measure removed the wrong quantity from the lines, because the two conversions between the move unit and the line unit converted a value to its own unit, hence did nothing. Steps to reproduce: - create a product in Units with available stock - create a delivery for 2 Dozen of it and mark it as todo - in the detailed operations, change the unit of the move line to Units (24) - lower the
Original PR description
Before this commit, decreasing the quantity of a move whose move lines are expressed in another unit of measure removed the wrong quantity from the lines, because the two conversions between the move…
Before this commit, decreasing the quantity of a move whose move lines are expressed in another unit of measure removed the wrong quantity from the lines, because the two conversions between the move unit and the line unit converted a value to its own unit, hence did nothing. Steps to reproduce: - create a product in Units with available stock - create a delivery for 2 Dozen of it and mark it as todo - in the detailed operations, change the unit of the move line to Units (24) - lower the move quantity from 2 to 1 Dozen The move line ends up with 23 Units instead of 12: the decrease of 1 Dozen is applied as 1 Unit on the line and considered fully processed. The remaining 11 units stay reserved and counted on the transfer. Convert the remaining decrease from the move unit to the line unit when taking it from a line, and the taken quantity back to the move unit when updating the remaining decrease. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278148 Forward-Port-Of: odoo/odoo#276774
When searching on the Website site, using the main search on the navbar, it opens a list view with the results (`website.list_hybrid`) which raises the warning on the logs (2 times): "Unknown directives or unused attributes: {'t-key'} in website.list_hybrid"  This happens after the attribute `t-key` was added to the template [\[1\]] because the template is only use
Original PR description
When searching on the Website site, using the main search on the navbar, it opens a list view with the results (`website.list_hybrid`) which raises the warning on the logs (2 times): "Unknown…
When searching on the Website site, using the main search on the navbar, it opens a list view with the results (`website.list_hybrid`) which raises the warning on the logs (2 times):
"Unknown directives or unused attributes: {'t-key'} in website.list_hybrid"

This happens after the attribute `t-key` was added to the template [\[1\]] because the template is only used in QWeb. The validation for them doesn't include the `t-key` [\[2\]] as one of the "iter_directives" nor has a `_compile_directive_*` method to check and remove it from the validation as it's done with the `t-as` and `t-foreach`.
This also causes the raise of the warnings on tours that use the tour method `searchProduct` (of the module `website_sale`) because it uses the first input with the name of search and happens to be the search on the navbar.

[\[1\]]: https://github.com/odoo/odoo/commit/7b1d82aa
[\[2\]]: https://github.com/odoo/odoo/blob/f52cfb09/odoo/addons/base/models/ir_qweb.py#L1400
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#179017Steps: 1) Make a new SH database 2) Install the discuss app 3) Open the discuss app. Leave a channel. Issue: The channel does not close and remains visible in the user's list of channels. The user can still send messages in the channel despite having just left it. Notes: The issue is only reproducible on SH databases due to differences in how websocket messages are sent to the browser. This PR ensures that after a successful "action_unfollow" network call, the discuss channel is close
Original PR description
Steps: 1) Make a new SH database 2) Install the discuss app 3) Open the discuss app. Leave a channel. Issue: The channel does not close and remains visible in the user's list of channels. The user can still send messages in the channel despite having just left it. Notes: The issue is only reproducible on SH databases due to differences in how websocket messages are sent to the browser. This PR ensures that after a successful "action_unfollow" network call, the discuss channel is closed on the front-end. opw-6396587 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277672
Description of the issue/feature this PR addresses: A cash rounding line resolves its company-dependent profit/loss account against the active company instead of the invoice's own company, which breaks multi-company invoicing whenever the invoice's company differs from the active one. Current behavior before PR: - Enable Multi-Companies in the settings. - Create a second company (Company B). - Open Accounting > Configuration > Cash Roundings. - Create a cash rounding with strategy "Add a
Original PR description
Description of the issue/feature this PR addresses: A cash rounding line resolves its company-dependent profit/loss account against the active company instead of the invoice's own company, which…
Description of the issue/feature this PR addresses: A cash rounding line resolves its company-dependent profit/loss account against the active company instead of the invoice's own company, which breaks multi-company invoicing whenever the invoice's company differs from the active one. Current behavior before PR: - Enable Multi-Companies in the settings. - Create a second company (Company B). - Open Accounting > Configuration > Cash Roundings. - Create a cash rounding with strategy "Add a rounding line" and precision 1.00. - Make Company A the active company in the company switcher. - Set the cash rounding's profit and loss accounts to Company A accounts. - Switch the active company to Company B. - Set the cash rounding's profit and loss accounts to Company B accounts. - Make Company A the active company again, keeping both companies active. - Create a customer invoice for Company B. - Add one invoice line whose total is not a multiple of the rounding precision. - Set the invoice's cash rounding to the one above. > Adding the rounding line raises a cross-company UserError: the company-dependent account is resolved against Company A while the invoice belongs to Company B. Desired behavior after PR is merged: The rounding line resolves the company-dependent profit/loss account against the invoice's own company, so the rounding line always uses that company's account and no cross-company error is raised. Covered by the added test TestAccountMoveCashRoundingMultiCompany. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273410
Currently, the property value is not displayed on the Kanban card, even when the `Display in Cards` option is enabled. This PR ensures that if `Display in Cards` option is enabled for a property, its value is displayed on the corresponding equipment Kanban card. **Steps to reproduce:** - Install the Maintenance module. - Open `Equipment`. - Open an existing equipment record or create a new one and save it. - Click the actions (gear) menu from the equipment form view. - Select `Add Prop
Original PR description
Currently, the property value is not displayed on the Kanban card, even when the `Display in Cards` option is enabled. This PR ensures that if `Display in Cards` option is enabled for a property, its value is displayed on the corresponding equipment Kanban card. **Steps to reproduce:** - Install the Maintenance module. - Open `Equipment`. - Open an existing equipment record or create a new one and save it. - Click the actions (gear) menu from the equipment form view. - Select `Add Properties`. - Add a property and enable the `Display in Cards` option. Open the Kanban view. **Expected behavior:** The property value should be displayed on the Kanban card when the `Display in Cards` option is enabled. Issue: [#277479](https://github.com/odoo/odoo/issues/277479) Forward-Port-Of: odoo/odoo#277757
## Steps to Reproduce: _(cryptography version > 43.0.0)_ 1. Install the `l10n_sa_edi` module. 2. Switch to SA Company. 3. Set the company name to an Arabic string between 32 and 64 characters. (e.g; `مجموعة النخبة العالمية للاستشارات الفنية`) 5. Accounting > Configuration > Journals. 6. Open a Sales type journal. 7. Click "Re-onboard" in the ZATCA tab. 8. Enter an OTP and click "Request". ## Error: `ValueError: Attribute's length must be >= 1 and <= 64, but it was 98` ## Caus
Original PR description
## Steps to Reproduce: _(cryptography version > 43.0.0)_ 1. Install the `l10n_sa_edi` module. 2. Switch to SA Company. 3. Set the company name to an Arabic string between 32 and 64 characters. (e.g;…
## Steps to Reproduce: _(cryptography version > 43.0.0)_
1. Install the `l10n_sa_edi` module.
2. Switch to SA Company.
3. Set the company name to an Arabic string between 32 and 64 characters.
(e.g; `مجموعة النخبة العالمية للاستشارات الفنية`)
5. Accounting > Configuration > Journals.
6. Open a Sales type journal.
7. Click "Re-onboard" in the ZATCA tab.
8. Enter an OTP and click "Request".
## Error:
`ValueError: Attribute's length must be >= 1 and <= 64, but it was 98`
## Cause:
The CSR validation checks the length of characters, if combined common_name (or other fields) are less than 64 characters, it passes the condition. - [1] But the cryptography library validates UTF-8 byte length for string values. Arabic characters take 2 bytes in UTF-8, causing the byte length to exceed the 64-byte limit enforced by the cryptography.
**Note:**
Starting with cryptography version 43.0.0, the library enforces the UTF-8 byte length limit for CSR string values during certificate creation. (Ref: https://github.com/pyca/cryptography/pull/11201)
## Fix:
Validate the UTF-8 encoded byte length instead of the character length.
[1] - https://github.com/odoo/odoo/blob/a66fedcaf555660e484a2becc49a9b7e602f5924/addons/l10n_sa_edi/models/certificate.py#L92
sentry-7608376856
Forward-Port-Of: odoo/odoo#277822
Forward-Port-Of: odoo/odoo#276861**Problem**: When a stock move has no quantity, the computation of the lot cost fails because it tries to divide by zero. **Fix**: Add a check to the ```move._get_valued_qty()``` to make sure it is not zero before performing the division. **Steps to reproduce:** 1. Create a product tracks quantity by lot, and valuation by Lot/Serial. 2. Assign a FIFO costing method category to it. 3. Update on hand quantity to 10 4. Reduce the on hand quantity to 5 and update to 10 again. 5. Go to t
Original PR description
**Problem**: When a stock move has no quantity, the computation of the lot cost fails because it tries to divide by zero. **Fix**: Add a check to the ```move._get_valued_qty()``` to make sure it is not zero before performing the division. **Steps to reproduce:** 1. Create a product tracks quantity by lot, and valuation by Lot/Serial. 2. Assign a FIFO costing method category to it. 3. Update on hand quantity to 10 4. Reduce the on hand quantity to 5 and update to 10 again. 5. Go to the in/out smart button and change the quantity of the most recent sml to 0. 6. Updating the on hand quantity to any larger number raises the error. **Notes**: This issue is created by the recent pr https://github.com/odoo/odoo/pull/273728. If a database has the same workflow before the commit, the error will be raised when checking the on hand quantity or trying to make a stock.picking of that product after checking out the commit. opw-6400941 Forward-Port-Of: odoo/odoo#277878
7 changes
Enhancements to existing features
With this update: - For UBL imports, bank details are also used to help identify the partner by matching the bank account number. The retrieval logic has also been improved: 1. If VAT exists in the XML: - If a partner found with no VAT then enrich that partner by filing VAT from xml - If a partner found with a different VAT than the one in the XML, then a new partner will be created Task [link](https://www.odoo.com/odoo/project.task/5485563) task-5485563
Original PR description
With this update: - For UBL imports, bank details are also used to help identify the partner by matching the bank account number. The retrieval logic has also been improved: 1. If VAT exists in the XML: - If a partner found with no VAT then enrich that partner by filing VAT from xml - If a partner found with a different VAT than the one in the XML, then a new partner will be created Task [link](https://www.odoo.com/odoo/project.task/5485563) task-5485563
Resolved issues and error corrections
In commit 611ed3c430026d5fbeac0e565c379ae57a2a30bc `NOT IN ...` was converted to `!= ANY(...) but it should have been `!= ALL(...). task-None Forward-Port-Of: odoo/odoo#278445
Original PR description
In commit 611ed3c430026d5fbeac0e565c379ae57a2a30bc `NOT IN ...` was converted to `!= ANY(...) but it should have been `!= ALL(...). task-None Forward-Port-Of: odoo/odoo#278445
Steps to reproduce: ------------------- 1. Install sale_timesheet. 2. Create a service product with: - Invoicing Policy: Prepaid/Fixed Price - Create on Order: Project & Task 3. Create a sales order with this product. 4. Open the generated project > dashboard and verify that "To Invoice" shows $1. 5. Create a project update and observe that "To Invoice" also shows $1. 6. Return to the sales order, create and post the invoice. 7. Open the project dashboard again and verify that "T
Original PR description
Steps to reproduce: ------------------- 1. Install sale_timesheet. 2. Create a service product with: - Invoicing Policy: Prepaid/Fixed Price - Create on Order: Project & Task 3. Create a sales order…
Steps to reproduce: ------------------- 1. Install sale_timesheet. 2. Create a service product with: - Invoicing Policy: Prepaid/Fixed Price - Create on Order: Project & Task 3. Create a sales order with this product. 4. Open the generated project > dashboard and verify that "To Invoice" shows $1. 5. Create a project update and observe that "To Invoice" also shows $1. 6. Return to the sales order, create and post the invoice. 7. Open the project dashboard again and verify that "To Invoice" is now $0. 8. Create another project update. Issue: ------ The project update margin still displays $1 under "To Invoice" even though the sales order has already been fully invoiced. Cause: ------ The project update template displays the aggregated profitability totals (`profitability['total']['revenues']` and `profitability['total']['costs']`) instead of the dedicated `to_bill_to_invoice` and `billed_invoiced` values, causing stale "to invoice" amounts to persist after invoicing. Solution: --------- Use the `to_bill_to_invoice` and `billed_invoiced` values when rendering the project update profitability report. opw-6323869 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273605
`ref` already gives back a recordset if it found the reference. There is no need to research using the id on the same model, as `ref` calls `exists`, which already does the "same" query that's present here. Closes #137826 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276554
Original PR description
`ref` already gives back a recordset if it found the reference. There is no need to research using the id on the same model, as `ref` calls `exists`, which already does the "same" query that's present here. Closes #137826 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276554
When running `ŧest_free_reservation`, it could happen on very rare occasions that both moves would be created at a different second. In such cases, the test would fail. Since we want to test the case with *exact* same dates, we can't use `assertAlmostEqual` which is usually better for dates. Instead, we freeze the time for the duration of the creation / assignation. runbot-944453 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of:
Original PR description
When running `ŧest_free_reservation`, it could happen on very rare occasions that both moves would be created at a different second. In such cases, the test would fail. Since we want to test the case with *exact* same dates, we can't use `assertAlmostEqual` which is usually better for dates. Instead, we freeze the time for the duration of the creation / assignation. runbot-944453 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278103
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Configure a multi-company environment with a `Main Company` and a `Secondary Company` - Go to the setting enable Lots & Serial Numbers and switch into `Secondary Company` - Create a warehouse for the Secondary Company - In the Secondary Company, create a lot-tracked storable product - Create and validate a delivery for that product - Open the Traceability Report - Print the report Is
Original PR description
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `stock` module - Configure a multi-company environment with a `Main Company` and a `Secondary Company` - Go to the setting…
Version:
--------
- 18.0+
Steps to reproduce:
-------------------
- Install `stock` module
- Configure a multi-company environment with a `Main Company`
and a `Secondary Company`
- Go to the setting enable Lots & Serial Numbers and switch into
`Secondary Company`
- Create a warehouse for the Secondary Company
- In the Secondary Company, create a lot-tracked storable product
- Create and validate a delivery for that product
- Open the Traceability Report
- Print the report
Issue:
------
The report header always displays the Main Company, even though the
traceability report belongs entirely to the Secondary Company.
Cause:
------
https://github.com/odoo/odoo/blob/2d54db3ac0b6d807e580315e2633f3e2b10a700c/addons/stock/static/src/client_actions/stock_traceability_report_backend.xml#L9
Clicking Print calls onClickPrint(), which builds the PDF URL and
downloads it with download() (a plain XMLHttpRequest POST), landing on
the `type='http'` route `/stock/<output_format>/<report_name>`
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/stock/static/src/client_actions/stock_traceability_report_backend.js#L125-L134
That controller calls stock.traceability.report.get_pdf() without ever setting
`company_id` in the rendering context.
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/stock/controllers/main.py#L23
Inside `get_pdf()`, the report header is rendered by passing an `rcontext`
dict to `web.internal_layout`.
That template resolves the company to display using the following priority:
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/addons/web/views/report_templates.xml#L805-L816
1. `company_id` — an explicit company record in the render context
2. `o.company_id` — the company of the document object `o`
3. `res_company` — the fallback, injected by `_render_template()` as
`self.env.company`
Because `get_pdf()` never sets `company_id` or `o` in `rcontext`, the
template always falls through to `res_company`.
https://github.com/odoo/odoo/blob/3bd6b10c3f9ad8d93062b6b46490500edb8c9697/odoo/addons/base/models/ir_actions_report.py#L770
This is populated by `ir.actions.report._render_template()`
as `self.env.company`, which resolves to the first company in
the user's `allowed_company_ids` list — typically the main company
regardless of which company owns the lot,
picking, or stock moves being printed.
As a result, the report content belongs to the secondary company while the
header always shows the main company.
Fix:
----
Resolve the company from the record on which the traceability report is
opened (using `active_model` and `active_id`) and pass it explicitly as
`company_id` when rendering the report.
`web.internal_layout` already gives precedence to an explicit
`company_id` over the default `res_company`, ensuring the report header
always displays the company that owns the traced record.
When the record has no company set, the header falls back to
`res_company`. Since the print request is a raw `type='http'` download
that never receives the company switcher's context, `user.context`
(holding `allowed_company_ids`) is now forwarded in the download POST
and merged into the environment by the controller - as done in
`web/controllers/report.py` - so the fallback resolves to the currently
active company instead of the user's default one.
<details>
<summary>Click here to see the results:</summary>
<p><strong>Before:</strong></p>
<div class="image-row">
<img src="https://github.com/user-attachments/assets/7e3a5d65-9114-4bce-9139-a88cff7c261f" />
</div>
<p><strong>After:</strong></p>
<div class="image-row">
<img src="https://github.com/user-attachments/assets/0a105f80-b6ae-400d-a787-fb8706d5f519" />
</div>
</details>
---
opw-6345446
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#273595Miscellaneous changes
When a bus process restarts, every client on every database it serves loses its websocket at the same instant and immediately schedules a reconnection. Each database that comes back triggers a registry recompute server-side, so a tight reconnection window makes all of those recomputes land together and pile up on the freshly started process. The jitter added to each reconnection delay was only one second, far too narrow to break up that wave. Widen it to thirty seconds so the retries of the m
Original PR description
When a bus process restarts, every client on every database it serves loses its websocket at the same instant and immediately schedules a reconnection. Each database that comes back triggers a…
When a bus process restarts, every client on every database it serves loses its websocket at the same instant and immediately schedules a reconnection. Each database that comes back triggers a registry recompute server-side, so a tight reconnection window makes all of those recomputes land together and pile up on the freshly started process. The jitter added to each reconnection delay was only one second, far too narrow to break up that wave. Widen it to thirty seconds so the retries of the many clients fan out over a much wider window and the registry recomputes spread over time instead of colliding. Raise the ceiling on the retry delay to two minutes to match that wider spread, and drop the exponential growth factor: with a thirty-second jitter accumulating on every attempt, the delay already climbs on its own, so scaling it further only pushed clients toward the ceiling sooner without spreading them any better. 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#276869
7 changes
New functionality added to Odoo
Frontdesk locations can now notify hosts and visitors through WhatsApp when someone checks in, using configurable templates. This gives businesses another communication channel and ensures WhatsApp is used as a fallback when Discuss is not available or when the host is on leave.
Original PR description
Frontdesk currently supports email, SMS, and Discuss notifications for visitor check-ins. This adds WhatsApp as an additional notification channel for deployments where it is the preferred communication method. Stations can now be configured to send WhatsApp notifications using a selected template. Discuss notifications fall back to WhatsApp when the host has no linked user, following the existing SMS behavior. Visitors are also notified through WhatsApp when their host is on leave. A validation constraint ensures WhatsApp can only be enabled when associated hosts have valid international phone numbers. Unit tests cover the notification flow, fallback behavior, validation, and host-on-leave cases. Task-5929330
Enhancements to existing features
When employees or administrators try to create an expense card before Stripe is connected, they are now directed to the settings page to complete the connection. This makes the next step clearer and reduces confusion during card setup.
Original PR description
When a user tries to create a card but the configuration is not connected, redirect the user towards the settings to do the connection. task-6272805
Belgian payroll individual account reports now include ecovouchers paid to employees, covering both monthly and termination-related entries. This helps payroll users maintain more complete and accurate employee reporting.
Original PR description
In order to maintain proper reporting for payroll app users, individual accounts report must include ecovouchers paid to the employees therefore eco-voucher entries (terminating and monthly) were added to the report. Task: 6370378
Resolved issues and error corrections
Trial balance reports now avoid showing negligible rounding leftovers as balances when exported to Excel. This prevents accounts that should balance to zero from displaying confusing tiny scientific-notation values, improving report accuracy and clarity for finance users.
Original PR description
Steps to reproduce -------------------- - Install account_reports module; - Create a new account; - Create a miscellanous operation for the previous month using thenew account with a credit amount of $8.28; - Create a second MISC for the current month with two lines using the account : debit = 262.67 and credit = 254.39; - Open the trial balance report and filter the new account (end balance should be 0); - Export the report as XLSX; The end balance value is 2.84e-14 due to float rounding issues. opw-6369016 Forward-Port-Of: odoo/enterprise#125416 Forward-Port-Of: odoo/enterprise#123896
Scanning the original manufacturing order barcode now correctly finds related split manufacturing orders instead of showing a “not found” error. This helps warehouse and production teams continue barcode-based manufacturing flows after an order has been split.
Original PR description
### Steps to reproduce: - Create a product FP with a BOM: 1 X COMP (enough units in stock) - Create and confirm an MO for 3 units - Click on the cog wheel icon > Split the MO in 3 - On the barcode app > Operations > Manufacturing - Scan the name of your base MO #### > Error: No product or order found for barcode ... ### Expected behavior: Scanning an existing MO only adds its barcode as a `search_default_name`: https://github.com/odoo/enterprise/blob/598a8e335605fd68e3ceb5c1170864243426f994/stock_barcode_mrp/models/mrp_production.py#L162-L178 However, while this search is performed with an ilike, we only check the existence of an exact match before raising an error, which does not happen since our splitted MOs have a name: barcode-001, barcode-002, barcode-003,... opw-6376937 Forward-Port-Of: odoo/enterprise#123931
The portal now accurately reduces a user’s pending signature count after they sign their assigned document. This prevents users from seeing completed signing tasks as still outstanding and improves trust in the portal status display.
Original PR description
Version: master Steps to reproduce: - Create a sign request with two signers. - Assign the first signature to a portal user. - Log in as the portal user and sign the document. Issue: After signing, the to-sign count in the portal does not decrease. This is because the query only checks the overall sign request state instead of the individual signer's item state, so the count remains unchanged Fix: Added an item level state check to the count query so it only counts items that are still pending for that specific user. Task ID: 6412976
This fixes Peppol settings so the purchase journal is only required when it should be, especially when French PDP features are installed for non-French companies. It also ensures that choosing Documents for import sends invoices only to Documents, avoiding duplicate handling in Invoicing.
Original PR description
Fixes the settings view for the account_peppol_purchase_journal_id. account_peppol, documents_account_peppol and l10n_fr_pdp all wants to use a specific condition for the required attribute of the view. With PDP especially, once l10n_fr_pdp is installed, the view forces the base condition, even if documents_account_peppol is installed, and even if the company is not even French. On a non-French company registered/registering on Peppol, the journal shouldn't be mandatory if documents_account_peppol_folder_id is set up. To ease things up, it is now using a computed field. task-6304479 Forward-Port-Of: odoo/enterprise#120724
16 changes
Enhancements to existing features
Current behavior before PR: Threads couldn't be recognized by reading messages in the chat but only in the channel list. Desired behavior after PR is merged: As in 19.0, when a thread (sub-channel) has been created from a message in a channel, the originating message displays a preview card below it showing the thread name, last message preview, author prefix, and timestamp. This backports that feature to 18.0 by: - Adding an 'after-reactions' extension slot to the mail.Message template
Original PR description
Current behavior before PR: Threads couldn't be recognized by reading messages in the chat but only in the channel list. Desired behavior after PR is merged: As in 19.0, when a thread (sub-channel) has been created from a message in a channel, the originating message displays a preview card below it showing the thread name, last message preview, author prefix, and timestamp. This backports that feature to 18.0 by: - Adding an 'after-reactions' extension slot to the mail.Message template - Adding a new SubChannelPreview component that renders the thread preview card (sub_channel_preview.js/xml/scss) - Patching the Message component to render SubChannelPreview after reactions when message.linkedSubChannel exists and is not the current thread (message_patch.js/xml/scss) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This PR replaces the "ting" notification sound with a more pleasant and common notification sound. If Odoo's Discuss is used as a main communication method within an organization, the notification sound is important. It should be a pleasant sound so that users don't receive it as unpleasant and may disable it eventually. At the same time the sound should be clear and not too low so that it doesn't get overlooked easily. The "ting" sound can received as too rough. In future Odoo versions "t
Original PR description
This PR replaces the "ting" notification sound with a more pleasant and common notification sound. If Odoo's Discuss is used as a main communication method within an organization, the notification sound is important. It should be a pleasant sound so that users don't receive it as unpleasant and may disable it eventually. At the same time the sound should be clear and not too low so that it doesn't get overlooked easily. The "ting" sound can received as too rough. In future Odoo versions "ting" has been replaced by "dm_02" in #186944 which is not clear enough and could be overlooked. The sound introduced by this PR aligns more with other messenger and chat systems and has a pleasant, short and clear sound. Alternatively to replacing the sound file we could add it as a new sound file and use it as the default for Discuss. Let me know if you prefer that. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
Before this commit, the down payments line of the project profitability panel had no drill down action for salespersons and billing users without accounting access, because the group references were written with a trailing comma inside the XML id, making the two checks silently fail for everyone. Only the accounting read group check, written correctly, was effective. Steps to reproduce: - create a service product with "Create on Order: Project & Task", sell it on a sale order and confirm it
Original PR description
Before this commit, the down payments line of the project profitability panel had no drill down action for salespersons and billing users without accounting access, because the group references were…
Before this commit, the down payments line of the project profitability panel had no drill down action for salespersons and billing users without accounting access, because the group references were written with a trailing comma inside the XML id, making the two checks silently fail for everyone. Only the accounting read group check, written correctly, was effective. Steps to reproduce: - create a service product with "Create on Order: Project & Task", sell it on a sale order and confirm it - create a down payment invoice from the sale order and post it - create a user with Sales "User: All Documents" access, Project "User" access and no accounting access - as that user, open the dashboard of the generated project and look at the Down Payments line of the profitability panel The Down Payments amount is displayed as plain text, while a user with accounting access can click it to open the related invoices, as intended for the salesperson too. Solution: Move the commas out of the group references. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When running `ŧest_free_reservation`, it could happen on very rare occasions that both moves would be created at a different second. In such cases, the test would fail. Since we want to test the case with *exact* same dates, we can't use `assertAlmostEqual` which is usually better for dates. Instead, we freeze the time for the duration of the creation / assignation. runbot-944453 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of:
Original PR description
When running `ŧest_free_reservation`, it could happen on very rare occasions that both moves would be created at a different second. In such cases, the test would fail. Since we want to test the case with *exact* same dates, we can't use `assertAlmostEqual` which is usually better for dates. Instead, we freeze the time for the duration of the creation / assignation. runbot-944453 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278103
Steps to reproduce: - Install `l10n_cl` module - Create one branch of the CL company - Give user(not admin) access to company branch and login with user - Go to Accounting > Customers > Invoices - Click New > AccessError Cause: This error occurs because the user is working within a branch of the main company. The code tries to access the journal’s company, which is set to the parent company. As the user does not have access to the parent company, fetching the country code fails. Solu
Original PR description
Steps to reproduce: - Install `l10n_cl` module - Create one branch of the CL company - Give user(not admin) access to company branch and login with user - Go to Accounting > Customers > Invoices - Click New > AccessError Cause: This error occurs because the user is working within a branch of the main company. The code tries to access the journal’s company, which is set to the parent company. As the user does not have access to the parent company, fetching the country code fails. Solution: In some cases, strict company access rules cause `AccessError` and block normal flows, especially with parent–child company setups where a child needs data from the parent. To ensure smooth processing, temporary `sudo()` usage is required in specific places. opw-6087460
Seven entries of the Mexican chart of accounts template carry a name belonging to a **different** group, copied from a neighbouring entry. Each record's XML ID still states the intended name, which is what this restores. | Code | Field | Before | After | |---|---|---|---| | `6` | `name@es` | Gastos generales | Gastos | | `252.07` | `name@es` | `account_subgroup_hipotecas_por_pagar_a_largo_plazo_nacional` | Hipotecas por pagar a largo plazo nacional | | `602` | `name`, `name@es` | Cost of sales
Original PR description
Seven entries of the Mexican chart of accounts template carry a name belonging to a **different** group, copied from a neighbouring entry. Each record's XML ID still states the intended name, which…
Seven entries of the Mexican chart of accounts template carry a name belonging
to a **different** group, copied from a neighbouring entry. Each record's XML ID
still states the intended name, which is what this restores.
| Code | Field | Before | After |
|---|---|---|---|
| `6` | `name@es` | Gastos generales | Gastos |
| `252.07` | `name@es` | `account_subgroup_hipotecas_por_pagar_a_largo_plazo_nacional` | Hipotecas por pagar a largo plazo nacional |
| `602` | `name`, `name@es` | Cost of sales / Costo de venta | Selling expenses / Gastos de venta |
| `613` | `name@es` | Amortización contable | Depreciación contable |
| `614` | `name` | Accounting depreciation | Accounting amortisation |
| `701.06` | `name`, `name@es` | Interest on foreign bank charges / Intereses a cargo bancario extranjero | Interest payable by national natural persons / Intereses a cargo de personas físicas nacional |
| `702` | `name@es` | Utilidad cambiaria | Productos financieros |
### Why it is not cosmetic
The electronic accounting Chart of Accounts XML takes the `Desc` attribute of
every `<Ctas>` element from the *account group name* — `cfdicoa.xml`
(`t-att-Desc="account.get('name')"`), fed by `trial_balance.py`
`_l10n_mx_get_coa_values()`. Any `es_*` database therefore declares:
```xml
<catalogocuentas:Ctas CodAgrup="702" NumCta="702" Desc="Utilidad cambiaria" Nivel="1" Natur="A"/>
```
whereas the SAT catalogue (Anexo 24) publishes `702` as *Productos financieros*,
with `702.01 Utilidad cambiaria` … `702.10 Otros productos financieros` beneath
it. `CodAgrup` comes from `code_prefix_start` and stays correct, so the file
still validates against the XSD, but the declared description does not match the
official nomenclature. Trial Balance and Pólizas are unaffected — neither
exports group names.
### Evidence
- `252.07` contains its own XML ID as the Spanish name.
- `602` duplicates `501.01`, yet its children are `Sueldos y Salarios`,
`Compensaciones`, `Tiempos extras`.
- `613` and `614` are swapped in one language each: `613`'s children are
depreciations, `614`'s are amortisations.
- `701.06` duplicates `701.05` in both languages; the correct name is symmetric
to `701.07` and to `702.06`.
- `6` is the only single-digit root group whose Spanish name does not match its
XML ID (`account_group_gastos`).
### Notes
Introduced in d782b8b92557; correct in 15.0, where the names lived in
`account.account.tag.csv`. Still present in 18.0, 19.0 and master, hence
targeting 17.0. Template data only — existing databases are unaffected until the
chart is (re)installed, and renaming a group moves no balance.
Forward-Port-Of: odoo/odoo#277426`ref` already gives back a recordset if it found the reference. There is no need to research using the id on the same model, as `ref` calls `exists`, which already does the "same" query that's present here. Closes #137826 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276554
Original PR description
`ref` already gives back a recordset if it found the reference. There is no need to research using the id on the same model, as `ref` calls `exists`, which already does the "same" query that's present here. Closes #137826 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276554
## Steps to Reproduce: 1. Install the Sales and Studio modules. 2. Create a new menu for "**Sales Order Line**". 3. Open the menu in list view and group by "**Order**". 4. Sort by "**Order Reference**". ## Issue: Sale order lines appear to be sorted randomly when grouped by Order and sorted by Order Reference. ## Cause: When sorting on a many2one field, the `_order_field_to_sql()` method uses the comodel's default `_order` to generate the SQL query. - [1] Since `order_id` is a many
Original PR description
## Steps to Reproduce: 1. Install the Sales and Studio modules. 2. Create a new menu for "**Sales Order Line**". 3. Open the menu in list view and group by "**Order**". 4. Sort by "**Order…
## Steps to Reproduce: 1. Install the Sales and Studio modules. 2. Create a new menu for "**Sales Order Line**". 3. Open the menu in list view and group by "**Order**". 4. Sort by "**Order Reference**". ## Issue: Sale order lines appear to be sorted randomly when grouped by Order and sorted by Order Reference. ## Cause: When sorting on a many2one field, the `_order_field_to_sql()` method uses the comodel's default `_order` to generate the SQL query. - [1] Since `order_id` is a many2one on `sale.order.line` model, sorting by the `order_id` (Order Reference) also applies this default ordering of `sale.order` model, which is `date_order desc, id desc`. As a result, sale order lines are not ordered by SO name, but also by the corresponding sale order's order date. This ordering changes the order of the records, making the result appear random from the user's perspective, even though they explicitly sorted by Order Reference. ## Fix: This commit removes the `date_order` from the default ordering of the sale order and keeps only ordering by id. This prevents the sale order's order date (date_order) from affecting the ordering of sale order lines. This follows the same approach previously accepted for purchase orders. Task: https://www.odoo.com/odoo/project/49/tasks/2367965 PR: https://github.com/odoo/odoo/pull/60542 [1] - https://github.com/odoo/odoo/blob/16a1a545e2809a2172053f4db6193f425900e4ec/odoo/models.py#L5652-L5671 opw-6348322
Description of the issue this commit addresses: When a member of the Invoicing group tries to create a payment trough the L10nPlAccountPaymentRegister wizard, upon clicking "Create Payment", an AccessError is thrown. Invoicing group members should be able to handle payments so this is an issue. --- Steps to reproduce: 1. Make sure sale_management and l10n_pl_bank_verification are installed. 2. Create a new user with "Invoicing" Accounting group. 3. Create a new sales order with sai
Original PR description
Description of the issue this commit addresses: When a member of the Invoicing group tries to create a payment trough the L10nPlAccountPaymentRegister wizard, upon clicking "Create Payment", an…
Description of the issue this commit addresses: When a member of the Invoicing group tries to create a payment trough the L10nPlAccountPaymentRegister wizard, upon clicking "Create Payment", an AccessError is thrown. Invoicing group members should be able to handle payments so this is an issue. --- Steps to reproduce: 1. Make sure sale_management and l10n_pl_bank_verification are installed. 2. Create a new user with "Invoicing" Accounting group. 3. Create a new sales order with said user (any customer, any product) 4. Confirm the quotations and, from its form view, "Create Invoice". 5. Confirm the invoice and, from its form view, "Pay". 6. Upon clicking "Create Payment", an Access Error is thrown. --- Desired behavior after this commit is merged: This commit makes sure an Invoicing group member is able to create the payment withtout AccessErrors being thrown. --- task-none feedback from: https://github.com/odoo/odoo/pull/267992 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
`_get_belgian_cocontractant_note()` resolves the co-contractant fiscal position through chart_template.ref(), which uses env.company. The "Send invoices automatically" cron runs as the inactive OdooBot user, so env.company is OdooBot's default company, not the invoice's. That company can differ from the invoice's and even be archived, in which case ref() raises "IndexError: tuple index out of range" (parent_ids is empty for an archived company) Steps to reproduce: - Set the main company to a
Original PR description
`_get_belgian_cocontractant_note()` resolves the co-contractant fiscal position through chart_template.ref(), which uses env.company. The "Send invoices automatically" cron runs as the inactive OdooBot user, so env.company is OdooBot's default company, not the invoice's. That company can differ from the invoice's and even be archived, in which case ref() raises "IndexError: tuple index out of range" (parent_ids is empty for an archived company) Steps to reproduce: - Set the main company to a non-Belgian company, and invoice from another active Belgian company. - Move every active user off the main company and archive it - Send a Belgian 0% invoice through the cron. => IndexError: tuple index out of range in chart_template.ref opw-6398778 Forward-Port-Of: odoo/odoo#278326
### Issue before this commit: When importing an electronic invoice from SDI that is failing with an exception, the resulting account.move record was saved in the "Miscellaneous Operations" journal instead of the correct one (Vendor Bills), even though the move_type itself was correct. ### Steps to reproduce the issue: Pre steps: you need to have access to https://iap-services-test.odoo.com/odoo 1. Download Accounting and l10n_it 2. Go to Settings > Companies and set the VAT of IT company
Original PR description
### Issue before this commit: When importing an electronic invoice from SDI that is failing with an exception, the resulting account.move record was saved in the "Miscellaneous Operations" journal…
### Issue before this commit: When importing an electronic invoice from SDI that is failing with an exception, the resulting account.move record was saved in the "Miscellaneous Operations" journal instead of the correct one (Vendor Bills), even though the move_type itself was correct. ### Steps to reproduce the issue: Pre steps: you need to have access to https://iap-services-test.odoo.com/odoo 1. Download Accounting and l10n_it 2. Go to Settings > Companies and set the VAT of IT company the same as the one in the xml 3. Go to Settings > Italian Electronic Invoicing and select Test 4. Go into the code and insert an Exception inside the function _l10n_it_edi_import_invoice after self.move_type = move_type (or create any type of exception from the user interface) 5. Go to IAP service into IT EDI app and see that your company is there as user 6. Click into the record > receive move button > upload your xml > create 7. Go to your DB > Scheduled Actions > filter with IT > IT EDI: Receive invoices from the SdI > Run Manually 8. Go to Journal entries, remove the filter and find your imported bill 9. You can see it was inserted into the Miscellaneous Operations Journal instead of a Vendor Bill Journal ### Cause of the issue: The move is created inside a savepoint context manager, designed so that even if parsing fails, an empty move with the attachment still remains. The problem is that if the exception is raised, the savepoint rollback undoes everything that follows, but the journal was already determined before the correct move_type was known, leaving the move in the wrong default journal. ### Reason to introduce the fix: The fix is needed to ensure that, regardless of where parsing fails, the move's journal is correctly set even if an exception occurs so that it is possible to find the move in the correct section even if not imported correctly. opw-6397712 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278111
Once a ZATCA invoice is posted, the "Reset to Draft" button is still shown on the form until the chain index is set on the move. In that window, a user can click it (or force it visible from Studio on an already-accepted invoice) and reset the move to draft, even though it has been -- or is about to be -- submitted to ZATCA. The invoice can then be resubmitted, breaking the ZATCA chain. Steps to reproduce: 1. Configure a SA company and set up ZATCA. 2. Create and post a customer invoice. 3
Original PR description
Once a ZATCA invoice is posted, the "Reset to Draft" button is still shown on the form until the chain index is set on the move. In that window, a user can click it (or force it visible from Studio on an already-accepted invoice) and reset the move to draft, even though it has been -- or is about to be -- submitted to ZATCA. The invoice can then be resubmitted, breaking the ZATCA chain. Steps to reproduce: 1. Configure a SA company and set up ZATCA. 2. Create and post a customer invoice. 3. On the posted invoice, click "Reset to Draft" -> the move becomes draft, while the ZATCA submission still goes through. Fix: - Add a user error on account.move.button_draft if the invoice has l10n_sa_chain_index set task-6208977 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#270766
odoo/odoo#155588 was a workaround to the lack of location permissions in the iOS app, skipping geolocation entirely for check in/out. Since odoo/mobile#118 added support for them, we can now revert that fix so iOS users get prompted for their location again. task-6279460 Forward-Port-Of: odoo/odoo#276934
Original PR description
odoo/odoo#155588 was a workaround to the lack of location permissions in the iOS app, skipping geolocation entirely for check in/out. Since odoo/mobile#118 added support for them, we can now revert that fix so iOS users get prompted for their location again. task-6279460 Forward-Port-Of: odoo/odoo#276934
# How to reproduce - Create an eLearning course - In Options, set "Show Course To" to Course Attendees - Add an attendee - Click on the "Go to website" smart button - Publish the course - Add content that is an image - Select a file & tile, then save # The issue In the mail sent to the attendee, the image is not displayed # Cause To display the image, the mail has a link to this route : https://github.com/odoo/odoo/blob/65dbcabcd243abf24d6d3c3788d2caff66485790/addons/web/controlle
Original PR description
# How to reproduce - Create an eLearning course - In Options, set "Show Course To" to Course Attendees - Add an attendee - Click on the "Go to website" smart button - Publish the course - Add content that is an image - Select a file & tile, then save # The issue In the mail sent to the attendee, the image is not displayed # Cause To display the image, the mail has a link to this route : https://github.com/odoo/odoo/blob/65dbcabcd243abf24d6d3c3788d2caff66485790/addons/web/controllers/binary.py#L185 However, it seems the request sent to the server via the mail client to retrieve the image does not keep the user session. We therefore try to see the image as the "Public user", which is forbidden since the visibility of the course is limited to attendees. # Proposed solution Add an access token in the image link.
The state_id field was not cleared when editing an address and switching to a country without states — the state selector reset visually, but the stale state_id was still saved to the backend. Steps to reproduce: 1. Add a product to the cart. 2. Go to checkout and edit the address, selecting a country that has states. 3. Edit the address again, now selecting a country without states. 4. Save and check the contact in the backend: state_id still holds the state from the previo
Original PR description
The state_id field was not cleared when editing an address and switching to a country without states — the state selector reset visually, but the stale state_id was still saved to the backend. Steps to reproduce: 1. Add a product to the cart. 2. Go to checkout and edit the address, selecting a country that has states. 3. Edit the address again, now selecting a country without states. 4. Save and check the contact in the backend: state_id still holds the state from the previous country. Solution: reset the state_id select options for the new country. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Miscellaneous changes
Steps to reproduce the problem: * Create a SO line by code setting a specific unit price. * Modify afterwards the quantity. Result: The unit price is reset. Expected behavior: The unit price is kept. You can exercise it with this code in the shell: ```python from odoo import Command partner = env["res.partner"].create({"name": "Test partner"}) product = env["product.product"].create({"name": "Test product", "list_price": 60.0}) order = env["sale.order"].create( {
Original PR description
Steps to reproduce the problem: * Create a SO line by code setting a specific unit price. * Modify afterwards the quantity. Result: The unit price is reset. Expected behavior: The unit price is kept.…
Steps to reproduce the problem:
* Create a SO line by code setting a specific unit price.
* Modify afterwards the quantity.
Result: The unit price is reset.
Expected behavior: The unit price is kept.
You can exercise it with this code in the shell:
```python
from odoo import Command
partner = env["res.partner"].create({"name": "Test partner"})
product = env["product.product"].create({"name": "Test product", "list_price": 60.0})
order = env["sale.order"].create(
{
"partner_id": cls.partner.id,
"order_line": [Command.create({"product_id": cls.product.id, "price_unit": 100})],
}
)
print(order.order_line.price_unit) # It's 100
order.order_line.product_uom_qty = 2
print(order.order_line.price_unit) # It's 60!
```
This is because when the technical price is not set on SO line creation, the value is set on precompute as the unit price, thus being considered non manually modified, and consequently being reset.
It can be fixed setting a different value from the unit price. For not conflicting with any of the creation possible values, a high negative number is set.
@Tecnativa5 changes
Enhancements to existing features
Password managers and browsers rely on the standardized `/.well-known/change-password` URL to automatically locate a site's password change form, instead of relying on unreliable heuristics to detect it inside the page. Without this endpoint, users depending on password manager integrations (Chrome, Safari, 1Password, Bitwarden, etc) have no reliable way to be redirected to the actual reset form, resulting in a degraded UX and inconsistent behavior across browsers. This implements the Chan
Original PR description
Password managers and browsers rely on the standardized `/.well-known/change-password` URL to automatically locate a site's password change form, instead of relying on unreliable heuristics to detect it inside the page. Without this endpoint, users depending on password manager integrations (Chrome, Safari, 1Password, Bitwarden, etc) have no reliable way to be redirected to the actual reset form, resulting in a degraded UX and inconsistent behavior across browsers. This implements the Change Password URL specification by exposing a public route that redirects to `/web/reset_password`. Reference: https://wicg.github.io/change-password-url/ --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This commit fixes an issue with the campaign_id field on mailing.mailing so that we can only use actual utm.campaign for it. Before this commit, when enabled it was possible to select any type of campaign even one created by marketing automation. As those creates a utm campaign linked to them. Difference being they are marked as auto campaigns. So when selecting those, they aren't shown in the campaigns' menu's views. To fix this we add a domain to the campaign_id field so that the user ca
Original PR description
This commit fixes an issue with the campaign_id field on mailing.mailing so that we can only use actual utm.campaign for it. Before this commit, when enabled it was possible to select any type of campaign even one created by marketing automation. As those creates a utm campaign linked to them. Difference being they are marked as auto campaigns. So when selecting those, they aren't shown in the campaigns' menu's views. To fix this we add a domain to the campaign_id field so that the user can only select actual campaigns. Disabling the previously mentioned behavior. task-6290440
When an employee has many validated accrual allocations on the same leave type and at least one approved future leave on that leave type, opening the time off dashboard, the employee form, "My Profile" or validating a new allocation becomes very slow. The slowdown gets worse with each extra allocation. ### Steps to reproduce 1. Install Time Off. 2. Time Off > Configuration > Accrual Plans: create a plan. 3. Time Off > Management > Allocations: create and validate an Accrual Allocation fo
Original PR description
When an employee has many validated accrual allocations on the same leave type and at least one approved future leave on that leave type, opening the time off dashboard, the employee form, "My…
When an employee has many validated accrual allocations on the same leave type and at least one approved future leave on that leave type, opening the time off dashboard, the employee form, "My Profile" or validating a new allocation becomes very slow. The slowdown gets worse with each extra allocation.
### Steps to reproduce
1. Install Time Off.
2. Time Off > Configuration > Accrual Plans: create a plan.
3. Time Off > Management > Allocations: create and validate an Accrual Allocation for an employee (e.g., Paid Time Off).
4. Time Off > Management > Time Off: create and approve a request for the same employee starting a few months in the future.
5. Create and validate several more accrual allocations of the same type for the same employee. Each validation gets progressively slower.
6. Open the dashboard or employee form; Odoo hangs for several seconds.
### Cause
The reason is that `hr.employee._get_consumed_leaves` and `hr.leave.allocation._process_accrual_plans` call each other in a loop:
```text
_get_consumed_leaves
_get_future_leaves_on
_process_accrual_plans
_get_leaves_taken
_get_consumed_leaves
...
```
The existing `precomputed_allocations` guard only stops re-entry for the single allocation being simulated. All sibling allocations on the same employee and leave type still trigger a full nested simulation, so the work grows very fast with the number of allocations.
On top of that, `_process_accrual_plans` walks the timeline one tick at a time (one day for daily plans). On every tick it calls `_get_leaves_taken`, which calls `_get_consumed_leaves` again. For most of those ticks nothing has changed: no leave has entered the window, the allocation has not hit its capacity, and the `leaves_taken` value is the same as the previous tick. But the heavy work runs anyway.
### Fix
1. Memoize `_get_future_leaves_on` by `(allocation.id, accrual_date)` on a per-request dict carried through `env.context`.
2. In `_process_accrual_plans`, fetch the relevant leave `date_from` values once before the `while` loop and only recompute `leaves_taken` when it can actually have changed: a new leave date entered the window, or the allocation was at full capacity in the previous iteration. When the employee has no relevant leaves on this leave type, `leaves_taken` stays `0` for the whole loop and the heavy call is skipped entirely.
opw-5975939Windows nightly builds have been failing for several days with this obscure NSIS error message in Odoo 19.0: Internal compiler error #12345: error mmapping datablock to 30283637 Root cause: the accumulated size of `.po` files across all modules has grown past a threshold where the NSIS solid compressor tries to mmap a buffer larger than the ~2 GiB address space available to the 32-bit makensis running under Wine. Simply dropping the `/SOLID` option makes the build pass but nearly doubl
Original PR description
Windows nightly builds have been failing for several days with this obscure NSIS error message in Odoo 19.0: Internal compiler error #12345: error mmapping datablock to 30283637 Root cause: the…
Windows nightly builds have been failing for several days with this obscure NSIS error message in Odoo 19.0:
Internal compiler error #12345: error mmapping datablock to 30283637
Root cause: the accumulated size of `.po` files across all modules has grown past a threshold where the NSIS solid compressor tries to mmap a buffer larger than the ~2 GiB address space available to the 32-bit makensis running under Wine. Simply dropping the `/SOLID` option makes the build pass but nearly doubles the size of the final installer, which is not acceptable.
The chosen fix is to pre-bundle all `.po` files into a single solid 7z archive and extract it at install time using the `Nsis7z` plugin. This keeps the NSIS datablock well below the and yields comparable or better final installer size than the previous approach, along with faster build times.
While at it, this commit also modernizes the Windows build environment to unblock a separate wine-devel install regression that has been affecting Odoo 17.0 nightlies on Debian Bookworm.
Changes:
- Bundle `.po` files into `i18n_bundle.7z` inside the build container prior to invoking makensis; extract it at install time via the `Nsis7z` plugin.
- Bump the base image from Debian Bookworm to Trixie.
- Switch from `wine-devel` to `wine-stable`, which resolves the install regression on Bookworm-based builds.
- Upgrade NSIS to the latest release.
- Refactor the NSIS installation step to remove the hardcoded version from `package.py`.
This fix is made in Odoo 17.0 to unblock the wine-devel issue there and to benefit from the smaller installer size on supported stable branches.Code cleanup and technical improvements
Owl considers declared component props mandatory unless they are marked optional. The `required: true` flags therefore duplicate the default and add noise to the prop definitions. Remove those flags from `PlacesAutoComplete`, all four props remain mandatory.
Original PR description
Owl considers declared component props mandatory unless they are marked optional. The `required: true` flags therefore duplicate the default and add noise to the prop definitions. Remove those flags from `PlacesAutoComplete`, all four props remain mandatory.