Daily updates from Odoo
Monday, June 15, 2026
36 changes · saas-19.2
Resolved issues and error corrections
This update clarifies bank statement communications for split transactions. Previously, all lines of a split transaction received the same message, making it difficult to understand each charge. Now, transaction categories are used to add specific details to each line, aligning with CodaBox's breakdown and improving user clarity.
Original PR description
Currently, when global transaction is split into multiple lines, Odoo assigns the exact same communication text to every single split line. This makes it difficult for users to identify what each specific charge is for. To fix this, this commit introduces the transaction category data. Using this data to append specific transaction details to the end of the communication label. As a result, each split line now has a clear, descriptive label that closely matches the detailed breakdown provided by CodaBox. task-6059709 Forward-Port-Of: odoo/enterprise#113811
This update fixes an issue where the vehicle contract report was incorrectly calculating total costs due to overlapping data joins. The change replaces multiple joins with a single, more efficient join, ensuring accurate reporting of recurring costs for vehicles. This improves the reliability of financial reporting within the Fleet module.
Original PR description
Steps to reproduce: ------------------- 1. Install Fleet with demo data. 2. Create a contract for a vehicle (A) with a recurring cost of 1000 and "Monthly" frequency. 3. Go to Reporting > Costs and…
Steps to reproduce: ------------------- 1. Install Fleet with demo data. 2. Create a contract for a vehicle (A) with a recurring cost of 1000 and "Monthly" frequency. 3. Go to Reporting > Costs and verify the monthly cost (it shows 1000). 4. Create another contract for the same vehicle (A) with a recurring cost of 50 and "Monthly" frequency. 5. Check the monthly cost again. Issue: ------ The reported cost is incorrect. Instead of 1050 (1000 + 50), it shows 2100. Cause: ------ The query uses multiple LEFT JOINs on the contract table, including: https://github.com/odoo/odoo/blob/9ca36dbe53692309bac84329de3b54a1c510cce0/addons/fleet/report/fleet_report.py#L103 These joins overlap and produce duplicate rows for the same vehicle and month, which results in inflated cost totals. Solution: --------- Replace the multiple LEFT JOINs with a single LATERAL join. This ensures the contract table is processed once per vehicle per month and avoids duplication, resulting in correct totals. **Before:** <img width="940" height="609" alt="image" src="https://github.com/user-attachments/assets/e5b3e747-1135-4674-97c9-4e4fd9986dfd" /> **After:** <img width="1053" height="590" alt="image" src="https://github.com/user-attachments/assets/f0df3819-07fb-4de5-aab3-5b4c6f10d213" /> opw-6024132 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256051
This update corrects a technical issue within the HR module that was causing inaccurate reporting related to employee contract overlaps. The fix ensures that contract overlap calculations are now more precise, leading to more reliable data for HR and management decisions. This improves the accuracy of our reporting on employee contracts.
This update resolves a bug that caused crashes when editing records with x2many fields containing properties. The fix ensures that all related data consistently shares the same object, preventing data inconsistencies and improving overall stability. This enhances the reliability of the system when working with complex data structures.
Original PR description
Have an x2many field displayed as a list in a form view. In the arch, the x2many form view **isn't** inlined. In that x2many form view, there's a properties field. When a record is clicked,…
Have an x2many field displayed as a list in a form view. In the arch, the x2many form view **isn't** inlined. In that x2many form view, there's a properties field. When a record is clicked, `extendRecord` is called to add the new fields (those of the form) into `this.fields` and those fields are fetched. If there're properties in the property definition, fake fields are created to represent them (see `_processProperties`). However, because of extendRecord, the static list and the record don't share the same reference to the `fields` object. As a consequence, the `fields` object of the static list isn't updated with the fake property fields. If the user closes the record, and opens/closes it again, there's a crash, because the record is re-updated with the fields of the static list, and thus doesn't know about those property fields anymore. This commit fixes the issue by ensuring that we keep the same `fields` object when extending a record, s.t. the list and all its records always share the same object. Bug originally reported here: https://github.com/odoo/odoo/pull/268312 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269717
This update fixes an issue where purchase order line prices were incorrectly set to zero when using reordering rules with expired vendor pricelists. The fix ensures that the product's original cost or a valid fallback price is used, preventing inaccurate pricing on purchase orders. This improves the reliability of purchase order generation.
Original PR description
Version: ---------- - 18.0+ Steps to reproduce: ----------------------- 1 - Install the `purchase` and `stock` modules. 2 - Create a storable product with tracking enabled. Set the Cost (standard…
Version: ---------- - 18.0+ Steps to reproduce: ----------------------- 1 - Install the `purchase` and `stock` modules. 2 - Create a storable product with tracking enabled. Set the Cost (standard price) to 50. 3 - Open the product form and go to the Purchase tab. * Add a vendor with: * Quantity: 2 * Price: 10 4 - Create a Reordering Rule for this product: * Route: Buy * Trigger: Manual * To Order Quantity: 2 5 - Click on the Order button to generate a purchase order. 6 - Open the generated Purchase Order and verify the Unit Price on the purchase order line. 7 - Open the same product and go to the Purchase tab. In the existing vendor line, add an End Date lower than today so the vendor pricelist becomes expired. 8 - Reopen the same reordering rule. Change To Order Quantity to 1. 9 - Click on the Order button again Issue: ----- The generated purchase order line gets a Unit Price of 0 instead of keeping the product cost or a valid fallback price. Root Cause: -------------- - When clicking on `Order`, it triggers `action_replenish`, which calls the procurement flow: `_procure_orderpoint_confirm` → `run` → `run` → `_run_buy`. - Inside `_run_buy`, the system checks whether a `purchase.order.line` already exists. In this case, the PO line exists, so it calls `_update_purchase_order_line`. https://github.com/odoo/odoo/blob/47ef8b75d0c90001b9989a95f09b962c5b286c53/addons/purchase_stock/models/stock_rule.py#L137 - In `_update_purchase_order_line`, the system tries to fetch a seller using `_select_seller`, - which internally calls `_get_filtered_sellers`. https://github.com/odoo/odoo/blob/47ef8b75d0c90001b9989a95f09b962c5b286c53/addons/product/models/product_product.py#L759 - However, if the seller's `end_date` is less than `today`, `_get_filtered_sellers` skips that seller and returns no valid seller. https://github.com/odoo/odoo/blob/47ef8b75d0c90001b9989a95f09b962c5b286c53/addons/product/models/product_product.py#L731-L733 - As a result, `_update_purchase_order_line` does not find any seller and falls back to setting `price_unit` to `0`, causing the purchase order line price to be updated incorrectly. https://github.com/odoo/odoo/blob/47ef8b75d0c90001b9989a95f09b962c5b286c53/addons/purchase_stock/models/stock_rule.py#L259 --- opw-6117461 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269971 Forward-Port-Of: odoo/odoo#262396
This update ensures that non-mandatory text fields in sign documents appear with a transparent background when using dark mode in a web browser. A recent update to PDF.js automatically adjusted background colors based on the browser theme, causing a visual inconsistency. This fix corrects this issue, maintaining a consistent and professional appearance across all sign documents.
Original PR description
## Issue When using the browser's dark mode, non-mandatory text fields in sign documents appear with a dark background, which does not match the aesthetic of the rest of the page. ## Steps to…
## Issue
When using the browser's dark mode, non-mandatory text fields in sign documents appear with a dark background, which does not match the aesthetic of the rest of the page.
## Steps to reproduce
1. Set your browser's theme to a dark theme (in Chrome, go to Settings > Appearance > Theme, chose a theme from the dark options)
2. Install Sign (`sign`)
3. Open a Sign template and add 3 Text fields:
- Mandatory
- Non-mandatory
- Read-only (for comparison)
4. Click *Sign Now*
5. **The non-mandatory text field has a dark background.**
## Cause
Since a [PDF.js update](https://github.com/mozilla/pdf.js/commit/ae1cbc6a9ecc738d6777830488ad5481b97338bc), the `light dark` color-theme was added to `:root`. This means that the element will react to the settings of the browser and adapt its background and text color. In this case, there's no other `background-color` provided to mandatory fields, resulting in them using the dark color of the browser theme.
## Fix
We make the default background of text fields transparent then we update the selector of `.o_sign_sign_item_required` to prevent their `background-color` from being overwritten by that new transparent background.
| | Before | After |
|------------|--------|-------|
| **Light mode** | <img width="211" height="99" alt="6213059-before-light" src="https://github.com/user-attachments/assets/c4c70394-c7c2-4dbf-92b9-c1362d1cf9c8" /> | <img width="207" height="89" alt="6213059-after-light" src="https://github.com/user-attachments/assets/63142be5-9f7d-4d5d-94e8-ef9428e1b778" /> |
| **Dark mode** | <img width="220" height="95" alt="6213059-before-dark" src="https://github.com/user-attachments/assets/19149c3d-511e-407c-821e-f318f373368a" /> | <img width="210" height="103" alt="6213059-after-dark" src="https://github.com/user-attachments/assets/0b412d4f-061f-41b3-aae9-569b9a8219dc" /> |
opw-6213059
Forward-Port-Of: odoo/enterprise#117589This update fixes an issue where the Datev export incorrectly displayed currency amounts due to using the company currency instead of the invoice's currency. The change ensures accurate reporting of tax and currency rates when exporting ledger data to Datev, improving financial reporting accuracy.
Original PR description
There is an issue in the Datev export functionality. In the current functionality, the code calculates a delta between the taxes in the `tax_totals` and the ones on the journal items. Issue is, the tax amounts from tax_totals were always in company currency, while the entry itself can use a foreign one. This replaces the use of company currency with the use of the invoice's currency and appropriately adjusts the test featuring foreign currency. Steps: Create a foreign currency. Create an invoice with a taxed product using the currency. Export the ledger to Datev. Inspect the resulting csv. Note that neither the final listed price, nor the rate listed for the currency align with the ones in the db. opw-6275889 Forward-Port-Of: odoo/enterprise#120293
This update ensures that inventory counts accurately reflect products without lot numbers. Previously, scanning these products caused incorrect updates to inventory quantities, leading to discrepancies. The fix correctly handles lotless products during inventory adjustments, ensuring accurate tracking.
Original PR description
### Steps to reproduce: 1. Create a product tracked by lot 2. Put 10 units in WH/Stock without lot 3. Inventory > Operations > Adjustments > Physical Inventory 4. Select the line referring to your…
### Steps to reproduce: 1. Create a product tracked by lot 2. Put 10 units in WH/Stock without lot 3. Inventory > Operations > Adjustments > Physical Inventory 4. Select the line referring to your product and request an inventory count + Show Expected Quantity 5. Open the barcode app > Count Inventory 6. Scan your product #### > The line is not selected, in particular, next scans will be re-interpreted as product scans rather than new serial creation for your product. ### Cause of the issue: Scanning your product search a line to select if any: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L1432-L1435 https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L1630-L1632 However, the `findLine` will fail since this method calls the `_canOverrideTrackingNumber` to determine if the lot of the barcodData matches the one of the line: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L1859-L1863 But, the override of the `_canOverrideTrackingNumber` method for the `BarcodeQuantModel` does not handle the absence of lotName in the barcodeData correctly as it does not consider that a line without lot can be overridden by an empty lotName: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_quant_model.js#L729-L731 Note however that the super call does: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L795-L798 ### Issue 2: ### Steps to reproduce: - Steps 1 -> 5 - Click on your product line to select it - Scan a new lot to add one new unit referring to that lot - Confirm (1) - Apply Now #### > User Error: Quant's editing is restricted, you can't do this operation Since the line is selected, you have a currentLine during the `processBarcode` and hence the existing line will be updated using the `lotName``: https://github.com/odoo/enterprise/blob/cf3c2fce8a6b7b2d7547d44a0e4423f887986d52/stock_barcode/static/src/models/barcode_model.js#L1560-L1584 However, writing on the line will then try to write on the related quant during the validation process which will be forbiden since we are not allowed to change the lot of an existing quant: https://github.com/odoo/odoo/blob/e3b0ca11d99b2ef819cdad68b169112cd73668b6/addons/stock/models/stock_quant.py#L351-L360 Now, the issue is that actually due to the nature of the line and of the barcode data, the line lot is not expected to be updated but rather a new line is expected to be created: https://github.com/odoo/enterprise/blob/cf3c2fce8a6b7b2d7547d44a0e4423f887986d52/stock_barcode/static/src/models/barcode_model.js#L795-L798 Additional issue: Fixing issue 1 and 2 highlight and other issue of the validation process: - Steps 1 -> 6 > The line gets selected - Scan a newlot > a new subline is added referring to 1 unit of your new quant - Confirm (1) > Some serials where not counted, set them as missing #### > Check your quants: the 10 unit lotless quant was not updated but a new quant for 1 units was created for your newlot ### Cause of the issue: Applying all quantities is expecting to toggle them as counted before applying to update the existing quants: https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/stock_barcode/static/src/models/barcode_quant_model.js#L72-L82 https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/stock_barcode/static/src/models/barcode_quant_model.js#L287-L296 However, only line tracked by serial numbers are set as counted: https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/stock_barcode/static/src/models/barcode_quant_model.js#L60-L63 opw-6212923 Forward-Port-Of: odoo/enterprise#118373
This update fixes a potential issue in the knowledge article tour process. It ensures the system correctly identifies the target article before allowing users to share, favorite, or edit it. This improves the user experience and prevents errors during these common actions.
Original PR description
With this commit, We ensure we're in the correct article before making any changes (share, add to favorites, edit) using `waitUntil`. We've added a `checkArticle` function to ensure the article is in the correct place in the menu. runbot-error-id~234645 Forward-Port-Of: odoo/enterprise#110123
This update ensures that Latin American invoices correctly display the company's chosen document layout (e.g., Bubble) in the invoice header. Previously, custom layouts weren't being applied, leading to a standard header. This change improves the visual consistency and branding of invoices for LATAM clients.
Original PR description
Problem: When printing an invoice for a Latin American (LATAM) company, the company's document layout is not used in the header of the invoice. For example, if an Argentinian company has set up a…
Problem: When printing an invoice for a Latin American (LATAM) company, the company's document layout is not used in the header of the invoice. For example, if an Argentinian company has set up a Bubble layout as its document layout, the header of the invoice will not have the bubble. Steps to reproduce: 1. Install l10n_ar 2. Create an invoice using Electronic Sales Journal 3. Set document layout to Bubble in the company settings 4. Print the invoice 5. Notice that the header of the invoice does not have the bubble Cause: Most LATAM localizations use custom headers for their reports. In report_templates of l10n_latam_invoice_document, it checks if custom_header is set to decide whether to display the custom header. If custom_header is set, the div with class "header" will be hidden, and the custom header will be displayed after the div with class "header". Since the div with class "header" contains the background image that corresponds to the document layout, the background image will not be displayed when div with class "header" is hidden. Solution: Instead of hiding the entire div with class "header" when custom_header is set, only hide the table inside the header. This way, the background image of the document layout will still be displayed even when a custom header is used. opw-6204062 Forward-Port-Of: odoo/odoo#267164
This update fixes a potential issue where certified point-of-sale configurations could allow users to enter negative quantities on order lines. This has now been resolved across both the backend and frontend of the Odoo system, ensuring accurate order tracking and reporting. This change improves data integrity and prevents errors related to negative stock levels.
Original PR description
Certified pos configs should not allow to set negative quantities on order lines. We now prevent it from both backend and frontend. see odoo/odoo#269487 task-5942777 Forward-Port-Of: odoo/enterprise#119702
This update corrects a potential issue in the Swiss payroll module where users could incorrectly request refunds on payslips. Swiss payroll regulations limit payments to one per month, so the system now directs users to cancel and re-create the payslip for accurate corrections. This ensures compliance with Swiss tax laws.
Original PR description
Prevent refunds for CH payslips since only one payslip per month is allowed for Swiss payroll. Users should cancel the payslip and create a new one to apply corrections. task-5951981 Forward-Port-Of: odoo/enterprise#107943
This update corrects an issue where sale order references were incorrectly linked to the user's company instead of the order's company. This fix ensures accurate reference processing, particularly in multi-company environments, by using the correct company context for journal lookups. This improves the reliability of sale order referencing and payment processing.
Original PR description
Description of the issue/feature this PR addresses: Fixes an issue where the sale order reference computation was fetching the invoice journal based on the logged-in user's current company instead of…
Description of the issue/feature this PR addresses: Fixes an issue where the sale order reference computation was fetching the invoice journal based on the logged-in user's current company instead of the company associated with the specific payment provider or transaction context. This caused incorrect reference processing or errors in multi-company environments when a user was logged into one company but processing an order from another. Current behavior before PR: The function searches for the account.journal using self.company_id.id. Since self in this context (likely a payment provider or transaction record) might be evaluated under the active user's environment context, it fetched the journal from the user's currently active company (allowed_company_ids), disregarding the actual company related to the sale order or the transaction. Desired behavior after PR is merged: The invoice journal search uses the correct company context (e.g., order.company_id.id or the specific company linked to the payment record), ensuring that the sale order reference is processed using the appropriate journal from the correct company, regardless of which company the logged-in user is currently switched into. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269558
This update resolves an issue where the 'smart button' on the appraisal module wouldn't automatically select the correct employee. The fix ensures that the employee ID is correctly passed when using the appraisal action, regardless of the user's navigation path within the system. This improves the user experience and prevents data entry errors.
Original PR description
[FIX] hr_appraisal: fix auto-fill of employee in appraisal Bug production: 1 - employee app -> department -> select employees -> select any employee -> use appraisal smart button in top ->…
[FIX] hr_appraisal: fix auto-fill of employee in appraisal
Bug production:
1 - employee app -> department -> select employees -> select any employee -> use appraisal smart button in top -> employee_id is not coming
Bug cause:
1 - When we press smart button of appraisal action_send_appraisal_request in hr_employee is called.
2 - It send the self.env.context as a context and active_model and active_id.
3 - In hr_appraisal, _get_default_employee function calculates the default employee_id by looking to context and especially by looking to active model and id.
3.1 - If active_model is hr.employee and there is active_id, it finds the employee automatically (that is the case when we are coming directly from employee -> smart button hr_appraisal)
3.2 - When we first click to department and then we click to employee and smart button, active_model is hr.department and default_employee_id cannot be calculated in default version.
Bug solution:
1 - I have passed the default_employee_id to the context in action_send_appraisal_request function. Since we know the employee in the action_send_appraisal_request function we can pass it directly.
task - 6285434This update fixes an issue where multiple taxes applied on Brazilian sales orders were displayed on a single line, making them difficult to read. The change adds a line break to separate tax details, improving clarity and usability for users. This ensures accurate tax reporting for Brazilian customers.
Original PR description
Upon creating a SO in the Brazilian localization and computing taxes, tax details are displayed on the SO lines. However, when multiple taxes are applied, all tax details are shown on a single line, making them difficult to read. Add a line break between tax details so that each tax is displayed on a separate line. Before: https://www.awesomescreenshot.com/image/61178015?key=703ceba935bbf0b97f4b45c649722827 After: https://www.awesomescreenshot.com/image/61178078?key=3b980b91b7657aa48dec9b825549ebeb opw-6234768
This update corrects a translation issue in sale order reports, ensuring addresses are displayed in the correct language based on the partner's settings, not the user's. Previously, the GST/HST number was incorrectly translated to French. This change ensures accurate reporting for international customers.
Original PR description
Issue: --- User lang is used to translate address info instead of partner lang. Steps to reproduce: 1- Setup Canada company. 2- Create a partner with GST/HST number set and English lang. 3- Create a SO with the created partner. 4- Change user language to French. 5- Download SO report. The `GST/HST number` is translated to French. Cause: --- This is due to bba2fc505f5d0b4770eacc6877155b1aeda6d772. In the fix c679a9670494c8e6fca92e94d8dba9cca254cb16 we fixed the issue but the doc lang set is added after address set. opw-6252648
This update resolves an issue where reloading the Point of Sale while the system was in a specific state caused data loss and errors. The fix prevents a race condition between sending data and loading new information, ensuring a smoother and more reliable user experience for Point of Sale operations. This improves the overall stability of the POS system.
Original PR description
When the user reloads the POS while the session is in opening_control, the beforeunload sendBeacon and the new pos_web request race. If the beacon is processed first it deletes the session and load_data fails. task-6259527 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268668 Forward-Port-Of: odoo/odoo#267190
This update ensures that stock reports automatically print when a Point of Sale order is validated. Previously, the print job wasn't triggered, but this change adds a system to retrieve and execute report actions, streamlining the order fulfillment process. This improves efficiency and reduces manual steps.
Original PR description
Validating a `pos.order` creates a stock move in inventory. However, when configuring reports to automatically print on validation, the print job wasn't triggered from the pos. We added a way to retrieve report actions and execute them. Task: 5392414 Forward-Port-Of: odoo/odoo#269614 Forward-Port-Of: odoo/odoo#239084
This update resolves a critical issue where VoIP registration would fail due to a delayed response when a user left a session open and inactive. The fix automatically recreates the registration process, ensuring consistent connectivity and preventing error dialogs. This improves the user experience and reliability of VoIP calls.
Original PR description
Leaving a session open and idle (page open, no activity at all) eventually pops an error dialog: UncaughtPromiseError > RequestPendingError REGISTER request already in progress, waiting for final…
Leaving a session open and idle (page open, no activity at all) eventually pops an error dialog:
UncaughtPromiseError > RequestPendingError
REGISTER request already in progress, waiting for final response
at Registerer.register (sip.js)
at Registerer.register (registerer.js)
at UserAgent.attemptReconnection (user_agent_service.js)
When the WebSocket transport drops while a REGISTER is in flight (which happens on an idle tab: SIP.js sends a periodic re-REGISTER before the registration expires, and the socket may be closed by an idle timeout or by the machine going to sleep in the meantime), the final response never comes back. SIP.js only clears its internal `waiting` flag from the REGISTER response callbacks (onAccept/onReject/onRedirect); it is never reset on transport loss or request timeout. The Registerer is then stuck `waiting` forever, and every subsequent register() rejects with a RequestPendingError.
On top of that, our wrapper's register() did not return the SIP.js promise, and attemptReconnection() called it without awaiting, so the rejection escaped the surrounding try/catch and surfaced as an unhandled promise rejection. Worse, the WebSocket error was resolved right after, so the user appeared reconnected while VoIP registration was actually dead until the page was reloaded.
This commit makes register() recreate the underlying SIP.js Registerer when it is stuck `waiting` (a clean instance starts with waiting=false), and return the promise so callers can await it. attemptReconnection() now awaits it, so any rejection goes through the existing retry/back-off logic instead of bubbling up as an uncaught error.
The recreation is intentionally conditional: disposing a healthy registerer would send an unregister (REGISTER expires=0) racing with the fresh register (expires=600) and could leave us unregistered, so we only recreate when a request is actually stuck.
Forward-Port-Of: odoo/enterprise#120424
Forward-Port-Of: odoo/enterprise#119701This update corrects a bug that caused bank statement imports to incorrectly multiply amounts by 100. This issue occurred when both the bank statement extraction and import modules were active. The fix ensures accurate import of currency values by preventing the CSV wizard from parsing debit and credit columns a second time.
Original PR description
Steps to reproduce --- 1. With Accounting installed, import a bank statement CSV that has separate Debit and Credit columns using number separators (e.g. a line with "1.234,56"). 2. Map the columns…
Steps to reproduce --- 1. With Accounting installed, import a bank statement CSV that has separate Debit and Credit columns using number separators (e.g. a line with "1.234,56"). 2. Map the columns to Debit and Credit and import. The imported amounts are multiplied by 100: "1.234,56" is imported as 123,456.00. Issue --- This only happens when both `account_bank_statement_import_csv` and `account_bank_statement_extract` are installed, which is the default in any Accounting database since both modules are auto-installed. `account_bank_statement_extract` turns debit and credit into real Monetary fields on `account.bank.statement.line`: https://github.com/odoo/enterprise/blob/af863c5a53d0ab50fe67cb9ea910391d4a1979dd/account_bank_statement_extract/models/account_bank_statement_line.py#L7-L8 Because they are now real fields, the generic importer already converts those columns to floats: https://github.com/odoo/odoo/blob/bfa39854e56da4bf23295d62f63d66973ad0d78e/addons/base_import/models/base_import.py#L1281-L1285 The CSV statement wizard then parses the same columns a second time: https://github.com/odoo/enterprise/blob/d7ab7ee1287342638006e290ede20b955aae8370/account_bank_statement_import_csv/wizard/account_bank_statement_import_csv.py#L92-L93 The first pass correctly reads "1.234,56" as "1234.56", but the second pass sees a lone dot, mistakes it for the thousands separator, strips it, and produces 123456. The wizard now parses debit and credit only when they are virtual fields, so when they are real fields the values parsed by the generic importer are reused instead of being parsed twice. Without `account_bank_statement_extract`, debit and credit exist only as virtual import fields, so the generic importer skips them and the wizard parses them once. That is why the regression stays hidden until the extract module is present. opw-6227083 --- Forward-Port-Of: odoo/enterprise#118979
This update fixes an issue where product imports (specifically from UBL invoices) incorrectly associated products based on name. The fix ensures that product matching uses a proper cache key, preventing incorrect product assignments and ensuring accurate data retrieval during import processes. This improves the reliability of UBL invoice processing.
Original PR description
**PROBLEM** When retrieving a product by name, there is no cache_key for the search_method criteria. This leads to the cache_key frozendict being an frozen dict with None values. This means, once we retrieve a first product with the search_method criteria, all following product will match its cache_key, so we ends up associating a product to all subsequent lines, even if they don't have anything in common. **STEP TO REPRODUCE** 1. Create a product with the name: "CASTELTORRE MERLOT DELLE VENEZIE 75CL 10,5i" (it's important the name is not exactly matching) 2. Import the xml which is attached to the bug fix ticket. 3. Notice the product column on all the lines after a certain point have the CASTELTORRE product, even though the corresponding line in the ubl is for another product. opw-6227280 Forward-Port-Of: odoo/odoo#265987
This update resolves an issue preventing the automatic creation of vendor partners when importing electronic invoices (like XRechnungen) using the Peppol EAS 'EM' (Email) method. The fix allows for the '@' character in email endpoints, addressing a validation error that was incorrectly rejecting valid email addresses. This ensures seamless import of invoices with email-based Peppol connections.
Original PR description
### Issue When importing an electronic bill (such as a German XRechnung) that uses the Peppol EAS 'EM' (Email) with an email address as the endpoint, the import fails during the automatic partner…
### Issue When importing an electronic bill (such as a German XRechnung) that uses the Peppol EAS 'EM' (Email) with an email address as the endpoint, the import fails during the automatic partner creation An error is logged in the chatter stating that the Peppol endpoint is not valid and should contain only letters and digits Since 'EM' stands for Email, the system should allow the '@' character and validate the endpoint format ### Cause While the export logic supported the 'EM' EAS, the validation flow triggered during automatic partner creation on import was too restrictive The global regex `PEPPOL_ENDPOINT_INVALIDCHARS_RE` did not include the '@' character, causing the validation to fail for any email address Additionally, there was no specific format check implemented for the 'EM' EAS type to ensure the endpoint is a valid email string ### Steps to reproduce - Install `account_edi_ubl_cii` - Go to Accounting / Vendors / Bills - Upload an electronic invoice containing an EM EAS and an email endpoint (you can use the added test file or the one from the ticket) Before the fix, an error is raised in the chatter and the partner cannot be created automatically opw-6205745 Forward-Port-Of: odoo/odoo#266894
This update ensures that overtime hours recorded in the system are accurately recognized as additional working time. Previously, these hours weren't being fully accounted for, leading to potential discrepancies in employee tracking and payroll. This fix improves the accuracy of time reporting.
Original PR description
make sure that Overtime Hours entries is concidered as extra hours Task: 6279514 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269539
This update corrects a calculation error in the Saudi HR payroll system related to government contributions (GOSI). Specifically, it now accurately prorates GOSI contributions based on the employee's actual worked days, excluding unpaid leave, ensuring accurate payroll processing for Saudi employees. This improves the reliability and compliance of the system.
Original PR description
Task: 6279514 Forward-Port-Of: odoo/enterprise#119990
This update resolves a technical issue where the Urbanpiper order information screen incorrectly displayed customer details even after the customer was removed. The fix ensures that customer information is only shown when a customer is actually linked to the order, improving the user experience and preventing error messages.
Original PR description
Steps to reproduce: ==== - Place an order through Urbanpiper. - Edit the order and remove the customer. - Open the ticket screen and click the info button. - A traceback occurs. Cause: ==== - Customer details were rendered even when no customer was linked to the order. Fix: ==== - Display customer details only when a customer is present on the order. task-6233812 Forward-Port-Of: odoo/enterprise#120290 Forward-Port-Of: odoo/enterprise#118147
This update fixes an issue where the tag container overlapped with the header on the sign page, particularly when translations resulted in a taller header. The changes automatically adjust the container's position and reduce its height to ensure a clean and consistent layout across different languages and content lengths.
Original PR description
Description: - The `.o_sign_template_tags_and_save` container relied on a hardcoded vertical offset (`top: 65px`) while being absolutely positioned. This assumed a fixed control panel height and…
Description: - The `.o_sign_template_tags_and_save` container relied on a hardcoded vertical offset (`top: 65px`) while being absolutely positioned. This assumed a fixed control panel height and caused the tags container to overlap with the header content when the neutralized red header bar expanded to multiple lines due to longer translated strings. - Replaced `top: 65px` with `top: auto` to remove the dependency on a fixed vertical offset and allow the element to be positioned according to its computed static position. - Reduced the height of `.o_field_widget.o_field_many2many_tags` from `50px` to `35px` to better fit the available space within the header area and prevent visual overlap between tag rows and surrounding elements. - This change preserves the existing positioning strategy while making the layout resilient to variable header heights caused by translations and other content-dependent UI variations. 19 - https://github.com/odoo/enterprise/blob/3db8db2eac3dff1485c6a1c977c80e573bfe6cab/sign/static/src/scss/sign_backend.scss#L486 Before fix: <img width="1874" height="443" alt="image" src="https://github.com/user-attachments/assets/196feab3-3460-4ed9-9f57-d7744e9c4e4b" /> After fix: <img width="1319" height="412" alt="image" src="https://github.com/user-attachments/assets/93ae5bcd-f0f0-4999-9cf7-f83b82d689ac" /> Forward-Port-Of: odoo/enterprise#118937
This update corrects a missing rule in the employer cost calculation process, ensuring accurate reporting for employer contributions. This change was identified following a review and directly addresses a previous fix to the overall calculation. It improves the reliability of payroll data.
Original PR description
In this previous PR https://github.com/odoo/enterprise/pull/106839 the computation of the employer cost was fixed and many rules were flagged as needed in that computation. After a report, we found one of the rules was missing so we add it in this PR. Task: 6088412 Forward-Port-Of: odoo/enterprise#112681
This update fixes a bug that prevented receipt printing from the Odoo App's Point of Sale interface. The fix allows users to print receipts for paid orders, mirroring the functionality available in the desktop version. This ensures consistent receipt printing across all Odoo App experiences.
Original PR description
**Steps to reproduce:** - Go on the Odoo App, start the pos - Go to orders, and go to paid ones - Click on review - Click on Print Receipt - It doesn't do anything, but it prints correctly on browser or desktop **Why the fix:** The Odoo app does not support the iframe printing, so we use this commit to make a hook function to be able to patch it in the enterprise related commit in pos_mobile. This is a backport of eb1e824 Enterprise PR: https://github.com/odoo/enterprise/pull/120043 opw-6186261
This update resolves an issue preventing printing receipts from the Odoo Mobile App. The fix allows the app to correctly print receipts, mirroring the functionality available on the desktop and web versions. It's a necessary update to ensure consistent printing across all Odoo platforms.
Original PR description
**Steps to reproduce:** - Go on the Odoo App, start the PoS - Go to orders, and go to paid ones - Click on review - Click on Print Receipt - It doesn't do anything but it prints correctly on browser or desktop **Why the fix:** This is a partial backport of 41e4549 that fixes the app to allow the way we created IFRAMES in PoS since 19.2, allowing us to print on the app again. Community PR: https://github.com/odoo/odoo/pull/265024 opw-6186261
This update fixes a visual issue where suggestion icons weren't appearing in the Odoo Assistant. The problem was due to a missing activity type, which prevented the icons from being correctly displayed. By adding this information, the Assistant now accurately shows suggestion icons for activities like 'Working on task'.
Original PR description
- When the Assistant detected activities such as 'Working on task', the suggestion icon was not displayed because the event type was not assigned. Unlike `aw.rule` matches, the Odoo URL resolver only set the label and related record information, but did not set the activity type required by `getIcon()`. - Expose the activity type through `get_assistant_data` and assign the activity type when resolving model URLs in extractWatcherActivity. task-6259793 Forward-Port-Of: odoo/enterprise#120370
This update ensures that website snippet templates are correctly generated during the website builder process. Previously, a configuration issue caused errors when using certain themes, but this fix guarantees that all necessary templates are created, resulting in a smoother website building experience for our users. It resolves a potential issue where the website wouldn't render correctly after building.
Original PR description
Steps to reproduce: - Start from a database where the eCommerce app is not installed. - Open the website configurator. - In the first step, choose "I want an eCommerce". - In the Pages and Features…
Steps to reproduce: - Start from a database where the eCommerce app is not installed. - Open the website configurator. - In the first step, choose "I want an eCommerce". - In the Pages and Features step, select all Pages. - Select a theme that adds an eCommerce category snippet, for example "Treehouse". - Build the website. => During the first `configurator_apply`, `website_sale` is installed after the theme and the configured menu items are already created. => The homepage rendering then needs a `website_sale` configurator snippet template requested by the theme, but it was not generated during that first call. => The client retries `configurator_apply`. It now succeeds because `website_sale` is fully installed, but page and menu creation runs again and duplicates the menu items. Before this commit, primary snippet template generation only read the manifest of the module being generated. When `website_sale` was installed from the first `configurator_apply`, it did not see addon snippets declared by the already installed theme. The first call could therefore fail while rendering the homepage after pages and menus were created. After this commit, generation also reads installed theme addon snippets that target the module being generated. The `website_sale` configurator templates requested by the selected theme are created before the first homepage rendering, so `configurator_apply` does not retry after creating menu items. task-5973739 Forward-Port-Of: odoo/odoo#261022
This update fixes an issue where changes made to leave details within the popover form weren't being saved correctly. The fix introduces a delay to handle rapid changes and ensures that modifications are saved, improving the user experience when managing time off requests. It also maintains access to key actions like 'Refuse' and 'Delete'.
Original PR description
Steps:- - Navigate Payroll > Time Offs. - Create a leave of any type (STO, PTO etc...) - Click on the pill after creating leave. - Try to change values on popover. - Changed values are not saved!! Cause:- There is no save action trigger on popover form. Fix:- - Hooked `debounceAutoSave` method on every field value changes. - `debounceAutoSave` will save record with 500ms debounce to batch rapid changes. - Set popover form to readonly mode for validated leaves (validate/validate1 states) - Remove readonly condition from action buttons footer to keep Refuse/Delete accessible task-[6117310](https://www.odoo.com/odoo/project/1251/tasks/6117310)
This update resolves an issue where the version timeline widget was causing unnecessary page reloads when versions were updated. The fix replaces a delayed refresh with a more efficient method of triggering a data update, resulting in smoother performance and faster loading times for version history.
Original PR description
A useEffect was added to clear the cache of the versions in case of generation or removal of versions. This is not the best as it waits for everything to be rendered and applied to the DOM to trigger a reload. The alternative is to add a context to the widget and to the orm.searchRead, to trigger a cache miss on version change. task-6289891 Forward-Port-Of: odoo/odoo#269089
This update fixes a visual issue where debit notes generated as PDFs incorrectly displayed 'INVOICE DINV...' instead of 'DEBIT NOTE DINV...'. This change ensures that debit notes are clearly distinguishable from invoices in printed and emailed documents. The fix was driven by a customer request to improve clarity and accuracy.
Original PR description
### Steps to reproduce the issue: 1. Download Invoice and Debit Notes 2. Go to an invoice (or create a new one) 3. Create a debit note for that invoice and print it or send it 4. In the PDF the title is 'INVOICE DINV....' instead of 'DEBIT NOTE DINV...' ### Reason to introduce the fix: Differentiate debit notes from invoices. opw-6252239 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268207
This update resolves an issue where the URL used for OAuth authentication with the Romanian tax authority (ANAF) was incorrectly generated. The previous method relied on the user's current session, leading to mismatched URLs and failing authentication. This change ensures the correct, standard URL is used, allowing for proper tax reporting functionality.
Original PR description
The `_compute_l10n_ro_edi_callback_url` method was using `request.httprequest.url_root` to build the OAuth callback URL. The URL is derived from the current HTTP request, meaning it reflects however the user accessed the session at that moment (e.g. internal IP, localhost, non-standard port). This produces a callback URL that does not match what was registered with ANAF, breaking the OAuth flow. 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#268974 Forward-Port-Of: odoo/odoo#265000
This update resolves an issue where the VoIP softphone would generate errors when receiving calls from numbers not linked to a contact. The fix ensures that task creation from contactless calls works as expected, and the 'Tasks' button is hidden when no contact is associated with the call, preventing errors and improving usability.
Original PR description
**Problem:** Two linked errors occur in the Phone (VoIP) softphone when a call is made to or received from a number that is not linked to any contact. **Steps to reproduce:** 1. Receive or make a…
**Problem:** Two linked errors occur in the Phone (VoIP) softphone when a call is made to or received from a number that is not linked to any contact. **Steps to reproduce:** 1. Receive or make a call from the softphone using a phone number that is not linked to any existing contact. 2. Open the call's actions and click "Create" > "Task". -> A client error appears and the task is not created. 3. On a voip.call form whose Contact has been removed, click the "Tasks" smart button. -> A server error is raised. **Current behavior:** Step 2 raises "Cannot read properties of undefined (reading 'id')" and step 3 raises "ValueError: not enough values to unpack (expected 1, got 0)". **Expected behavior:** Creating a task from a contactless call should open the task form without a default contact, and the Tasks smart button should not be reachable when the call has no contact. **Cause of the issue:** Both code paths assume a call always has a linked partner. In `action_list_patch.js`, `getCreateTaskAction` only checks `shouldShowTaskButton` in its predicate but reads `this.contact.id` in its `onClick`; for a contactless call `this.contact` is undefined. In `voip_call.py`, `action_view_tasks` delegates to `self.partner_id.action_view_tasks()`, whose `ensure_one()` fails on the empty partner recordset. Unlike the softphone "view tasks" action, which is gated by `this.contact?.task_count`, the form stat button had no visibility guard. **Fix:** The create-task action now mirrors the existing contact and lead actions, which already build their context conditionally on `this.contact`, so a contactless call simply opens the task form with no default partner. The Tasks stat button is hidden when there are no tasks, matching the softphone predicate and ensuring the partner-less code path is never reached. opw-6246641