Friday, October 17, 2025
44 changes · 19.0
New functionality added to Odoo
Adds localized accounting reports for Sri Lanka, including balance sheet and profit and loss reporting. This helps Sri Lankan businesses use Odoo with reports aligned to local accounting needs and improves report structure and balancing.
Original PR description
Implement a basic accounting package for Sri Lanka including: - COA - Tax groups - Taxes - Fiscal Positions - Tax reports (VAT001, WHT001) task-4352802 retargeted from master #224917
Enhancements to existing features
Small bank statement imports are now reconciled immediately, while larger imports are still processed in the background to avoid delays. This improves responsiveness for everyday small imports without slowing down heavier accounting workloads.
Original PR description
When doing an import, to avoid taking too much time we decided to trigger the cron directly but for small files it's not really efficient. When the file has less than 80 statement lines we do the auto reconcile otherwise we trigger the cron. task-5162686
Resolved issues and error corrections
This fixes several inventory costing issues so stock values better reflect actual quantities, locations, and recent cost corrections. Businesses should see more reliable FIFO/average cost calculations, valuation reports, and cost of goods sold figures, with expanded tests to reduce future regressions.
Original PR description
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
Payroll users can now view and manage contract offers directly from the employee form without needing recruitment permissions. This improves day-to-day payroll workflows by giving the right teams access to offer information where they need it.
Original PR description
Previously, the "Offers" smart button on the employee form was only available to recruitment users. This limited visibility for payroll officers who also need access to contract offers. This commit: - Changes the button visibility to `hr_payroll.group_hr_payroll_user` in `hr_employee_views.xml`. - Adds missing access rights in `ir.model.access.csv` for `hr.group_hr_user` (inherited by payroll users). - Updates the module manifest to include the new security CSV. The goal is to ensure payroll users can access and manage offers directly without requiring recruitment rights. task-5085078
The German tax report has been reorganized to better match the official ELSTER VAT return structure. This makes the report easier for German businesses and advisors to review and align with expected filing categories.
Original PR description
Rework the structure of the German Tax Report according to the very well detailed structure https://sevdesk.de/ratgeber/buchhaltung-finanzen/ustva/formular-elster/ task-5046641 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The German tax report has been reworked after removing a balance column, ensuring the report logic continues to match the new layout. This helps maintain accurate German tax reporting and reduces the risk of reporting issues after the layout change.
Original PR description
After removing the balance column, we need to refactor the code that depends on it task-5046641
The Hong Kong payroll Manulife MPF report is easier to use, with a button to populate employees and safeguards that preserve manual changes. It also corrects how new employee contribution data is split across months, improving report accuracy and reducing manual rework.
Original PR description
Improve the report UX, replacing the compute that didn't really work by a button to populate the employee list, avoid overriding changes done on generated lines, and avoiding to block the feature if some settings are not set to instead display fields for these to relevant users. Also fixes an issue with how the data is recorded for new employees, which would sum the first few months in a single line instead of spreading the data correctly. Precomputation is added to the lines in the report to ensure that the lines appear when the form is opened and do not require to play with the date for it. task-5091533
Refreshing webhooks from the settings now disconnects existing POS product links and sends a fresh menu update to UrbanPiper. This helps ensure the external delivery platform receives the latest product/menu setup after a webhook refresh.
Original PR description
Following this commit: - On refreshing webhooks from settings, products will be unlinked from pos. - Fresh menu will be updated to Urbanpiper platform task-5163764 Forward-Port-Of: odoo/enterprise#97000
Italian electronic invoices are now processed one at a time when sent through the external exchange service, reducing timeout issues when large batches are submitted. This helps prevent scheduled invoice processing from getting stuck and improves reliability for customers sending many invoices at once.
Original PR description
Some clients reported that when they send a full batch size=20 invoices at once, they get a timeout response and the cron job get's stuck. Processing invoices one by one instead of a full batch. IAP-apps PR: https://github.com/odoo/iap-apps/pull/1230 Task [link](https://www.odoo.com/odoo/project.task/5045529) task-5045529 Forward-Port-Of: odoo/odoo#231742 Forward-Port-Of: odoo/odoo#230146
This update prepares Point of Sale IoT connections for upcoming Chrome local network access rules. It helps ensure Odoo can continue communicating with local IoT devices, such as connected hardware, when accessed from secure browser sessions.
Original PR description
Enterprise PR: https://github.com/odoo/enterprise/pull/96850 Local Network Access restrictions will start shipping by default in Chrome 142. As part of this change, local requests will be allowed to use HTTP in an HTTPS context (gated by a browser permission prompt). This will work automatically when the IP is provided directly, however in the case of IoT we often use the odoo-iot DNS domain to resolve the IP. In this case, you must specify the option `targetAddressSpace: "local"` in the `fetch` request. This commit simply adds this change where appropriate. task-5157145 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231644 Forward-Port-Of: odoo/odoo#231014
This update prepares Odoo’s Point of Sale IoT connections for upcoming Chrome browser restrictions on local network access. It helps ensure local IoT devices can still be reached reliably when using the odoo-iot address, reducing the risk of disruption for stores using connected hardware.
Original PR description
Community PR: https://github.com/odoo/odoo/pull/231014 Local Network Access restrictions will start shipping by default in Chrome 142. As part of this change, local requests will be allowed to use HTTP in an HTTPS context (gated by a browser permission prompt). This will work automatically when the IP is provided directly, however in the case of IoT we often use the odoo-iot DNS domain to resolve the IP. In this case, you must specify the option `targetAddressSpace: "local"` in the `fetch` request. This PR simply adds this change where appropriate. As part of this we have also backported the change from jquery -> fetch. task-5157145 Forward-Port-Of: odoo/enterprise#97224 Forward-Port-Of: odoo/enterprise#96850
Warehouse teams can now choose which IoT printer is used for shipping labels instead of the system automatically picking the first suitable printer. This helps businesses route labels to the right printer by operation type and avoids confusing errors when a printer is not configured.
Original PR description
Printing shipping labels is performed from the backend, once the shipping info are received in the chatter. The printing command is sent to the frontend via the user bus, then though longpolling to the iot box. This commit adds the possibility to select a printer instead of choosing automatically the first (with the right report associated) on the list. As the change is made on a stable version, we are using system parameters to store the selected printer without adding a new field. We associate a printer with the picking type, in order for to be able to have different printers by default on different picking types. backport of odoo/enterprise#86818 Task: 4792491 Forward-Port-Of: odoo/enterprise#97396 Forward-Port-Of: odoo/enterprise#95794
Point of Sale settings now include a test button for Epson receipt printers, helping staff confirm printer setup before using it in daily operations. The test prints a sample receipt or shows a clear error, such as no paper or printer unreachable, and printing now has a 15-second timeout to avoid long waits.
Original PR description
This PR adds a test button to all the views in point of sale where the epos printer can be configured (pos config / res config and preparation printer) When clicked a test receipt is printed on the epos printer or else an error is shown like "no paper" / "failed to reach printer" etc. Finally it adds a timeout of 15s to Epos printing which isn't there now Task-5153542
Project action buttons now remain available for users who have not yet set up their own top bar preferences. When a user's configuration is missing, Odoo reuses the project manager's configuration so teams see the expected project actions without extra setup.
Original PR description
If the current user doesn't have a top bar configuration yet for a given project, we fallback on the top bar configuration of the project manager to show the actions. task-5072899 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Closing a session from a kiosk configuration now behaves like the dashboard Close Session button instead of opening the point of sale interface. This prevents staff from being redirected to the wrong screen and makes kiosk session management more consistent.
Original PR description
Currently when you're on the config of a kiosk, the link `Click here to close the session` opens the session. This was never intended when we have a kiosk. Now, if we have a kiosk, when selecting this link it will close the session the same way it does when selecting the button `Close Session` on the dashboard. opw-5024837
Online orders that were already paid through ecommerce are now recognized correctly when opened in the Point of Sale. The POS will account for the existing payment or hide fully paid orders, helping staff avoid charging customers twice.
Original PR description
Before, if you paid for something on the website with ecommerce, it would create a sale order with a transaction linked to it, but no invoice. So in the POS the order would show up in the Quotation/Order menu, but the POS didn't have any reference on the payment, so you would have to create another duplicate payment. Now the amount_paid (which is the amount already paid in transactions) is taken into account when calculating what's left to pay in the POS. So anytime you open a sale order in the POS it should create a down payment line for anything already paid on the website (the same as we were already doing for invoices). Also to avoid double payments, now the sale orders which have been already paid in full, even if they are not invoiced yet, will not show up in the POS. The invoice can still be created normally from the Sale app in Odoo. Task-5138081 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Mass mailing content now keeps dynamic placeholders in the correct position when a mailing becomes read-only after sending. This prevents unwanted line breaks and restores missing editor styling, so sent emails display as intended.
Original PR description
In editable fields, the Html Editor currently adds the data-oe-t-inline attribute to items that are identified as needing to be displayed inline However, this attribute is added by the editor and…
In editable fields, the Html Editor currently adds the data-oe-t-inline attribute to items that are identified as needing to be displayed inline However, this attribute is added by the editor and removed on save. As a result, if the editable body is ever set to readonly(for example: a mailing that is sent no longer allows users to edit its body), then the inline property appears to be lost: an inline dynamic attribute suddenly looks like it's on its own line. Steps to reproduce: - Create a mailing - Add a dynamic attribute in the middle of a line - Send the mailing - You will see a carriage return directly before and after the dynamic attribute Fix: The mass_mailing html field now applies the current inlining logic to readonly HTML. -- https://github.com/odoo/odoo/pull/229049 deleted several duplicated styles exclusive to the HTML builder from html_editor:common.scss, which were also present in qweb_plugin.scss. However, the mass_mailing html editor does not take into account this file to determine styles within the editor iframe (nor does it use any plugin in readonly mode.) To fix this, the missing styles are duplicated into mass_mailing, to be used in both editable and readonly modes. task-4852246
The Argentine VAT report export now correctly generates both required AFIP text files for type C invoices and invoices without taxes. This helps businesses submit complete tax reporting files and avoid missing-document issues with AFIP.
Original PR description
…afip code '0' **Description of the issue/feature this PR addresses:** This PR addresses an issue identified in the generation of .txt files for invoices that utilize AFIP tax code '0' **Current behavior before PR:** The system is only generating one of the two .txt files required by AFIP for specific invoice types. Affected Cases: - Invoices of type 'C'. - Invoices that have no taxes. **Desired behavior after PR is merged:** Two .txt files should be generated for all invoice types, as per AFIP requirements. [HERE](https://app.screencastify.com/watch/2mtioGVxEOwW0rAHJS2v) is a video replicating the issue: 1. In localization Argentina, create a vendor bill type 'C' 2. In 'Tax Return' report, filter by date and 'Tax Type: Purchase' 3. Download .ZIP file and see only one .txt Forward-Port-Of: odoo/enterprise#96052
The General Ledger now keeps the Initial Balance line at the top when users load account entries in smaller batches. This prevents missing or duplicated ledger lines and gives finance teams a complete, correctly ordered view of account activity.
Original PR description
### Issue: The "Initial Balance" line in the General Ledger is not the first line with the "Load more" option ### Steps to reproduce: - Accounting > Configuration > Accounting Reports > General…
### Issue: The "Initial Balance" line in the General Ledger is not the first line with the "Load more" option ### Steps to reproduce: - Accounting > Configuration > Accounting Reports > General Ledger - Change the Load more limit in the options to a small number, i.e. 4 - Open the General Ledger and unfold an account with more than 10 lines - There is no Initial Balance line, it appears when clicking "Load more" ### Cause: The General Ledger query have this line `ORDER BY 2, move_name, 1`. Here 2 refers to the date and 1to the `account_move_line.id`. But the initial balance line has these columns equal to `NULL` so this ORDER BY will place it at the end of the results. When the limit is smaller than the total number of lines, the initial balance is not fetched by the query. **Additional issue** The limit is incremented several times. In our case, we set the option at 4. It gets incremented [here](https://github.com/odoo/enterprise/blob/edb4ba5b98be9f9ae3617cc6e66c5e3376a1b56c/account_reports/models/account_report.py#L7172) because the load more option is triggered, and also [here](https://github.com/odoo/enterprise/blob/edb4ba5b98be9f9ae3617cc6e66c5e3376a1b56c/account_reports/models/account_general_ledger.py#L239) for no apparent reason (it is not needed "for the Initial balance"). So the query is called with `limit=6`, six lines are retrieved when clicking on "Load more". Considering a scenario where there are 10 lines for the account (with the initial balance) and "Load more limit" set to 4: - The first query gets the lines 1-6 but only 1-4 are displayed. - Clicking "Load more", the offset is 4, the query gets the lines 5-10. 10 being the initial balance, it is put in first position by [this piece of code](https://github.com/odoo/enterprise/blob/edb4ba5b98be9f9ae3617cc6e66c5e3376a1b56c/account_reports/models/account_general_ledger.py#L79-L91). So the lines displayed are 10, 5, 6, 7 - Last click on "Load more", offset is 8, query gets 9 and 10, displays 10, 9. In the end, one line is not displayed, and the initial balance is displayed twice. ### Solution: Add `NULLS FIRST` in `ORDER BY` to always have the Initial Balance as the first line returned by the query. Also remove the unnecessary `limit+1`. opw-5105652 Forward-Port-Of: odoo/enterprise#96136
Gift Card and E-Wallet products now appear in the Point of Sale even when the store is limited to selected product categories. This ensures staff can consistently sell these payment-related products without extra category setup.
Original PR description
Before this commit: =================== If the PoS configuration is restricted to specific categories, but the Gift Card and E-Wallet products do not have any category assigned, these products will not be visible in the PoS UI. After this commit: ==================== Gift Card and E-Wallet products are now always visible in the PoS UI, regardless of whether a PoS category is assigned or not. Purpose: ============ Gift Card and E-Wallet products should always be available for sale in the PoS. This ensures they can be sold physically from the PoS UI without requiring category assignment. Task-5103770 Forward-Port-Of: odoo/odoo#231626 Forward-Port-Of: odoo/odoo#228395
Electronic payments registered from an invoice will now keep the payment transaction connected to that invoice. This improves payment traceability and helps users see the full invoice-to-payment relationship correctly.
Original PR description
Steps to reproduce: - Create an invoice through Accounting app - Post the invoice - Register the payment using the "Register Payment" wizard with an electronic payment method. Description of the…
Steps to reproduce: - Create an invoice through Accounting app - Post the invoice - Register the payment using the "Register Payment" wizard with an electronic payment method. Description of the issue/feature this PR addresses: **The payment transaction was not being linked to the invoice for electronic payments.** To resolve this, I passed the current invoice IDs as context through action_register_payment in the account.move.line model. Then, I retrieved this context value in _prepare_payment_transaction_vals of the account.payment model to set the invoice_ids Many2many field. Current behavior before PR: The payment transaction is not linked to the invoice for electronic payments. Desired behavior after PR is merged: The payment transaction will be correctly linked to the invoice for electronic payments. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#208520 Forward-Port-Of: odoo/odoo#197091
Users can now create their first timesheet even if they do not have access to the company’s internal project. The system avoids selecting a project they cannot access by default, preventing an error and allowing the timesheet process to continue.
Original PR description
To reproduce: ============= - make the internal project of the company for invited internal users only - with internal user that doesn't have access to the internal project, and no previous timesheet created, try to create a timesheet - you get a traceback Problem: ======== when not having a previous timesheet, in the default value we set project_id based on the internal project of the company. But if the user doesn't have access to this project, it raises an access error. Solution: ========= check if the user has access to the internal project of the company, if not, use `False` as default value. opw-5119839 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229818
Checkout progress labels are now translated correctly when shoppers use a website in another language. This improves the checkout experience for multilingual stores by avoiding English-only step names.
Original PR description
Versions -------- - saas-18.3+ Steps ----- 1. Have a website; 2. enable a new language (other than English); 3. use website in this language; 4. go to checkout. Issue ----- The checkout steps on the top-left aren't translated. Cause ----- Commit dbd22d93183f2 added the `website.checkout.step` model. Like `website.menu`, they have a default record that gets set on initialization, which is then gets used to create a new record per website. The issue is that when enabling a new language, it only translates the default records. The records that are website-specific remain unchanged. Solution -------- Because they function the same we as `website.menu`, we can use the same approach that was taken to translate website menus, and add a `_load_module_terms` override to `ir.module.module`, constructing a SQL query that copies the translations from the default records to the website-specific records. opw-4985676 Forward-Port-Of: odoo/odoo#223019
The sale product configurator now uses screen space better on mobile when optional products include custom attribute fields. This keeps the text input and cart button easier to view and use, reducing friction for shoppers on smaller screens.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Create a product attribute with a single custom value; 2. add the attribute to a product A; 3. set product A as an optional product of product B; 4. go to product B's product page in mobile view; 5. click on the cart button. Issue ----- The custom text field takes up way too much real estate. Cause ----- The template isn't fully adapted for mobile view. Solution -------- Change `d-flex` to `d-lg-flex` on the `ptal` element, making the attribute name & input online display in-line on large screens. Additionally, change some bootstrap classes to also have the cart button button displayed within the screen. opw-5114495 Forward-Port-Of: odoo/odoo#231744 Forward-Port-Of: odoo/odoo#230743
Spreadsheet pivots now let users explore related fields from dimensions they have already selected, while still preventing exact duplicates. Date fields can also be reused with different time groupings, making analysis more flexible and reducing blocked reporting workflows.
Original PR description
Before this commit: - Once a dimension (e.g, 'Customer') was selected in a pivot, it could not be used for drilling into related fields, preventing cross-model exploration. - Date and datetime fields could not be re-selected to use different granularities (day, month, year, etc.). After this commit: - The pivot forbids re-selecting the exact same dimension but still allows users to drill and select fields from related models. - Date and datetime fields remain selectable to allow choosing different granularities, improving flexibility in pivot analysis. Task: [5114511](https://www.odoo.com/odoo/2328/tasks/5114511)
This update corrects how hierarchy-based searches work when some related records are not directly accessible to the current user. It helps ensure business data queries return the expected results while still respecting access rules.
Original PR description
We introduced a regression in https://github.com/odoo/odoo/pull/170009 for 'child_of'/'parent_of' operators on relational fields: With a domain leaf like `[('X2X', 'child_of', ids)]` where the X2X comodel has `_parent_store=True`, we don't take into account inaccessible children from the current user. That's incorrect, and we already fixed this behavior in ae038904face6766d93695dcaa9b07346d05282a, but the test added targeted 'res.partner' which has `_parent_store=False`.
Fix it by using a `_search()` on the sudoed comodel instead of the 'any' operator. In 19.0 we should use 'any!' operator instead.
Forward-Port-Of: odoo/odoo#231540
Forward-Port-Of: odoo/odoo#231458This fix ensures Mexican electronic invoice XML files are created with the correct file type even when the user lacks certain technical permissions. It prevents related accounting documents from being missed when document centralization is enabled, improving reliability for accounting workflows.
Original PR description
When creating an XML attachment as a user without Write access on the ir.ui.view model, the Mimetype will be set to plain/text. In particular, this causes issues when Accounting centralization is enabled in Documents, as the corresponding Document will only be generated if the Mimetype is application/xml. Creating the XML as Superuser avoids this issue. Similar to https://github.com/odoo/odoo/pull/124507 opw-5057038 Forward-Port-Of: odoo/enterprise#97258 Forward-Port-Of: odoo/enterprise#95197
Manufacturing order validation now handles cases where no finished move lines exist. This prevents unexpected crashes when posting labor costs from work orders, helping production teams complete validations more reliably.
Original PR description
In some cases, a Manufacturing Order may not have any finished move lines. When posting labor costs from work orders, it tries to access the first finished move in order to retrieve its account. If no finished move exists, this leads to a traceback at MO validation. This commit ensures a proper fallback account is used when no finished moves are linked to the MO, avoiding unexpected crashes. opw-4858696 opw-5066266 Forward-Port-Of: odoo/odoo#229339
SAF-T exports now report the tax payable amount correctly when reverse charge taxes are used, instead of showing zero. This helps Romanian tax reporting match authority expectations and reduces the risk of incorrect declarations.
Original PR description
When a reverse charge tax is used, we export a `TaxInformation` with a zero amount instead of the real amount of the tax. The tax authority requires to show the tax to pay and doesn't care about the tax to receive... In order to fix this, we only sum the tax details of lines having positive repartition lines. opw-5125678 Forward-Port-Of: odoo/enterprise#97315 Forward-Port-Of: odoo/enterprise#97117
The Belgian payroll salary configurator now checks the active company before applying Belgian-specific salary calculations. This prevents incorrect handling in other company contexts and ensures the gross salary is shown where expected.
Original PR description
Gross Salary did not appear previously as the extending function _get_compute_results in 10n_be_hr_contract_salary was returning the l10n_be_wage_with_mobility_budget right away without checking which company we are in. This change made sure before proceeding that we are in the correct active company, Belgian one in our case. task-4987491 Forward-Port-Of: odoo/enterprise#96678 Forward-Port-Of: odoo/enterprise#94905
Posting vendor bills now correctly keeps and creates analytic items when analytic accounts are set, even when journal auto-checking is disabled or lock dates apply. This prevents missing analytic reporting data and helps businesses keep cost tracking accurate.
Original PR description
To reproduce: 1. Ensure Analytic Accounting is activated in the accounting settings 2. Uncheck the option Auto-Check on Post in the Vendor Bills journal 3. Create a vendor bill and set analytic…
To reproduce: 1. Ensure Analytic Accounting is activated in the accounting settings 2. Uncheck the option Auto-Check on Post in the Vendor Bills journal 3. Create a vendor bill and set analytic accounts in at least one line 4. Post the vendor bill 5. Go to Accounting > Analytic Items 6. No analytic item was created for the vendor bill In some cases, such as when the vendor bill journal has `Auto-check on Post` disabled or a there is a lock date set, the analytic items are not created when posting the move, even if analytic accounts were set on the move lines. Cause: In #222196, a check is performed when writing an account.move.line, which unlinks analytic lines created for draft moves. However, this condition is too general, and if additional writes happen in between the analytic line creation and changing the move state to `posted`, the analytic lines are deleted. Solution: The unlinking on analytic lines should only be performed if `analytic_line_ids` are in vals. opw-5053179,opw-5154394 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231874
Uruguayan electronic invoices now include invoice lines that have a zero total, such as free delivery or fully discounted items. This ensures these lines are properly reported to the tax authority as free delivery, avoiding missing information in electronic invoice records.
Original PR description
## Description of the issue The client wants to register 0.0 line to the CFE (delivery line with price 0.0): based on our findings, the only way to report lines with 0 values to the DGI is by…
## Description of the issue The client wants to register 0.0 line to the CFE (delivery line with price 0.0): based on our findings, the only way to report lines with 0 values to the DGI is by configuring the line as a "free delivery." (invoice indicator 5). But this lines is not been reported as part of the CFE xml (neither as a Free Delivery line or discount ## Steps to reproduce 1. Create a Uruguayan electronic invoice (sales default journal on a UY company) 2. Add a line with quantity 1. price 0 3. Add a second line with quantity 1, price 500 and discount 100% ## Before this PR 1. if we have a line with price unit != 0.0 but with total price of the line 0.0 (as the second line), then we are reporting the invoice line as Free Delivery. 4. But, If we have an invoice with line with price unit 0.0 (example first line) then is not being informed in the CFE at all ## After this PR Both lines are informed to DGI using the invoice indicator 5 (Free Delivery) You can check this on to generate CFE XML in demo mode (not need to connect to UCFE) If you want more visual example please connect to UCFE in testing enviroment and check the generated PDF file. References [Odoo task](https://www.odoo.com/odoo/project/967/tasks/5015691) LATAM 1350 / ADHOC task 53445 Forward-Port-Of: odoo/enterprise#89808
When creating a vendor bill from an IRN in an Indian GST tax unit, the system now looks across all companies in the tax unit for a valid purchase journal. This prevents bill creation failures when the main company does not have its own purchase journal configured.
Original PR description
Before this PR: - The system searched for a purchase journal only in `company_id`. - In a tax unit with multiple companies, if the main company had no purchase journal configured, record creation failed with a 'NOT NULL constraint violated' error. After this PR: - The journal search now checks all companies in `company_ids` (or falls back to `company_id`), - allowing the system to find a valid purchase journal across the tax unit. Forward-Port-Of: odoo/enterprise#97255
Errors during IoT device actions are now reported accurately instead of being overwritten as successful connections. This helps users and support teams see when an IoT operation really failed, avoiding misleading status information in the interface.
Original PR description
Before this commit, if an error occurred during the execution of an action, it was catch in the _do_action method. To signal that an error occured, we put "error" in the status of the response. However, before this commit, the status was overriden with a "connected" value right after being set to "error", which led to the frontend thinking everything was fine. This is now solved by only setting one status. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231615
This fix improves Spanish Facturae e-invoice generation so product prices with extra decimal precision and globally rounded taxes are reflected correctly in the XML. It helps avoid rounding differences between invoices and submitted e-invoice files, reducing validation issues and accounting mismatches.
Original PR description
This PR is the opportunity to fix two mistakes in the XML generation of the e-Factura : 1. It is possible for a product to have more decimals than the currency, but the facturae always rounded…
This PR is the opportunity to fix two mistakes in the XML generation of the e-Factura : 1. It is possible for a product to have more decimals than the currency, but the facturae always rounded according to the currency. This would sometimes lead to both rounding errors and incomplete or incorrect values on the generated XML. This commit rounds product prices according to the unit price decimal while leaving the other computed field untouched as to not disturb the correct computation elsewhere. 2. When the tax rounding was set to round_globally, the TotalTaxOutput in the XML might differ from the actual tax_amount from the invoice because of rounding errors occurring during uncessary re-computation while building the XML. While stable is not the place to change all functions related, we can isolate computed tax output and tax withheld values and transmit them without any intermediary. As this file was changed in 18.0 another PR was needed from 17.0: https://github.com/odoo/odoo/pull/209623 (unit price decimals) and https://github.com/odoo/odoo/pull/229017 (tax rounding issue, detected after 209623 was closed) task-4650439 Forward-Port-Of: odoo/odoo#231424 Forward-Port-Of: odoo/odoo#229236
The Manufacturing Orders split wizard now handles multiple records safely, preventing an error that could block users from splitting production orders. This improves reliability for manufacturing teams using batch or multi-record workflows.
Original PR description
**Issues:** **1. Singleton error:** - When using the Split Manufacturing Orders wizard in MRP (mrp.production.split), singleton error occures given below <img width="1920" height="925" alt="image" src="https://github.com/user-attachments/assets/0697fa6e-989a-4391-bdb3-79fd5a1b5998" /> **2.Unsafe field initialization:** - **self.num_splits = 0** was set outside the loop, overwriting multi-record computations. - **self.valid_details = false** in also set outside the loop. **Fixes Implemented:** - Replaced self.max_batch_size → wizard.max_batch_size - Moved initialization of num_splits and valid_details inside the loop **Result:** - No more Expected singleton error. - Safe, consistent behavior even with multiple records. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes Indian e-invoicing so reverse charge, export, and Special Economic Zone sales report the correct GST rate and tax values. It helps businesses avoid incorrect tax reporting and improves alignment with Indian GST e-invoice rules.
Original PR description
[FIX] l10n_in{,_edi}: Sale RCM and SEZ(With LUT) Steps to reproduce: 1. Install `l10n_in_edi` 2. Create an invoice with a RC tax/SEZ (with LUT) tax 3. Confirm and Process for E-invoice 4. See the EDI…
[FIX] l10n_in{,_edi}: Sale RCM and SEZ(With LUT)
Steps to reproduce:
1. Install `l10n_in_edi`
2. Create an invoice with a RC tax/SEZ (with LUT) tax
3. Confirm and Process for E-invoice
4. See the EDI content, The GST rate is 0%
Before this
For RC and SEZ (with LUT) the tax rate and tax amount were sent
as `0` and (data going wrong for SEZ/Exports) for Indian E-invoicing.
Following the fix:
1. We rename the the IGST x% (SZ/EX) -> IGST x% (EX)
2. Introducing new taxes for SEZ with LUT
3. Fiscal for Export and SEZ renamed to Export (same for LUT)
4. Introducing new fiscal for SEZ and SEZ (LUT)
5. In case of Special Economic Zone normal taxes (IGST) should be applied
because as per the [API Doc](https://einv-apisandbox.nic.in/version1.03/generate-irn.html#validations)
It states -
**However, in case of Reverse charge and Export transactions (EXPWP), Total value of Item can match with either with tax values or without tax values. That is, the total value of item can include or exclude the tax values as per the business requirements.**
So SEZ without LUT should be passed as normal IGST
For Export without LUT
Label | Taxes | credit | debit| Tags
-------------------------------------------------------------------------------------------------------------
Product A | 18% IGST S (EX) | 100 | | Base IGST
IGST 18% | | 18 | | IGST
IGST Paid on SEZ/Export Sales | | | 18|
Creditor | | | 180|
Invoice Total 100
EDI with {'rate': 18.0, 'IgstAmt': 18.0, 'TotItemVal': 100}
For SEZ without LUT
Label | Taxes | credit | debit | Tags
-----------------------------------------------------------
Product A | 18% IGST S (SEZ) | 100 | | Base IGST
IGST 18% | | 18 | | IGST
Creditor | | | 118|
Invoice Total 118
EDI with {'rate': 18.0, 'IgstAmt': 18.0, 'TotItemVal': 118}
For Export/SEZ with LUT
Label | Taxes | credit | debit | Tags
-----------------------------------------------------------
Product A | 18% IGST S (SEZ) | 100 | | Base IGST
IGST 18% | | 18 | | IGST
IGST 18% | | | 18 | IGST
Creditor | | | 100|
Invoice Total 100
EDI with {'rate': 18.0, 'IgstAmt': 0.0, 'TotItemVal': 100}
For RCM
Label | Taxes | credit | debit | Tags
-------------------------------------------------------------------------------
Product A | 18% IGST S RC | 100 | | Base IGST || BASE IGST RC
IGST 18% RC | | 18 | | IGST
IGST 18% RC | | | 18| IGST RC
Creditor | | | 118|
Invoice Total 100
EDI with {'rate': 18.0, 'IgstAmt': 0, 'TotItemVal': 100}
task-4878805
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#228871
Forward-Port-Of: odoo/odoo#213931Users returning to kanban, pivot, and mobile list views will now be brought back to the same scroll position they left. This makes navigating back through breadcrumbs or switching views smoother and reduces time spent finding the previous place on the page.
Original PR description
When coming back to a view using the breadcrumb or with the view switcher, we want to restore the local state of the view as it was when we left it, in particular the scroll position. This is handled…
When coming back to a view using the breadcrumb or with the view switcher, we want to restore the local state of the view as it was when we left it, in particular the scroll position. This is handled by the `useSetupAction` hook, for all views (except for the list as the scrolling container is custom, because of the fixed table header). However, since [1], it was no longer working in kanban, pivot and list (mobile only). This was due to the fact that those views are now "lazy", i.e. they are rendered directly, without the data, such that the control panel is available asap. As a consequence, when `onMounted` is called (i.e. when the hook attempts to restore the scroll position), there's no scrollable content yet. This commit fixes the issue by allowing the controllers to restore the scroll position themselves, when their content is ready. In addition, a custom treatment was necessary for the kanban view, in mobile *and* if grouped, as each column has its own vertical scrollbar. [1] https://github.com/odoo/odoo/pull/205129 task~5086324 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#231339 Forward-Port-Of: odoo/odoo#230968
This update fixes how Odoo checks whether stored user sessions still exist when updating device log records. It processes large volumes of session log data in smaller batches, reducing the risk of long database operations that could slow down the system.
Original PR description
The commit: https://github.com/odoo/odoo/commit/6fb676a4e3566c781ddd57480a200cddc88d99ae adds the model `res.device.log` which will hold a lot of data. In order to use this data efficiently, we decide to process data with the boolean field `revoked` equal to `True` (via the indexes). This boolean field indicates whether the session that generated the log is still present on the disk. The commit: https://github.com/odoo/odoo/commit/e4c9d1794f2d4873755a8692f4861ba043fac943 adds an automatic verification mechanism to change this value if necessary. Between the time the model was created and the time the verification mechanism was implemented, the table may have become too large. This will result in a very long write within a transaction. The purpose of this commit is to introduce a method for performing the batch writing. Forward-Port-Of: odoo/odoo#225736
Fixes a crash that could occur when customers used keyboard navigation in the Helpdesk knowledge base search suggestions. This keeps the help center search experience stable and prevents users from seeing an error while looking for support articles.
Original PR description
Steps to Reproduce: 1. Navigate to '/helpdesk/customer-care-1/knowledgebase'. 2. Enter any text in the search bar to trigger suggestions. 3. Press the down arrow key twice. 4. A traceback error occurs, indicating an Odoo Client Error. Before this commit, we had a crash when a user types something in a searchbar in the website helpdesk and do keydowns: "Cannot read properties of undefined (reading 'nextElementSibling')" To fix this, we need to add the 'data-bs-toggle' attribute to let BS find it to set '_element' (which must be the previous sibling of the dropdown-menu). This data attribute was probably not set before because in this case the BS dropdown is not used on a button or a link as documented; we use it as an autocomplete functionnality. task-4752497 Forward-Port-Of: odoo/enterprise#97149 Forward-Port-Of: odoo/enterprise#90228
This fix prevents incoming Chilean electronic invoice emails from crashing after the first XML attachment is processed. Businesses can process DTE invoice emails more reliably, avoiding interrupted imports and manual follow-up.
Original PR description
Description of the issue/feature this PR addresses: Fixes https://github.com/odoo/odoo/issues/230014. Current behavior before PR: Crashes after processing the first XML because of savepoint implementation. Desired behavior after PR is merged: No crash. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Customers who must sign in before shopping are now redirected back to their cart, shop, or product page after logging in. This prevents lost checkout progress for flows such as appointment purchases and helps reduce payment drop-off.
Original PR description
**Steps to reproduce:** - Install eCommerce and Appointment - Set `Ecommerce Access` to `Logged in users` in Settings > Website - Go to the website without logging in - Create an appointment - Proceed to make the payment - You will get redirected to the sign-in page due to the setting - After logging-in the system doesn't redirect back to the checkout form **Issue:** When the user is not logged and the setting is applied, the user is directly sent to the login page without further redirection. **Fix:** Added redirect param to the original url target. opw-4965735 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231483 Forward-Port-Of: odoo/odoo#229346
German point-of-sale sessions can now close successfully even when an order is missing its assigned user. The export process uses the order creator as a fallback, keeping required transaction data valid and reducing disruption during fiscal reporting.
Original PR description
Before this commit, closing a session was blocked if an order was missing the user_id field during DSFinV-K export generation. Although the exact reproduction steps are not consistently found, this issue is recurrent. This change makes the code more robust by defaulting to the order's create_uid when the user_id is empty or missing, ensuring the transaction export data remains valid. opw-5123890 Forward-Port-Of: odoo/enterprise#96002
This fix prevents certain valid PDF font names from being changed into an invalid format when Odoo edits or adds content to a PDF. It helps avoid failures when generating or modifying PDF documents such as reports with banners.
Original PR description
Patch the following commit locally: https://github.com/py-pdf/pypdf/commit/8c542f331828c5839fda48442d89b8ac5d3984ac Issue: A PDF files contain `/FontName /TimesNewRomanGreek#5Bbold#5D`. While this is…
Patch the following commit locally: https://github.com/py-pdf/pypdf/commit/8c542f331828c5839fda48442d89b8ac5d3984ac Issue: A PDF files contain `/FontName /TimesNewRomanGreek#5Bbold#5D`. While this is a valid font descriptor, it gets converted to `/FontName /TimesNewRomanGreek[bold]` in `NameObject.read_from_stream` through `unhexlify` (see the complete call stack below) The converted value is not longer valid as `[` marks the start of a `ArrayObject`. The character should have been escaped back to `#5B` before being written in a new document. ```python /home/odoo/git/odoo/odoo/addons/account/models/ir_actions_report.py(37)_render_qweb_pdf_prepare_streams() -> stream = pdf.add_banner(stream, record.name or '', logo=True) /home/odoo/git/odoo/odoo/odoo/tools/pdf/__init__.py(288)add_banner() -> new_pdf.write(output) /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/_writer.py(935)write() -> self.write_stream(stream) /home/odoo/git/odoo/odoo/odoo/tools/pdf/__init__.py(127)write_stream() -> super().write_stream(*args, **kwargs) /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/_writer.py(908)write_stream() -> self._sweep_indirect_references(self._root) /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/_writer.py(1057)_sweep_indirect_references() -> data = self._resolve_indirect_object(data) /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/_writer.py(1102)_resolve_indirect_object() -> real_obj = data.pdf.get_object(data) /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/_reader.py(1256)get_object() -> retval = read_object(self.stream, self) # type: ignore /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/generic/_data_structures.py(841)read_object() -> return DictionaryObject.read_from_stream(stream, pdf, forced_encoding) /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/generic/_data_structures.py(270)read_from_stream() -> value = read_object(stream, pdf, forced_encoding) /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/generic/_data_structures.py(834)read_object() -> return NameObject.read_from_stream(stream, pdf) /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/generic/_base.py(469)read_from_stream() -> name = NameObject.unnumber(name) > /home/odoo/git/odoo/.env3.11/lib/python3.11/site-packages/PyPDF2/generic/_base.py(450)unnumber() -> while i >= 0: ``` opw-4991601 Forward-Port-Of: odoo/odoo#229489