Daily updates from Odoo
Wednesday, July 15, 2026
273 changes
13 changes
Resolved issues and error corrections
### Steps to reproduce 1. Create a invoice with a section and add products under it with values 2. Enable **Hide Composition** on the section. 3. Print the invoice PDF. <table> <tr> <td> <img width="1278" height="425" alt="image" src="https://github.com/user-attachments/assets/969a222a-5e2f-48e2-962d-fc1cf6440619" /> </td> </tr> </table> ### Description When an invoice contains a section and products in it with values and with **Hide Composition** enabled,
Original PR description
### Steps to reproduce 1. Create a invoice with a section and add products under it with values 2. Enable **Hide Composition** on the section. 3. Print the invoice PDF. <table> <tr> <td> <img…
### Steps to reproduce
1. Create a invoice with a section and add products under it with values
2. Enable **Hide Composition** on the section.
3. Print the invoice PDF.
<table>
<tr>
<td>
<img width="1278" height="425" alt="image" src="https://github.com/user-attachments/assets/969a222a-5e2f-48e2-962d-fc1cf6440619" />
</td>
</tr>
</table>
### Description
When an invoice contains a section and products in it with values and with **Hide Composition** enabled, the PDF invoice report incorrectly displays the **Disc.%** column header even though no discount values in that section line.
The report currently computes `display_discount` using `o.invoice_line_ids`:
```xml
<t t-set="display_discount" t-value="any(l.discount for l in o.invoice_line_ids)"/>
```
Since `o.invoice_line_ids` still contains the hidden product lines, `display_discount` evaluates to `True`, causing the **Disc.%** column header to be displayed. However, those product lines are replaced by the section line in the report, so no discount values are shown, resulting in an empty column.
### Current behavior
The **Disc.%** column is displayed, but all its cells are empty.
<table>
<tr>
<td>
<img width="808" height="488" alt="image" src="https://github.com/user-attachments/assets/7d9afee6-fef5-49c8-bc4e-b01caa8b43bd" />
</td>
</tr>
</table>
### Expected behavior
The **Disc.%** column should not be displayed when the reported lines do not contain any discounts.
<table>
<tr>
<td>
<img width="798" height="427" alt="image" src="https://github.com/user-attachments/assets/6ffe7985-a7d0-43f5-8d40-41e700ecbed3" />
</td>
</tr>
</table>
### Solution
Compute `lines_to_report` before evaluating `display_discount` and use it instead:
```xml
<t t-set="lines_to_report" t-value="o._get_move_lines_to_report()"/>
<t t-set="display_discount" t-value="any(l.discount for l in lines_to_report)"/>
```
Forward-Port-Of: odoo/odoo#276003
Forward-Port-Of: odoo/odoo#275793Only display the AI thread start message once the thread has finished loading, matching the behavior of regular Discuss channels and preventing a brief flash of the empty conversation. Update the AI-specific `showStartMessage` implementation to respect the base Thread loading state instead of always displaying the start message for AI channels. Enterprise PR : https://github.com/odoo/enterprise/pull/122808 task-6352578 --- I confirm I have signed the CLA and read the PR guidelines a
Original PR description
Only display the AI thread start message once the thread has finished loading, matching the behavior of regular Discuss channels and preventing a brief flash of the empty conversation. Update the AI-specific `showStartMessage` implementation to respect the base Thread loading state instead of always displaying the start message for AI channels. Enterprise PR : https://github.com/odoo/enterprise/pull/122808 task-6352578 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273991
Steps to reproduce: Have one invoice Posted, To Review Have one invoice Draft, To Review Dashboard will only says 1 To Review When clicking the link it shows 2 invoices After this commit- We append the domain of the filter with only posted moves task-6385625 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276261
Original PR description
Steps to reproduce: Have one invoice Posted, To Review Have one invoice Draft, To Review Dashboard will only says 1 To Review When clicking the link it shows 2 invoices After this commit- We append the domain of the filter with only posted moves task-6385625 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276261
Steps to Reproduce: - open notes - type `/link` to open link popover Issue: - The url input field and its icon are misaligned. Cause: - When url autocomplete are enabled in the link popover, the input field height is reduced, causing it to become smaller than its container. This results in misalignment between the input field and the icon. Solution: - Set the link popover url input height to 100% so it always matches the height of its container, ensuring proper alignment even when
Original PR description
Steps to Reproduce: - open notes - type `/link` to open link popover Issue: - The url input field and its icon are misaligned. Cause: - When url autocomplete are enabled in the link popover, the input field height is reduced, causing it to become smaller than its container. This results in misalignment between the input field and the icon. Solution: - Set the link popover url input height to 100% so it always matches the height of its container, ensuring proper alignment even when autocomplete is avaialble. task-6201175 Forward-Port-Of: odoo/odoo#267716
Chrome keeps suggesting autocompletion on empty selection field. https://github.com/odoo/odoo/commit/5e7bc4ab851dba3d2e0b965f69e06cfeacec5674 is the commit introducing `autocomplete="selectMenuAutocompleteOff"` and I don't know why this value has been chosen but Chrome seem to consider this token as invalid Steps to reproduce: - Put a selection field on a form view with Studio - Create a record, complete the selection field and save - Create a new record and click on the selection field
Original PR description
Chrome keeps suggesting autocompletion on empty selection field. https://github.com/odoo/odoo/commit/5e7bc4ab851dba3d2e0b965f69e06cfeacec5674 is the commit introducing `autocomplete="selectMenuAutocompleteOff"` and I don't know why this value has been chosen but Chrome seem to consider this token as invalid Steps to reproduce: - Put a selection field on a form view with Studio - Create a record, complete the selection field and save - Create a new record and click on the selection field Current Behaviour: Chrome keeps suggesting the previously filled values Desired Behaviour: No autocomplete from the browser. Forward-Port-Of: odoo/odoo#276142 Forward-Port-Of: odoo/odoo#274086
Steps to reproduce: - Add an `s_add_to_cart` snippet inside a mega menu - Open a product detail page for a storable product - Change the product variant several times - Stock availability messages keep appending under `availability_messages` instead of replacing the previous one `_onChangeCombinationStock` removed existing messages with `document.querySelector('.oe_website_sale').querySelectorAll(...)`, but appended the new message with `this.el.querySelector('div.availability_messages')
Original PR description
Steps to reproduce: - Add an `s_add_to_cart` snippet inside a mega menu - Open a product detail page for a storable product - Change the product variant several times - Stock availability messages…
Steps to reproduce:
- Add an `s_add_to_cart` snippet inside a mega menu
- Open a product detail page for a storable product
- Change the product variant several times
- Stock availability messages keep appending under `availability_messages` instead of replacing the previous one
`_onChangeCombinationStock` removed existing messages with `document.querySelector('.oe_website_sale').querySelectorAll(...)`, but appended the new message with
`this.el.querySelector('div.availability_messages').append(...)`.
`document.querySelector('.oe_website_sale')` only returns the first `.oe_website_sale` element in the document. When a mega menu contains an `s_add_to_cart` snippet, that element appears before the product page container, so the removal step runs on the wrong subtree and never clears the messages on the product page.
Fix by scoping the removal to `this.el`, the current `WebsiteSale` interaction root, so both removal and insertion target the same product page container.
Forward-Port-Of: odoo/odoo#276252
Forward-Port-Of: odoo/odoo#274928Previously, batch payment sequence will be created by simply select to create new company due to having lambda in default. Hence, the created sequence does not have a correct company_id set as company hasn't yet created. Switch to creating sequence in ``create`` function to avoid this issue. Also use ``range_year`` for payment prefix because it was set to use date range. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged:
Original PR description
Previously, batch payment sequence will be created by simply select to create new company due to having lambda in default. Hence, the created sequence does not have a correct company_id set as company hasn't yet created. Switch to creating sequence in ``create`` function to avoid this issue. Also use ``range_year`` for payment prefix because it was set to use date range. 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#276182 Forward-Port-Of: odoo/odoo#268689
When a POS line comes from a sale order, its invoice line name is overridden with the source sale order line's name. When a down payment is invoiced directly from the POS, the invoice is generated before the down payment POS line is linked to its sale order line, so sale_order_line_id is still empty and the override resolved to an empty recordset, setting the invoice line name to False. Only override the name when a sale order line is actually set, so the down payment line keeps its own name.
Original PR description
When a POS line comes from a sale order, its invoice line name is overridden with the source sale order line's name. When a down payment is invoiced directly from the POS, the invoice is generated before the down payment POS line is linked to its sale order line, so sale_order_line_id is still empty and the override resolved to an empty recordset, setting the invoice line name to False. Only override the name when a sale order line is actually set, so the down payment line keeps its own name. opw-6305649 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275516 Forward-Port-Of: odoo/odoo#274000
Currently, when using the "login with employee" feature and sending the order receipt by mail, the cashier name is not the name of the employee using the pos. Steps to reproduce: ------------------- * Use the login with employee feature * Open the pos * Connect with an employee not linked to the current user * Make an order * Send the receipt to the customer by mail. > The receipt from the shop shows the cashier's name, the receipt sent by mail shows the connected user as the cashier
Original PR description
Currently, when using the "login with employee" feature and sending the order receipt by mail, the cashier name is not the name of the employee using the pos. Steps to reproduce: ------------------- * Use the login with employee feature * Open the pos * Connect with an employee not linked to the current user * Make an order * Send the receipt to the customer by mail. > The receipt from the shop shows the cashier's name, the receipt sent by mail shows the connected user as the cashier opw-6291485 Forward-Port-Of: odoo/odoo#270013
### Before this PR When importing a FatturaPA XML, Odoo sets the fiscal position on the bill from the partner but does not apply it to the line taxes so a fiscal position that remaps taxes (partial deductibility, reverse charge, split payment) never map the imported lines. ### After this PR the fiscal position is correctly applied ### To reproduce 1. Apply to Italian vendor a fiscal position that maps the 22% purchase tax to a partial-deductibility tax (e.g. "22%" →"22% ind. 50%").
Original PR description
### Before this PR When importing a FatturaPA XML, Odoo sets the fiscal position on the bill from the partner but does not apply it to the line taxes so a fiscal position that remaps taxes (partial deductibility, reverse charge, split payment) never map the imported lines. ### After this PR the fiscal position is correctly applied ### To reproduce 1. Apply to Italian vendor a fiscal position that maps the 22% purchase tax to a partial-deductibility tax (e.g. "22%" →"22% ind. 50%"). 2. Import a FatturaPA XML from that vendor with 22% lines. 3. The bill header shows the fiscal position, but the lines keep the plain 22% tax instead of the mapped one. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275614 Forward-Port-Of: odoo/odoo#274738
**PROBLEM** amount_to_invoice_at_date is not calculated correctly when using UoM. **STEP TO REPRODUCE** 1. Create a product tracked by unit. 2. Create a purchase order with a UoM of pack of 6 (or some multiples of the Units UoM). 3. Confirm the PO and receive the products. 4. Go to the accounting app, reviews>bill to receive 5. Notice the po line on bill to receive as an incorrect amount. opw-6305324 Forward-Port-Of: odoo/odoo#275876 Forward-Port-Of: odoo/odoo#270327
Original PR description
**PROBLEM** amount_to_invoice_at_date is not calculated correctly when using UoM. **STEP TO REPRODUCE** 1. Create a product tracked by unit. 2. Create a purchase order with a UoM of pack of 6 (or some multiples of the Units UoM). 3. Confirm the PO and receive the products. 4. Go to the accounting app, reviews>bill to receive 5. Notice the po line on bill to receive as an incorrect amount. opw-6305324 Forward-Port-Of: odoo/odoo#275876 Forward-Port-Of: odoo/odoo#270327
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a barcode for the product with the B variant only - Go to the PoS, enter the barcode for the product with the B variant - The price is 1400 instead of 1200 **Why the fix:** The extra price for dynamic variants ordered through the barcode will be counted twice. This is because it is first count
Original PR description
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a…
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a barcode for the product with the B variant only - Go to the PoS, enter the barcode for the product with the B variant - The price is 1400 instead of 1200 **Why the fix:** The extra price for dynamic variants ordered through the barcode will be counted twice. This is because it is first counted in the _scan(code) method when we fetch the product from the models, then counted again when adding the line to the current order. https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/point_of_sale/static/src/app/services/pos_store.js#L1264-L1269 This step is necessary for the usual flow without the barcode as we need to add this extra price, but when using the barcode, the list price of the product we fetch is already 1200, as the extra price is already included when fetching it from the backend. It works for always attributes because we explicitly check that we are not adding the extra price again in the above code, and that the list price already includes the extra price. It also works for the never attributes because values.product_id.product_template_variant_value_ids.length is 0, so the code to update the extra price is never triggered. As we still need to add the extra price for the usual flow, we now just check if we have a code, meaning we added the product through the barcode and that we do not need to add it again, as the list price already accounts for the extra price. opw-6328600 Forward-Port-Of: odoo/odoo#272395
In main data service of this PoS indexedDB is called automatically after records are updated. ```js this.debouncedSynchronizeLocalDataInIndexedDB = debounce( this.synchronizeLocalDataInIndexedDB.bind(this), 300 ); ``` But sometimes, the indexedDB is directly called in the code via `synchronizeLocalDataInIndexedDB` which is not debounced and can lead to race conditions and potential data corruption. Now the `synchronizeLocalDataInIndexedDB` is inside a Mutex to avoid concurr
Original PR description
In main data service of this PoS indexedDB is called automatically after records are updated.
```js
this.debouncedSynchronizeLocalDataInIndexedDB = debounce(
this.synchronizeLocalDataInIndexedDB.bind(this),
300
);
```
But sometimes, the indexedDB is directly called in the code via `synchronizeLocalDataInIndexedDB` which is not debounced and can lead to race conditions and potential data corruption.
Now the `synchronizeLocalDataInIndexedDB` is inside a Mutex to avoid concurrent access to the indexedDB.
The old method is renamed to `_synchronizeLocalDataInIndexedDB` and is now private.
Forward-Port-Of: odoo/odoo#27589222 changes
Resolved issues and error corrections
### Steps to reproduce 1. Create a invoice with a section and add products under it with values 2. Enable **Hide Composition** on the section. 3. Print the invoice PDF. <table> <tr> <td> <img width="1278" height="425" alt="image" src="https://github.com/user-attachments/assets/969a222a-5e2f-48e2-962d-fc1cf6440619" /> </td> </tr> </table> ### Description When an invoice contains a section and products in it with values and with **Hide Composition** enabled,
Original PR description
### Steps to reproduce 1. Create a invoice with a section and add products under it with values 2. Enable **Hide Composition** on the section. 3. Print the invoice PDF. <table> <tr> <td> <img…
### Steps to reproduce
1. Create a invoice with a section and add products under it with values
2. Enable **Hide Composition** on the section.
3. Print the invoice PDF.
<table>
<tr>
<td>
<img width="1278" height="425" alt="image" src="https://github.com/user-attachments/assets/969a222a-5e2f-48e2-962d-fc1cf6440619" />
</td>
</tr>
</table>
### Description
When an invoice contains a section and products in it with values and with **Hide Composition** enabled, the PDF invoice report incorrectly displays the **Disc.%** column header even though no discount values in that section line.
The report currently computes `display_discount` using `o.invoice_line_ids`:
```xml
<t t-set="display_discount" t-value="any(l.discount for l in o.invoice_line_ids)"/>
```
Since `o.invoice_line_ids` still contains the hidden product lines, `display_discount` evaluates to `True`, causing the **Disc.%** column header to be displayed. However, those product lines are replaced by the section line in the report, so no discount values are shown, resulting in an empty column.
### Current behavior
The **Disc.%** column is displayed, but all its cells are empty.
<table>
<tr>
<td>
<img width="808" height="488" alt="image" src="https://github.com/user-attachments/assets/7d9afee6-fef5-49c8-bc4e-b01caa8b43bd" />
</td>
</tr>
</table>
### Expected behavior
The **Disc.%** column should not be displayed when the reported lines do not contain any discounts.
<table>
<tr>
<td>
<img width="798" height="427" alt="image" src="https://github.com/user-attachments/assets/6ffe7985-a7d0-43f5-8d40-41e700ecbed3" />
</td>
</tr>
</table>
### Solution
Compute `lines_to_report` before evaluating `display_discount` and use it instead:
```xml
<t t-set="lines_to_report" t-value="o._get_move_lines_to_report()"/>
<t t-set="display_discount" t-value="any(l.discount for l in lines_to_report)"/>
```
Forward-Port-Of: odoo/odoo#276003
Forward-Port-Of: odoo/odoo#275793The reporting labels "Difference" and "Balance" are confusing because "Difference" tracks system-qualified overtime while "Balance" represents accepted overtime hours. There is also a lack of consistency across views. This commit renames these fields to "Worked Extra Hours" and "Validated Extra Hours" to harmonize the naming everywhere task-6352142 Description of the issue/feature this PR addresses: Confusing and inconsistent naming for extra hours Current behavior before PR: - Rep
Original PR description
The reporting labels "Difference" and "Balance" are confusing because "Difference" tracks system-qualified overtime while "Balance" represents accepted overtime hours. There is also a lack of consistency across views. This commit renames these fields to "Worked Extra Hours" and "Validated Extra Hours" to harmonize the naming everywhere task-6352142 Description of the issue/feature this PR addresses: Confusing and inconsistent naming for extra hours Current behavior before PR: - Reporting uses "Difference" and "Balance". - Views use inconsistent labels. Desired behavior after PR is merged: Labels are consistently named "Worked Extra Hours" and "Validated Extra Hours" everywhere. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275944 Forward-Port-Of: odoo/odoo#273631
Steps to reproduce: Have one invoice Posted, To Review Have one invoice Draft, To Review Dashboard will only says 1 To Review When clicking the link it shows 2 invoices After this commit- We append the domain of the filter with only posted moves task-6385625 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276261
Original PR description
Steps to reproduce: Have one invoice Posted, To Review Have one invoice Draft, To Review Dashboard will only says 1 To Review When clicking the link it shows 2 invoices After this commit- We append the domain of the filter with only posted moves task-6385625 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276261
### [FIX] portal: fix parent company handling Before this commit, users could not update the company name from the portal, and creating a company resulted in a regular contact instead of a company. This happened because the additional_values passed to mark the parent as is_company=True were overridden to False when the customer did not have a VAT number. This commit sets is_company after creating the company, ensuring the parent contact is always created as a company. ### [FIX] portal:
Original PR description
### [FIX] portal: fix parent company handling Before this commit, users could not update the company name from the portal, and creating a company resulted in a regular contact instead of a company. This happened because the additional_values passed to mark the parent as is_company=True were overridden to False when the customer did not have a VAT number. This commit sets is_company after creating the company, ensuring the parent contact is always created as a company. ### [FIX] portal: make commercial fields editable Before this commit, there was no way to edit commercial fields after a user entered a company name in the address form. Setting a company name created a parent company, and editing commercial fields was blocked because the customer had a parent record. This commit allows commercial fields to be edited again for customer addresses whose parent company has only a single direct child. Forward-Port-Of: odoo/odoo#276015 Forward-Port-Of: odoo/odoo#275207
This fix is the same as this one https://github.com/odoo/odoo/pull/271577 but for the backend part of the code. After the fix, if you followed the same steps to reproduce and tried to close the session you would have an unbalanced entry for the session. Steps to reproduce: ------------------- * Create a 21% tax not included in price * Create a product with a price of 76.01 and the tax created above * Create a loyalty program with a 10% discount * Create a POS order with the product ab
Original PR description
This fix is the same as this one https://github.com/odoo/odoo/pull/271577 but for the backend part of the code. After the fix, if you followed the same steps to reproduce and tried to close the session you would have an unbalanced entry for the session. Steps to reproduce: ------------------- * Create a 21% tax not included in price * Create a product with a price of 76.01 and the tax created above * Create a loyalty program with a 10% discount * Create a POS order with the product above and apply the loyalty program * Validate the order and generate the invoice * Close the session > Observation: You need to force close the session because of unbalanced entry Why the fix: ------------ Apply the same fix for backend code. opw-6052112 Forward-Port-Of: odoo/odoo#276100 Forward-Port-Of: odoo/odoo#274985
Backport the changes from `b9370ea6b70ca3020c73a6940d70ff0cf954f69f` into `mail/convert_inline` to ensure Outlook-compatible image rendering. opw-3776054 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276071 Forward-Port-Of: odoo/odoo#269436
Original PR description
Backport the changes from `b9370ea6b70ca3020c73a6940d70ff0cf954f69f` into `mail/convert_inline` to ensure Outlook-compatible image rendering. opw-3776054 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276071 Forward-Port-Of: odoo/odoo#269436
Currently, when using the "login with employee" feature and sending the order receipt by mail, the cashier name is not the name of the employee using the pos. Steps to reproduce: ------------------- * Use the login with employee feature * Open the pos * Connect with an employee not linked to the current user * Make an order * Send the receipt to the customer by mail. > The receipt from the shop shows the cashier's name, the receipt sent by mail shows the connected user as the cashier
Original PR description
Currently, when using the "login with employee" feature and sending the order receipt by mail, the cashier name is not the name of the employee using the pos. Steps to reproduce: ------------------- * Use the login with employee feature * Open the pos * Connect with an employee not linked to the current user * Make an order * Send the receipt to the customer by mail. > The receipt from the shop shows the cashier's name, the receipt sent by mail shows the connected user as the cashier opw-6291485 Forward-Port-Of: odoo/odoo#270013
### Before this PR When importing a FatturaPA XML, Odoo sets the fiscal position on the bill from the partner but does not apply it to the line taxes so a fiscal position that remaps taxes (partial deductibility, reverse charge, split payment) never map the imported lines. ### After this PR the fiscal position is correctly applied ### To reproduce 1. Apply to Italian vendor a fiscal position that maps the 22% purchase tax to a partial-deductibility tax (e.g. "22%" →"22% ind. 50%").
Original PR description
### Before this PR When importing a FatturaPA XML, Odoo sets the fiscal position on the bill from the partner but does not apply it to the line taxes so a fiscal position that remaps taxes (partial deductibility, reverse charge, split payment) never map the imported lines. ### After this PR the fiscal position is correctly applied ### To reproduce 1. Apply to Italian vendor a fiscal position that maps the 22% purchase tax to a partial-deductibility tax (e.g. "22%" →"22% ind. 50%"). 2. Import a FatturaPA XML from that vendor with 22% lines. 3. The bill header shows the fiscal position, but the lines keep the plain 22% tax instead of the mapped one. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275614 Forward-Port-Of: odoo/odoo#274738
**PROBLEM** amount_to_invoice_at_date is not calculated correctly when using UoM. **STEP TO REPRODUCE** 1. Create a product tracked by unit. 2. Create a purchase order with a UoM of pack of 6 (or some multiples of the Units UoM). 3. Confirm the PO and receive the products. 4. Go to the accounting app, reviews>bill to receive 5. Notice the po line on bill to receive as an incorrect amount. opw-6305324 Forward-Port-Of: odoo/odoo#275876 Forward-Port-Of: odoo/odoo#270327
Original PR description
**PROBLEM** amount_to_invoice_at_date is not calculated correctly when using UoM. **STEP TO REPRODUCE** 1. Create a product tracked by unit. 2. Create a purchase order with a UoM of pack of 6 (or some multiples of the Units UoM). 3. Confirm the PO and receive the products. 4. Go to the accounting app, reviews>bill to receive 5. Notice the po line on bill to receive as an incorrect amount. opw-6305324 Forward-Port-Of: odoo/odoo#275876 Forward-Port-Of: odoo/odoo#270327
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per
Original PR description
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per the latest Worldline documentation, ensuring payment requests use the correct mapping. Forward-Port-Of: odoo/odoo#275881
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a barcode for the product with the B variant only - Go to the PoS, enter the barcode for the product with the B variant - The price is 1400 instead of 1200 **Why the fix:** The extra price for dynamic variants ordered through the barcode will be counted twice. This is because it is first count
Original PR description
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a…
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a barcode for the product with the B variant only - Go to the PoS, enter the barcode for the product with the B variant - The price is 1400 instead of 1200 **Why the fix:** The extra price for dynamic variants ordered through the barcode will be counted twice. This is because it is first counted in the _scan(code) method when we fetch the product from the models, then counted again when adding the line to the current order. https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/point_of_sale/static/src/app/services/pos_store.js#L1264-L1269 This step is necessary for the usual flow without the barcode as we need to add this extra price, but when using the barcode, the list price of the product we fetch is already 1200, as the extra price is already included when fetching it from the backend. It works for always attributes because we explicitly check that we are not adding the extra price again in the above code, and that the list price already includes the extra price. It also works for the never attributes because values.product_id.product_template_variant_value_ids.length is 0, so the code to update the extra price is never triggered. As we still need to add the extra price for the usual flow, we now just check if we have a code, meaning we added the product through the barcode and that we do not need to add it again, as the list price already accounts for the extra price. opw-6328600 Forward-Port-Of: odoo/odoo#272395
In main data service of this PoS indexedDB is called automatically after records are updated. ```js this.debouncedSynchronizeLocalDataInIndexedDB = debounce( this.synchronizeLocalDataInIndexedDB.bind(this), 300 ); ``` But sometimes, the indexedDB is directly called in the code via `synchronizeLocalDataInIndexedDB` which is not debounced and can lead to race conditions and potential data corruption. Now the `synchronizeLocalDataInIndexedDB` is inside a Mutex to avoid concurr
Original PR description
In main data service of this PoS indexedDB is called automatically after records are updated.
```js
this.debouncedSynchronizeLocalDataInIndexedDB = debounce(
this.synchronizeLocalDataInIndexedDB.bind(this),
300
);
```
But sometimes, the indexedDB is directly called in the code via `synchronizeLocalDataInIndexedDB` which is not debounced and can lead to race conditions and potential data corruption.
Now the `synchronizeLocalDataInIndexedDB` is inside a Mutex to avoid concurrent access to the indexedDB.
The old method is renamed to `_synchronizeLocalDataInIndexedDB` and is now private.
Forward-Port-Of: odoo/odoo#275892Steps to reproduce: - Open Chrome. - Set the browser zoom below or above 100%. - Edit a website page. - Hover a resize or padding handle in the overlay. => A white line appears in the middle of the handle. Before this commit, overlay handles changed their inner outline color on hover. With Chrome zoom levels different from 100%, this could leave a white line visible in the middle of the handle. After this commit, overlay handles change their background color on hover and use a consiste
Original PR description
Steps to reproduce: - Open Chrome. - Set the browser zoom below or above 100%. - Edit a website page. - Hover a resize or padding handle in the overlay. => A white line appears in the middle of the handle. Before this commit, overlay handles changed their inner outline color on hover. With Chrome zoom levels different from 100%, this could leave a white line visible in the middle of the handle. After this commit, overlay handles change their background color on hover and use a consistent inner outline width, so no white line is visible. task-6048647 Forward-Port-Of: odoo/odoo#273722
When a product attribute line is used in a confirmed sale order, Odoo archives it (active=False) instead of deleting it when removed from the product template. If the corresponding product.attribute record is also archived, settling that sale order in PoS crashes with: TypeError: Cannot read properties of undefined (reading 'create_variant') opw-6315766 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275273 Forward
Original PR description
When a product attribute line is used in a confirmed sale order, Odoo archives it (active=False) instead of deleting it when removed from the product template. If the corresponding product.attribute record is also archived, settling that sale order in PoS crashes with: TypeError: Cannot read properties of undefined (reading 'create_variant') opw-6315766 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275273 Forward-Port-Of: odoo/odoo#271778
Animated GIFs applied with an image shape freeze on Firefox and Safari when the shape's SVG is otherwise static. A dummy `<animateMotion dur="1ms" repeatCount="indefinite"/>` child on the <image> element keeps the animation running so the GIF plays. This hack was introduced in [1] but was missing from most shapes. This commit adds it to every <image> element that lacked it so any shape can be used with a GIF. task-5967171 [1]: https://github.com/odoo/odoo/commit/144e5ef799060da860a5fb1f
Original PR description
Animated GIFs applied with an image shape freeze on Firefox and Safari when the shape's SVG is otherwise static. A dummy `<animateMotion dur="1ms" repeatCount="indefinite"/>` child on the <image> element keeps the animation running so the GIF plays. This hack was introduced in [1] but was missing from most shapes. This commit adds it to every <image> element that lacked it so any shape can be used with a GIF. task-5967171 [1]: https://github.com/odoo/odoo/commit/144e5ef799060da860a5fb1fbe0fd009919afe79 Forward-Port-Of: odoo/odoo#275259
Problem: When posting expenses, if the expense domain is set as mandatory in any of the analytic plans, users can still submit expenses without entering an analytic distribution. This only happens when the expense is auto-approved on submission, which happens when the expense's employee is also the expense's manager or when the employee doesn't have an expense manager. Steps to reproduce: 1. Create an analytic plan with optional default applicability 2. Add an applicability rule with the d
Original PR description
Problem: When posting expenses, if the expense domain is set as mandatory in any of the analytic plans, users can still submit expenses without entering an analytic distribution. This only happens…
Problem: When posting expenses, if the expense domain is set as mandatory in any of the analytic plans, users can still submit expenses without entering an analytic distribution. This only happens when the expense is auto-approved on submission, which happens when the expense's employee is also the expense's manager or when the employee doesn't have an expense manager. Steps to reproduce: 1. Create an analytic plan with optional default applicability 2. Add an applicability rule with the domain set as Expense and set its applicability as mandatory. 3. Create a new expense 4. Set the expense's manager the same as the expense's employee. 5. Don't enter any analytic distribution. 6. Submit the expense 7. Notice how the expense is submitted and auto-approved without any error, even though no analytic distribution is entered and the analytic plan has a mandatory rule for expenses. Cause: The validation of the analytic distribution was only triggered on the approval of the expense, but when the expense is auto-approved on submission, the validation is not triggered at all. Solution: Move the validation of the analytic distribution to the do_approve method, which gets called both when an expense is approved and when it's auto-approved on submission. opw-6187340 Forward-Port-Of: odoo/odoo#270268
Currently, flexible weekly overtime deducts the raw leave interval duration. ## **Steps to reproduce:** - Install hr_holidays and hr_attendance - Create an employee with flex 40h/week working schedule. - Employee profile>setting>Default Ruleset>Employee schedule Rule and set `If the worked hours on a`: `week`. - Create a public holiday on Monday. - Record daily 8h from Tue to Sat (12 AM to 8 AM). ## **Observed Behavior:** Attendance List View computes "Worked Extra Hours" incorrectly
Original PR description
Currently, flexible weekly overtime deducts the raw leave interval duration. ## **Steps to reproduce:** - Install hr_holidays and hr_attendance - Create an employee with flex 40h/week working…
Currently, flexible weekly overtime deducts the raw leave interval duration. ## **Steps to reproduce:** - Install hr_holidays and hr_attendance - Create an employee with flex 40h/week working schedule. - Employee profile>setting>Default Ruleset>Employee schedule Rule and set `If the worked hours on a`: `week`. - Create a public holiday on Monday. - Record daily 8h from Tue to Sat (12 AM to 8 AM). ## **Observed Behavior:** Attendance List View computes "Worked Extra Hours" incorrectly as 20:30h ## **Expected Behavior:** "Worked Extra Hours" should be computed as 8h ## **Root Cause:** In [_get_daterange_overtime_undertime_intervals_for_quantity_rule](https://github.com/odoo/odoo/blob/53448e5445c8bcbf12126bf27bd675f4b9883d05/addons/hr_attendance/models/hr_attendance_overtime_rule.py#L290-L342), the system manually calculates overtime for flexible employees by deducting `schedule['leave']` durations from the expected working hours at [1]. However, for global public holidays, the system mishandles the timezone conversion within this schedule dictionary. Because public holiday intervals are stored and processed using UTC datetimes before being converted to the employee's local timezone, converting it to the employee's local timezone causes the holiday hours to shift and overlap into the next calendar day. As a result, the `schedule['leave']` calculation incorrectly thinks the employee had time off on normal working days, which throws off the final overtime amount. [1]: http://github.com/odoo/odoo/blob/53448e5445c8bcbf12126bf27bd675f4b9883d05/addons/hr_attendance/models/hr_attendance_overtime_rule.py#L304-L307 ## **Fix:** Replace the manual leave subtraction logic with the existing `_get_expected_hours_from_contract` method. This method naturally handles global public holidays and computes attendance intervals safely across different timezones without shifting hours into the wrong day. **opw-6259328,6284145** Forward-Port-Of: odoo/odoo#274831 Forward-Port-Of: odoo/odoo#269293
Modified `SampleServer._mockWebReadGroup` to intercept `groupby_read_specification`. It now dynamically fetches the requested related fields using `_mockWebSearchReadUnity` and safely injects them into the `__values` payload for each mock group, perfectly mirroring the standard ORM behavior. Task: [6307582](https://www.odoo.com/odoo/project/133/tasks/6307582) Forward-Port-Of: odoo/odoo#272135
Original PR description
Modified `SampleServer._mockWebReadGroup` to intercept `groupby_read_specification`. It now dynamically fetches the requested related fields using `_mockWebSearchReadUnity` and safely injects them into the `__values` payload for each mock group, perfectly mirroring the standard ORM behavior. Task: [6307582](https://www.odoo.com/odoo/project/133/tasks/6307582) Forward-Port-Of: odoo/odoo#272135
**Steps to reproduce:** - Create a product A, tracked by lots - Create a kit product, include a component A - Change the UoM to 0.5 - Go to the PoS, order this kit product - Also order the component A, with a quantity of 2 - Pay for it, ask for an invoice - Go to the created picking - The Demand column is correctly computed and is 0.5 - The Quantity column is wrong and is 2 **Why the fix:** When getting the data from https://github.com/odoo/odoo/blob/e0d84c7fbb270d0d1f82572daefa
Original PR description
**Steps to reproduce:** - Create a product A, tracked by lots - Create a kit product, include a component A - Change the UoM to 0.5 - Go to the PoS, order this kit product - Also order the component…
**Steps to reproduce:** - Create a product A, tracked by lots - Create a kit product, include a component A - Change the UoM to 0.5 - Go to the PoS, order this kit product - Also order the component A, with a quantity of 2 - Pay for it, ask for an invoice - Go to the created picking - The Demand column is correctly computed and is 0.5 - The Quantity column is wrong and is 2 **Why the fix:** When getting the data from https://github.com/odoo/odoo/blob/e0d84c7fbb270d0d1f82572daefa96c2978d3785/addons/point_of_sale/models/stock_picking.py#L283 we always get the component's line, as the move's product is the component, even if it used to be the kit product's move. This is because when exploding a kit's moves, it gets the kit's component as a product instead of keeping the kit product. This was introducing a weird behavior because we took the quantity from the component line, and not from the kit line, meaning the kit would always have the same quantity as the component. We now check if the move is actually a kit product's move, and if it is we adapt the qty to correct one by fetching the correct line's qty, and adapting it with the correct UoM. Changing the line in itself would not work, as the kit itself is not tracked by lots, so we would not enter https://github.com/odoo/odoo/blob/e0d84c7fbb270d0d1f82572daefa96c2978d3785/addons/point_of_sale/models/stock_picking.py#L284 and the move line would not be correctly created. opw-6153000 Forward-Port-Of: odoo/odoo#276098 Forward-Port-Of: odoo/odoo#262551
**Issue** The priority of a purchase order is not propagated to the corresponding picking **Steps to reproduce** - Create a PO for a product - Click on the star (set priority) - Confirm the PO and open the corresponding picking -> The priority is not set on the picking **Cause** The feature was introduced in 19.2 and worked through `_prepare_picking()` (4eb64d15d10a258e2902818304c29681fe268553): https://github.com/odoo/odoo/blob/4eb64d15d10a258e2902818304c29681fe268553/addons/purcha
Original PR description
**Issue** The priority of a purchase order is not propagated to the corresponding picking **Steps to reproduce** - Create a PO for a product - Click on the star (set priority) - Confirm the PO and…
**Issue** The priority of a purchase order is not propagated to the corresponding picking **Steps to reproduce** - Create a PO for a product - Click on the star (set priority) - Confirm the PO and open the corresponding picking -> The priority is not set on the picking **Cause** The feature was introduced in 19.2 and worked through `_prepare_picking()` (4eb64d15d10a258e2902818304c29681fe268553): https://github.com/odoo/odoo/blob/4eb64d15d10a258e2902818304c29681fe268553/addons/purchase_stock/models/purchase_order.py#L401 However a refactor in 19.3 removed that method without preserving the priority propagation (a1fb39eb6ae0d1abc12ab2aaf876b10baed4d7cd). Instead of using `_prepare_picking`, it creates the moves and confirm it: https://github.com/odoo/odoo/blob/a1fb39eb6ae0d1abc12ab2aaf876b10baed4d7cd/addons/purchase_stock/models/purchase_order.py#L387-L388 which will create the picking (if needed): https://github.com/odoo/odoo/blob/9221edd716ac241a301fa25d511fde0edb17b3f4/addons/stock/models/stock_move.py#L1449 https://github.com/odoo/odoo/blob/9221edd716ac241a301fa25d511fde0edb17b3f4/addons/stock/models/stock_move.py#L1476 opw-6275965
Before this commit When a website user had an active cart, opening the pickup location selector from a backend sale order could use the cart's delivery method instead of the one configured on the sale order. Steps to reproduce: 0. Switch to the debug mode 1. Configure 2 delivery methods (A and B) with pickup locations 2. On eCommerce add storable products to the cart and choose the delivery method A 3. In the backend, create a sale order and set the delivery method B 4. Try to set picku
Original PR description
Before this commit When a website user had an active cart, opening the pickup location selector from a backend sale order could use the cart's delivery method instead of the one configured on the sale order. Steps to reproduce: 0. Switch to the debug mode 1. Configure 2 delivery methods (A and B) with pickup locations 2. On eCommerce add storable products to the cart and choose the delivery method A 3. In the backend, create a sale order and set the delivery method B 4. Try to set pickup location and see the traceback This is caused by wrong location selector props validation and by the wrong locations fetching. This commit fixes the props of location selector to match the given ones and get the correct locations for the given delivery method. opw-6267741 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
#### Issue: Opening the MRP planning view could raise a traceback when a maintenance request had a `schedule_end` but no `schedule_date`. `TypeError: '<' not supported between instances of 'NoneType' and 'datetime.datetime'` #### Steps to reproduce: 1. Install maintenance, mrp, and mrp_maintenance. 2. Create a work center. 3. Create a maintenance request linked to that work center. 4. set a `Scheduled end` and Leave `Scheduled Date` empty. 5. Go to MRP > Planning > Work Orders. #
Original PR description
#### Issue: Opening the MRP planning view could raise a traceback when a maintenance request had a `schedule_end` but no `schedule_date`. `TypeError: '<' not supported between instances of 'NoneType'…
#### Issue: Opening the MRP planning view could raise a traceback when a maintenance request had a `schedule_end` but no `schedule_date`. `TypeError: '<' not supported between instances of 'NoneType' and 'datetime.datetime'` #### Steps to reproduce: 1. Install maintenance, mrp, and mrp_maintenance. 2. Create a work center. 3. Create a maintenance request linked to that work center. 4. set a `Scheduled end` and Leave `Scheduled Date` empty. 5. Go to MRP > Planning > Work Orders. #### Cause: `maintenance.request` stores `schedule_end` as a writable field, but no constraint enforces that `schedule_date` and `schedule_end` must be set together. Later, `mrp_maintenance` in `_get_maintenances_intervals` fetches maintenance intervals for the gantt view without filtering null bounds. If a request has `(schedule_date, schedule_end)` = `(False, datetime)`, that interval is passed to `Intervals(...)`, which crashes when comparing `None` with a `datetime`. #### Fix: Add a constraint on `maintenance.request` to require `schedule_date` and `schedule_end` to either both be set or both be empty. Also filter out incomplete intervals in the MRP maintenance gantt query in this enterprise PR: https://github.com/odoo/enterprise/pull/117710 opw-6225772 enterprise PR: https://github.com/odoo/enterprise/pull/117710 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265208
8 changes
Resolved issues and error corrections
The reporting labels "Difference" and "Balance" are confusing because "Difference" tracks system-qualified overtime while "Balance" represents accepted overtime hours. There is also a lack of consistency across views. This commit renames these fields to "Worked Extra Hours" and "Validated Extra Hours" to harmonize the naming everywhere task-6352142 Description of the issue/feature this PR addresses: Confusing and inconsistent naming for extra hours Current behavior before PR: - Rep
Original PR description
The reporting labels "Difference" and "Balance" are confusing because "Difference" tracks system-qualified overtime while "Balance" represents accepted overtime hours. There is also a lack of consistency across views. This commit renames these fields to "Worked Extra Hours" and "Validated Extra Hours" to harmonize the naming everywhere task-6352142 Description of the issue/feature this PR addresses: Confusing and inconsistent naming for extra hours Current behavior before PR: - Reporting uses "Difference" and "Balance". - Views use inconsistent labels. Desired behavior after PR is merged: Labels are consistently named "Worked Extra Hours" and "Validated Extra Hours" everywhere. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275944 Forward-Port-Of: odoo/odoo#273631
### Steps to reproduce 1. Create a invoice with a section and add products under it with values 2. Enable **Hide Composition** on the section. 3. Print the invoice PDF. <table> <tr> <td> <img width="1278" height="425" alt="image" src="https://github.com/user-attachments/assets/969a222a-5e2f-48e2-962d-fc1cf6440619" /> </td> </tr> </table> ### Description When an invoice contains a section and products in it with values and with **Hide Composition** enabled,
Original PR description
### Steps to reproduce 1. Create a invoice with a section and add products under it with values 2. Enable **Hide Composition** on the section. 3. Print the invoice PDF. <table> <tr> <td> <img…
### Steps to reproduce
1. Create a invoice with a section and add products under it with values
2. Enable **Hide Composition** on the section.
3. Print the invoice PDF.
<table>
<tr>
<td>
<img width="1278" height="425" alt="image" src="https://github.com/user-attachments/assets/969a222a-5e2f-48e2-962d-fc1cf6440619" />
</td>
</tr>
</table>
### Description
When an invoice contains a section and products in it with values and with **Hide Composition** enabled, the PDF invoice report incorrectly displays the **Disc.%** column header even though no discount values in that section line.
The report currently computes `display_discount` using `o.invoice_line_ids`:
```xml
<t t-set="display_discount" t-value="any(l.discount for l in o.invoice_line_ids)"/>
```
Since `o.invoice_line_ids` still contains the hidden product lines, `display_discount` evaluates to `True`, causing the **Disc.%** column header to be displayed. However, those product lines are replaced by the section line in the report, so no discount values are shown, resulting in an empty column.
### Current behavior
The **Disc.%** column is displayed, but all its cells are empty.
<table>
<tr>
<td>
<img width="808" height="488" alt="image" src="https://github.com/user-attachments/assets/7d9afee6-fef5-49c8-bc4e-b01caa8b43bd" />
</td>
</tr>
</table>
### Expected behavior
The **Disc.%** column should not be displayed when the reported lines do not contain any discounts.
<table>
<tr>
<td>
<img width="798" height="427" alt="image" src="https://github.com/user-attachments/assets/6ffe7985-a7d0-43f5-8d40-41e700ecbed3" />
</td>
</tr>
</table>
### Solution
Compute `lines_to_report` before evaluating `display_discount` and use it instead:
```xml
<t t-set="lines_to_report" t-value="o._get_move_lines_to_report()"/>
<t t-set="display_discount" t-value="any(l.discount for l in lines_to_report)"/>
```
Forward-Port-Of: odoo/odoo#276003
Forward-Port-Of: odoo/odoo#275793Steps to produce: --- - Install the `sales` module. - Create a product and `enable track inventory.` - Log in as user with only view access rights in products and also have the sales access rights. - Create a sale order containing product and confirm it. Issue: --- - An access error is raised during order confirmation. Root cause: --- - In [commit], to handle inventory tracking, the `qty_available` field was moved to `product.product`. Unlike before, this value is increased or
Original PR description
Steps to produce: --- - Install the `sales` module. - Create a product and `enable track inventory.` - Log in as user with only view access rights in products and also have the sales access rights. -…
Steps to produce: --- - Install the `sales` module. - Create a product and `enable track inventory.` - Log in as user with only view access rights in products and also have the sales access rights. - Create a sale order containing product and confirm it. Issue: --- - An access error is raised during order confirmation. Root cause: --- - In [commit], to handle inventory tracking, the `qty_available` field was moved to `product.product`. Unlike before, this value is increased or decreased depending on the operation performed. - As a consequence, creating or updating a sale order triggers a write to this `qty_available` field on the related product. This write happens under the current user's permissions, so users who only have read access to products (but can create/edit sale orders) hit an `AccessError`, since they lack write access on `product.product`. Solution: --- - Use `sudo()` when accessing the required product quantity information to ensure the operation can be completed without requiring additional product access rights. The same issue also occurs when confirming a purchase order. [commit]: https://github.com/odoo/odoo/commit/ca96992919b11105da44238c3e522f8eec4a740b opw-6290608 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270067
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per
Original PR description
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per the latest Worldline documentation, ensuring payment requests use the correct mapping. Forward-Port-Of: odoo/odoo#275881
Backport the changes from `b9370ea6b70ca3020c73a6940d70ff0cf954f69f` into `mail/convert_inline` to ensure Outlook-compatible image rendering. opw-3776054 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276071 Forward-Port-Of: odoo/odoo#269436
Original PR description
Backport the changes from `b9370ea6b70ca3020c73a6940d70ff0cf954f69f` into `mail/convert_inline` to ensure Outlook-compatible image rendering. opw-3776054 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276071 Forward-Port-Of: odoo/odoo#269436
### Before this PR When importing a FatturaPA XML, Odoo sets the fiscal position on the bill from the partner but does not apply it to the line taxes so a fiscal position that remaps taxes (partial deductibility, reverse charge, split payment) never map the imported lines. ### After this PR the fiscal position is correctly applied ### To reproduce 1. Apply to Italian vendor a fiscal position that maps the 22% purchase tax to a partial-deductibility tax (e.g. "22%" →"22% ind. 50%").
Original PR description
### Before this PR When importing a FatturaPA XML, Odoo sets the fiscal position on the bill from the partner but does not apply it to the line taxes so a fiscal position that remaps taxes (partial deductibility, reverse charge, split payment) never map the imported lines. ### After this PR the fiscal position is correctly applied ### To reproduce 1. Apply to Italian vendor a fiscal position that maps the 22% purchase tax to a partial-deductibility tax (e.g. "22%" →"22% ind. 50%"). 2. Import a FatturaPA XML from that vendor with 22% lines. 3. The bill header shows the fiscal position, but the lines keep the plain 22% tax instead of the mapped one. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275614 Forward-Port-Of: odoo/odoo#274738
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a barcode for the product with the B variant only - Go to the PoS, enter the barcode for the product with the B variant - The price is 1400 instead of 1200 **Why the fix:** The extra price for dynamic variants ordered through the barcode will be counted twice. This is because it is first count
Original PR description
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a…
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a barcode for the product with the B variant only - Go to the PoS, enter the barcode for the product with the B variant - The price is 1400 instead of 1200 **Why the fix:** The extra price for dynamic variants ordered through the barcode will be counted twice. This is because it is first counted in the _scan(code) method when we fetch the product from the models, then counted again when adding the line to the current order. https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/point_of_sale/static/src/app/services/pos_store.js#L1264-L1269 This step is necessary for the usual flow without the barcode as we need to add this extra price, but when using the barcode, the list price of the product we fetch is already 1200, as the extra price is already included when fetching it from the backend. It works for always attributes because we explicitly check that we are not adding the extra price again in the above code, and that the list price already includes the extra price. It also works for the never attributes because values.product_id.product_template_variant_value_ids.length is 0, so the code to update the extra price is never triggered. As we still need to add the extra price for the usual flow, we now just check if we have a code, meaning we added the product through the barcode and that we do not need to add it again, as the list price already accounts for the extra price. opw-6328600 Forward-Port-Of: odoo/odoo#272395
In main data service of this PoS indexedDB is called automatically after records are updated. ```js this.debouncedSynchronizeLocalDataInIndexedDB = debounce( this.synchronizeLocalDataInIndexedDB.bind(this), 300 ); ``` But sometimes, the indexedDB is directly called in the code via `synchronizeLocalDataInIndexedDB` which is not debounced and can lead to race conditions and potential data corruption. Now the `synchronizeLocalDataInIndexedDB` is inside a Mutex to avoid concurr
Original PR description
In main data service of this PoS indexedDB is called automatically after records are updated.
```js
this.debouncedSynchronizeLocalDataInIndexedDB = debounce(
this.synchronizeLocalDataInIndexedDB.bind(this),
300
);
```
But sometimes, the indexedDB is directly called in the code via `synchronizeLocalDataInIndexedDB` which is not debounced and can lead to race conditions and potential data corruption.
Now the `synchronizeLocalDataInIndexedDB` is inside a Mutex to avoid concurrent access to the indexedDB.
The old method is renamed to `_synchronizeLocalDataInIndexedDB` and is now private.
Forward-Port-Of: odoo/odoo#27589213 changes
Resolved issues and error corrections
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per
Original PR description
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per the latest Worldline documentation, ensuring payment requests use the correct mapping. Forward-Port-Of: odoo/odoo#275881
Issue: ---------------------------------------- The units (day, year, etc.) aren't being translated in the Milestones view. Steps to reproduce: ---------------------------------------- - Switch the language to French - Go on an Accrual plan form view - In the milestones view, the units aren't translated Cause: ---------------------------------------- We input the key value of the selections fields `start_type` and `added_value_type`. These values aren't translated. Solution: --
Original PR description
Issue: ---------------------------------------- The units (day, year, etc.) aren't being translated in the Milestones view. Steps to reproduce: ---------------------------------------- - Switch the language to French - Go on an Accrual plan form view - In the milestones view, the units aren't translated Cause: ---------------------------------------- We input the key value of the selections fields `start_type` and `added_value_type`. These values aren't translated. Solution: ---------------------------------------- We create a dictionary with the same keys as the fields and a translated value as values. In the view, we read the values of the dictionary to get the translated units. opw-6367235 Forward-Port-Of: odoo/odoo#275575
### Before this PR When importing a FatturaPA XML, Odoo sets the fiscal position on the bill from the partner but does not apply it to the line taxes so a fiscal position that remaps taxes (partial deductibility, reverse charge, split payment) never map the imported lines. ### After this PR the fiscal position is correctly applied ### To reproduce 1. Apply to Italian vendor a fiscal position that maps the 22% purchase tax to a partial-deductibility tax (e.g. "22%" →"22% ind. 50%").
Original PR description
### Before this PR When importing a FatturaPA XML, Odoo sets the fiscal position on the bill from the partner but does not apply it to the line taxes so a fiscal position that remaps taxes (partial deductibility, reverse charge, split payment) never map the imported lines. ### After this PR the fiscal position is correctly applied ### To reproduce 1. Apply to Italian vendor a fiscal position that maps the 22% purchase tax to a partial-deductibility tax (e.g. "22%" →"22% ind. 50%"). 2. Import a FatturaPA XML from that vendor with 22% lines. 3. The bill header shows the fiscal position, but the lines keep the plain 22% tax instead of the mapped one. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275614 Forward-Port-Of: odoo/odoo#274738
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a barcode for the product with the B variant only - Go to the PoS, enter the barcode for the product with the B variant - The price is 1400 instead of 1200 **Why the fix:** The extra price for dynamic variants ordered through the barcode will be counted twice. This is because it is first count
Original PR description
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a…
**Steps to reproduce:** - Create a dynamic variant with 2 values, A and B - B should have an extra price of 200 - Create a product which has those two variants, with a price of 1000 - Set up a barcode for the product with the B variant only - Go to the PoS, enter the barcode for the product with the B variant - The price is 1400 instead of 1200 **Why the fix:** The extra price for dynamic variants ordered through the barcode will be counted twice. This is because it is first counted in the _scan(code) method when we fetch the product from the models, then counted again when adding the line to the current order. https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/point_of_sale/static/src/app/services/pos_store.js#L1264-L1269 This step is necessary for the usual flow without the barcode as we need to add this extra price, but when using the barcode, the list price of the product we fetch is already 1200, as the extra price is already included when fetching it from the backend. It works for always attributes because we explicitly check that we are not adding the extra price again in the above code, and that the list price already includes the extra price. It also works for the never attributes because values.product_id.product_template_variant_value_ids.length is 0, so the code to update the extra price is never triggered. As we still need to add the extra price for the usual flow, we now just check if we have a code, meaning we added the product through the barcode and that we do not need to add it again, as the list price already accounts for the extra price. opw-6328600 Forward-Port-Of: odoo/odoo#272395
When creating or editing a portal billing address, the Company Name field was pre-filled from `commercial_company_name`. For contacts without a parent company, the commercial partner is the contact itself, so the contact name was shown as the company name. Use the partner's actual parent company name instead, so the field stays empty when no company is linked while still showing the existing parent company when one exists. see: https://github.com/odoo/odoo/commit/18a59cf26f2d9400f76deec483
Original PR description
When creating or editing a portal billing address, the Company Name field was pre-filled from `commercial_company_name`. For contacts without a parent company, the commercial partner is the contact itself, so the contact name was shown as the company name. Use the partner's actual parent company name instead, so the field stays empty when no company is linked while still showing the existing parent company when one exists. see: https://github.com/odoo/odoo/commit/18a59cf26f2d9400f76deec483f6ddab87da0c55 Task-6372638
Click Working Files menu, then open studio. Before this commit there was an error, because the accounting code tried to check access rights on an new record (no id) After this commit there is no crash. runbot-error-941248 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
Click Working Files menu, then open studio. Before this commit there was an error, because the accounting code tried to check access rights on an new record (no id) After this commit there is no crash. runbot-error-941248 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
Before this commit, when making a test print from the POS backend, the following issues would occur: - Very slow response - Missing cut, and extra 'A' character is printed This commit fixes both these issues. The slow response is avoided by not performing the network tests when they aren't used in the printed receipt. The cut issue is solved by appending a newline character to the message. task-6391141 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/s
Original PR description
Before this commit, when making a test print from the POS backend, the following issues would occur: - Very slow response - Missing cut, and extra 'A' character is printed This commit fixes both these issues. The slow response is avoided by not performing the network tests when they aren't used in the printed receipt. The cut issue is solved by appending a newline character to the message. task-6391141 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Animated GIFs applied with an image shape freeze on Firefox and Safari when the shape's SVG is otherwise static. A dummy `<animateMotion dur="1ms" repeatCount="indefinite"/>` child on the <image> element keeps the animation running so the GIF plays. This hack was introduced in [1] but was missing from most shapes. This commit adds it to every <image> element that lacked it so any shape can be used with a GIF. task-5967171 [1]: https://github.com/odoo/odoo/commit/144e5ef799060da860a5fb1f
Original PR description
Animated GIFs applied with an image shape freeze on Firefox and Safari when the shape's SVG is otherwise static. A dummy `<animateMotion dur="1ms" repeatCount="indefinite"/>` child on the <image> element keeps the animation running so the GIF plays. This hack was introduced in [1] but was missing from most shapes. This commit adds it to every <image> element that lacked it so any shape can be used with a GIF. task-5967171 [1]: https://github.com/odoo/odoo/commit/144e5ef799060da860a5fb1fbe0fd009919afe79 Forward-Port-Of: odoo/odoo#275259
Loading a certificate could raise an unhandled exception instead of failing gracefully. Clearing the content, uploading a bundle with a corrupted certificate block, or handling certificates with unsupported signature algorithms or malformed extensions all could end up in a traceback. Guard those paths to ensure loading errors are handled. opw-6370529 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I
Original PR description
Loading a certificate could raise an unhandled exception instead of failing gracefully. Clearing the content, uploading a bundle with a corrupted certificate block, or handling certificates with unsupported signature algorithms or malformed extensions all could end up in a traceback. Guard those paths to ensure loading errors are handled. opw-6370529 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#275325
Previously: 1.`purchase_cdnur_regular` section was assigned to credit/debit notes of: - import of goods - import of services without RCM However: - import of goods should be handled through bill of supply - import of services without RCM is not possible Therefore, with this commit, such journal items are moved to `purchase_out_of_scope`. 2.`purcha
Original PR description
Previously:
1.`purchase_cdnur_regular` section was assigned to credit/debit notes of:
- import of goods
- import of services without RCM However:
- import of goods should be handled through bill of supply
- import of services without RCM is not possible Therefore, with this commit, such journal items are moved to `purchase_out_of_scope`.
2.`purchase_imp_services` section included import of services both with and
without RCM. Since import of services without RCM is not possible, those
journal items are now moved to `purchase_out_of_scope`.
3.Credit/debit notes of import of services with RCM were previously moved to
`purchase_out_of_scope`, which was incorrect. With this commit, they are now
correctly moved to `purchase_imp_services`.
task-6330737
Forward-Port-Of: odoo/odoo#272453Problem: When posting expenses, if the expense domain is set as mandatory in any of the analytic plans, users can still submit expenses without entering an analytic distribution. This only happens when the expense is auto-approved on submission, which happens when the expense's employee is also the expense's manager or when the employee doesn't have an expense manager. Steps to reproduce: 1. Create an analytic plan with optional default applicability 2. Add an applicability rule with the d
Original PR description
Problem: When posting expenses, if the expense domain is set as mandatory in any of the analytic plans, users can still submit expenses without entering an analytic distribution. This only happens…
Problem: When posting expenses, if the expense domain is set as mandatory in any of the analytic plans, users can still submit expenses without entering an analytic distribution. This only happens when the expense is auto-approved on submission, which happens when the expense's employee is also the expense's manager or when the employee doesn't have an expense manager. Steps to reproduce: 1. Create an analytic plan with optional default applicability 2. Add an applicability rule with the domain set as Expense and set its applicability as mandatory. 3. Create a new expense 4. Set the expense's manager the same as the expense's employee. 5. Don't enter any analytic distribution. 6. Submit the expense 7. Notice how the expense is submitted and auto-approved without any error, even though no analytic distribution is entered and the analytic plan has a mandatory rule for expenses. Cause: The validation of the analytic distribution was only triggered on the approval of the expense, but when the expense is auto-approved on submission, the validation is not triggered at all. Solution: Move the validation of the analytic distribution to the do_approve method, which gets called both when an expense is approved and when it's auto-approved on submission. opw-6187340 Forward-Port-Of: odoo/odoo#270268
#### Issue: When creating a reordering rule for a shared manufactured product in a multi-company database, saving the rule may raise an `AccessError` on `mrp.bom`. The orderpoint is still created, but the user sees a record-rule error if the product also has BoMs in companies that are not currently active. #### Example: A product is shared across multiple companies, and each company has its own BoM for that product. In the reproduced case, the active company has the correct variant Bo
Original PR description
#### Issue: When creating a reordering rule for a shared manufactured product in a multi-company database, saving the rule may raise an `AccessError` on `mrp.bom`. The orderpoint is still created,…
#### Issue: When creating a reordering rule for a shared manufactured product in a multi-company database, saving the rule may raise an `AccessError` on `mrp.bom`. The orderpoint is still created, but the user sees a record-rule error if the product also has BoMs in companies that are not currently active. #### Example: A product is shared across multiple companies, and each company has its own BoM for that product. In the reproduced case, the active company has the correct variant BoM. However, the orderpoint computation first checks the broader product-template BoM relation, which may include BoMs from the other companies. As a result, Odoo can try to access a BoM from another company while the user is only working in the active company, causing an access error. #### Steps to reproduce: Use a multi-company database with MRP enabled. Create or use a shared product available to multiple companies. Create BoMs for that product in more than one company. Set the active company to the company where the reordering rule should be created. Create a reordering rule for the product. Save the reordering rule. Note the AccessError related to mrp.bom. #### Root Cause: The MRP orderpoint computations read `product_id.bom_ids` directly. This is the product-template BoM relation and can include BoMs from other companies for a shared product. Reading fields on those BoMs, such as `product_uom_id`, can hit the standard `mrp.bom` multi-company record rule. #### Fix: Prefer `product_id.variant_bom_ids` before falling back to `product_id.bom_ids` in the affected orderpoint computations. This avoids reading template-level BoMs from other companies when the product has a variant-specific BoM for the current reordering-rule use case. opw-6253743 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267411
**Steps to reproduce:** - Install Contacts app - Open any record - Go to the chatter - Create an activity with a description - Duplicate the tab - Go back to the initial tab - Description doesn't appear anymore - Refreshing shows it but will remove it from the other tab **Issue:** Behavior comes from the broadcasting of activity changes between tabs `new browser.BroadcastChannel("mail.activity.channel");`. Computed fields are not recomputed on the receiver side after value inserti
Original PR description
**Steps to reproduce:** - Install Contacts app - Open any record - Go to the chatter - Create an activity with a description - Duplicate the tab - Go back to the initial tab - Description doesn't…
**Steps to reproduce:**
- Install Contacts app
- Open any record
- Go to the chatter
- Create an activity with a description
- Duplicate the tab
- Go back to the initial tab
- Description doesn't appear anymore
- Refreshing shows it but will remove it from the other tab
**Issue:**
Behavior comes from the broadcasting of activity changes between tabs `new browser.BroadcastChannel("mail.activity.channel");`.
Computed fields are not recomputed on the receiver side after value insertion in `_onActivityBroadcastChannelMessage` (also related components are not (re)mounted, e.g. when a new activity is created the other tab doesn't show it without a refresh).
This means that `isNoteEmpty` keeps its default value `true` (added by `this.toData()`) and the `note` stays hidden here [1]:
```xml
<div t-if="!props.activity.isNoteEmpty" class="o-mail-Activity-note text-break" t-out="props.activity.note"/>
```
**Fix:**
Remove computed fields in activity `serialize` before broadcasting them to ensure they don't force the default value.
(note installing `calendar` in 19.3+ removes this issue due to [2] which overrides the condition on `isNoteEmpty`)
[1] https://github.com/odoo/odoo/commit/eb9f0658c3da1a9fef69f1cc1117c2d44f9d61b1
[2] https://github.com/odoo/odoo/commit/44e2c2c5ca07849fd8964140f3ca61122c47f0c6
opw-6247412
Forward-Port-Of: odoo/odoo#276032
Forward-Port-Of: odoo/odoo#2755288 changes
Resolved issues and error corrections
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per
Original PR description
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per the latest Worldline documentation, ensuring payment requests use the correct mapping. Forward-Port-Of: odoo/odoo#275881
*: website, website_sale `forEach` is a synchronous operation, so it doesn't support promises. We refactor its usage to use `for` loops. task-4794299 Forward-Port-Of: odoo/odoo#275993 Forward-Port-Of: odoo/odoo#275262
Original PR description
*: website, website_sale `forEach` is a synchronous operation, so it doesn't support promises. We refactor its usage to use `for` loops. task-4794299 Forward-Port-Of: odoo/odoo#275993 Forward-Port-Of: odoo/odoo#275262
# How to reproduce - Set an employee's work schedule to flexible 40hrs/week with 8hrs of work per day - Create a new attendance for that employee that : - Is the very first attendance of that employee - Is not on a monday (e.g. a Friday) - Create a second attendance for that employee that : - Is atleast one week after the first attendance - Is one of the two days of the week before the day of the week of the first attendance (e.g. a Wednesday or a Thursday) - Go to the settings, upda
Original PR description
# How to reproduce - Set an employee's work schedule to flexible 40hrs/week with 8hrs of work per day - Create a new attendance for that employee that : - Is the very first attendance of that…
# How to reproduce - Set an employee's work schedule to flexible 40hrs/week with 8hrs of work per day - Create a new attendance for that employee that : - Is the very first attendance of that employee - Is not on a monday (e.g. a Friday) - Create a second attendance for that employee that : - Is atleast one week after the first attendance - Is one of the two days of the week before the day of the week of the first attendance (e.g. a Wednesday or a Thursday) - Go to the settings, update the value for "Tolerance Time In Favor Of Company" and save - Come back to the second attendance # The problem The Extra Hours have changed and are equal to the worked time # Cause When we update the tolerance time, we recompute the overtime of every attendance of every employee. In this recomputation, we compute the `expected_attendance` of every employee and transforms them into a dict of the expected working time for each day : https://github.com/odoo/odoo/blob/281658e86971687656f3235ac1ff8afcb52f2908/addons/hr_attendance/models/hr_attendance.py#L349-L356 Later, if an attendace of the employee was not in their expected working days, then we consider that all hours worked were overtime : https://github.com/odoo/odoo/blob/281658e86971687656f3235ac1ff8afcb52f2908/addons/hr_attendance/models/hr_attendance.py#L381-L384 This makes sense but our issue is that days in the middle of the week are considered "time-off" when they should not. That's because for flexible working schedules, we emulate the expected working hours based on the total hours per week and the maximum hours per day : https://github.com/odoo/odoo/blob/281658e86971687656f3235ac1ff8afcb52f2908/addons/resource/models/resource_calendar.py#L384-L386 For every "week", we start from the first day and continue forward by greedily using all hours for that day until there is no more hours for the week. The problem is that since this PR, we don't start "weeks" on mondays, but on the `start_datime` : https://github.com/odoo/odoo/commit/af36e73108cef4326f6125c3af491b07a51534fe And in our case, `start_datetime` is the very first attendance day of the employee : https://github.com/odoo/odoo/blob/281658e86971687656f3235ac1ff8afcb52f2908/addons/hr_attendance/models/hr_attendance.py#L344 So our expected working days are desynched with the days of the week # Proposed solution We partly revert https://github.com/odoo/odoo/commit/af36e73108cef4326f6125c3af491b07a51534fe opw-6289079 Forward-Port-Of: odoo/odoo#269820
## Steps to reproduce: - Install sale_timesheet - Create a timesheet with a Sale order item linked to it - Change the sale order item on that timesheet - Change the project linked to the timesheet to a non-billable project - Notice the sale order item still linked to the timesheet ## Cause: When computing the so_line we filter out the records that has is_so_line_edited as true, so when changing the SOL before changing the project we don't reset so_line field when setting a non-bill
Original PR description
## Steps to reproduce: - Install sale_timesheet - Create a timesheet with a Sale order item linked to it - Change the sale order item on that timesheet - Change the project linked to the timesheet to a non-billable project - Notice the sale order item still linked to the timesheet ## Cause: When computing the so_line we filter out the records that has is_so_line_edited as true, so when changing the SOL before changing the project we don't reset so_line field when setting a non-billable project. ## Fix: We reset the is_so_line_edited field to false when changing the project to a non-billable one. opw-6311549 Forward-Port-Of: odoo/odoo#275919
Animated GIFs applied with an image shape freeze on Firefox and Safari when the shape's SVG is otherwise static. A dummy `<animateMotion dur="1ms" repeatCount="indefinite"/>` child on the <image> element keeps the animation running so the GIF plays. This hack was introduced in [1] but was missing from most shapes. This commit adds it to every <image> element that lacked it so any shape can be used with a GIF. task-5967171 [1]: https://github.com/odoo/odoo/commit/144e5ef799060da860a5fb1f
Original PR description
Animated GIFs applied with an image shape freeze on Firefox and Safari when the shape's SVG is otherwise static. A dummy `<animateMotion dur="1ms" repeatCount="indefinite"/>` child on the <image> element keeps the animation running so the GIF plays. This hack was introduced in [1] but was missing from most shapes. This commit adds it to every <image> element that lacked it so any shape can be used with a GIF. task-5967171 [1]: https://github.com/odoo/odoo/commit/144e5ef799060da860a5fb1fbe0fd009919afe79 Forward-Port-Of: odoo/odoo#275259
Problem: After updating a file name, the link popover still shows the original file name. Cause: The link popover always displays the attachment name instead of the current link content. Solution: Use the link content as the popover title so it reflects the updated file title. Steps to reproduce: - Go to To-Do → Create New. - Upload a file. - Change its title. - Observe that the title shown in the link popover still uses the original file name. task-6213840 --- I confirm I
Original PR description
Problem: After updating a file name, the link popover still shows the original file name. Cause: The link popover always displays the attachment name instead of the current link content. Solution: Use the link content as the popover title so it reflects the updated file title. Steps to reproduce: - Go to To-Do → Create New. - Upload a file. - Change its title. - Observe that the title shown in the link popover still uses the original file name. task-6213840 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270817 Forward-Port-Of: odoo/odoo#264127
Only admin users have read access to the `payment.provider` model. Opening the PoS payment method form as a non-admin would raise an access error because the `online_payment_provider_ids` many2many field tries to fetch `payment.provider` records on form load. Grant read-only access on `payment.provider` to `group_pos_manager` so POS admins can use the field. Restrict the field's group in the form view to `point_of_sale.group_pos_manager,base.group_system` so it is not rendered for users witho
Original PR description
Only admin users have read access to the `payment.provider` model. Opening the PoS payment method form as a non-admin would raise an access error because the `online_payment_provider_ids` many2many field tries to fetch `payment.provider` records on form load. Grant read-only access on `payment.provider` to `group_pos_manager` so POS admins can use the field. Restrict the field's group in the form view to `point_of_sale.group_pos_manager,base.group_system` so it is not rendered for users without either role. opw-6208656 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265573 Forward-Port-Of: odoo/odoo#263837
On touch devices (smartphones, tablets), the in-browser notification sound plays through the media audio channel, which is not affected by the device's silent mode. This causes unexpected sound playback when the device is set to silent. Suppress _playSound() on devices with maxTouchPoints > 1 (touch/mobile). Push notifications handle alerts on mobile and properly respect the device's silent mode. The side effect is that also laptops with touch screen are affected and need to use web push n
Original PR description
On touch devices (smartphones, tablets), the in-browser notification sound plays through the media audio channel, which is not affected by the device's silent mode. This causes unexpected sound playback when the device is set to silent. Suppress _playSound() on devices with maxTouchPoints > 1 (touch/mobile). Push notifications handle alerts on mobile and properly respect the device's silent mode. The side effect is that also laptops with touch screen are affected and need to use web push notifications in order to get notification sounds played. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275797
27 changes
Resolved issues and error corrections
This fixes an installation blocker for the Peruvian electronic invoicing localization caused by a typo in an internal database query. Businesses using or enabling Peru localization can install the module successfully again.
Original PR description
A refactor/cleanup [1] introduced a buggy SQL query preventing the Peruvian localization install. [1]: https://github.com/odoo/enterprise/commit/e182608f13c6eefae11339bba24e80497c2b3903#diff-deaab3f5010fea8defc8af11dc186415ecc9079d86d307537b09222dda7ab751R119 task-none
This update fixes issues in the social CRM and social feed experience where post menus could appear empty, feed refreshes could fail due to timeouts, and LinkedIn image uploads could error. The changes make day-to-day social media management more reliable and reduce interruptions for users working with social posts and leads.
Original PR description
Bug 1 === Since b75755ea8ac65ce5ce973412e3c4194fa1bd6fd3 , the menu on the stream post could be visible but empty. The reason is that we checked for `this.isConvertibleToLead` instead of `this.isConvertibleToLead()`. We take advantage of this bug fix to correctly overwrite the condition without replacing the entire button (which can break other module overwriting the same element). Bug 2 === Sometimes, when refreshing the feed view, an error occurs because the request timeout. To fix it, we increase the timeout when doing requests in batch. Bug 3 === When uploading an image in LinkedIn, an error happens. The reason is that `LocalBinaryFile` is now returned when reading Binary field, and in the requests API, the `data` arguments expect the bytes. (for other media, we upload the image with `file` argument). Task-6254983 Forward-Port-Of: odoo/enterprise#123949 Forward-Port-Of: odoo/enterprise#118329
Subscription product pages now load correctly when a discount is configured directly on a recurring plan without a pricelist. This prevents website errors during price calculation and ensures customers see the intended discounted recurring price.
Original PR description
**Problem:** On the website, a subscription product page returns a 500 error when a discount is set directly on the recurring plan (a time-based pricing rule with a plan but no pricelist). **Steps to…
**Problem:** On the website, a subscription product page returns a 500 error when a discount is set directly on the recurring plan (a time-based pricing rule with a plan but no pricelist). **Steps to reproduce:** 1. Create a subscription product with a recurring plan. 2. Add a recurring price rule for that plan with no pricelist, set as a percentage discount (base = sales price). 3. Open the product page on the website. **Current behavior:** The page fails with a 500: Internal Server Error during price computation. **Expected behavior:** The page loads and shows the discounted recurring price. **Cause of the issue:** For a recurring price rule based on the sales price, `_compute_base_price` looks up "the no-pricelist rule for the plan" to use as its base, via `_get_applicable_rules_domain(plan_id=...)`. When the discount is set directly on the plan, the rule being computed has no pricelist itself, so that search returns the very same rule and calls `_compute_price` on it again, leading to infinite recursion. **Fix:** Excluding the rule itself from the base-rule lookup lets a no-pricelist plan rule resolve its base from the product's sales price (the super() fallback) instead of re-entering its own computation. A rule applied through a pricelist is unaffected, since its no-pricelist base rule is a different record. opw-6306105 Forward-Port-Of: odoo/enterprise#121466
Fixed an issue where outbound FedEx shipment labels could lose their reference field when return labels were enabled. This helps businesses keep the expected shipment reference visible on original delivery labels while still supporting return labels.
Original PR description
Issue ----- When setting the delivery method to create return labels aswell, the reference (`REF`) field is not present on the original outbound shipment. <img width="438" height="148" alt="image" src="https://github.com/user-attachments/assets/42acce7b-6177-4f8f-81d3-ad6dfd3e4bb2" /> Steps to reproduce ----- - Setup Fedex - Enable returns - Create a product (set weight) - Create a delivery for the product - Set carrier as Fedex - Validate delivery - Open the label > REF field is empty Cause ----- Fedex doesn't include references on the label of returns. When the option for returns is enabled, the outbound shipment is marked as a "Courtesy return". It doesn't make sense to specify a return reason on the original shipment. Expected outcome (after fix) ---- <img width="428" height="146" alt="image" src="https://github.com/user-attachments/assets/0d22e147-da90-4aa4-b3ca-2d996c7cc147" /> ----- Ticket: opw-6101620 Forward-Port-Of: odoo/enterprise#118659
Fixed a conflict that caused Obox quality-control cameras to stop working after the IoT module was installed. Users can continue taking required quality-check photos without seeing a false camera-not-found error, and irrelevant IoT controls are hidden when no IoT device is configured.
Original PR description
Steps to reproduce: - Install `obox_quality_control` but do not install `iot`. - Configure a quality check to take a picture with an Obox camera. - Validate a receipt an confirm the camera works as expected. - Now install the `iot` module, and try to take a picture again. **Expected behaviour:** The camera still works as expected. **Actual behaviour:** There is a 'Camera not found' error. This issue is caused by both the Obox and IoT quality modules adding an `identifier` field to the quality control wizard. The fix is simply to use a different name for the Obox field. In addition, we now hide the IoT button in the wizard if the IoT device is not set. task-6329066 Forward-Port-Of: odoo/enterprise#122490
Fixes an installation and upgrade failure in the Peru electronic invoicing module that could affect databases with existing journal entries. This helps ensure updates complete successfully and required invoice data is filled in correctly.
Original PR description
### Description Installing or upgrading `l10n_pe_edi` aborts with a `psycopg2.errors.SyntaxError` whenever `account_move` already contains rows: ``` psycopg2.errors.SyntaxError: syntax error at or…
### Description
Installing or upgrading `l10n_pe_edi` aborts with a `psycopg2.errors.SyntaxError` whenever `account_move` already contains rows:
```
psycopg2.errors.SyntaxError: syntax error at or near "AND"
LINE 9: AND l10n_pe_edi_operation_type IS NULL
```
### Root cause
The `init_storage` SQL that backfills `l10n_pe_edi_operation_type` (added in e182608f13c6 `[REF] *: use init_storage`) closes the `WHERE` clause with a stray semicolon right after the country condition:
```sql
WHERE res_company.id = account_move.company_id
AND move_type IN ('out_invoice', 'out_refund')
AND res_country.code = 'PE'; -- stray ';' ends the UPDATE
AND l10n_pe_edi_operation_type IS NULL -- parsed as a new statement -> syntax error
```
The semicolon terminates the `UPDATE` early, so `AND l10n_pe_edi_operation_type IS NULL` is parsed as a separate statement starting with `AND`.
`init_storage` only runs when the table already has rows (`_init_column_data` in `odoo/orm/fields.py` skips empty tables), which is why the crash surfaces on databases that already contain journal entries — e.g. runbot `*-all` builds, or `button_immediate_install` over a populated database.
### Fix
Remove the stray semicolon so the NULL guard stays part of the `WHERE` clause.
### Validation
Reproduced and verified on `master` (community + enterprise), with a row present in `account_move`:
- **Before:** `-u l10n_pe_edi` fails with `syntax error at or near "AND"` at `LINE 9`.
- **After:** the module installs/updates cleanly and the column is backfilled without error.Payroll runs now correctly identify when expected payslips are missing. This ensures payroll teams receive the right warning and can address gaps before processing payroll.
Original PR description
The missing payslip in a payrun warning wasn't triggered correctly because we were filtering on the schedule pay of the payrun and this field was removed in a previous PR. task-6329134 Forward-Port-Of: odoo/enterprise#121641
Sales commission plans now reject salesperson start dates that fall outside the plan's effective period. This prevents invalid commission setup and helps ensure salespeople are assigned only within eligible plan dates.
Original PR description
Version: 18.0 Steps to reproduce: - open sale commission plans and create a new plan with an effective period - go to the salesperson tab and add a salesperson - set the salesperson from date after the plan end date issue: salesperson period start date was accepted even if it was set after the plan end date fix: added validation to raise an error when the salesperson start date falls outside the plan effective period task id: 6241188 Forward-Port-Of: odoo/enterprise#122870 Forward-Port-Of: odoo/enterprise#118289
Twitter replies are now blocked in Odoo when the account is not allowed to respond, such as when the tweet does not mention the account or quote one of its tweets. This prevents failed or inappropriate automated replies and helps avoid unwanted outreach to Twitter users.
Original PR description
Purpose ======= To prevent LLM from spamming Twitter users, Twitter does not allow to reply to a tweet if we are not mentioned in it, or if the tweet does not quote one of our tweet. For that reason, we disable the reply button when needed. Task-5964524
Canadian EFT batch payment exports now use each payment's ID as the Item Trace Number instead of filling it with zeros. This helps ensure files comply with CPA-005 banking rules and avoids payment rejections by Canadian financial institutions.
Original PR description
Issue: The Item Trace Number according to CPA-005 standard should be a nonzero sequence that serves as unique reference ID for payments. Currently, Odoo sets the Item Trace Number of all payments as…
Issue: The Item Trace Number according to CPA-005 standard should be a nonzero sequence that serves as unique reference ID for payments. Currently, Odoo sets the Item Trace Number of all payments as a zero-filled sequence According to CPA-005 standards on the Item Trace Number: "The data elements (b), (c) and (d) each must be greater than zero or the TRANSACTION WILL BE REJECTED" (page 36). https://www.payments.ca/sites/default/files/standard005eng.pdf Steps to reproduce: 1. Install the module l10n_ca_payment_cpa005 2. Go into "CA Company" 3. In the configuration for "CA Company", add something to the fields "Short Name used in Canadian EFT" and "Company ID" i.e. "CCC" 4. Set all the fields in the "Canadian EFT/CPA Configuration" section of the bank journal 5. Set the bank record on the bank journal. Set the field "Financial Institution ID Number" field of the "Account Number" record of the bank journal to any numerical sequence 6. Create a bank account on "Azure Interior" and make sure to check the field to trust the bank account that you created (otherwise there will be an error) 7. Create two payments with the vendor of "Azure Interior" using the payment method of "Canadian EFT" 8. Create a batch payment for both payments created 9. Validate the batch payment and the export file should show up in the chatter 10. Note that in the export file, the Item Trace Number for each payment is set to be all zeros, whereas it should be a nonzero identification sequence Solution: Set the Item Trace Number to be the payment's id opw-6323432 Forward-Port-Of: odoo/enterprise#124016 Forward-Port-Of: odoo/enterprise#123633
The timesheet assistant now captures time spent in Odoo applications even when the activity cannot be linked to a specific project, task, or ticket. This helps users get more complete time suggestions, with these activities shown as separate key entries for easier review.
Original PR description
This PR adds support for tracking time spent in the Odoo apps in the assistant, for when we can't trace URLs to a project/task/ticket. The activities detected this way are marked as key events, such that each appears as an individual line in the assistant suggestions. With this, most of the time users spend working in their Odoo database should be reflected in the assistant suggestions. Task-6250449 Forward-Port-Of: odoo/enterprise#123147 Forward-Port-Of: odoo/enterprise#119096
The database authentication module was added to the translation workflow so translators can provide localized text. The update also corrects wording mistakes and tidies an internal error check, improving clarity with minimal user impact.
Original PR description
The aim of this commit is to allow the translator to work on this module translation and fix a typo that was made. Task-id: None Forward-Port-Of: odoo/enterprise#124038
Printing an appraisal form from the action menu now waits briefly so the menu can close first. This prevents the dropdown from appearing on the printed document, giving users a cleaner and more professional printout.
Original PR description
When printing the appraisal form from the action (cog) menu, the drop down menu itself was incorrectly showing up in the printed document. This happened because the browser started printing immediately before the menu had time to close. By adding a small delay before triggering the print action, the menu now has time to completely close, so it no longer appears in the final print. task-6369240 Forward-Port-Of: odoo/enterprise#123242
This update corrects a database query issue in the Peru electronic invoicing module. It helps prevent errors when processing accounting documents, improving reliability for affected users.
This update improves manufacturing work order planning by showing planned work orders by default and aligning shop floor card options with company settings. It also corrects engineering change cost calculations so bill of materials cost differences better reflect real operation cost changes.
Original PR description
Forward-Port-Of: odoo/enterprise#122639
Fixes an issue where the cursor could jump backwards while users typed in Studio's XML editor. The editor now keeps cursor position reliably per editing session, making report and view editing smoother and less disruptive.
Original PR description
Steps to reproduce the issue: -> Open studio -> Edit any view -> Edit xml => Cursor moves backwards when typing Some components inside of the report editor were managing the cursor position based on the document manually. Rendering timings could cause the cursor to move while typing. This commit internalizes the cursor position in the CodeEditor and keep track of them based on the sessionsId, making sure that the cursor position is always correct and only changing when switching between sessions while also making the component API simpler. Community: https://github.com/odoo/odoo/pull/274681 Forward-Port-Of: odoo/enterprise#123244
This change updates an accounting reports screen so it continues to work with the latest underlying interface framework. It prevents a compatibility issue that could affect the display or behavior of the account return check kanban view.
Original PR description
The previous code worked because owl was too permissive.
Mexican payroll payslip forms no longer crash when users add Daily Salary or Integration Factor fields with Odoo Studio. This helps payroll teams review salary-related calculations safely, including while creating off-cycle payslips before an employee is selected.
Original PR description
Users frequently use Odoo Studio to display the Daily Salary (`l10n_mx_daily_salary`) and Integration Factor (`l10n_mx_integration_factor`) fields on the payslip form to verify salary rule…
Users frequently use Odoo Studio to display the Daily Salary (`l10n_mx_daily_salary`) and Integration Factor (`l10n_mx_integration_factor`) fields on the payslip form to verify salary rule computations. However, doing so raises a traceback immediately upon closing the Studio editor, as well as when attempting to create a new Off-Cycle payslip.
### Steps to reproduce:
* Install `l10n_mx_hr_payroll` and `web_studio`.
* Switch to "INNOVACION VALOR Y DESARROLLO SA SA" company.
* Go to Payroll > Payslips > Payslips and create a "New Off-Cycle"
* Use the Studio editor to add `l10n_mx_daily_salary` or `l10n_mx_integration_factor` fields.
* Close the Studio editor.
### Current behavior:
A traceback is raised depending on the field added
#### For the Daily Salary field:
```py
File "/Users/ivgm/odev/worktrees/19.0/enterprise/l10n_mx_hr_payroll/models/hr_payslip.py", line 21, in _compute_daily_salary
payslip.l10n_mx_daily_salary = payslip.version_id.wage / payslip._rule_parameter('l10n_mx_schedule_table')[payslip.version_id.schedule_pay]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: False
```
#### For the Integration Factor field:
```py
File "/Users/ivgm/odev/worktrees/19.0/enterprise/l10n_mx_hr_payroll/models/hr_payslip.py", line 33, in _compute_integration_factor
payslip.employee_id.with_context(before_date=payslip.date_from)._get_first_contract_date()
File "/Users/ivgm/odev/worktrees/19.0/odoo/addons/hr/models/hr_employee.py", line 493, in _get_first_contract_date
versions = self._get_first_versions_filtered(no_gap=no_gap).filtered(lambda x: x.contract_date_start)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ivgm/odev/worktrees/19.0/odoo/addons/hr/models/hr_employee.py", line 461, in _get_first_versions_filtered
self.ensure_one()
File "/Users/ivgm/odev/worktrees/19.0/odoo/odoo/orm/models.py", line 5942, in ensure_one
raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: hr.employee()
```
### Expected behavior:
No error is raised, and the fields are correctly displayed on the form view.
### Solution:
* Add Guard Clause: When creating a "New Off-Cycle" payslip, `payslip.version_id` is not initially set because no employee has been selected yet. Added a condition to check if `version_id` exists before computing the values to prevent the traceback.
* View Update: Since displaying these fields is a highly requested feature for traceability, they have now been added to the form view.
target: 19.0
task-6267003
Forward-Port-Of: odoo/enterprise#121718The attendance Gantt view now hides empty parentheses in progress bar labels when there is no extra information to show. This removes confusing visual clutter and makes attendance planning information easier to read.
Original PR description
The label should not display empty parenthesis if there is no extra info to display task-6391439
Point of Sale receipts will no longer include the separate terminal receipt generated by Worldline payments. This keeps customer receipts cleaner and avoids redundant payment information being printed or shown.
Original PR description
This PR removes the terminal receipt from Worldline we are currently inserting in the Point Of Sale receipt We don't adapt the driver code to get the receipt as we cannot change C method prototypes task-6373975 Forward-Port-Of: odoo/enterprise#123770
The payroll payrun chatter panel and button are now limited to the correct payrun screens. This prevents confusing extra options from appearing in unrelated payroll views, giving users a cleaner and more predictable experience.
Original PR description
The global `PayRunChatterService` was leaking state across shared views, causing the chatter panel and button to appear on views accessed outside the PayRun layout (e.g., via the main Payroll > Time Offs menu). Fix this by introducing a `useEffect` hook in `PayRunLayout` that checks for a valid `payrun_id` or `payRunReactive` state on view render. If absent, the chatter service state is explicitly reset and closed. The control panel button is also wrapped in a contextual `t-if` check, fully isolating the feature to its intended screens. Task : 6347871 Forward-Port-Of: odoo/enterprise#123570
Employees and managers can now request and save appraisals even when the scheduled appraisal date has already passed. This removes an unnecessary error that blocked late appraisal requests and avoids requiring users to manually adjust dates they may not have permission to change.
Original PR description
# How to reproduce You need to simulate the fact that you are creating an appraisal late so either : A) Directly edit the `next_appraisal_date` in SQL B) Go to Employee App > any Employee > Settings,…
# How to reproduce You need to simulate the fact that you are creating an appraisal late so either : A) Directly edit the `next_appraisal_date` in SQL B) Go to Employee App > any Employee > Settings, set Next Appraisal Date to tomorrow and wait for 2 days Then : - Click on Request Appraisal - Save # The problem An error is shown saying "You cannot set 'Next Appraisal Date' in the past.". You can workaround this by changing the Next Appraisal Date to a date in the future, but the problem is not every user has the right to do this. # Cause `next_appraisal_date` is also defined in hr.appraisal as a relate field of hr.employee : https://github.com/odoo/enterprise/blob/0226ad15abc8db70f8e379fddec3d83d15749c85/hr_appraisal/models/hr_appraisal.py#L56-L57 When creating an hr.appraisal, `next_appraisal_date` is present in `vals_list` because it is defined in the view since : https://github.com/odoo/enterprise/commit/58fba3098f33db82dfbccca2db229550402ed3ab https://github.com/odoo/enterprise/blob/0226ad15abc8db70f8e379fddec3d83d15749c85/hr_appraisal/views/hr_appraisal_views.xml#L92 This triggers a write on `next_appraisal_date` of hr.employee which triggers a constraint : https://github.com/odoo/enterprise/blob/0226ad15abc8db70f8e379fddec3d83d15749c85/hr_appraisal/models/hr_employee.py#L81-L85 opw-6147865 Forward-Port-Of: odoo/enterprise#123817 Forward-Port-Of: odoo/enterprise#114876
Payroll start warnings now include the evaluation logic needed to determine when they should appear. This helps payroll teams receive the right warning before starting a pay run, reducing confusion and the risk of missed checks.
Original PR description
In this commit, we finxed the definition of start payrun warning to include the evaluation code in the warning definition. task-6179707
Rental planning now only blocks resources for company-wide leave when that leave applies to their working calendar, preventing unnecessary allocation conflicts. The update also strengthens related rental planning website and backend tests to help keep booking behavior reliable.
Original PR description
## [FIX] sale_renting_planning: check global leaves working schedule Before this commit: any `resource.calendar.leaves` with no `resource_id` created would prevent all resources from being allocated…
## [FIX] sale_renting_planning: check global leaves working schedule
Before this commit: any `resource.calendar.leaves` with no `resource_id` created would prevent all resources from being allocated during the leave date.
After this commit: any `resource.calendar.leaves` with `no resource_id` would be applied only to resources with the same `calendar_id` as the leave.
if the leave has no `calendar_id` then the leave applies to all `resource.calendars`
if a resource has no `calendar_id` then leaves with no `calendar_id` apply to it as well
## [IMP] {website_}sale_renting_planning: move tests from industry and fix existing ones
This commit moves the tests from [odoo/industry#1980](vscode-file://vscode-app/snap/code/237/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) to their respective standard modules.
It also fixes the logic behind some tests as they weren't testing a `planning.role` with `sync_shift_rental` enabled.
task-6179505
Forward-Port-Of: odoo/enterprise#120983
Forward-Port-Of: odoo/enterprise#116430Belgian payroll pay runs no longer fail when an employee has multiple contract or work schedule versions within the same month. This ensures payslips can be generated reliably for employees with mid-month changes, reducing payroll processing interruptions.
Original PR description
Currently, there is an error while running payrun step with employee who has multiple version in 1 month. ``` number_of_hours = (work100_wds - worked_day).number_of_hours ValueError: Expected singleton: hr.payslip.worked_days(233, 234) ``` Step to reproduce: 1. Create Employee with multiple version in 1 month 2. Create New PayRun during that month 3. Run the PayRun until Payslip step 4. Expected error on payslip steps reason: substraction of work100_wds and worked_day generate more than 1 value, if we have multiple version in 1 month task-6296276 Forward-Port-Of: odoo/enterprise#122723 Forward-Port-Of: odoo/enterprise#122483
This update fixes several issues around how taxes are calculated and stored when documents switch tax modes. It improves consistency for invoices, purchases, sales, and Italian electronic invoice imports, reducing the risk of incorrect totals or validation issues.
Original PR description
- changing python constraint on document tax mode on account.move to SQL - style enhancements to the overlap_badge_tab and new component - removing inconsistent rounding in purchase.order - adding document tax mode logic to account.tax compute_all method - adding missing document tax mode ‘tax_excluded’ setting to l10n_it_edi during account.move creation of imported invoices odoo/odoo/pull/272730 Following up: https://github.com/odoo/odoo/pull/251800 Forward-Port-Of: odoo/enterprise#122246
Sendcloud shipping labels now correctly handle delivery addresses where the house number contains a dot, such as “12.345”. This prevents incorrect address data from being sent to the carrier and helps avoid malformed labels or delivery issues.
Original PR description
Issue ----- Labels have unexpected format when the delivery address has a dot (`.`) in the number. Steps to reproduce ----- - Set up Sendcloud (carrier shouldn't matter) - Enable logs - Create a customer (with valid address, phone and email) - Address must contain a dot, eg Grand Place 12.345 - Deliver a product to the customer - Add sendcloud as delivery method - Go to the logs - Open the "sendcloud request parcels" log > house_number is 12 Cause ----- The `house_number` field is populated using `_get_house_number`, where the regex used to extract the number from the address line does not accept the `.` character. https://github.com/odoo/enterprise/blob/f93882555864a1f0a2a3e3863780096c78923bfa/delivery_sendcloud/models/sendcloud_service.py#L323 ----- Ticket: opw-6295904 Forward-Port-Of: odoo/enterprise#123820 Forward-Port-Of: odoo/enterprise#123266
6 changes
Resolved issues and error corrections
Steps to reproduce: - In Outlook, create a recurrence with an exception that is not the first occurrence. - Run the Microsoft calendar synchronization in Odoo. - The exception is imported without microsoft_id or ms_universal_event_id, and follow_recurrence is set to True. Outlook exceptions are converted without their identifiers, and calendar.event creation overwrites their explicit follow_recurrence=False value. Preserve both the Microsoft identifiers and the detached exception state dur
Original PR description
Steps to reproduce: - In Outlook, create a recurrence with an exception that is not the first occurrence. - Run the Microsoft calendar synchronization in Odoo. - The exception is imported without microsoft_id or ms_universal_event_id, and follow_recurrence is set to True. Outlook exceptions are converted without their identifiers, and calendar.event creation overwrites their explicit follow_recurrence=False value. Preserve both the Microsoft identifiers and the detached exception state during import. opw-5129848
steps to reproduce: ----------- - install the industry_fsm_repair module - create a product with type goods and enable `create repair` - enable `create repair orders` from returns in delivery orders in operation types - create a sale order with an fsm product and a goods product - confirm the sale order and validate the delivery - return the delivery and validate it (wh/in/0000x) - open the return receipt (wh/in/0000x) and create a repair - create an fsm user without sto
Original PR description
steps to reproduce: ----------- - install the industry_fsm_repair module - create a product with type goods and enable `create repair` - enable `create repair orders` from returns in delivery orders…
steps to reproduce: ----------- - install the industry_fsm_repair module - create a product with type goods and enable `create repair` - enable `create repair orders` from returns in delivery orders in operation types - create a sale order with an fsm product and a goods product - confirm the sale order and validate the delivery - return the delivery and validate it (wh/in/0000x) - open the return receipt (wh/in/0000x) and create a repair - create an fsm user without stock access - log in with the fsm user - open a task, go to `pick up`, and open the stock move - open the repair order issue: -------- the fsm user does not have access to stock lots and repair tags, which causes an access error. fix: ---- added the stock user group to the repair tags and stock lot fields so that users without the stock user group cannot access them. technical: ------ in the stable version, i did not extend the repair view in the industry_fsm_repair module. instead, i added the group directly in the repair module. In master, the group is added through the industry_fsm_repair module. task-6032336
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per
Original PR description
opw-6368979 Description of the issue/feature this PR addresses: Update the Worldline Cofidis payment method mapping to match the latest payment product ID defined in the Worldline documentation. Current behavior before PR: The Cofidis payment method was mapped to the outdated payment product ID (3012), causing payment requests to use an incorrect mapping. Desired behavior after PR is merged: The Cofidis payment method is mapped to the correct payment product ID (5129) as per the latest Worldline documentation, ensuring payment requests use the correct mapping. Forward-Port-Of: odoo/odoo#275881
Description of the issue/feature this PR addresses: Current behavior before PR: meeting.rrule is stored as a full dateutil rrule string, e.g.: "DTSTART:20250218T113209\nRRULE:FREQ=YEARLY;COUNT=720" Passing the full multi-line string as a single RRULE property value causes vobject to emit two RRULE lines, where the first one ("RRULE:DTSTART:...") has no FREQ. This is not standard-compliant and is rejected by calendar clients (e.g. Thunderbird: "invalid frequency null"). Desired behavior af
Original PR description
Description of the issue/feature this PR addresses:
Current behavior before PR: meeting.rrule is stored as a full dateutil rrule string, e.g.: "DTSTART:20250218T113209\nRRULE:FREQ=YEARLY;COUNT=720"
Passing the full multi-line string as a single RRULE property value causes vobject to emit two RRULE lines, where the first one ("RRULE:DTSTART:...") has no FREQ. This is not standard-compliant and is rejected by calendar clients (e.g. Thunderbird: "invalid frequency null").
Desired behavior after PR is merged: Only a single RRULE line is generated.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prMicrosoft issues a new refresh token on every access token refresh (rolling 90-day sliding window). The previous code discarded it, causing users to be forced to re-authenticate every 90 days once the original token expired. Closes #253543 Forward-Port-Of: odoo/odoo#268284
Original PR description
Microsoft issues a new refresh token on every access token refresh (rolling 90-day sliding window). The previous code discarded it, causing users to be forced to re-authenticate every 90 days once the original token expired. Closes #253543 Forward-Port-Of: odoo/odoo#268284
Issue: --- If a product template has dynamic attributes, some variants might not exist. For those variants, we are showing wrong stock in the website. To reproduce: 1- Create a product with a dynamic attribute and two values. 2- Publish the product and uncheck sell when out-of-stock and check show product when the qty is less than 5. 3- Create a purchase order with qty = 4 for the first value, so a variant is created for it. 4- Go to the website shop. Open the product. 4 available qty i
Original PR description
Issue: --- If a product template has dynamic attributes, some variants might not exist. For those variants, we are showing wrong stock in the website. To reproduce: 1- Create a product with a dynamic…
Issue: --- If a product template has dynamic attributes, some variants might not exist. For those variants, we are showing wrong stock in the website. To reproduce: 1- Create a product with a dynamic attribute and two values. 2- Publish the product and uncheck sell when out-of-stock and check show product when the qty is less than 5. 3- Create a purchase order with qty = 4 for the first value, so a variant is created for it. 4- Go to the website shop. Open the product. 4 available qty in stock is shown for the first variant which is correct. 5- Select 2nd variant. As you see, still 4 available qty is shown which is wrong. As the out-of-stock sale is unchecked, an out-of-stock warning should be shown. Cause and Fix: --- This is due to `isMainProduct` being always False when `product_id` is not set which makes `free_qty` and `out_of_stock` not to be updated. Also in `get_combination_info_website`, `is_storable` value is set to variant `is_storable` field which will be False if product variant is not exist. opw-6237602 Forward-Port-Of: odoo/odoo#273104
3 changes
Resolved issues and error corrections
The partner credit limit warning on quotations and customer invoices depends on which company the user is currently working in, instead of the company of the document itself. Steps to reproduce: - Enable Sale Credit Limit in the settings of My Company (San Francisco) - Set a Credit Limit of 100 on a customer, e.g. Deco Addict - Create a draft quotation of 500 for that customer => The credit limit warning banner is displayed, as expected - Switch the active company to any other company, fo
Original PR description
The partner credit limit warning on quotations and customer invoices depends on which company the user is currently working in, instead of the company of the document itself. Steps to reproduce: -…
The partner credit limit warning on quotations and customer invoices depends on which company the user is currently working in, instead of the company of the document itself. Steps to reproduce: - Enable Sale Credit Limit in the settings of My Company (San Francisco) - Set a Credit Limit of 100 on a customer, e.g. Deco Addict - Create a draft quotation of 500 for that customer => The credit limit warning banner is displayed, as expected - Switch the active company to any other company, for example My Company (Chicago), keeping access to both companies - Open the same quotation again => The warning banner is gone, although neither the quotation nor the customer changed The credit fields used to build the warning are evaluated against the user's active company: credit_limit is a company-dependent field, and credit / credit_to_invoice are computed on the receivables of the current company. When the active company is not the document's company, the warning is checked against the wrong ledger and the wrong limit, so it can disappear on an over-limit customer or show up for a healthy one. Both computes already contain the line that was meant to handle this, but the result of with_company() was discarded, making it a no-op. Assign it, as every other compute in these files already does, so the warning is always evaluated in the document's company. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Before this commit: If a user, with crm.leads linked to it, decided to request a password reset AND during that password reset process decided to activate the google oauth for their account, it would cause a crash. The reason is, during the password rest + oauth activation, self.env.user is an empty record set, which obviously will fail during the _is_portal check, due to its call to ensure_one() opw-6347228
Original PR description
Before this commit: If a user, with crm.leads linked to it, decided to request a password reset AND during that password reset process decided to activate the google oauth for their account, it would cause a crash. The reason is, during the password rest + oauth activation, self.env.user is an empty record set, which obviously will fail during the _is_portal check, due to its call to ensure_one() opw-6347228
... opw-6270530 closes #268601
Original PR description
... opw-6270530 closes #268601