Daily updates from Odoo
Thursday, June 25, 2026
254 changes
8 changes
Resolved issues and error corrections
This update resolves a technical issue that could cause errors in the planning module when start and end dates are not specified. By adding a check, the system now avoids attempting planning operations when this critical information is missing, ensuring smoother and more reliable planning processes. This improves the overall stability of the Enterprise version.
Original PR description
Add a guarding condition to the auto-plan or send behavior to avoid doing those operations when no start/end dates are defined --- Task-6312650
This update resolves a potential issue during Odoo upgrades where errors could occur when rules were being processed. The fix prevents errors when fields needed for rule evaluation aren't immediately available, ensuring smoother and more reliable upgrades. This improves the overall stability of the Odoo system.
Original PR description
In a [recent fix], the `_get_all_rules()` method was changed to skip the models that are not yet loaded (during upgrades). However, some rules can be added to an existing model by another module. In that case, the rule is processed even though the fields used in that rule are not yet loaded. This leads to a traceback during upgrades because `optimize()` is trying to access those fields. This commit adds the rule without pre-evaluating it if an `ValueError` is raised during the optimization step. [recent fix]: https://github.com/odoo/odoo/pull/267676
This update resolves a bug in the testing process for SEPA Direct Debit payments. The test was failing because the payment status was incorrectly identified as 'reconciled' instead of 'paid'. This change ensures the payment is validated only when it's in the correct 'paid' state, improving test reliability.
Original PR description
The `test_expiry` test creates a payment via the `pay_with_mandate` method. Depending on eg. the installed modules, the resulting payment ends up either `paid` or `reconciled`. Afterwards, the test tries to validate the payment, which requires that it not be in the `reconciled` state. This causes an error linked below. This PR adds a condition to ensure the payment is in the `paid` state before attempting to validate it. Error: https://runbot.odoo.com/odoo/error/240557 Forward-Port-Of: odoo/enterprise#112224
This update fixes a minor issue within the Odoo composer tool that prevented users from correctly placing the cursor at the end of lines when adding mentions. The fix adds a special character to ensure proper browser handling of text editing, improving the user experience. This ensures users can accurately format their messages.
Original PR description
### Purpose of this PR: - Inserting a mention in the composer results in a paragraph ending with a bare `<a>` element and no trailing text node. This causes the browser to mishandle the End key, moving the caret to the start of the next paragraph instead of the end of the current line. - Fix by appending a \uFEFF (zero-width no-break space) text node. task-6295924 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271802 Forward-Port-Of: odoo/odoo#269699
This update fixes an issue where the VAT displayed in the product information popup was incorrect, leading to an inaccurate total price. The fix ensures that the product's tax rate is correctly calculated based on the pricelist and fiscal position settings, resulting in the correct total price being shown.
Original PR description
Steps to reproduce: ------------------- 1. Create a product with a tax (e.g. 15%). 2. Create a pricelist that changes the price (e.g. 100 to 200). 3. Create a fiscal position mapping the tax (e.g.…
Steps to reproduce: ------------------- 1. Create a product with a tax (e.g. 15%). 2. Create a pricelist that changes the price (e.g. 100 to 200). 3. Create a fiscal position mapping the tax (e.g. 15% to 30%). 4. Add the pricelist and the fiscal position in PoS. 5. Add the product to the cart, and select the tax and the pricelist created in the previous steps. 6. Long press on the product to see its info. The price should be 200 now after selecting the pricelist. Also the tax should be 30% bc of the FP mapping, i.e. total price should be 200 + 30% = 260. However, we observe that VAT shows 15 (15%) instead of 60 (30%), and Price incl. Tax shows 230 instead of 260. What's happening: ----------------- On the frontend, `getTaxDetails()` is called with no options, so it uses the product `list_price` (100) and `taxes_id` (15%), giving VAT = 15. Alos, on the backned, `self.taxes_id` is used directly to compute the taxes, even though the pricelist price is correct (200), fiscal position is ignored, hence 200 + 15% = 230 instead of 200 + 30% = 260. The fix: -------- On frontend, we pass the pricelist and fiscal position to `getTaxDetails`, and compute the tax name from the mapped taxes. On the backend, we read the `fiscal_position_id` from the context and apply the tax mapping, so the correct taxes are used. opw-6200632 Forward-Port-Of: odoo/odoo#271396 Forward-Port-Of: odoo/odoo#266012
This update fixes a potential issue where changes to knowledge articles (sharing, favorites, editing) weren't reliably applied. The update ensures the correct article is loaded before any modifications are made, enhancing the user experience and data consistency. This improves the reliability of the knowledge base.
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#110642 Forward-Port-Of: odoo/enterprise#110123
This update fixes a temporary access error users experienced when switching between companies within a payroll payrun. The change ensures a smoother transition by verifying access permissions before loading the payrun data, preventing brief errors and redirecting users back to the payrun list.
Original PR description
Steps to reproduce: 1- Open a payrun 2- Switch companies Issue: You get an access error for a moment and then get redirected to payrun list view Cause: When switching companies, the payrun reloads but since it is in the context of a different company, you get an access error. Solution: First check in js before fetching that you have access to the payrun, if not, redirect to the list view instead. Task-6008140
This update ensures that all members of a tax unit, not just the main company, have read access to tax return checks. This allows for quicker identification and resolution of issues causing failures in tax reporting, improving overall data accuracy and efficiency.
Original PR description
Before this commit: Tax Unit Members other than main company have read access to tax returns but don't have read access to tax return checks. After this commit: Tax Unit members other than main company are given read access to tax return checks also, so they can fix checks failing because of them. task-5951364 Forward-Port-Of: odoo/enterprise#113118
4 changes
Resolved issues and error corrections
This update corrects a bug in the Mod349 report, ensuring that invoices marked as paid within the selected period are now correctly included. The previous version incorrectly removed these invoices due to a flaw in the report's filtering logic. This change ensures accurate reporting of financial data.
Original PR description
The mod349 report engine has been refactored to use tax tags (commit : 5f36778288a1b60245acec74677421666448351f). To avoid redundancies, the query used to get the invoice lines to include is designed to remove the amounts that have been reconciled with a credit note during the selected period. However, the current query removes the lines from any invoice that is reconciled with a move created in the period. As a result, invoices that have been paid in the period are also removed from the report. opw-6250491
A technical issue in the 'test_product_level_discount' tour was intermittently failing. This update ensures the order status update request is fully processed before the tour searches for the order, preventing incorrect results. Applying a 'Paid' filter to the ticket screen guarantees the tour searches the correct order list.
Original PR description
The tour `test_product_level_discount` was failing intermittently because the order status update request was not fully processed before the nextstep executed. As a result, the tour searched for the order in the wrong ticket list. This commit adds a proper wait for the backend request after updating the order status and applies the Paid filter on the ticket screen to ensure the tour searches in the correct order list. Runbot Error: [241140](https://runbot.odoo.com/odoo/runbot.build.error/241140)
This update fixes an error in the Austrian localization of Odoo Enterprise that incorrectly used a fixed 15-day rule for VAT and EC sales list reporting deadlines. The fix now accurately reflects the official Austrian filing deadlines, ensuring compliance and preventing potential penalties. This improves data accuracy for Austrian users.
Original PR description
**[FIX] l10n_at_reports: correct Austrian return deadlines** The Austrian localization used a fixed `15 days` rule for both VAT returns and EC sales lists. This does not match the filing deadlines: the VAT return is due on the 15th day of the second following month while the EC sales list is due by the end of the following month (sources below). This fix replaces the hardcoded day offset with month-based deadline computation sources: https://www.usp.gv.at/themen/steuern-finanzen/umsatzsteuer-ueberblick/weitere-informationen-zur-umsatzsteuer/umsaetze-mit-auslandsbezug/zusammenfassende-meldung-zm.html https://www.usp.gv.at/en/themen/steuern-finanzen/umsatzsteuer-ueberblick/weitere-informationen-zur-umsatzsteuer/entstehen-der-steuerschuld-und-pflichten/umsatzsteuervoranmeldung.html opw-6147343 Forward-Port-Of: odoo/enterprise#116212
This update resolves an issue where the CoA reload process could inadvertently create duplicate reports. The CoA framework is now responsible for managing existing records, ensuring data integrity and preventing redundant report generation. This change improves system efficiency and accuracy.
Original PR description
It is the burden of the CoA framework to check for that. See community commit for more information. Forward-Port-Of: odoo/enterprise#121643
1 change
Resolved issues and error corrections
This update fixes an issue where quality alerts weren't being created when receiving emails without a company assigned. The fix ensures that a default company is now automatically applied, preventing errors and guaranteeing that all incoming emails are properly recorded within the quality alert system. This improves data accuracy and reporting.
Original PR description
Steps to reproduce 1. Install quality 2. Create an incoming email server 3. Go to Quality > Configuration > Quality Teams > Team > add alias email 4. Do not fill the company field 5. Send email to this alias 6. Fetch emails from incoming email server Issue: - Record is not created in the quality alert Root cause: - For the Quality alert model, the field `company_id` is required, but while we fetch emails We haven't set the `company_id` on the quality alert team, resulting in trying to insert a null value on the quality alert model. Solution: - Give a default value to company_id. - Raise a validation error on not having a company_id - Update alias default values on changing company_id opw-5917791 Forward-Port-Of: odoo/enterprise#118516 Forward-Port-Of: odoo/enterprise#109947
1 change
Resolved issues and error corrections
This update corrects a display issue in the Helpdesk module where ticket labels in list and form views didn't always reflect the most current state selection. The fix removes outdated label fields from the views, ensuring all views show the correct, up-to-date state labels, matching the kanban view.
Original PR description
Steps to reproduce: ------------------------ 1. Install Helpdesk 2. Go to All Tickets and check the kanban state selection value 3. Go to Settings > Field Selection and search for kanban_state in…
Steps to reproduce:
------------------------
1. Install Helpdesk
2. Go to All Tickets and check the kanban state selection value
3. Go to Settings > Field Selection and search for kanban_state in `helpdesk.ticket` model
4. Change one of the state selection values (e.g., "Ready" to "Testing Ready")
5. Go back and check the state selection value in list and form views
Current behavior:
-----------------------
Kanban view correctly shows the updated label (e.g., "Testing Ready"),
but list and form views still display the old default value (e.g., "Ready").
Root cause:
---------------
The [state_selection](https://github.com/odoo/odoo/blob/c09cefdb0ed68b1b7367b77b18a5ee5d66c94900/addons/web/static/src/views/fields/state_selection/state_selection_field.js#L57-L65) widget uses `legend_${state}` field values when available.
Since list and form views included these legend fields, the widget resolved labels from them
instead of the actual selection values, causing inconsistent display.
Fix:
-----
Remove `legend_normal`, `legend_blocked`, and `legend_done` fields from the list and form views,
So the widget falls back to the real selection labels, consistent with how the kanban view behaves.
Reference commit: https://github.com/odoo/enterprise/commit/65f3b88254e3a66e2c5dcb5142d30f6b1996d999
opw-6238765
Forward-Port-Of: odoo/enterprise#11970710 changes
Resolved issues and error corrections
This update resolves an issue where users with sales permissions couldn't modify production orders. The fix ensures that sales users have the necessary access to update production order details, streamlining workflows and improving user flexibility. This was caused by a security rule preventing access to the order data.
Original PR description
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a…
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue: Writing on the `move_raw_ids` will trigger a call of the `_autoconfirm_production` in order to confirm the newly created move: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L990-L991 https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L1422-L1423 During this confirmation process, one calls the `_merge_moves` method in order to merge this new move (if relevant) to any already existing one. https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/stock/models/stock_move.py#L1575-L1576 Now, the issue is that, `sale_stock_renting` modeule overrides the method `_prepare_merge_moves_distinct_fields` determining the fields relevant to the merge by requiring a read access to the `is_rental_order` compute field of the `sale_order` linked to the MO: https://github.com/odoo/enterprise/blob/b66097122ba3a758734ac6fb2b26579c35cb72c2/sale_stock_renting/models/stock_move.py#L34-L40 However, due to the 'Personal Orders' ir.rule, the user does not have a read access to this record: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/sale/security/ir_rules.xml#L44-L49 Enterprise: https://github.com/odoo/enterprise/pull/121135 opw-6275658 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271371 Forward-Port-Of: odoo/odoo#271017
This update resolves an issue preventing sales users with 'Own Documents Only' access from modifying production orders. The fix adjusts security rules to grant necessary read access, ensuring sales users can correctly update production order details when renting stock.
Original PR description
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a…
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue: Writing on the `move_raw_ids` will trigger a call of the `_autoconfirm_production` in order to confirm the newly created move: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L990-L991 https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L1422-L1423 During this confirmation process, one calls the `_merge_moves` method in order to merge this new move (if relevant) to any already existing one. https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/stock/models/stock_move.py#L1575-L1576 Now, the issue is that, `sale_stock_renting` module overrides the method `_prepare_merge_moves_distinct_fields` determining the fields relevant to the merge by requiring a read access to the `is_rental_order` compute field of the `sale_order` linked to the MO: https://github.com/odoo/enterprise/blob/b66097122ba3a758734ac6fb2b26579c35cb72c2/sale_stock_renting/models/stock_move.py#L34-L40 However, due to the 'Personal Orders' ir.rule, the user does not have a read access to this record: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/sale/security/ir_rules.xml#L44-L49 Community: https://github.com/odoo/odoo/pull/271017 opw-6275658 Forward-Port-Of: odoo/enterprise#121135
This update fixes a display issue in Helpdesk where ticket state labels in list and form views didn't reflect the most recent changes made in the Kanban view. The fix removes outdated reference fields, ensuring all views show the correct, up-to-date state labels for improved consistency and accuracy.
Original PR description
Steps to reproduce: ------------------------ 1. Install Helpdesk 2. Go to All Tickets and check the kanban state selection value 3. Go to Settings > Field Selection and search for kanban_state in…
Steps to reproduce:
------------------------
1. Install Helpdesk
2. Go to All Tickets and check the kanban state selection value
3. Go to Settings > Field Selection and search for kanban_state in `helpdesk.ticket` model
4. Change one of the state selection values (e.g., "Ready" to "Testing Ready")
5. Go back and check the state selection value in list and form views
Current behavior:
-----------------------
Kanban view correctly shows the updated label (e.g., "Testing Ready"),
but list and form views still display the old default value (e.g., "Ready").
Root cause:
---------------
The [state_selection](https://github.com/odoo/odoo/blob/c09cefdb0ed68b1b7367b77b18a5ee5d66c94900/addons/web/static/src/views/fields/state_selection/state_selection_field.js#L57-L65) widget uses `legend_${state}` field values when available.
Since list and form views included these legend fields, the widget resolved labels from them
instead of the actual selection values, causing inconsistent display.
Fix:
-----
Remove `legend_normal`, `legend_blocked`, and `legend_done` fields from the list and form views,
So the widget falls back to the real selection labels, consistent with how the kanban view behaves.
Reference commit: https://github.com/odoo/enterprise/commit/65f3b88254e3a66e2c5dcb5142d30f6b1996d999
opw-6238765
Forward-Port-Of: odoo/enterprise#119707This update ensures that custom reports attached to invoices display their intended names in email attachments, rather than using a default CFDI-based filename. The change resolves an issue caused by how the system handles localization overrides, improving the clarity and accuracy of invoice attachments for users.
Original PR description
Steps to reproduce: * Install `l10n_mx_edi` (or `l10n_sa_edi`). * Go to **Accounting → Customers → Invoices**. * Open **Studio** and, from the top bar, go to **Reports**. * Duplicate the standard…
Steps to reproduce: * Install `l10n_mx_edi` (or `l10n_sa_edi`). * Go to **Accounting → Customers → Invoices**. * Open **Studio** and, from the top bar, go to **Reports**. * Duplicate the standard **Invoice PDF** report. * Open the duplicated report and make any modification to it. * Enable **Developer Mode**. * Go to **Settings → Technical → Actions → Reports** and update the custom report's **Printed Report Name**. * Go to **Settings → Technical → Email → Templates** and create a new invoice email template. * Add the custom report to the template's **Dynamic Reports**. * Create and confirm an invoice for a **Mexican company**. * Click **Send** and select the newly created email template. Observed behavior: * The custom report attachment uses the CFDI-based filename instead of its own report name, making it appear as a duplicate of the standard invoice attachment. Cause: * `_get_placeholder_mail_template_dynamic_attachments_data` relied on the `invoice_report` context key to pass the extra report into `_get_invoice_report_filename`. However, localization overrides (e.g. `l10n_mx_edi`, `l10n_sa_edi`) unconditionally return their own filename without checking the context, so the extra report's `print_report_name` was never evaluated. Fix: * Introduce `_get_invoice_mail_template_dynamic_report_filename` on `account.move` that directly evaluates a given report's `print_report_name`, bypassing the localization override chain. * Call this new method in `_get_placeholder_mail_template_dynamic_attachments_data` instead of the context-based `_get_invoice_report_filename` call. This avoids the need to patch every localization override and cleanly separates the concern of naming dynamic report attachments from the main invoice report filename logic. opw-6228268 Forward-Port-Of: odoo/odoo#271489
This update resolves a bug that prevented the translate button from working correctly when adding new records within related fields (like survey answers). The fix ensures that the translate button is hidden when a record is newly created and doesn't have a unique ID, preventing database errors and improving the user experience. This ensures translations can be applied correctly after saving new data.
Original PR description
The translate button next to a translatable field saves the record before opening the translation dialog for its id. Since https://github.com/odoo/odoo/commit/a85ca9679e3855936afc66b034d05d75f672dd26…
The translate button next to a translatable field saves the record before opening the translation dialog for its id. Since https://github.com/odoo/odoo/commit/a85ca9679e3855936afc66b034d05d75f672dd26 it saves record.model.root rather than the record itself. When the field belongs to a new record still edited inside an x2many, for example an answer added in the survey question popup, saving the root only saves the parent and the new line keeps no database id. The dialog then opens with the id set to false and calls update_field_translations on it, which builds WHERE id = false and the database rejects it with operator does not exist: integer = boolean. Such a record gets no id of its own, and after a save and reload there is no reliable way to match the saved line back to the one that was clicked, so the dialog can never open for it. A canTranslate getter in TranslationButton returns false for a new record whose model root is another record, which is exactly a line still edited inside an x2many, and the template only renders the button when it is true. The variant in editable lists, where model.root is a list rather than a record, was handled in https://github.com/odoo/odoo/commit/cb34b318004c3ca9db755d8dbbad429609220df3. Steps to reproduce: 1. Activate a second language in Settings > Translations > Languages 2. Open the Surveys app and create a survey 3. Add a question, then in the Answers tab add a line and type a value 4. Click the EN button next to the answer, fill the second language, and Save => RPC error operator does not exist: integer = boolean from WHERE id = false Ticket [link](https://www.odoo.com/odoo/project.task/6260427) opw-6260427 Forward-Port-Of: odoo/odoo#270410 Forward-Port-Of: odoo/odoo#267781
This fix resolves an issue where forecasting availability was incorrect after a product was scrapped following a subcontractor resupply. The update ensures that the forecast accurately reflects the available stock after the resupply, preventing inaccurate availability calculations. This improves the reliability of inventory planning.
Original PR description
[FIX] stock,*: properly compute forecast availability after PO resupply scrap * : mrp_subcontracting_purchase # How to reproduce - Enable Subcontracting in the settings - Create Product A with : -…
[FIX] stock,*: properly compute forecast availability after PO resupply scrap * : mrp_subcontracting_purchase # How to reproduce - Enable Subcontracting in the settings - Create Product A with : - Quantity : > 0 - Routes : Buy & Resupply Subcontractor on Order - Create Product B - Create BOM for that Product with - BOM Type : Subcontracting - Subcontractors : any - Component : Product A - Create a PO for Product B - Confirm the PO Order - Use the Resupply smart button - Click on the gear icons > Scrap - Scrap Product A # The problem A traceback will appear. # Cause There are two main ways to get the picking type's code of a move. Either : - `product_code` which is a related field to `picking_id.picking_type_id.code` : https://github.com/odoo/odoo/blob/0442c66d26b0c23313f17c566b16e34e7b22c2b6/addons/stock/models/stock_move.py#L174 - `picking_type_id.code` where `picking_type_id` is a computed field : https://github.com/odoo/odoo/blob/0442c66d26b0c23313f17c566b16e34e7b22c2b6/addons/stock/models/stock_move.py#L283-L287 When we scrap the products, we call the `do_scrap()` function that creates a new scrap move : https://github.com/odoo/odoo/blob/0442c66d26b0c23313f17c566b16e34e7b22c2b6/addons/stock/models/stock_scrap.py#L158 When we do so, the create move's `picking_code` wil be the code of the picking type of the current picking (The subcontractor resupply) : https://github.com/odoo/odoo/blob/0442c66d26b0c23313f17c566b16e34e7b22c2b6/addons/stock/models/stock_scrap.py#L151 But `picking_type_id.code` will be different because there is a `default_picking_type_id` value set in the context by : https://github.com/odoo/odoo/blob/0442c66d26b0c23313f17c566b16e34e7b22c2b6/addons/purchase_stock/models/purchase_order.py#L223 In our case, theses values end up not being the same. Later, when we compute the forecast information of the move, we prefetch virtual available keys and put the moves in a dict based on those keys. The computation of the virtual available key is based on the `picking_code` of the move : https://github.com/odoo/odoo/blob/0442c66d26b0c23313f17c566b16e34e7b22c2b6/addons/stock/models/stock_move.py#L488-L490 https://github.com/odoo/odoo/blob/0442c66d26b0c23313f17c566b16e34e7b22c2b6/addons/stock/models/stock_move.py#L496-L499 When later we try to fetch back the move, we compute the virtual available key based on `picking_type_id.code` : https://github.com/odoo/odoo/blob/0442c66d26b0c23313f17c566b16e34e7b22c2b6/addons/stock/models/stock_move.py#L529-L536 But since `picking_code` and `picking_type_id.code` are different, the output `key_virtual_available` is also different. Essentially, we add the move in the dict with key A and then try to fetch it back using key B, which gives us a KeyError. opw-6145887
This update fixes an issue where flexible work schedules were incorrectly calculating expected hours due to timezone differences. The fix ensures accurate hour tracking by considering the full date and time, preventing overestimation of expected work time when employees work in significantly different time zones.
Original PR description
**Problem:** When the time zone of an employee's schedule is different from the employee's time zone, and that the employee's time zone has more than 9 hours of difference with UTC. and the schedule…
**Problem:**
When the time zone of an employee's schedule is different from the employee's time zone, and that the employee's time zone has more than 9 hours of difference with UTC. and the schedule is flexible and is set to 40h per week. When we open the Attendances app, the expected hours for this employee show 48h.
**Steps to reproduce:**
- Create an employee with a flexible 40h/week schedule and a contract.
- Set employee timezone to Asia/Pyongyang and the working schedule timezone to Europe/Brussels.
- Open Attendances > Overview > Dashboard in week view.
- denominator shows 48h or any other number than 40h.
**Cause:**
In flexible calendars, weekly expected hours are computed by iterating within `[start_dt, end_dt]`. and That logic truncated bounds to `.date()`, assuming `end_dt - 1 second` would always move to the previous day.
That assumption breaks when employee timezone differs from schedule timezone and the employee timezone is far from UTC (like Asia/Pyongyang). so, `end_datetime` is no longer near midnight in local time, so subtracting one second keeps the same date. The loop then includes one extra day and allocates an extra 8h, showing 48h expected instead of 40h in Attendances.
**Fix:**
This change keeps full datetime bounds (instead of truncating to date), so comparisons preserve timezone offset and time of day precision. This prevents the extra day and restores correct weekly expected hours. The original code before this 332cb43 was like this:
```python
start_date = start_datetime.date()
end_datetime_adjusted = end_datetime - relativedelta(seconds=1)
end_date = end_datetime_adjusted.date()
```
this will not work as `.date()` will do the same problem of the extra day allocation.
Affected from 18.0 -> 18.4
Fixed in 19.0+ by this
Backport of https://github.com/odoo/odoo/pull/252847
opw-6171432
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#268346
Forward-Port-Of: odoo/odoo#262805This update ensures that invoice data is accurately reflected after vendor bills are imported and automatically completed from purchase orders. Previously, changes to invoice lines, taxes, and payment terms caused stale data in EPD lines, leading to discrepancies. Now, the system correctly updates all invoice details, maintaining consistency between invoices and journal entries.
Original PR description
When a vendor bill is imported and auto-completed from a purchase order, then invoice lines, taxes, fiscal position, and payment terms can change. Existing EPD dynamic lines that lose their epd_key are skipped by sync and keep stale tax tags and amounts, causing mismatches between Invoice Lines and Journal Items. This commit makes EPD sync include keyless existing EPD lines so they are rewritten or removed during dynamic recomputation after PO auto-complete. Journal items remain consistent with the final invoice lines, taxes, and early discount configuration. Ticket [link](https://www.odoo.com/odoo/project.task/6047505) opw-6047505 Forward-Port-Of: odoo/odoo#271631 Forward-Port-Of: odoo/odoo#265539
This update optimizes a key process within our stock management system, specifically the `_compute_forecast_information` function. By removing an inefficient loop, we’ve significantly reduced processing time when dealing with large quantities of stock data, leading to faster Manufacturing Order access. This improves overall system responsiveness.
Original PR description
Before this commit, database with large amounts of `stock.move` records could face slow downs when trying to access Manufacturing Orders. While this is partially due to very heavy computations being…
Before this commit, database with large amounts of `stock.move` records could face slow downs when trying to access Manufacturing Orders. While this is partially due to very heavy computations being done, another factor was the use of a loop in `_compute_forecast_information`. This loop would iterate over a recordset of `stock.move` records and put them into a dictionary, sorted by location. As the size of the recordset grew, this loop would take longer and longer. Here, we remove this loop and instead use a built in method to speed things up. ## Benchmarks: |Record count|Time before|Queries before|Time after|Queries after| |------------|-----------|--------------|----------|-------------| |6,262 |0.13s |68 |0.12s |68 | |68,882 |0.60s |112 |0.58s |109 | |432,317 |5.49s |398 |3.68s |309 | |757,702 |15.33s |1,141 |5.79s |599 | [opw-6310415](https://www.odoo.com/odoo/action-6450/6310415?debug=assets) Forward-Port-Of: odoo/odoo#271677
This update ensures that partner bank accounts are usable within all child companies, even if the partner is associated with a parent company. Previously, this functionality was limited, causing potential disruptions for users managing multiple company branches. This change improves efficiency and simplifies bank account management across the Odoo system.
Original PR description
Even when a partner has the 'company_id' filled with the parent company, his bank account should be usable in the child companies. This was done in odoo/odoo#262173 from 19.2 but we need to backport it in stable task-6309694 Forward-Port-Of: odoo/odoo#271470
3 changes
Resolved issues and error corrections
A minor typo in the system's redirection logic for signatures has been corrected. This ensures users are correctly directed to the correct page for managing their signatures, improving the user experience. This fix prevents potential confusion and ensures proper functionality.
Original PR description
There was a typo when forward-porting PR 116949, the redirection should be /my/signatures instead of /my/signature/signatures.
This update resolves an issue where undoing a planning action incorrectly removed allocated hours. The fix creates the necessary planning role directly within the test environment, ensuring the undo operation functions as expected and maintains accurate time tracking. This improves the reliability of the planning module.
Original PR description
Fix by creating the planning role directly within the test, making it self-contained. runbot error-939985 Forward-Port-Of: odoo/enterprise#121111
This update fixes a display inconsistency in Helpdesk ticket views. Previously, list and form views showed the default state label instead of the updated one seen in the Kanban view. The fix removes outdated field references, ensuring all views now accurately reflect the selected state.
Original PR description
Steps to reproduce: ------------------------ 1. Install Helpdesk 2. Go to All Tickets and check the kanban state selection value 3. Go to Settings > Field Selection and search for kanban_state in…
Steps to reproduce:
------------------------
1. Install Helpdesk
2. Go to All Tickets and check the kanban state selection value
3. Go to Settings > Field Selection and search for kanban_state in `helpdesk.ticket` model
4. Change one of the state selection values (e.g., "Ready" to "Testing Ready")
5. Go back and check the state selection value in list and form views
Current behavior:
-----------------------
Kanban view correctly shows the updated label (e.g., "Testing Ready"),
but list and form views still display the old default value (e.g., "Ready").
Root cause:
---------------
The [state_selection](https://github.com/odoo/odoo/blob/c09cefdb0ed68b1b7367b77b18a5ee5d66c94900/addons/web/static/src/views/fields/state_selection/state_selection_field.js#L57-L65) widget uses `legend_${state}` field values when available.
Since list and form views included these legend fields, the widget resolved labels from them
instead of the actual selection values, causing inconsistent display.
Fix:
-----
Remove `legend_normal`, `legend_blocked`, and `legend_done` fields from the list and form views,
So the widget falls back to the real selection labels, consistent with how the kanban view behaves.
Reference commit: https://github.com/odoo/enterprise/commit/65f3b88254e3a66e2c5dcb5142d30f6b1996d999
opw-6238765
Forward-Port-Of: odoo/enterprise#1197079 changes
Enhancements to existing features
This update adds functionality to accurately calculate and report Belgian withholding tax exemptions for overtime hours (natures 44-59) within the 274.XX declaration. It leverages validated payslips and existing hour caps to ensure accurate calculations, streamlining the reporting process for Belgian employees.
Original PR description
Compute the withholding-tax exemption for overtime hours (natures 44–59) within the Belgian 274.XX declaration. Overtime worked-day lines are collected from validated payslips, bucketed by rate and sector (CP124/CP302/immovable work), and allocated to the appropriate nature codes while respecting each employee's annual hour cap. Hours already declared in earlier months of the same year are carried forward so the cap is enforced cumulatively. The exemption rate is stored as an updatable rule parameter. A white-cash-register flag on the company controls the higher cap for CP302 employees. New work-entry types, an XLS extra-hours sheet, a PDF section, and extended tests are included. Task Id: 5430988
This update allows users to easily duplicate existing website appointment menus, streamlining the process of creating similar appointment pages. Previously, this functionality required a manual step. This change improves efficiency and simplifies website management for the team.
Original PR description
The corresponding community PR makes it possible to duplicate multi-level template menus but The duplication function needs to be explicitly called. Task-6030210
This update enhances payroll reports to accurately reflect data for all companies within a branch structure. Previously, reports only included data for the root company. Now, reports automatically include data from the root company and all its child companies, ensuring more complete and accurate reporting. Thorough testing has been conducted to verify data integrity.
Original PR description
This tasks was about switching from a (1 report - 1 company) paradigm to a (1 report - many companies). The implementation is done in two parts: 1 - first ensure that the report is created with a…
This tasks was about switching from a (1 report - 1 company) paradigm to a (1 report - many companies). The implementation is done in two parts: 1 - first ensure that the report is created with a root company as company_id 2 - include that root company and all child companies in the reported data 1 -> This was done by enforcing the user to have a root company as self.env.company. It looked easier and safer, therefore more robust. 2 -> This was done by creating a new computed property __branch_ids__ and extending the search domain for related payslips or data. When relevant, the field company_id was added in the views. As well as search filters and group_by. (Cases where it's not relevant is for instance that the report is a pdf) **Testing** - Two tests were created for each report: - One to ensure you cannot generate a report from a branch / child company. (exception for social balance sheet) - One to make ensure that - only employees from the relevant companies (root + children) are included in the reported data - employees from root and all children are included in the reported data task-6220264
This update enhances the reliability of communication between our Self and POS systems and OBOX devices. It now includes a timeout feature, allowing jobs to be awaited even when devices aren't on the same network, ensuring smoother operations and preventing delays when devices are offline.
Original PR description
Is now possible to await OBOX jobs with a specific timeout in PoS ans Self Order. This is usefull when the user device isn't connected on the same network as the OBOX and others hardware. taskId: 6248159 Forward-Port-Of: odoo/enterprise#118646
Resolved issues and error corrections
This update resolves a technical issue impacting the performance of the Gantt chart within the Enterprise module. Specifically, a variable name was corrected to enhance the functionality and stability of the underlying planning service. This change ensures smoother chart operation for users.
Original PR description
task-6200248
This update corrects a bug in how appointment invitations are sent, ensuring they are only triggered for 'booked' or 'requested' appointments. Previously, invitations were incorrectly sent for cancelled appointments or when status was updated. This ensures accurate and timely appointment notifications for users.
Original PR description
This PR fix three issues related to the sending of the appointment invitations. Each one has its own commit: - Commit 1 sends invitations only if the event either "booked" or "request". Previously they were sent even if the appointment was cancelled. - Commit 2 prevents the sending of regular invitations and always sends appointment invitation to new attendees of existing booked appointments. - Commit 3 sent appointment invitations if the status of an existing event is set "request". It also add the status change in the log as it would have been if it was done at the creation. Community PR: https://github.com/odoo/odoo/pull/260073 Task-6139036 Forward-Port-Of: odoo/enterprise#121381 Forward-Port-Of: odoo/enterprise#114304
This update resolves a stability issue in the point-of-sale tour. Previously, the tour could fail due to asynchronous order processing, leading to duplicate requests. By adding a delay to ensure requests are fully completed, this fix prevents race conditions and improves the reliability of the tour.
Original PR description
The tour could fail because `sendOrderInPreparationUpdateLastChange` is asynchronous when sending the order to the kitchen. The test was continuing to the next steps before the request was fully resolved, which could lead to sending the order again while the previous call was still in progress. This commit updates the tour to explicitly wait for the async call to complete before continuing, by adding a delay step after clicking the order button. This prevents race conditions during the test. --- Runbot Error: https://runbot.odoo.com/odoo/runbot.build.error/181846 Forward-Port-Of: odoo/enterprise#121237 Forward-Port-Of: odoo/enterprise#110909
A recent update to the Odoo Enterprise system (version 19.2 and later) caused a test for the 'hr_holidays_gantt' module to fail. This was due to an issue with a payroll-related field in the test's configuration. This fix ensures the test runs successfully, maintaining the functionality of the holiday Gantt chart.
Original PR description
__ ## Error description When the test runs with only the module `hr_holidays_gantt` installed, it fails. ## Origin of the issue There's a payroll related field in the `read_specification` variable. ### Note The error is only triggered since 19.2. __ original commit: https://github.com/odoo/odoo/pull/256636 Forward-Port-Of: odoo/enterprise#121119
Code cleanup and technical improvements
This update changes how processors within Odoo handle data transformation. Previously, processors were limited in returning falsy values, now they can explicitly return null or undefined to signal no processing or a deliberate choice. This allows for more flexible and controlled data flow within Odoo's modules.
Original PR description
*: knowledge, web_studio Previously, `processThrough` used `|| item` to fall back to original value if a processor returned a falsy value. This prevented processors from intentionally returning falsy values (e.g. null, undefined). Now each processor is responsible for returning a value explicitly: - Return the transformed value if processing occurred. - Return the original item if no processing is needed or processing is in place. - Return null/undefined to intentionally pass a falsy value. Community PR: https://github.com/odoo/odoo/pull/255801 task-6030633
8 changes
Enhancements to existing features
This update enhances the mobile bank reconciliation process by introducing a dedicated, simplified view. Now, users on mobile devices will see key information like statement date and remaining balance alongside the reconciliation details, providing better context and improving usability. The changes maintain the existing desktop functionality.
Original PR description
Current behavior before PR: On mobile devices, the bank reconciliation dialog relied on the base kanban view of account move line, which is difficult to handle and lacked contextual information about…
Current behavior before PR: On mobile devices, the bank reconciliation dialog relied on the base kanban view of account move line, which is difficult to handle and lacked contextual information about the statement being reconciled. Desired behavior after PR is merged: The bank reconciliation flow on mobile uses a dedicated kanban view with a simplified layout. An informational line is displayed above the main view, showing the statement date, reference, and remaining balance for better context. Changes implemented: - Added a mobile-specific kanban view for bank reconciliation dialog. - Displayed an information line above the kanban view with statement date, reference, and balance like desktop view for bank reconciliation dialog. - Moved 'onSelectionChanged' to 'BankRecSelectCreateDialog' and shared it through 'bankRecInfo', moved 'remainingAmountFormatted' into the state, and removed the duplicated getters from the list and kanban renderers. - Kept the existing desktop layout and behavior unchanged. - Added a HOOT test to check the mobile bank reconciliation dialog. task-5502469
This update introduces a new field for Belgian IBANs on bank journals, enabling more accurate import of bank statements. The extension number, found in CODA files, helps identify the correct journal for synchronization with Codabox or Codaclean. This improves the reliability of bank statement data import.
Original PR description
Original commit message: Bank journal can have the same bank account number, to be able to have a difference between them. We will add an extension number field on the journal that will be displayed…
Original commit message: Bank journal can have the same bank account number, to be able to have a difference between them. We will add an extension number field on the journal that will be displayed only when having a synchronization with codabox or codaclean. This extension number can be found in the CODA file when the second line of the coda start with '12', which means that we have a belgian iban. With that we are able to know the journal to where we want to import the statement. task-5254158 Backport commit message: This commit backports the code to handle extension number in stable. Some adaptations were done to allow this backport. 1. We have a new module for the new field and the view. 2. Except that, the code stays in the existing modules with a condition that check if the extension number is present in the journal's field list. NB: This implementation is pretty bad but the existing code doesn't include hooks to extend to add customization. To avoid a whole refactoring in stable, this approach was chosen. 3. A test and a test file from the codabox module are deleted because we don't want to create a new module for tests only. task-6116452
Resolved issues and error corrections
This update resolves an issue where the system was incorrectly registering only the last scanned serial number when creating manufacturing orders with serial-tracked products. The fix ensures that all scanned serial numbers are accurately recorded on the manufacturing order, allowing for proper production tracking. This improves the reliability of the barcode MRP process.
Original PR description
Steps to reproduce ------------------ Serial-tracked finished product: 1. Create a serial-tracked finished product and an un-tracked component. 2. Create a Manufacturing Order with quantity 2 and…
Steps to reproduce ------------------ Serial-tracked finished product: 1. Create a serial-tracked finished product and an un-tracked component. 2. Create a Manufacturing Order with quantity 2 and confirm it. 3. Open the Barcode app, scan the MO, then scan a first serial number SN_X1. 4. Scan a second serial number SN_X2. 5. Validate. Lot-tracked finished product: 1. Create a lot-tracked finished product with a one-component BoM and an existing lot LOT_A. 2. Create a Manufacturing Order and confirm it. 3. Open the Barcode app, scan the MO, then scan the existing lot LOT_A. 4. Scan a different, not-yet-existing lot LOT_B. 5. Validate. Issue ----- Only the last scanned serial is registered on the MO, and validation then fails because the count of producing serials does not match qty_producing for a serial-tracked finished product. updateLine overwrote lot_producing_ids with [args.lot_id] on every scan, so the first serial was dropped when the second one was scanned, and the same branch never staged a freshly typed lot_name, so a brand-new serial typed on a serial-tracked MO was lost before reaching the backend. https://github.com/odoo/enterprise/blob/4a2f1da5466740b7758d1962e5241620845d616b/stock_barcode_mrp/static/src/models/barcode_mrp_model.js#L407 Two behaviours of the shared barcode dispatcher make a single accumulating branch insufficient. The final-product line must keep exposing a producing lot, otherwise the base hasUnassignedQty check counts a scanned serial as zero once a quantity is already set, leaving qty_producing stuck below the demand. https://github.com/odoo/enterprise/blob/f622064871bf55b93890606d16407c50cf4419a6/stock_barcode/static/src/models/barcode_model.js#L1446 But exposing a producing lot makes the dispatcher treat the next serial as a conflicting tracking number, since the base _canOverrideTrackingNumber considers a different lot name non-overridable. https://github.com/odoo/enterprise/blob/f622064871bf55b93890606d16407c50cf4419a6/stock_barcode/static/src/models/barcode_model.js#L796-L798 So the scan is diverted to a new line through the override gate instead of updating the header line. https://github.com/odoo/enterprise/blob/f622064871bf55b93890606d16407c50cf4419a6/stock_barcode/static/src/models/barcode_model.js#L1585 For a lot-tracked finished product the producing lot can be corrected by scanning a different value, but the lot branch only stored a freshly typed value in lot_name and overwrote lot_producing_ids with the single existing lot. https://github.com/odoo/enterprise/blob/4a2f1da5466740b7758d1962e5241620845d616b/stock_barcode_mrp/static/src/models/barcode_mrp_model.js#L404-L407 The header reads its lot from lot_producing_ids whenever that relation is set and only falls back to lot_name when it is empty. https://github.com/odoo/enterprise/blob/4a2f1da5466740b7758d1962e5241620845d616b/stock_barcode_mrp/static/src/components/header.js#L45-L58 The save path only promotes lot_name to a producing lot when lot_producing_ids is empty, so scanning an existing lot then a new one neither displayed nor recorded the new lot and the finished product was produced under the old lot. https://github.com/odoo/enterprise/blob/4a2f1da5466740b7758d1962e5241620845d616b/stock_barcode_mrp/static/src/models/barcode_mrp_model.js#L628 Solution -------- Accumulate scanned serials by appending to lot_producing_ids instead of replacing it, and stage a freshly typed lot_name as a new producing lot when the finished product is tracked by serial, so every serial reaches the backend. Keep the final-product line exposing the last producing lot so each scanned serial is still counted as one unit instead of resetting the quantity to zero once several serials are registered. Override _canOverrideTrackingNumber for the final-product line so a serial scan updates the header line rather than being diverted to a new line, which is the only valid path for the finished product since it is a single header line backed by the lot_producing_ids relation. Persist the producing serials with explicit x2many commands, separating already-existing lots from freshly typed ones, so both are written on the MO. Reject a serial that is already registered on the MO so the same number cannot be produced twice in one session. For a lot-tracked finished product, build a producing lot from the scanned value, using the existing lot or a freshly typed lot name, and store it in lot_producing_ids so the new lot is both displayed and persisted through the same x2many commands as the serial case. Leave the produced quantity unchanged when the scanned lot differs from the one already registered, since replacing the lot is a correction and not an extra unit, and keep incrementing it when the same lot is scanned again. opw-6189620
This update enhances access to tax return checks for all members of a tax unit, allowing for quicker resolution of issues. It also includes a warning banner if a user's active companies don't match the tax return, and disables the status update button if the user lacks write access, preventing errors.
Original PR description
[FIX] account_reports: show return checks to every tax unit member Before this commit: Tax Unit Members other than main company have read access to tax returns but don't have read access to tax…
[FIX] account_reports: show return checks to every tax unit member Before this commit: Tax Unit Members other than main company have read access to tax returns but don't have read access to tax return checks. After this commit: Tax Unit members other than main company are given read access to tax return checks also, so they can fix checks failing because of them. *** [IMP] account_reports: Warn on company mismatch in tax returns Adds a warning banner to the return kanban view, when the user's active companies do not match the companies on the return. Backport of: https://github.com/odoo/enterprise/commit/48fea3df68ec2cc9ed1ba538e1b480210611bcde *** [IMP] account_reports: disable check status button if don't have write access Before this commit: Only main company of tax unit have write access on check, so when main company is not selected and user tries to change status of check, access error is thrown. After this commit: Disable check status button if user don't have write access on check. *** task-5951364
This update resolves an issue where the website generator tool in version 19.0 was limited to importing only 100 pages. This change ensures the tool accurately imports the correct number of pages, improving website creation functionality. This fix addresses a limitation impacting website design and content management.
Original PR description
The tool for 19.0 could only import up to 100 pages so matching it with the comment.
This update resolves an issue where automatic bank reconciliation rules incorrectly replaced original payment references with account names when multiple statement lines used the same account. Previously, this created an inconsistent user experience. The fix ensures that the original payment reference is preserved, providing a more accurate and reliable reconciliation process.
Original PR description
### Issue: When creating an automatic reconciliation rule by assigning the same account to multiple bank statement lines, the rule incorrectly overrides the original payment reference of subsequent…
### Issue: When creating an automatic reconciliation rule by assigning the same account to multiple bank statement lines, the rule incorrectly overrides the original payment reference of subsequent lines with the account name This creates an inconsistent user experience Using the "Set Account" button directly keeps the statement line payment reference as the journal item label However, clicking the automatically generated reconciliation model button replaces that reference with the account name Before the fix, clicking the automated rule button on a third matching line overrides its label with the account name instead of keeping its unique reference ### Cause: In `_create_reconciliation_rule`, when an automatic model is generated, the dictionary used to create the counterpart line explicitly set `label` to `rule_data['account'].name` When a reconciliation model line has a specific label defined, Odoo uses it to replace the statement line `payment_ref` on the generated counterpart move lines Removing this default value allows the system to fall back on the original payment reference ### Steps to reproduce: - Install `account_accountant` - Go to the Bank Reconciliation widget from the Accounting Dashboard - Create 2 statement lines without partners (e.g., Ref: "Test Ref 1" and "Test Ref 2") - Set the same account on both lines using Set Account - This automatically creates a Reconciliation Rule named after the account - Create a 3rd statement line with a matching reference (e.g., "Test Ref 3") - Click the newly available automatic reconciliation button for this line Before the fix, checking the generated entry label shows the account name instead of "Test Ref 3" To check unfold the details, click on the pencil icon of a line opw-6246833
This update corrects a bug where quality checks remained active after merging multiple manufacturing orders. Previously, the merge process didn't trigger the necessary cleanup, leaving lingering quality checks. This fix ensures that pending quality checks are automatically removed when manufacturing orders are merged, streamlining the workflow and preventing unnecessary data.
Original PR description
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `quality_mrp` - Create a manufactured product with a BoM - Create a Quality Point for the `Manufacturing` operation of that…
Version: -------- - 18.0+ Steps to reproduce: ------------------- - Install `quality_mrp` - Create a manufactured product with a BoM - Create a Quality Point for the `Manufacturing` operation of that product - Create and confirm multiple Manufacturing Orders - Verify that each MO generates a quality check - From the MO list view, select the MOs and merge them from the gear menu(merge) Issue: ------ When Manufacturing Orders are merged, All MOs are cancelled but it keep their quality checks in the 'To Do' state. As a result: - The quality checks remain linked to cancelled MOs - The 'Quality Checks' smart button is still displayed on cancelled MOs Expected behavior: ------------------ - Pending quality checks should be deleted when the MO is cancelled - The 'Quality Checks' smart button should no longer be displayed Cause: ------ A previous fix introduced logic to remove pending quality checks when a Manufacturing Order is cancelled: odoo-dev@db93bd2 This logic was implemented in `action_cancel()` by unlinking quality checks associated with the cancelled MO: https://github.com/odoo/enterprise/blob/20bc0eb5c2cec67eecd3b44450934e23370b48f2/quality_mrp/models/mrp_production.py#L94-L97 However, when MOs are merged, the merge flow does not call `action_cancel()`. Instead, it directly invokes `_action_cancel()` on the source Manufacturing Orders: https://github.com/odoo/odoo/blob/aca0b7289c68fc7a75d47ab313f5f791ebf30f7d/addons/mrp/models/mrp_production.py#L2480 Since the quality check cleanup is implemented only in `action_cancel()`, it is bypassed during the merge process. As a result, the source MOs are cancelled but their pending quality checks remain in place. --- opw-6260735 Forward-Port-Of: odoo/enterprise#121536 Forward-Port-Of: odoo/enterprise#119525
This update fixes a display inconsistency in Helpdesk tickets. Previously, list and form views showed the default state label instead of the selected one. This change ensures all views – including kanban, list, and form – accurately reflect the current state selection, improving data clarity and user experience.
Original PR description
Steps to reproduce: ------------------------ 1. Install Helpdesk 2. Go to All Tickets and check the kanban state selection value 3. Go to Settings > Field Selection and search for kanban_state in…
Steps to reproduce:
------------------------
1. Install Helpdesk
2. Go to All Tickets and check the kanban state selection value
3. Go to Settings > Field Selection and search for kanban_state in `helpdesk.ticket` model
4. Change one of the state selection values (e.g., "Ready" to "Testing Ready")
5. Go back and check the state selection value in list and form views
Current behavior:
-----------------------
Kanban view correctly shows the updated label (e.g., "Testing Ready"),
but list and form views still display the old default value (e.g., "Ready").
Root cause:
---------------
The [state_selection](https://github.com/odoo/odoo/blob/c09cefdb0ed68b1b7367b77b18a5ee5d66c94900/addons/web/static/src/views/fields/state_selection/state_selection_field.js#L57-L65) widget uses `legend_${state}` field values when available.
Since list and form views included these legend fields, the widget resolved labels from them
instead of the actual selection values, causing inconsistent display.
Fix:
-----
Remove `legend_normal`, `legend_blocked`, and `legend_done` fields from the list and form views,
So the widget falls back to the real selection labels, consistent with how the kanban view behaves.
Reference commit: https://github.com/odoo/enterprise/commit/65f3b88254e3a66e2c5dcb5142d30f6b1996d999
opw-6238765
Forward-Port-Of: odoo/enterprise#1197078 changes
Resolved issues and error corrections
This update fixes an issue where duplicating a purchase order receipt incorrectly inflated the received quantity on the original purchase order. The change ensures that only the quantity of the initial delivery is counted, resolving a discrepancy in how received quantities are calculated. This improves the accuracy of purchase order tracking.
Original PR description
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- *…
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- * Create a PO and confirm it * Open the receipt, validate and duplicate it * Go on the duplicated receipt and change its Operation Type * Confirm the duplicated receipt. -> the Received Qty on the Po counted the duplicated and modified transfer. Observation: ------------- When we duplicate a stock.picking, we will call ```copy``` and copy all its ```move_ids``` (stock.move), and in stock.move we will copy the ```purchase_line_id``` : https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/models.py#L5868 https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/models.py#L5881-L5892 https://github.com/odoo/odoo/blob/3e6d93bef49bb2718e8aa1756f95c2a6117c8d55/addons/purchase_stock/models/stock_move.py#L13-L15 the ```purchase_line_id``` will keep the link with the pol. The fields are copied since they have ```copy=True``` https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/addons/stock/models/stock_picking.py#L614 https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/fields.py#L304 Because new stock moves are linked directly to the Purchase Order Line (POL), the qty_received calculation aggregates all associated move quantities. https://github.com/odoo/odoo/blob/cfc63060926db4cec773c159b8ecf97dc0b36d1a/addons/purchase_stock/models/purchase_order_line.py#L73-L76 opw-6088239
This update resolves an issue where the system incorrectly imported invoice quantities from UBL files. Specifically, it ensures that the 'invoiced_quantity' and 'base_quantity' values in imported invoices accurately reflect the quantities specified in the original UBL document. This prevents discrepancies in order data.
Original PR description
…ase_quantity equal to zero **STEP TO REPRODUCE** 1. Import the 2fact ubl from the bugfix ticket. 2. Notice some line are imported with quantity = 1, but the quantity invoiced in the ubl is 0. opw-6260558
This update fixes a crash that occurred when Odoo's subscription module was run outside of its normal web environment (like in tests or cron jobs). The fix ensures the system correctly handles situations where an active HTTP request isn't present, preventing a runtime error.
Original PR description
When executing code outside of a web thread (such as in unit tests, cron jobs, or CLI commands), an actual HTTP request does not exist, leaving the global `request` proxy unbound. In these scenarios, the unbound proxy evaluates to False. Because of Python's `and` evaluation, the expression `request and request.params...` returned the unbound proxy itself instead of None. This caused a RuntimeError later when the proxy was compared to other values. We now explicitly check `request.env` to verify an active request exists, properly falling back to None when there is no HTTP context. runbot-938513
This update resolves an issue where the HTML editor's paste functionality was unreliable, leading to errors when saving selections. The fix ensures that selections are correctly updated during paste operations and after restoring previous editor states, improving the overall user experience and data integrity.
Original PR description
### Steps to reproduce: - Insert a file using /file command and upload a file. - Type any powerbox command (e.g. /file, /media) - Press Enter to select the command - IndexSizeError: Failed to execute…
### Steps to reproduce: - Insert a file using /file command and upload a file. - Type any powerbox command (e.g. /file, /media) - Press Enter to select the command - IndexSizeError: Failed to execute 'setBaseAndExtent' on 'Selection': There is no child at offset 5. ### Description of the issue/feature this PR addresses: - makeSavePoint() of history_plugin uses preserveSelection() to save current selection. However, preserved selections remain registered in the cursor update mechanism and continue to be updated when the editor adjusts cursors during DOM changes. - During normalization, updateFeffs() updates all preserved cursors. Because the savepoint selection is stored using preserveSelection(), it is updated as well and can become inconsistent with the DOM state that the savepoint later restores, resulting in an IndexSizeError. ### Solution (backport-https://github.com/odoo/odoo/commit/1eb0e6de8f566d260ecb6c0dae3436e87ffe8436): - Update preserved cursors after steps restoration so they stay in sync with the restored DOM state. - Stage the selection in the clipboard plugin after `before_paste_handlers`, ensuring the selection reflects the final adjusted state before pasting. - Fix `selectFullText` to trigger `pointerup` to have a correct staged selection. task-6298761 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where the system incorrectly processed Viettel S-Invoice XML files, specifically when invoices were delivered in a double-zipped format. The fix now correctly handles both single and double-zipped invoices, ensuring seamless integration with the Viettel e-Invoicing platform and preventing errors.
Original PR description
Description of the issue/feature this PR addresses: The actual XML extraction hardcoded the double-zipped case by reading only the first entry of the outer zip (`zip_file.infolist()[0]`), assuming it was always a nested zip containing the XML. This made it fail when: - The XML was directly in the outer zip (single-zipped). - The zip contained multiple files and the first nested zip didn't hold the XML. Current behavior before PR: After sending an Invoice to Viettel S-Invoice, the e-Invoicing platform would return a ZIP containing one XML file. The XML File being double-unzipped, a traceback is raised. Desired behavior after PR is merged: The fix rewrites _recursive_zip_xml_file_data to actually be recursive. Invoices can be sent to Viettel S-Invoice without raising a traceback. opw-[6249929](https://www.odoo.com/odoo/project.task/6249929?debug=1) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update ensures that custom reports attached to invoices display their intended names in email attachments, rather than a default CFDI-based filename. The fix addresses an issue where localization overrides were preventing the correct report name from being used, leading to duplicate attachments. This improves the clarity and usability of invoice attachments.
Original PR description
Steps to reproduce: * Install `l10n_mx_edi` (or `l10n_sa_edi`). * Go to **Accounting → Customers → Invoices**. * Open **Studio** and, from the top bar, go to **Reports**. * Duplicate the standard…
Steps to reproduce: * Install `l10n_mx_edi` (or `l10n_sa_edi`). * Go to **Accounting → Customers → Invoices**. * Open **Studio** and, from the top bar, go to **Reports**. * Duplicate the standard **Invoice PDF** report. * Open the duplicated report and make any modification to it. * Enable **Developer Mode**. * Go to **Settings → Technical → Actions → Reports** and update the custom report's **Printed Report Name**. * Go to **Settings → Technical → Email → Templates** and create a new invoice email template. * Add the custom report to the template's **Dynamic Reports**. * Create and confirm an invoice for a **Mexican company**. * Click **Send** and select the newly created email template. Observed behavior: * The custom report attachment uses the CFDI-based filename instead of its own report name, making it appear as a duplicate of the standard invoice attachment. Cause: * `_get_placeholder_mail_template_dynamic_attachments_data` relied on the `invoice_report` context key to pass the extra report into `_get_invoice_report_filename`. However, localization overrides (e.g. `l10n_mx_edi`, `l10n_sa_edi`) unconditionally return their own filename without checking the context, so the extra report's `print_report_name` was never evaluated. Fix: * Introduce `_get_invoice_mail_template_dynamic_report_filename` on `account.move` that directly evaluates a given report's `print_report_name`, bypassing the localization override chain. * Call this new method in `_get_placeholder_mail_template_dynamic_attachments_data` instead of the context-based `_get_invoice_report_filename` call. This avoids the need to patch every localization override and cleanly separates the concern of naming dynamic report attachments from the main invoice report filename logic. opw-6228268
This update optimizes a key process within our stock management system, specifically the `_compute_forecast_information` function. By removing an inefficient loop, we’ve significantly reduced the time it takes to access Manufacturing Orders, particularly for databases with many stock records. This results in faster response times and a smoother user experience.
Original PR description
Before this commit, database with large amounts of `stock.move` records could face slow downs when trying to access Manufacturing Orders. While this is partially due to very heavy computations being…
Before this commit, database with large amounts of `stock.move` records could face slow downs when trying to access Manufacturing Orders. While this is partially due to very heavy computations being done, another factor was the use of a loop in `_compute_forecast_information`. This loop would iterate over a recordset of `stock.move` records and put them into a dictionary, sorted by location. As the size of the recordset grew, this loop would take longer and longer. Here, we remove this loop and instead use a built in method to speed things up. ## Benchmarks: |Record count|Time before|Queries before|Time after|Queries after| |------------|-----------|--------------|----------|-------------| |6,262 |0.13s |68 |0.12s |68 | |68,882 |0.60s |112 |0.58s |109 | |432,317 |5.49s |398 |3.68s |309 | |757,702 |15.33s |1,141 |5.79s |599 | [opw-6310415](https://www.odoo.com/odoo/action-6450/6310415?debug=assets) Forward-Port-Of: odoo/odoo#271677
This update ensures that partner bank accounts are usable within all child companies, even if the partner is associated with a parent company. Previously, this restriction limited functionality. This change improves efficiency and simplifies processes for users managing multiple company branches.
Original PR description
Even when a partner has the 'company_id' filled with the parent company, his bank account should be usable in the child companies. This was done in odoo/odoo#262173 from 19.2 but we need to backport it in stable task-6309694 Forward-Port-Of: odoo/odoo#271470
2 changes
Resolved issues and error corrections
This update fixes an issue where recurring subscription revenue was incorrectly displayed as 'To Invoice' even after invoices were fully processed. The change ensures that invoiced amounts are accurately deducted from revenue calculations, providing a more precise view of subscription income. This improves financial reporting accuracy.
Original PR description
**Steps to reproduce:** - Create a Sale Order for a service product with a recurring plan - Confirm it - Go to the Project Dashboard and observe MRR shown under "To Invoice" - Create an invoice for the subscription and post it - Go back to the dashboard **Issue:** Even after fully invoicing a subscription, its value is still shown under `to_invoice` in the revenues section. **Fix:** The profitability computation was not deducting the already invoiced amount from the total expected revenue. We now subtract the `amount_invoiced` from `amount_to_invoice`, ensuring that fully invoiced subscriptions no longer appear under `to_invoice`. task- 4797525
This update resolves an issue where creating and modifying contact records with blog posts would sometimes cause an error. The fix ensures that website URL calculations are skipped for temporary blog posts, preventing the system from attempting to generate URLs for records that don't yet have a permanent ID. This improves the stability and reliability of the contact form.
Original PR description
Steps to reproduce: 1. Install Blog, Contacts, and Studio 2. Open Contact form page and a new page with many2many field "Blog Post" 3. Save and create a contact record with email and a blog post. 4. Save and try to modify the email. Issue: `ValueError: Cannot slug non-existent record` Cause: - Since[1] Invisible fields also trigger `onchange` and compute methods during view processing. In this flow, `blog.post` records can be handled as transient `NewId` records. `_compute_website_url` was calling `slug(blog_post)` unconditionally, but `slug()` only accepts persisted records with a real id. Thus ValueError Solution: - Skip the website URL computation for non-persisted blog posts. - backport of https://github.com/odoo/odoo/commit/62ced8ac646fc781da24346f12c5dc9b9a0c592d [1] - https://github.com/odoo/odoo/commit/db63cb770365be1f81ba051fe6ca5a246dbc9036 opw-6175092