Daily updates from Odoo
Wednesday, July 15, 2026
53 changes · saas-19.3
Resolved issues and error corrections
This fix prevents an error when opening Dimona data for an employee whose private street address is missing. It helps Belgian payroll users continue their workflow instead of being blocked by a technical traceback.
Original PR description
action_open_dimona guards on `self.employee_id.private_street` but then runs re.findall on `self.private_street` Forward-Port-Of: odoo/enterprise#124029
Signature certificates now show the applicant's actual email address when an offer is generated and signed from Recruitment. This avoids confusing placeholder emails on official signing records and keeps certificate logs accurate for HR processes.
Original PR description
similar to https://github.com/odoo/enterprise/pull/120566/changes/b5b6589c9c91980e41d025ae74082af63907debc When generating an offer from the recruitment application and signing it, the applicant's…
similar to https://github.com/odoo/enterprise/pull/120566/changes/b5b6589c9c91980e41d025ae74082af63907debc When generating an offer from the recruitment application and signing it, the applicant's email address is incorrectly displayed. ### **Steps to Reproduce:** 1) Install sign, recruitment, hr_contract_salary 2) Create an new application and add basic detail like name and email as (path and path@test.com) 3) Generate offer and sign with all the required signer. 4) Open the application form view and open the certificate. ### **Observed Behavior:** Email is not set correctly in the generated certificate (appearing as john@example.com). ### **Expected Behavior:** The email of the applicant should be correctly set(e.g as path@test.com) ### **Root Cause:** When the applicant signs the document, their email is explicitly set to `False` at [1]. This is done because the applicant is not linked to any user yet. Later, when generating the certificate, the system attempts to display the user's partner email at [2], which is `False`, causing the default fallback value (`john@example.com`) to be printed. [1]- https://github.com/odoo/enterprise/blob/49226f4109c7d7bb48340949951e70f4245d0e5b/hr_contract_salary/controllers/main.py#L53-L54 [2]- https://github.com/odoo/enterprise/blob/49226f4109c7d7bb48340949951e70f4245d0e5b/sign/report/sign_log_reports.xml#L59 ### **Fix:** Use `signer_email` instead of the partner's email to ensure the correct email is displayed on the certificate every time. **opw-6280170** Forward-Port-Of: odoo/enterprise#124215 Forward-Port-Of: odoo/enterprise#123767
This fix prevents payroll screens from crashing when users add Daily Salary or Integration Factor fields to Mexican payslip forms with Odoo Studio. It ensures these values are only calculated once the needed employee and contract details are available, so users can create off-cycle payslips and review salary information safely.
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 French reports module now formats the fiscal year end date consistently in the required month-day format. This prevents invalid report values when the fiscal year end month has only one digit, helping ensure compliant submissions.
Original PR description
Aspone force the end fiscal year in zone AD to follow the format MMdd. Before this commit, fiscalyear_last_month could be only one number and so we would end up with something like '930'. We will now add :02d to format the integer with a width of 2. task-6253745
Shopee order lines now show the specific variant SKU in the description instead of the broader template SKU when products have variants. This makes order details clearer for teams handling fulfillment, customer service, and sales reconciliation.
Original PR description
Currently, _prepare_order_lines_values resolves SKU as `item_sku or model_sku`. Shopee always sends item_sku (product.template SKU), so when a listing has variants the order line description shows the template SKU ([item_sku]) even though the correct variant is linked via `model_sku`. task_id: 6335110 Forward-Port-Of: odoo/enterprise#124031
Belgian payroll contract templates now correctly carry over three previously missing fields when creating contract versions. Simulation versions are also kept from triggering Dimona-related processes, reducing the risk of unnecessary administrative actions.
Original PR description
Three fields were missing in the copying process from the contract template Forward-Port-Of: odoo/enterprise#124235
New planning slots now use the company’s working hours in the company timezone, so default start and end times appear correctly. This prevents users from seeing shifted hours when creating schedule entries for companies in non-UTC timezones.
Original PR description
Issue: ---------------------------------------- When creating a new slot, no resrouces are set so we use the calendar of the company but the hours are offset because of the timezone. Steps to reproduce: ---------------------------------------- - Have planning Installed - Have an hour based calendar, from 8 to 16 each day for example - Have the company timezone in UTC+2, same for you the user - Go in Planning "Schedule By Resource" view - Click "New" - The default start and end time are 10am and 6pm (2h offset) Cause: ---------------------------------------- `default_get()` calls `_company_working_hours()` to get the company calendar hours. But they are returned in UTC, so when displaying them they are converted to the user timezone and are offsetted. Solution: ---------------------------------------- `_company_working_hours()` should return the compny hours in the company timezone. opw-6333993 Forward-Port-Of: odoo/enterprise#123033
Payslip reports in Belgian payroll now correctly show eco voucher lines again. This prevents missing benefit information after the eco voucher setup was changed, helping employees and payroll teams see accurate payslip details.
Original PR description
Since changing Eco vouchers to property input, the eco vouchers line on the report does not appear, this commit fixes it by calling the correct method in the template task-6370164
Automatic bank statement reconciliation now gives failed lines one retry before excluding them. This helps avoid losing items because of temporary system issues, improving reliability for accounting teams.
Original PR description
The auto reconcile cron drops the lines whenever they raise an error which is an issue for things like serialization errors. Now the code retries failed lines once before dropping them to make sure it's an issue with the lines. task-6273202 Forward-Port-Of: odoo/enterprise#119383
A new test checks that overtime is calculated correctly for employees with flexible schedules when leave is involved. This helps prevent payroll or time tracking errors from reappearing in future updates.
Original PR description
For PR: https://github.com/odoo/odoo/pull/274831 This commit adds a test case to ensure that overtime is correctly calculated for the flexible employee opw-6259328,6284145 Forward-Port-Of: odoo/enterprise#123830
Rental pickup and return receipts now include the separate invoicing and shipping address details when customer addresses are enabled. This prevents missing address information on customer-facing rental documents and helps ensure deliveries, returns, and billing are handled with the right contact details.
Original PR description
**Steps to Reproduce:** 1. Install sale_renting and enable "Customer Addresses" in the settings 2. Confirm a rental order with shipping address and invoice address 3. Print the Pickup and Return Receipt **Issue:** Only the general partner address is printed; the invoicing/shipping `information_block` is missing **Why this happens:** The 19.2 layout rework (abf18ba250bae2f390f93f70abef1d7fb601c524) switched `web.external_layout` calls to accept macro arguments (e.g. `address="address"`). report_rental_order_document was only partially migrated: `address` was set above the t-call and passed as an argument, but `information_block` was left as a t-set inside the call body, which was the old convention. Once external_layout is called with explicit arguments, content t-set nodes in the body no longer populate the callee's scope, so address_layout's `t-if="information_block"` never triggers. opw-6366091 Forward-Port-Of: odoo/enterprise#124077
Opening the manufacturing planning view now ignores maintenance requests with incomplete scheduling information instead of failing. This prevents a blocking error for planners when a maintenance request has an end date but no start date.
Original PR description
#### Issue: Opening the MRP planning view could raise a traceback when a maintenance request had a ``Scheduled End`` but no ``Scheduled Date``. ```TypeError: '<' not supported between instances of 'NoneType' and 'datetime.datetime'``` #### Cause: In `_get_maintenances_intervals`, `mrp_maintenance` loaded maintenance intervals for gantt unavailability without filtering out incomplete rows. If an interval like False, datetime reached Intervals, it crashed when comparing None with a datetime. #### Fix: Filter out incomplete maintenance intervals in the gantt query. Also added a constraint on `maintenance.request` to require `schedule_date` and `schedule_end` to either both be set or both be empty in this community PR: https://github.com/odoo/odoo/pull/265208 opw-6225772 Forward-Port-Of: odoo/enterprise#117710
Subscription product pages now correctly show the original price crossed out next to the Buy Once price when one-time purchases are enabled. This makes discounts or price comparisons clearer for shoppers and helps avoid confusion during purchase decisions.
Original PR description
Version - saas-19.1 Steps to reproduce: - Enable 'Accept One Time Sale' on a subscription product - Open the product page on the website Issue: For subscription products with one time sale enabled, the original price was not shown as a strikethrough next to the Buy Once price. Fix: - Captured and exposed the original price to the template before it gets overwritten during subscription price processing - Added the missing strikethrough element to the Buy Once section of the product page Task ID - 6260207 Forward-Port-Of: odoo/enterprise#119488
Managers will no longer see the Print option twice in the Planning Gantt view. This keeps the interface cleaner and avoids confusion when using planning actions.
Original PR description
Issue: - Managers see the "Print" action twice in the Gantt view: once as a standalone button and once in the Actions dropdown. Cause: - The standalone Print button is guarded on `!this.isManager`, but `isManager` lives on the model. The expression is therefore always truthy, so the button always renders. Fix: - Use `!this.model.isManager` instead. task-6364971
Fixed demo-mode social feed comments so they use the correct built-in demo contact data after older demo data was removed. This ensures comment authors display the right profile image in demo feeds, making demonstrations look consistent and credible.
Original PR description
Bug === Since ce264a2 , we remove the demo partner in the social_demo module, but we didn't update the code to use the demo data in base. Task-6293738 Forward-Port-Of: odoo/enterprise#124151 Forward-Port-Of: odoo/enterprise#120821
The AI chatbox now appears in front of key website editor controls, including the toolbar and snippet selector dialog. This prevents the assistant from being hidden during editing, especially when mass mailing features are installed.
Original PR description
This PR addresses two problems relative to the AI chatbox z-index. 1. AI chatbox should appear above the toolbar, but used to appear below instead. 2. AI chatbox should appear above snippet selector dialog, but used to appear below if `mass_mailing` was installed. task-6366360
AI conversations will no longer fail just because the automatic chat title update encounters an error. This keeps the user's AI exchange running smoothly, while a test now confirms the issue stays fixed.
Original PR description
Before this commit, if there was an error during the ai chat renaming process, the whole request would fail. That was the case because in the `generate_response` controller method, we would try-catch the `_generate_channel_name` method and if an exception was caught we would return with the raised error. Renaming the chat is not a critical process. Even if it fails, the user conversation with the AI can continue normally. After this commit, instead of returning the caught exceptions, we just continue without handling them. Also in this commit, a test was added to check that an exception doesn't block the rest of the generate_response function. Task-6356851
Users can now return from a budget report detail page to the report list without seeing an error. The budget report now uses a valid default sorting order, preventing a crash during normal breadcrumb navigation.
Original PR description
Problem:
The `budget.report` model had its default sorting (`_order`) set to False. When a user navigates back to the report list view via the breadcrumbs, the web client invokes `web_read_group`, which runs `self._order.split(',')`. Because `_order` is a boolean rather than a string, this raises an AttributeError and throws an RPC_ERROR.
Solution:
Set `_order = 'date desc'` on `budget.report`. Both queries within the `_table_query` UNION ALL expose a `date` column, providing a semantically correct and safe default ordering constraint.
Steps to replicate:
- Go to Accounting > Accounting > Analytic Budgets.
- Select any budget.
- Click 'Audit' on any budget line to land on the budget report view.
- Click to open any individual record.
- Navigate back using the breadcrumbs.
- -> RPC_ERROR: AttributeError: 'bool' object has no attribute 'split'
opw-6372610
Forward-Port-Of: odoo/enterprise#124191### 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
Since #198829, a `t-att-class` has been added to the `loadOlder` template that relies on `mountedAndLoaded` of thread state to control the visibility of the `Load More` button. But it doesn't read the value from the state properly. As a result, the button is always transparent. This change fixes this by reading the value from the state. Forward-Port-Of: odoo/odoo#275934 Forward-Port-Of: odoo/odoo#275253
Original PR description
Since #198829, a `t-att-class` has been added to the `loadOlder` template that relies on `mountedAndLoaded` of thread state to control the visibility of the `Load More` button. But it doesn't read the value from the state properly. As a result, the button is always transparent. This change fixes this by reading the value from the state. Forward-Port-Of: odoo/odoo#275934 Forward-Port-Of: odoo/odoo#275253
…nding When cash rounding is enabled with "Only for cash payment methods", an order partially paid in cash and completed with an online payment could neither request the correct online amount nor be marked as paid. Steps to reproduce: - Enable cash rounding (e.g. 0.05, HALF-UP) with "Only for cash payment methods" - Create an order with a total of 15.28 - Add a cash payment of 10.00, then an online payment for the remainder The frontend requests 5.28 for the online payment, but as so
Original PR description
…nding When cash rounding is enabled with "Only for cash payment methods", an order partially paid in cash and completed with an online payment could neither request the correct online amount nor be…
…nding When cash rounding is enabled with "Only for cash payment methods", an order partially paid in cash and completed with an online payment could neither request the correct online amount nor be marked as paid. Steps to reproduce: - Enable cash rounding (e.g. 0.05, HALF-UP) with "Only for cash payment methods" - Create an order with a total of 15.28 - Add a cash payment of 10.00, then an online payment for the remainder The frontend requests 5.28 for the online payment, but as soon as the order contained a cash payment the server rounded the whole order total: get_and_set_online_payments_data() returned an unpaid amount of 5.30 (15.30 - 10.00), so the validation failed with "Invalid online payments". Even once the online payment of 5.28 was processed, the order remained stuck in draft with the money captured: _is_pos_order_paid() compared the paid amount (15.28) against the rounded total (15.30). Only the part of the order actually settled in cash must be rounded: non-cash payments (card, online, ...) always pay their exact share. - get_amount_unpaid() now returns the exact residual of the order when the rounding only applies to cash payment methods. - _get_rounded_amount() now only rounds the amount not covered by non-cash payments, resolving its old TODO. Cash-only orders and orders where the cash payment settles the rounded remainder are unaffected. opw-6314690 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275472 Forward-Port-Of: odoo/odoo#275305
When an order is validated, the state is set to "paid" and a sync to the server is attempted. If the network dropped during that sync, the order could be permanently lost: the 300ms IndexedDB debounce had not yet fired, so the paid order lived only in memory, and no guard prevented the cashier from accidentally closing or refreshing the tab in that window. opw-6237823 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#27515
Original PR description
When an order is validated, the state is set to "paid" and a sync to the server is attempted. If the network dropped during that sync, the order could be permanently lost: the 300ms IndexedDB debounce had not yet fired, so the paid order lived only in memory, and no guard prevented the cashier from accidentally closing or refreshing the tab in that window. opw-6237823 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275159 Forward-Port-Of: odoo/odoo#267799
Description of the issue/feature this PR addresses: When reversing or replacing an invoice with a C-symbol (tax code requiring approval), the reverse_moves method used an undefined `_l10n_vn_edi_lookup_invoice`, which is an old artifact from 19.2. This commit replaces it by a call to the SInvoiceService `lookup_invoice`, following the same pattern used throughout the rest of the module. Steps to reproduce: 1- Install `l10n_vn_edi_viettel` 2- Use credentials to put in Account settings
Original PR description
Description of the issue/feature this PR addresses: When reversing or replacing an invoice with a C-symbol (tax code requiring approval), the reverse_moves method used an undefined…
Description of the issue/feature this PR addresses: When reversing or replacing an invoice with a C-symbol (tax code requiring approval), the reverse_moves method used an undefined `_l10n_vn_edi_lookup_invoice`, which is an old artifact from 19.2. This commit replaces it by a call to the SInvoiceService `lookup_invoice`, following the same pattern used throughout the rest of the module. Steps to reproduce: 1- Install `l10n_vn_edi_viettel` 2- Use credentials to put in Account settings 3- Fill the TIN under res.company 4- Go to symbols under configuration, fetch and select a symbol with a 'C' in the name 5- Create invoice, use symbol for VN e-invoice. Click Send 6- Create Credit note, click confirm on wizard Current behavior before PR: Validating the Credit Note would raise a Traceback. ``` AttributeError: 'account.move' object has no attribute '_l10n_vn_edi_lookup_invoice' ``` Desired behavior after PR is merged: Validating the Credit Note should process as expected, without errors. opw-6348241 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
With 8f25ed0bf363, the case of a comodel with active_test set was handled differently for the False value. Align to the previous behaviour. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
With 8f25ed0bf363, the case of a comodel with active_test set was handled differently for the False value. Align to the previous behaviour. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When registering a payment for multiple bills from different partners, the `source_currency_id` becomes empty/evaluates differently in the wizard. Because of this, the `currency_conversion_div` `invisible` condition failed, causing the UI to redundantly display the exchange rate even when the currencies were identical (e.g., showing '1 EUR = 1 EUR'). This commit simplifies the invisible condition to only check if the `currency_id` matches the `company_currency_id`, keeping the UI clean. se
Original PR description
When registering a payment for multiple bills from different partners, the `source_currency_id` becomes empty/evaluates differently in the wizard. Because of this, the `currency_conversion_div` `invisible` condition failed, causing the UI to redundantly display the exchange rate even when the currencies were identical (e.g., showing '1 EUR = 1 EUR'). This commit simplifies the invisible condition to only check if the `currency_id` matches the `company_currency_id`, keeping the UI clean. see ent pr- https://github.com/odoo/enterprise/pull/118183 task- 6237870
**Steps to reproduce:** 1. Install Sales and EasyPost modules and enable delivery methods in the Settings. 2. Configure a new delivery method in [Sales -> Configuration -> Delivery Methods], choose provider as EasyPost and set the API keys. 3. Set any margin % on the delivery method. 4. Add the shipping line to a sale order via "Add shipping". **Issue:** Unit Price displays at a 4dp precision while Subtotal correctly displays at a 2dp precision **Why this happens:** `_apply_margins(
Original PR description
**Steps to reproduce:** 1. Install Sales and EasyPost modules and enable delivery methods in the Settings. 2. Configure a new delivery method in [Sales -> Configuration -> Delivery Methods], choose provider as EasyPost and set the API keys. 3. Set any margin % on the delivery method. 4. Add the shipping line to a sale order via "Add shipping". **Issue:** Unit Price displays at a 4dp precision while Subtotal correctly displays at a 2dp precision **Why this happens:** `_apply_margins()` returns a float from margin arithmetic calculation with no currency rounding applied. `rate_shipment()` writes this unrounded value directly to res['price'], which becomes the delivery line's price_unit. opw-6355318 Forward-Port-Of: odoo/odoo#275233
Typing in an HTML field (e.g. a contact's Internal Notes) and validating a URL-like token with Enter or Space can crash the editor with "IndexSizeError: The index is not in the allowed range", leaving the user unable to continue typing. It happens on Safari (not Chromium). The trigger is a URL-like token that the editor auto-converts into a link. The splitText calls in prepareConvertToLink, run during beforeinput, leave Safari's native selection anchored on an empty text node with an out-of-ran
Original PR description
Typing in an HTML field (e.g. a contact's Internal Notes) and validating a URL-like token with Enter or Space can crash the editor with "IndexSizeError: The index is not in the allowed range",…
Typing in an HTML field (e.g. a contact's Internal Notes) and validating
a URL-like token with Enter or Space can crash the editor with
"IndexSizeError: The index is not in the allowed range", leaving the
user unable to continue typing. It happens on Safari (not Chromium).
The trigger is a URL-like token that the editor auto-converts into a
link. The splitText calls in prepareConvertToLink, run during
beforeinput, leave Safari's native selection anchored on an empty text
node with an out-of-range offset. Anything reading the selection
afterwards then works from a broken position: on Enter, splitBlock
reads it and makeActiveSelection ends up throwing in Range.setStart;
on Space, the browser inserts the character in the wrong node and the
selection is corrupted the same way.
```
UncaughtClientError > IndexSizeError
Uncaught Javascript Error > The index is not in the allowed range.
setStart@[native code]
createEditorSelection@.../web.assets_web.min.js:12239:15
getSelectionData@.../web.assets_web.min.js:12242:145
updateActiveSelection@.../web.assets_web.min.js:12230:92
@.../web.assets_web.min.js:12218:873
handler@.../web.assets_web.min.js:14366:121
```
Steps to reproduce:
1. Use Safari (Chromium-based browsers work fine)
2. Open any record with an HTML field (e.g. Contacts -> a contact ->
Internal Notes).
3. Type a URL-like token such as KF.16D2.0204.CG (.CG is a valid TLD,
so the editor auto-links it). Do not paste it.
4. Place the caret at the end of that token and press Enter or Space.
5. IndexSizeError is raised and the editor stops accepting input.
Fix it at the source: re-anchor the selection right after the splits in
prepareConvertToLink, so every consumer sees a valid caret position.
Since moving the selection during beforeinput makes WebKit cancel the
pending text insertion, the Space case now prevents the default and
performs the conversion, the space insertion and the caret placement
itself, in two history steps so that undo still reverts the link
conversion while keeping the typed space.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#275587
Forward-Port-Of: odoo/odoo#270910When multiple invoices were sent to MyInvois in a single batch and at least one document failed validation, the failure branch of _myinvois_submit_documents added self.invoice_ids (all invoices in the batch) to invoice_to_cancel instead of the current record's invoices. Every sibling in the batch was then cancelled locally, even those whose own MyInvois submission had been accepted and moved to in_progress. The account.move ended up in state 'cancel' while its myinvois.document stayed 'valid'
Original PR description
When multiple invoices were sent to MyInvois in a single batch and at least one document failed validation, the failure branch of _myinvois_submit_documents added self.invoice_ids (all invoices in the batch) to invoice_to_cancel instead of the current record's invoices. Every sibling in the batch was then cancelled locally, even those whose own MyInvois submission had been accepted and moved to in_progress. The account.move ended up in state 'cancel' while its myinvois.document stayed 'valid', which violates the intended synchronization between the two records and blocked users from posting the credit note. Scope the cancellation to record.invoice_ids so only the invoice tied to the failing document is cancelled. 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#274727
CertificateAdapter presents a client certificate stored in the database instead of on disk when opening an HTTPS connection (used by the l10n_es EDI modules verifactu, sii and tbai). It loaded that certificate on the connection path of requests 2.31, but requests >= 2.32 changed that path (no longer calls get_connection()), so the step was skipped and the call crashed with: "TypeError: expected str, bytes or os.PathLike object, not certificate" Odoo pins requests 2.31.0 (max depending on Pyth
Original PR description
CertificateAdapter presents a client certificate stored in the database instead of on disk when opening an HTTPS connection (used by the l10n_es EDI modules verifactu, sii and tbai). It loaded that…
CertificateAdapter presents a client certificate stored in the database instead of on disk when opening an HTTPS connection (used by the l10n_es EDI modules verifactu, sii and tbai). It loaded that certificate on the connection path of requests 2.31, but requests >= 2.32 changed that path (no longer calls get_connection()), so the step was skipped and the call crashed with: "TypeError: expected str, bytes or os.PathLike object, not certificate" Odoo pins requests 2.31.0 (max depending on Python version), but online databases can use the version shipped by the OS (2.32.x on recent Ubuntu 26). Set the certificate up when the adapter is created instead of on that connection call. That step runs the same on every requests version, so the fix works both before and after 2.32. Steps to reproduce: - Spanish company with Veri*Factu and a certificate, on a server running requests >= 2.32 (saas-19.3 database for exemple on ubuntu 26) - Post a customer invoice and send it to Veri*Factu. => TypeError Reference: https://github.com/psf/requests/blob/f361ead047be5cb873174218582f7d8b9fcd9f49/HISTORY.md?plain=1#L146 Ticket [link](https://www.odoo.com/odoo/project.task/6366028) opw-6366028 Forward-Port-Of: odoo/odoo#275324
The `retry` button shown after a failed initial fetch did nothing when clicked (it goes through `thread.fetchMoreMessages` which is for load older and load newer). This change routes the click through `fetchMessages` when the failure is an initial one. task-6223358 backport of #272153 Forward-Port-Of: odoo/odoo#276088 Forward-Port-Of: odoo/odoo#275300
Original PR description
The `retry` button shown after a failed initial fetch did nothing when clicked (it goes through `thread.fetchMoreMessages` which is for load older and load newer). This change routes the click through `fetchMessages` when the failure is an initial one. task-6223358 backport of #272153 Forward-Port-Of: odoo/odoo#276088 Forward-Port-Of: odoo/odoo#275300
**Steps to reproduce:** 1. Go to Website > Edit a page. 2. Add multiple Badges side by side. 3. Save the page. 4. Switch the website language, click on Edit/Translate and translate the badges. 5. Save. **Issue:** After saving in translate mode, all badge elements are merged into one. **Why this happens:** During save, `cleanForSave` triggers `mergeAdjacentInlines` on a detached clone of the dirty element. This clone lacks all the css styling, so `getComputedStyle` returns `""` f
Original PR description
**Steps to reproduce:** 1. Go to Website > Edit a page. 2. Add multiple Badges side by side. 3. Save the page. 4. Switch the website language, click on Edit/Translate and translate the badges. 5.…
**Steps to reproduce:** 1. Go to Website > Edit a page. 2. Add multiple Badges side by side. 3. Save the page. 4. Switch the website language, click on Edit/Translate and translate the badges. 5. Save. **Issue:** After saving in translate mode, all badge elements are merged into one. **Why this happens:** During save, `cleanForSave` triggers `mergeAdjacentInlines` on a detached clone of the dirty element. This clone lacks all the css styling, so `getComputedStyle` returns `""` for all padding/margin on detached nodes. Consequently, `areSimilarElements` incorrectly considers sibling `s_badge` spans as identical and merges them. A recent fix (https://github.com/odoo/odoo/commit/91972ec2bbd85f9cfd7a1af794bbb2385a312f30) applied to `BadgeOptionPlugin` registers `s_badge` as unsplittable via `unsplittable_node_predicates`, preventing the merge in normal edit mode. However, translate mode loads a separate plugin, `BadgeTranslationPlugin`, which was added in the commit https://github.com/odoo/odoo/commit/cbb2eb2edfeecbc21a70c1a3cba81ad0a7ac9c75 that lacks the same predicate. opw-6261146 Forward-Port-Of: odoo/odoo#276040 Forward-Port-Of: odoo/odoo#273986
This update resolves an issue where the customer list in the POS module was blank when using the Taiwan localization. The fix updates the Chart of Accounts to ensure all customers are displayed correctly, regardless of the company's localization setting. This ensures accurate sales reporting and customer management within the Taiwan market.
Original PR description
## Current behavior: Currently, when we go into POS using l10n_tw localization, none of the customers appear on the list. ## Expected behavior: All customers should be shown when using Taiwan localization ## Steps to reproduce: 1. Install l10n_tw and POS modules 2. Use the default US company, observe the customer list in POS. All of them are shown 3. Create and switch to a Taiwan company, go back to POS 4. Observe that no customers are shown ## Cause of the issue: Since 19.0, there is a check where if the default payable or receivable account set on the partner is non-trade, those accounts do not appear ## Fix: - Updated AR accounts in COA template file - Added migration script to version 1.1 opw-6298634 Forward-Port-Of: odoo/odoo#274150 Forward-Port-Of: odoo/odoo#270738