Daily updates from Odoo
Monday, July 6, 2026
376 changes
21 changes
New functionality added to Odoo
This update introduces a new 'Profitability' field to account analytic lines, enabling a clearer breakdown of revenue and loss within the Analytic Report. This enhancement provides better visibility into the financial performance of transactions, allowing for more informed decision-making.
Original PR description
[IMP] account: group analytic items by profitability This commit add a new field 'Profitability' on the account analytic line model, this will allow to visually split analytic line items in 2 categories: 'Revenue' and 'Loss' in the Analytic Report task-4959636 Forward-Port-Of: odoo/odoo#272369 Forward-Port-Of: odoo/odoo#262962
This update adds PayU as a new payment option for our customers. This expands payment choices and supports a growing market, streamlining the checkout process for users who prefer PayU.
Original PR description
Add new payment provider PayU. See README.md for more details. task-6219530 Forward-Port-Of: odoo/odoo#267962
Resolved issues and error corrections
A recent test for adding products to invoices was failing due to an outdated element search within the Odoo system. This update corrects the test to correctly identify a key element, ensuring the invoice product catalog tour functions as intended. This resolves a minor technical issue impacting test reliability.
Original PR description
The tour preciously looked for a `o_field_product_label_section_and_note_cell` element to verify product was added. In the configuration used, the element did not exist, despite the line with the product being present. This caused the tour test to fail. This PR makes it look for a `o_account_label_text_cell` instead to successfully detect the line. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a minor issue where the mailing domain dropdown remained visible when a target model wasn't selected. The fix ensures the recipient count is correctly set, preventing errors and improving the user experience. While a mailing requires a target model, this update ensures proper functionality.
Original PR description
On a mailing, when attempting to remove the target model, `_compute_recipients_count` will attempt to recompute the recipient count. As the new target domain is empty, recipient count will not be set. This will cause an traceback, as the compute method was unsuccessful in assigning a recipient count. (This is a minor issue, as a mailing cannot be saved without a target model anyways; however, this causes the mailing domain dropdown to remain visible when it should be hidden.) Steps to reproduce: - Create a new mailing - Blank out the target model field (recipients) Fix: `_compute_recipients_count` assigns recipient count to False (empty column).
This update resolves a bug that prevented users from correctly selecting section templates within Sales Orders. The fix corrects a data entry error that was causing a validation issue when creating sales orders with section templates. This ensures the sales order creation process functions smoothly.
Original PR description
## Steps to Reproduce: 1. Install the sale_margin module. 2. Sales > Configuration > Templates. 3. Create a template with type 'Section', and add a section line. 4. Create a Sales Order, click Add…
## Steps to Reproduce: 1. Install the sale_margin module. 2. Sales > Configuration > Templates. 3. Create a template with type 'Section', and add a section line. 4. Create a Sales Order, click Add Section, and select the created template. ## Error: `ValueError: Expected singleton: res.currency()` ## Cause: The `_prepare_order_line_values()` method mistakenly stores the converted purchase price in the `currency_id` field instead of `purchase_price`. When these values are used to create a sales order line, leaving currency_id unset. - [1] As a result, the onchange later fails when it expects a valid currency. - [2] ## Fix: Pass the correct field value of `purchase_price` instead of `currency_id`. [1]: https://github.com/odoo/odoo/blob/f2f656371f81683ee3fe558932df53a2d0c5d374/addons/sale_management/models/sale_order_template.py#L346-L350 [2]: https://github.com/odoo/odoo/blob/f2f656371f81683ee3fe558932df53a2d0c5d374/addons/sale_margin/models/sale_order_line.py#L76 opw-6347869
This update fixes an issue where splitting a restaurant order didn't correctly apply the original order's fiscal position and pricelist to the new order. Now, when splitting, the new order inherits the correct tax settings and pricing rules, ensuring accurate financial reporting and order fulfillment. This improves the reliability of order splitting functionality.
Original PR description
When splitting an order, the new order was created without the original's fiscal position and pricelist, so its lines fell back to the default taxes Steps to reproduce: 1. Create a fiscal position with some tax mapping 2. Create a pricelist with some price rules 3. Add the fiscal position and pricelist to the delivery preset 4. Create a restaurant order as delivery 5. Split the order 6. Pay both of them 7. First order will have the default taxes and prices list instead of preset's ones Part of: https://github.com/odoo/odoo/pull/268862 -opw-6246434 Forward-Port-Of: odoo/odoo#273452 Forward-Port-Of: odoo/odoo#272837
This update resolves an issue where the extra price for product variants was incorrectly displayed when a pricelist used a fixed pricing model. The fix ensures that the extra price badge is hidden in the product configurator and website views when the pricelist's calculation method is fixed, aligning with expected behavior.
Original PR description
Issue: --- If pricelist.compute_price is fixed, extra price of variant is not taken into calculation, but it's shown in extra price badge. Steps to reproduce: --- 1- Create a product template with two variants. 2- Apply extra price for each attribute values. 3- Apply a pricing with a fixed price for the product on a pricelist. 4- Create a SO and apply the pricelist. Add the product to SOL. 5- Open product configurator on SOL. - As you see, the extra price is shown but it's not effective. 6- Open the product in website with the pricelist. - Here also the extra price is shown but it's not effective. Cause: --- This is caused because there is no mechanism to hide extra price having pricelist.compute_price == fixed. Fix: --- We need to fix the issue both in sale and website_sale separately by having a flag to ensure extra price badge is hidden if compute_price is fixed. opw-6276208 Forward-Port-Of: odoo/odoo#272541 Forward-Port-Of: odoo/odoo#270140
This update fixes an issue where the restaurant floor plan selector would overlap other parts of the interface when multiple floor plans were available. Adding horizontal scrolling ensures the floor plan is always visible and accessible, providing a better user experience for restaurant staff.
Original PR description
In this commit: ---------------- - Added horizontal scrolling for the floor selector when multiple floor plans are available, preventing it from overlapping other components. Task: 6356983 Forward-Port-Of: odoo/odoo#274092 Forward-Port-Of: odoo/odoo#273637
This update fixes a technical issue related to printer test setup by moving mocking to the client-side. Additionally, the printer setup tours have been streamlined for easier testing and a more intuitive user experience, particularly when using demo data.
Original PR description
We moved printer requests mocking client-side in tests to avoid creating fake controllers. We also improved the tour to search the actual printer name in the printer selection wizard, and made the zebra tour start directly from the product instead of searching it (simplifies search when tests are run with demo data).
This update fixes an issue where payment redirection wasn't correctly updating after processing. Previously, the landing route was set earlier, causing inconsistencies. Now, the updated landing route from the transaction is passed through, ensuring correct redirection to the cart payment page.
Original PR description
In commit 2cb589169fb77f98900997b9266ad309dcf602f9, a feature was introduced to redirect to cart payment when transaction was canceled or if an error occurred. Since commit 4588e939e3619949473f26223ada82c642c4bede, processing was triggered after we reach the payment_status page. At this point the landing route was already set in 'el.dataset.landingRoute' so any changes done to the landing_route by the processing won't be reflected in this js handling of redirection. As a solution, we return the updated landing route of the transaction in the post_processing api call. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where switching settings apps on mobile devices didn't correctly update the browser's URL. Now, refreshing the page will reliably take the user back to the settings app they were previously using, ensuring a smoother user experience.
Original PR description
Before this commit, when switching applications in the settings view on mobile, the URL fragment was not correctly updated to reflect the active application. Because of this, if the page was reloaded, the user would be redirected back to the first application in the settings instead of the one they were currently viewing. This commit ensures the URL fragment is properly updated upon selection, preserving the user's current context if the page is refreshed. task-id 6333778
This update fixes a potential issue where users could still register payments against invoices that were marked as blocked. Now, blocked invoices are correctly displayed in lists and payments cannot be registered through standard flows. This ensures accurate financial reporting and prevents incorrect payment processing.
Original PR description
When an invoice is blocked for payment, the form view hides the Pay button, but users could still register a payment from list/payment-item flows. Prevent payment registration for blocked invoices in both the invoice action path and the payment register wizard path. Also make blocked invoices display as Blocked in invoice lists instead of Posted or Sent. task-6310234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270830
This update fixes an issue where changing the start date of a work order incorrectly calculated its duration. The fix ensures that the duration remains accurate when only the start date is adjusted, aligning with previous behavior and preventing incorrect end date calculations. This improves the reliability of work order planning.
Original PR description
**Problem:** On a planned work order, changing only the start date (e.g. in the planning gantt edit dialog) corrupts the expected duration instead of just shifting the end date. The duration drifts…
**Problem:** On a planned work order, changing only the start date (e.g. in the planning gantt edit dialog) corrupts the expected duration instead of just shifting the end date. The duration drifts to a wrong value, and in some cases (e.g. dependent work orders) collapses to 0. **Steps to reproduce:** 1. Plan a work order on a workcenter (start, end, expected duration). 2. Open it and change only the start date to a time that is not on a working-hours boundary. 3. The end date updates, but the expected duration is now wrong. **Expected behavior:** Changing the start date replans the work order: the duration is kept and the end date is recomputed from it. This is how 19.0 behaves and how dragging the pill in the gantt already behaves. **Cause of the issue:** Changing date_start triggers _onchange_date_start, which recomputes date_finished from start + duration via plan_hours. That cascades into _onchange_date_finished, which recomputes duration_expected from the dates via get_work_duration_data. Since the resource calendar refactor in 19.2, plan_hours and get_work_duration_data are no longer exact inverses around the work order's own planned slot, so the round trip drifts the duration. **Fix:** Only recompute the duration when the end date was edited on its own. When date_finished already matches the planned end for the current duration, it was merely derived from the start change, so the duration is kept. This keeps the duration authoritative when moving the work order while still recomputing it on a genuine end-date resize. opw-6231569 Forward-Port-Of: odoo/odoo#271508
This update resolves a technical issue that was preventing tests for our Point of Sale and POS Stock modules from running correctly. The change ensures that test code doesn't accidentally alter the system's core data, allowing the tests to pass and maintain the stability of these important features.
Original PR description
Avoid polluting the Odoo model registry and failing `test_lint_override_signature` by using `patch.object` instead of manual assignment. This ensures the injected method is properly torn down after the test block, keeping the registry clean and bypassing static analysis failure as the patched method is only used for tests. Note: this commit is a follow-up of odoo/odoo@163225c3f9c0f51c40c9b1ae6ec00ba1c8f16017 runbot-939298 Forward-Port-Of: odoo/odoo#274318
This update corrects a technical issue where a key field related to product removal strategies was incorrectly loaded in the Point of Sale module. Now, this field is correctly loaded within the pos_stock module, ensuring accurate stock management and reporting for point-of-sale transactions. This improves the overall reliability of the POS system.
Original PR description
Before this commit: ==== - removal_strategy_id field was loaded in point_of_sale instead of pos_stock Following this commit: ==== - Field is now been loaded in pos_stock Error-941369 Forward-Port-Of: odoo/odoo#274297
This update standardizes the technical names used for website types within the Odoo platform. Previously, inconsistent capitalization (camelCase) was used, which has now been corrected to snake_case. This ensures greater clarity and consistency across the codebase, improving maintainability.
Original PR description
Avoid using camelCase for website type technical names and use snake_case consistently for technical identifiers. task-[6284263](https://www.odoo.com/odoo/project/974/tasks/6284263) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268829
This update ensures GIF functionality in Odoo continues to work by switching from the soon-to-be-terminated Tenor GIF API to the Klipy GIF API. This change is necessary to avoid disruptions to GIF sharing within the system. Users should be aware that updating the API key is required for GIF functionality to remain operational.
Original PR description
Tenor API will be terminated on June 30, 2026: https://developers.google.com/tenor/guides/quickstart This commit makes the Tenor API key input settings use a Klipy GIF API key instead of a Tenor GIF API key. To keep GIF working after this commit, the API key must necessarily be changed to a Klipy GIF API key, as the old Tenor API key would be considered as an invalid Klipy API key. Task-5491965 Upgrade: https://github.com/odoo/upgrade/pull/10516 Forward-Port-Of: odoo/odoo#273182 Forward-Port-Of: odoo/odoo#250113
This update fixes an issue where breaking a combo in the Point of Sale system didn't properly update the preparation display. The fix ensures that the preparation display is now notified when a combo is reorganized, preventing unnecessary kitchen tickets and streamlining the order preparation process. This improves efficiency and reduces potential errors.
Original PR description
Issue: Breaking a combo back into individual lines was not notifying the preparation display. Fix: breakCombo now go through sendOrderInPreparation (with byPassPrint) the preparation display is updated and no ticket is printed. To avoid triggering a sound and a kitchen ticket for a reorganization the kitchen already knows about, thread a `silent` context flag through sendOrderInPreparation down to _send_load_orders_message. 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
A recent update caused internal server errors when blog comments were enabled. This fix removes a leftover reference to a field, resolving the issue and ensuring blog pages function correctly with comments active. This improves the overall stability of the blog feature.
Original PR description
**Description of the problem** Traceback on blog pages when comments are active. **How to reproduce** (Starting from a fresh database with `website` and `website_blog` installed with demo data) 1. Open edit mode on a blog post 2. Activate comments 3. PROBLEM: Internal Server Error **Origin of the problem** Commit [1] removed the `website_message_ids` field, but a single occurrency was left behind in the codebase, causing a traceback on the first attempt to open the blog page. **FIX** This commit removes the reference to the field `website_message_ids`. [1]: https://github.com/odoo/odoo/pull/261003 task-6364928
A bug in the public tour process caused it to repeatedly run and fail due to delayed uploads. This fix correctly scopes the tour's uploads to the composer, ensuring it waits for its own attachments to be processed. This resolves a recurring test failure and improves the tour's reliability.
Original PR description
discuss_channel_public_tour uploads two files and waits for their attachment cards before clicking Send. The card selectors were not scoped to the composer, and message attachments render the exact…
discuss_channel_public_tour uploads two files and waits for their attachment cards before clicking Send. The card selectors were not scoped to the composer, and message attachments render the exact same card. The tour runs twice per test: on the second run, the message posted by the first run already displays identical text.txt and image.png cards, so the waits matched immediately and the tour never waited for its own uploads (build logs show the steps passing before the upload requests even reached the server). Send was then clicked during the upload window. The trigger can catch the button enabled from a render preceding the upload registration, while processMessage checks the live model, still finds an attachment uploading, and silently drops the message. The persistent "cheese" message step then timed out. Scope the selectors to the composer so the tour genuinely waits for its own uploads; this also makes the guest access token check read the composer image instead of the first run's message image. https://runbot.odoo.com/odoo/error/941300
This update resolves a bug that prevented the generation and sending of French PDP reports. The issue stemmed from incorrectly formatting the report data before sending, which caused a system crash. This fix ensures reports are now processed correctly and reliably.
Original PR description
Before this commit, it was impossible to send a `l10n.fr.pdp.reports.flow` as we included a raw file in the payload without decoding it. This causes the JSONification to crash. 1. Install l10n_fr_pdp 2. Create a record of `l10n.fr.pdp.reports.flow` 3. Try to send it 4. See crash opw-6330820 **19.3+** Forward-Port-Of: odoo/odoo#272513
10 changes
Enhancements to existing features
This update ensures that restaurant staff can now always access course management features, even when Course Allocation is enabled. A helpful message has also been added to guide users through the course creation process. This improves the overall functionality for restaurants using the Odoo Point of Sale system.
Original PR description
Before this commit: ======================= The Courses menu was always hidden because it was restricted to `base.group_no_one`, making course management inaccessible even when Course Allocation was enabled in a restaurant PoS. After this commit ====================== The Courses menu now always visible. A help message is also added to the Courses action to guide users when creating courses. Task-6317914 Forward-Port-Of: odoo/odoo#271308
This update adds a 'Profitability' field to account analytic lines, enabling a clearer breakdown of revenue and loss within the Analytic Report. This enhancement provides better visibility into profitability trends, helping businesses understand the financial performance of their operations.
Original PR description
[IMP] account: group analytic items by profitability This commit add a new field 'Profitability' on the account analytic line model, this will allow to visually split analytic line items in 2 categories: 'Revenue' and 'Loss' in the Analytic Report task-4959636 Forward-Port-Of: odoo/odoo#262962
Resolved issues and error corrections
This update ensures that taxes are correctly saved when editing POS orders in the backend, specifically during return and exchange scenarios. Previously, the system silently dropped tax information during the save process due to the `tax_ids` field being read-only. The fix adds a setting to force the save, guaranteeing tax data is preserved.
Original PR description
The `tax_ids` field on `pos.order.line` is defined with `readonly=True`. When editing a POS order from the backend (e.g. during a return/exchange flow), the `_onchange_product_id` method correctly…
The `tax_ids` field on `pos.order.line` is defined with `readonly=True`. When editing a POS order from the backend (e.g. during a return/exchange flow), the `_onchange_product_id` method correctly sets `tax_ids` from the product, and the computed `tax_ids_after_fiscal_position` displays the mapped taxes in the UI. However, because `tax_ids` is readonly, the web client does not include it in the save payload. As a result, the taxes are silently dropped on save and `tax_ids_after_fiscal_position` recomputes to empty. Steps to reproduce: 1. Create and pay a POS order with a product that has taxes 2. Go to the backend (Point of Sale > Orders) and open that order 3. Initiate a return for the order 4. In the return order, add a new product (exchange scenario) 5. Observe that taxes are correctly shown on the new line 6. Click Save 7. The taxes disappear from the order line The fix adds `force_save="1"` to the `tax_ids` field in both the list and form views of `pos.order.line`, consistent with how `price_subtotal` and `price_subtotal_incl` are already handled in the same views. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261672 Forward-Port-Of: odoo/odoo#253680
This update ensures that non-global rules behave correctly when a group association is removed. Previously, rules without groups could unexpectedly trigger, leading to potential inaccuracies. This fix corrects a technical issue to guarantee rules only apply when a group is actively defined.
Original PR description
A non-global rule is expected to have at least one group. However, it is technically possible to remove a rule's last group without making the rule global. This may happen for instance, when the group relation is removed in plain SQL. In that case, the rule should not apply at all.
This update resolves a discrepancy in the testing process for the pos_qfpay module. A necessary step to ensure correct payment terminal functionality was missing in the tests, which has now been added. This ensures the payment processing system operates as intended.
Original PR description
In odoo/odoo#270240 we removed the automated "send" call on payment terminals, but the test for pos_qfpay wasn't updated in the fw port. This commit fixes by adding a call to "send" in the test.
This update fixes a potential issue where users could still register payments against invoices that were marked as blocked for payment. The changes now prevent payment registration through all interfaces and display blocked invoices clearly as 'Blocked' in invoice lists, ensuring accurate financial reporting and preventing incorrect payment processing.
Original PR description
When an invoice is blocked for payment, the form view hides the Pay button, but users could still register a payment from list/payment-item flows. Prevent payment registration for blocked invoices in both the invoice action path and the payment register wizard path. Also make blocked invoices display as Blocked in invoice lists instead of Posted or Sent. task-6310234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270830
This update fixes an issue where changing the start date of a work order would incorrectly calculate the expected duration. The fix ensures that the duration remains accurate when only the start date is adjusted, aligning with previous behavior and preventing disruptions to scheduling.
Original PR description
**Problem:** On a planned work order, changing only the start date (e.g. in the planning gantt edit dialog) corrupts the expected duration instead of just shifting the end date. The duration drifts…
**Problem:** On a planned work order, changing only the start date (e.g. in the planning gantt edit dialog) corrupts the expected duration instead of just shifting the end date. The duration drifts to a wrong value, and in some cases (e.g. dependent work orders) collapses to 0. **Steps to reproduce:** 1. Plan a work order on a workcenter (start, end, expected duration). 2. Open it and change only the start date to a time that is not on a working-hours boundary. 3. The end date updates, but the expected duration is now wrong. **Expected behavior:** Changing the start date replans the work order: the duration is kept and the end date is recomputed from it. This is how 19.0 behaves and how dragging the pill in the gantt already behaves. **Cause of the issue:** Changing date_start triggers _onchange_date_start, which recomputes date_finished from start + duration via plan_hours. That cascades into _onchange_date_finished, which recomputes duration_expected from the dates via get_work_duration_data. Since the resource calendar refactor in 19.2, plan_hours and get_work_duration_data are no longer exact inverses around the work order's own planned slot, so the round trip drifts the duration. **Fix:** Only recompute the duration when the end date was edited on its own. When date_finished already matches the planned end for the current duration, it was merely derived from the start change, so the duration is kept. This keeps the duration authoritative when moving the work order while still recomputing it on a genuine end-date resize. opw-6231569 Forward-Port-Of: odoo/odoo#271508
This change addresses a temporary issue where the standard price of products in purchase orders was being incorrectly calculated due to timing conflicts during price updates. The fix ensures the correct standard price is applied, preventing inaccurate costing. This improves the reliability of purchase order pricing.
Original PR description
The below test sometimes fail for an incorrect reason and leads to a false positive:…
The below test sometimes fail for an incorrect reason and leads to a false
positive:
https://github.com/odoo/odoo/blob/6dbeac3a42f46b42c638c05aea8285452c944c3f/addons/stock_dropshipping/tests/test_purchase_order.py#L21
Here is another way to reproduce the issue with a higher probability of
false positive (and it is actually easier to read and understand what the
test is doing and what's wrong). It needs to edit the following test:
https://github.com/odoo/odoo/blob/ec58c5e12987401659ea0d75d3be2905ad1d807d/addons/purchase_stock/tests/test_create_picking.py#L953
With the below diff:
```diff
--- a/addons/purchase_stock/tests/test_create_picking.py
+++ b/addons/purchase_stock/tests/test_create_picking.py
@@ -965,6 +965,7 @@ class TestCreatePicking(ProductVariantsCommon):
'price': 500.0,
'discount': 10,
})]
+ self.product_id_1.standard_price = 1.0
po = self.env['purchase.order'].create(self.po_vals) # create a PO for 5 units
po.button_confirm()
with Form(po) as po_form:
```
It will lead to:
```
Traceback (most recent call last):
File ".../test_create_picking.py", line 976, in test_average_cost_updated_after_po_with_discount
self.assertEqual(self.product_id_1.standard_price, 450.0)
AssertionError: 1.0 != 450.0
```
Here are the explanations: when receiving an AVCO product, at some point, we
recompute its standard price. To do so, among several operations, we take
the last manual update, and we ignore all previous SM:
https://github.com/odoo/odoo/blob/2dbd88657395da965125c8f085da93e04c9c8f0a/addons/stock_account/models/product.py#L463-L465
This is an issue when things are done too quickly. See the pattern:
```py
self.product_a.standard_price = 5.0 # -> define valuation_from_date
po.confirm() # with another cost
receipt.button_validate() # -> define move.date
```
In case of a fast execution, both dates will be equal. We therefore ignore
the SM and rely on the manual update to define the standard price, which is
not expected. This explains the above `AssertionError`.
Fixing the codebase is quite tricky since the opposite use case could also
happen, aka first processing a receipt and only then modifiying the standard
price.
Tests side, a more important solution should probably be implemented to ease
their redaction and avoid this basic pattern. Yet, a WIP task is changing
the valo for Odoo 20, so the whole logic may change. Second, the current
issue is impacting a lot of builds, so we need to move forward. For both
reason, the commit only "fixes" the current test.
runbot-939955
Forward-Port-Of: odoo/odoo#273078This update optimizes how Odoo forms respond to changes. Previously, opening a form triggered onchange methods multiple times for each field that changed, leading to slower performance. This fix reduces redundant calls within a single update, resulting in a faster and more responsive user experience.
Original PR description
When an onchange method depends on several fields that all change at once (for example two fields that both have a default value), opening the form triggers that method once per field, even though a single call would suffice. This adds a per-pass set of already-applied onchange methods so that, within the same batch of changed fields, each method is invoked only once. Note this does not guarantee a method is called exactly once overall: it may still run again in later onchange passes; we only remove the redundant calls within a single pass. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273843 Forward-Port-Of: odoo/odoo#251813
This update resolves an issue where the 'Remaining Extra Hours' value in the employee attendance recap was incorrectly displaying as 00:00. The previous calculation method resulted in a strictly positive value, even when extra hours were owed. This change ensures the 'Remaining Extra Hours' accurately reflects the owed time off, aligning with other overtime calculations.
Original PR description
## Issue In the attendance view of an employee, a recap of the current extra hours is displayed, showing four values: 1. Total Extra Hours Worked 2. Total Compensable Extra Hours 3. Time Off Taken…
## Issue
In the attendance view of an employee, a recap of the current extra hours is displayed, showing four values:
1. Total Extra Hours Worked
2. Total Compensable Extra Hours
3. Time Off Taken from Extra Hours
4. Remaining Extra Hours
Each of the above values can be negative but the last one, which can seem odd as it appears to be calculated from the other values.
<img width="299" height="168" alt="6293174-before" src="https://github.com/user-attachments/assets/4377e2fd-f5f2-41a4-a82b-6f2598378499" />
## Steps to reproduce
1. Install *HR Attendance Holidays* (`hr_holidays_attendance`)
2. In Settings, toggle *Absence Management* and *Display Extra Hours*
3. For an employee E:
- In the Payroll tab, set the Working Hours to the *Standard 40 hours/week* schedule
- In the Settings tab, set the Overtime Ruleset to the *Default Ruleset*, and toggle the *Give back as time off* action for the *Employee Schedule Rule* rule
4. Create an attendance for employee E:
- Any day where they are expected to work 8 hours
- From 10am to 5pm (6 hours with lunch)
5. In the Employees app, go to employee E and click the *Monthly Hours* smart button
6. __In the *Balance* recap above the list of attendances, the *Remaining Extra Hours* row shows 00:00, which seems wrong compared to the other fields above (*Total Extra Hours Worked* and *Total Compensable Extra Hours*) which appear negative.__
## Cause
The `unspent_overtime` (*Remaining Extra Hours* in the balance recap) is computed by adding positive values, making it strictly positive.
https://github.com/odoo/odoo/blob/30c9e8c5b1e34b94c8aab8681e2c051a3b70f013/addons/hr_holidays_attendance/models/hr_employee.py#L62-L65
This was added by https://github.com/odoo/odoo/commit/2144bcfba1ac53c82fc7f2870a72bb13abee97e4, with no justification on why this value needs to be positive.
## Impact on "Time Off taken from Extra Hours"
Before this change, after following the above steps, a value of `-2:00` would be displayed in the *Time Off Taken from Extra Hours* row. This is no longer the case after this fix, since the `'unspent_compensable_overtime'` (*Remaining Extra Hours*) value is used to compute that row:
https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/hr_holidays_attendance/static/src/views/extra_hours_list_view.js#L39-L42
Instead, a value of `00:00` is shown. Before, we were substracting 0 hour of `unspent_compensable_overtime` to the -2 hours of `compensable_overtime`, now we are subectracting -2 hours of `unspent_compensable_overtime` to the same -2 hours of `compensable_overtime`. This is a side effect that was ignored, as it seems to make at least as much sense as showing `-2:00`.
<img width="321" height="179" alt="6293174-after" src="https://github.com/user-attachments/assets/907d5fb8-0c36-4b2e-bca7-1cec41baf22b" />
opw-6293174
Forward-Port-Of: odoo/odoo#273634
Forward-Port-Of: odoo/odoo#2712728 changes
New functionality added to Odoo
This update introduces a new 'Profitability' field to account analytic lines, enabling a clearer breakdown of revenue and loss within the Analytic Report. This enhancement provides greater visibility into profitability trends, helping users better understand financial performance.
Original PR description
[IMP] account: group analytic items by profitability This commit add a new field 'Profitability' on the account analytic line model, this will allow to visually split analytic line items in 2 categories: 'Revenue' and 'Loss' in the Analytic Report task-4959636 Forward-Port-Of: odoo/odoo#262962
This update adds PayU as a new payment option for our customers. This integration expands payment choices and supports a growing market, streamlining the checkout process for users who prefer PayU.
Original PR description
Add new payment provider PayU. See README.md for more details. task-6219530 Forward-Port-Of: odoo/odoo#267962
Enhancements to existing features
This update enhances the error messages related to leave validity checks, particularly when creating public holidays. This improves the user experience for both customers troubleshooting issues and our support team, reducing the need for manual debugging.
Original PR description
The current message is pretty useless as of now when a lot of leaves are being written to, notably when creating a public holiday, which sets the state of all the leaves overlapping the public holiday's day to be reevaluated, and if an error occurs, you have to go through every employee's leave allocation and leaves taken to hopefully find one who might have to many days taken/not enough allocated. This extra information will be a huge QOL improvement, for the customer who will be able to troubleshoot his issue himself more easily, but also for our support team as the only way to debug those kind of issues now is to put a breakpoint there and see what employee has an issue. opw-4411999 Forward-Port-Of: odoo/odoo#270888 Forward-Port-Of: odoo/odoo#200376
Resolved issues and error corrections
This update fixes an issue where project templates weren't correctly associated with sale orders, preventing proper billing and limiting template choices. It now ensures project templates are linked to the sale order's company, improving accuracy and usability. This ensures users can select the appropriate project template based on the sale order.
Original PR description
Fix 1 : project, sale_timesheet: remove default_allow_billable context in Create a Project --------------------- **Issue:** When a project is created from the sale app, it is not billable by default,…
Fix 1 : project, sale_timesheet: remove default_allow_billable context in Create a Project --------------------- **Issue:** When a project is created from the sale app, it is not billable by default, and the sale order / sale order line are not set. **Fix:** Remove default_allow_billable = False in the Create a Project **Note:** default_allow_billable = True already exists in action_view_project_ids, but that default context is replaced when opening the project directly from the view. This happens because default_allow_billable = False is set in the Create a Project action. Fix 2: sale_project: show only relevant project templates per company ---------------- **Steps:** - Install sale_project - Create two companies (A, B) - Create three project templates: - Template A (company A) - Template B (company B) - Template C (no company → visible to all) - Create a sale order for company A with a service product - Confirm the sale order - Create a project and try to select a template **Issue:** All project templates were visible even if the sale order had a company set. **Fix:** Added a filter (domain) on the project template field so only templates for the sale order’s company or templates with no company are shown. Users cannot select templates from other companies. task-5074893 Forward-Port-Of: odoo/odoo#260496 Forward-Port-Of: odoo/odoo#229309
This update fixes an issue where invoices weren't accurately reflecting timesheet hours after a partial refund was issued on a sales order. The change ensures that previously invoiced hours are properly deducted when generating new invoices, preventing over-invoicing. This improves the accuracy of billing and reporting.
Original PR description
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create a service product invoiced on delivered quantities with timesheet tracking - Create and confirm a SO for quantity 1 - Log 20h…
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create a service product invoiced on delivered quantities with timesheet tracking - Create and confirm a SO for quantity 1 - Log 20h on timesheets - Invoice the SO - Create a credit note for 11 hours => only 9 hours are invoiced - Log 5h more on timesheets - Back to the SO > create invoice again > All the 25hrs are to invoiced, although 9 of them were invoiced before ### Cause of Issue: When generating the new invoice, `_recompute_qty_to_invoice` calls `_get_delivered_quantity_by_analytic` which retrieves the analytic values for the SO line. The values retrieved are later used to determine the delivered quantity, which is later assigned to be `line.qty_to_invoice` without taking into account the already invoiced hours. https://github.com/odoo/odoo/blob/7a6518e39d34575a3977e7c4a0053a45223e203c/addons/sale_timesheet/models/sale_order_line.py#L176-L186 ### Fix: Ensures that hours that have already been completely invoiced are deducted from the quantity to invoice. opw-6253650 Forward-Port-Of: odoo/odoo#273156 Forward-Port-Of: odoo/odoo#268025
This update resolves an issue where invoices for Italian VAT (IT) were incorrectly calculating taxes. Now, invoices can include both the 0% Digital Operations Indicator (DOI) tax and other applicable taxes, ensuring accurate plafond calculations and tax deductions. This improves the functionality for IT VAT compliance.
Original PR description
- Create a declaration of intent in the customer's contact - Issue an invoice that includes both the 0% E (DoI tax) and any other tax - You will see how the plafond is not updated and the amount of this invoice is not deducted from it The method _compute_l10n_it_edi_doi_amount specifically exclude from the doi amount lines with the doi tax and another tax. However it should be possible to use both on a single line. We can use the amount subtotal because the doi is always 0%. opw-6253475 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267669
This update fixes a bug where email bounces from mailing campaigns weren't accurately recorded for contacts. Now, the system correctly updates bounce counts when emails fail to deliver, providing a more reliable view of mailing campaign performance. This ensures accurate reporting and helps optimize future campaigns.
Original PR description
Previously, when a mailing campaign sent out an email to a mailing.contact, and that email bounced, the bounce would not increment the contact's bounce count. This commit makes it so that the bounce count is correctly updated when a mailing campaign sends an email that bounces. task-4893615 Forward-Port-Of: odoo/odoo#226362
This update fixes a potential issue where users could still register payments against invoices that were marked as blocked for payment. The changes now prevent payment registration through all interfaces and display blocked invoices clearly as 'Blocked' in invoice lists, ensuring accurate financial reporting and preventing errors.
Original PR description
When an invoice is blocked for payment, the form view hides the Pay button, but users could still register a payment from list/payment-item flows. Prevent payment registration for blocked invoices in both the invoice action path and the payment register wizard path. Also make blocked invoices display as Blocked in invoice lists instead of Posted or Sent. task-6310234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270830
11 changes
New functionality added to Odoo
This update adds PayU as a new payment option for our customers. This expands payment choices and supports a growing market. Details are available in the PayU documentation linked in the pull request.
Original PR description
Add new payment provider PayU. See README.md for more details. task-6219530 Forward-Port-Of: odoo/odoo#267962
Enhancements to existing features
This update introduces a new 'Profitability' field to account analytic lines, enabling a clearer separation of revenue and loss items within the Analytic Report. This enhancement provides better visibility into the financial performance of each analytic line, improving reporting accuracy and decision-making.
Original PR description
[IMP] account: group analytic items by profitability This commit add a new field 'Profitability' on the account analytic line model, this will allow to visually split analytic line items in 2 categories: 'Revenue' and 'Loss' in the Analytic Report task-4959636 Forward-Port-Of: odoo/odoo#262962
Resolved issues and error corrections
This update fixes an issue where cash rounding records were incorrectly shared across all Indian companies. Previously, a single record was duplicated, leading to errors when opening invoices. The change ensures each new Indian company has its own unique cash rounding record, resolving data inconsistencies and improving invoice processing.
Original PR description
### Issue: When creating a new Indian company, the `Half Up` cash rounding is reassigned to the new company instead of being duplicated Previous Indian companies lose access to it, causing errors…
### Issue: When creating a new Indian company, the `Half Up` cash rounding is reassigned to the new company instead of being duplicated Previous Indian companies lose access to it, causing errors when opening invoices that reference the cash rounding if the user doesn't have access to that company ### Cause: `cash_rounding_in_half_up` was defined as a `data` record with a fixed XML ID (`l10n_in.cash_rounding_in_half_up`) `_get_in_account_cash_rounding` referenced that XML ID directly and set `company_id` to the current company on each chart of accounts installation This reassigned the single shared record to the new company instead of creating a new one Moving the definition to the `@template` decorator without a module-prefixed XML ID lets the chart of accounts system create one record per company, as intended ### Steps to reproduce: - Install `l10n_in` and switch to `IN Company` - Check the Cash Rounding records grouped by company - Create a new Indian company - Enable both `IN Company` and the new company - Check the Cash Rounding records grouped by company again Before the fix, only the last created Indian company has the Cash Rounding record opw-6318857
This update resolves an issue where archived employee order data remained visible in the POS system. The fix ensures that orders processed by an archived employee are no longer displayed when searching for 'Paid' orders. This improves data accuracy and prevents confusion for users.
Original PR description
Steps to reproduce on runbot:
- Enable "Log in with Employees"
- Connect to the POS with an employee
- Process an order
- Go to the backend
- Archive the employee
- Connect to the POS with another employee
- Go to the "Order" tab and search for "Paid" orders
Error:
Odoo Server Error: {archived_employee_id}
[opw-6223243](https://www.odoo.com/odoo/project/49/tasks/6223243)
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#273394
Forward-Port-Of: odoo/odoo#266364This update fixes a potential issue where users could still register payments against blocked invoices, even though the payment button was hidden. Now, blocked invoices are correctly displayed as 'Blocked' in lists and payments cannot be registered through standard flows. This ensures accurate financial reporting and prevents incorrect payment processing.
Original PR description
When an invoice is blocked for payment, the form view hides the Pay button, but users could still register a payment from list/payment-item flows. Prevent payment registration for blocked invoices in both the invoice action path and the payment register wizard path. Also make blocked invoices display as Blocked in invoice lists instead of Posted or Sent. task-6310234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270830
This update fixes an issue where the 'To Pay' section on point-of-sale receipts incorrectly displayed the total due instead of the actual cash payment amount. The change ensures the receipt accurately reflects the price plus tax, aligning with previous behavior and improving clarity for users.
Original PR description
**Steps to reproduce:** - Create a rounding method, only for cash, rounding of 100 - Create a product, costing 100 - Go to the PoS, order and pay for the product with cash - The "To Pay" section is the total due, and not what we actually paid - It is 115 but it should be 100 as this is what we pay for **Why the fix:** The current behavior is to display the total due, not rounded, just everything we have to pay for. Before 19.0, what we paid for was displayed, in this exemple it would display 100 and not 115. This is correct as it seems it is what this section of the receipt is about. We now use **total_amount_currency** which is computed like this https://github.com/odoo/odoo/blob/006a6a1cc6e50bd8b328d0cabb7abbcf610e34bb/addons/account/static/src/helpers/account_tax.js#L1411-L1414 So it is the price + the tax + the rounding, in this exemple it would be **100 + 15 + (-15)** opw-6225613 Forward-Port-Of: odoo/odoo#265298
This update resolves a rare technical problem within Odoo's web interface that could occasionally cause a test to fail. The fix ensures that popovers are properly closed, preventing errors that arise when components are destroyed during the testing process. This improves the stability of the web interface.
Original PR description
Add an extra step to close the popover and prevent the `Component is destroyed` error[1], which can happen during hoots cleanup, similar to the issue we see when some dialogs perform RPCs as they are being destroyed. [1]: https://runbot.odoo.com/runbot/build/115972540 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273826 Forward-Port-Of: odoo/odoo#273085
This update fixes a technical error that prevented users from accessing the 'By Employee' report within the Time Off module when specific employee settings were configured. The issue stemmed from a singleton problem, now resolved to ensure the report functions correctly for all users. This ensures accurate reporting on employee time off requests.
Original PR description
A singleton error appears when opening the "By Employee" report under Time Off. Steps to reproduce: 1)Install the l10n_fr_hr_holidays module. 2)Switch to the French company. 3)Open any employee record. 4)Set Working Hours (resource_calendar_id) to empty. 5)Set Hours Per Week. 6)Create a time off request for any past date. 7)Go to Reporting → By Employee. Task:-6043142 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
This update resolves an issue where users with access restricted to a 'branch' company were unable to properly validate purchase orders for components linked to a different 'company1' company. The fix ensures the system correctly handles valuation calculations when components are associated with different company IDs, preventing access errors.
Original PR description
### Steps to reproduce: - Have a company with a branch say "company1" and "branch" - Create two products: Final product (FP), Component (Comp) - Set the company_id of FP to "branch" and of Comp to…
### Steps to reproduce: - Have a company with a branch say "company1" and "branch" - Create two products: Final product (FP), Component (Comp) - Set the company_id of FP to "branch" and of Comp to "company1" - Associate both products with a product category set to avco in company1 (the field is company dependant) - Create a bom for FP with company_id set to "branch": 1 X Comp - Impersonate a user whose only allowed and default is "branch" - Create and confirm an MO for 1 unit of FP - Set the qty_producing to 1 unit and validate #### > Access Error: Access to unauthorized or invalid companies. ### Cause of the issue: Validating the MO will, validate the component move and set its value: https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/stock_account/models/stock_move.py#L168-L173 But, in order to determine this value, it is necessary to determine its `property_cost_method`: https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/stock_account/models/product.py#L60-L69 Now, the issue is that the `product_template` of the component belongs to "company1" so that the user is unauthorized to read the valuation method of the product category for "company1". opw-6216141 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272429
This update fixes a testing issue within the account_edi_ubl_cii module by using a real, partial XML file for partner bank account retrieval tests. This ensures more accurate and reliable testing of the system's ability to process UBL invoices, leading to greater confidence in the financial data being imported.
Original PR description
Move the partner retrieval bank account number test to the `test_ubl_import_bis3_invoice_be_retrieve_partner.py` file and use a partial XML instead of a generated XML. Forward-Port-Of: odoo/odoo#273575 Forward-Port-Of: odoo/odoo#269995
This update fixes a minor typo in the Odoo email responsive design code. The correction ensures the email layout renders correctly across different devices, improving the user experience for recipients. This change is a routine maintenance task to maintain consistent email quality.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274343
12 changes
Enhancements to existing features
This update adds a 'Profitability' field to account analytic lines, enabling a clearer breakdown of revenue and loss within the Analytic Report. This enhancement provides better visibility into profitability trends and improves financial analysis capabilities.
Original PR description
[IMP] account: group analytic items by profitability This commit add a new field 'Profitability' on the account analytic line model, this will allow to visually split analytic line items in 2 categories: 'Revenue' and 'Loss' in the Analytic Report task-4959636 Forward-Port-Of: odoo/odoo#262962
Resolved issues and error corrections
This update fixes an issue where invoices weren't accurately reflecting timesheet hours after a partial refund was issued on a sales order. The change ensures that previously invoiced hours are properly deducted when generating new invoices, preventing over-invoicing and ensuring accurate reporting. This improves the reliability of sales order billing.
Original PR description
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create a service product invoiced on delivered quantities with timesheet tracking - Create and confirm a SO for quantity 1 - Log 20h…
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create a service product invoiced on delivered quantities with timesheet tracking - Create and confirm a SO for quantity 1 - Log 20h on timesheets - Invoice the SO - Create a credit note for 11 hours => only 9 hours are invoiced - Log 5h more on timesheets - Back to the SO > create invoice again > All the 25hrs are to invoiced, although 9 of them were invoiced before ### Cause of Issue: When generating the new invoice, `_recompute_qty_to_invoice` calls `_get_delivered_quantity_by_analytic` which retrieves the analytic values for the SO line. The values retrieved are later used to determine the delivered quantity, which is later assigned to be `line.qty_to_invoice` without taking into account the already invoiced hours. https://github.com/odoo/odoo/blob/7a6518e39d34575a3977e7c4a0053a45223e203c/addons/sale_timesheet/models/sale_order_line.py#L176-L186 ### Fix: Ensures that hours that have already been completely invoiced are deducted from the quantity to invoice. opw-6253650 Forward-Port-Of: odoo/odoo#273156 Forward-Port-Of: odoo/odoo#268025
This update corrects a bug where unreserving a production order would prevent byproducts from being created. The fix ensures that byproducts are properly adjusted when an order is unreserved, maintaining accurate inventory levels. This resolves an issue impacting production planning and material availability.
Original PR description
On a mo that has byproducts, if you unreserve, it will also set the quantity of byproducts to 0 Steps to reproduce: ------------------- * Create a Products main, component and byproduct * Create a…
On a mo that has byproducts, if you unreserve, it will also set the quantity of byproducts to 0 Steps to reproduce: ------------------- * Create a Products main, component and byproduct * Create a bom for main with component as component and byproduct as byproduct * Create and confirm a mo for main * Set qty_producing to quantity ot produce * click on "Unreserve" (do_unreserve) * click on "Check availability" (action_assign) * Produce All -> the byproducts will not be produced. Observation: ------------- When updating the qty_producing value it will also update the quantity of the byproducts moves: https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/mrp/models/mrp_production.py#L892-L893 https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/mrp/models/mrp_production.py#L1350 https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/stock/models/stock_move.py#L2382 The quantity on the byproducts move has been updated. When clicking on Unreserve it will call do_unreserve, https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/mrp/models/mrp_production.py#L2297-L2298 It will filters the moves that do not need to be unreserved and select the others: https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/stock/models/stock_move.py#L900 and it will unlink all the sml from the moves: https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/stock/models/stock_move.py#L919 Which will set the quantity on the byproduct moves to 0. When Producing all (button_mark_done) since the qty_producing has already been set, it will simply mark the byproduct move has picked. https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/mrp/models/mrp_production.py#L1323-L1324 In our case, this means that the no byproducts will be created since, the quantity was previously set to 0 opw-6296562 Forward-Port-Of: odoo/odoo#272216
This update clarifies the descriptions for both User and Administrator groups within the Project module. The changes improve clarity regarding user access to projects and reporting capabilities, ensuring accurate understanding of permissions.
Original PR description
This commit improves the grammar of the Project user group description. ### **For User:** **Before -** `User can user the your employees' schedule` **After -** `User: Can manage tasks in projects shared with them.` ### **For Admin:** **Before -** `Administrator can manage the employees' schedule` **After -** `Administrator: Can manage projects and stages, with access to reporting and configuration.` **opw-6340390** Forward-Port-Of: odoo/odoo#273061
This update resolves an issue where invoices were displaying an incorrect final amount due due to a misinterpretation of loyalty program discounts. The fix ensures that tax calculations are accurate, particularly when loyalty discounts are applied, preventing a small discrepancy in the invoice total. This improves the reliability of the POS order process.
Original PR description
When computing taxes for the order, we group the base lines based on a grouping key. One of the components of this key is `is_refund`, and reward lines where considered as refund lines, which caused…
When computing taxes for the order, we group the base lines based on a grouping key. One of the components of this key is `is_refund`, and reward lines where considered as refund lines, which caused them to be grouped separately. This caused a discrepency between the tax amount computed in the frontend and the one computed in the backend. Steps to reproduce: ------------------- * Change the rounding method to globally * Create a 21% tax not included in price * Create a product with a price of 76.01 and the tax created above * Create a loyalty program with a 10% discount * Create a POS order with the product above and apply the loyalty program * Validate the order and generate the invoice > Observation: The invoice states that 0.01$ is still due Why the fix: ------------ In `round_tax_details_tax_amounts`, we try to detect any delta with the expeced tax amount. To do that we group the base lines based on a grouping key. The grouping key `is_refund` was incorrectly set to `true` for reward lines, which caused them to not be grouped. The delta was then not detected and tax amounts were not adjusted. We now make sure not to consider reward lines as refund. opw-6052112 Forward-Port-Of: odoo/odoo#273397 Forward-Port-Of: odoo/odoo#271577
This update strengthens the website's security by preventing unauthorized users from subscribing to stock notifications for unavailable products or using existing customer email addresses. The change adds validation to ensure subscriptions are legitimate and prevents potential misuse of user accounts, enhancing overall system security.
Original PR description
Description of the issue/feature this PR addresses: Currently, in the website_sale_stock module, there is no backend validation when subscribing to notifications for products without stock. This…
Description of the issue/feature this PR addresses: Currently, in the website_sale_stock module, there is no backend validation when subscribing to notifications for products without stock. This allows public users to potentially use emails that belong to registered accounts. Current behavior before PR: Users could subscribe to stock notifications for products that don’t exist or cannot be added (no stock). Public users could use emails already associated with registered accounts, allowing them to subscribe on behalf of another user. No validation is enforced, leading to potential security issues. Desired behavior after PR is merged: Adding a subscription for a non-existent or unavailable product raises a ValidationError. Public users trying to subscribe with an email that belongs to a registered user receive an AccessError prompting them to sign in first. Backend validation prevents misuse of registered user emails and improves security. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273691 Forward-Port-Of: odoo/odoo#271880
This update resolves an issue where reverting inventory adjustments with packages resulted in negative quantities appearing within those packages. The fix ensures that quantities are accurately restored after a revert, preventing inconsistencies in package inventory levels. This improves data accuracy and reliability for stock management.
Original PR description
Currently when the user reverts an inventory adjustment move line with a package the package contains extra line showing negative quantity of the product. ## Steps to produce: - Install Inventory…
Currently when the user reverts an inventory adjustment move line with a package the package contains extra line showing negative quantity of the product.
## Steps to produce:
- Install Inventory without demo data
- Settings Enable 'Packages'
- Create a product:
- Cheese burger
- On hand > Create a new quant
- Package: 'Burgerbox' and 'On Hand Quantity`: 1 and save
- Set the On Hand quantity to zero and save
- History > Revert the Inventory adjustment line from WH/stock to Inventory adjustment by selecting it and reverting via actions.
- Products > Packages > BurgerBox
## Observed Behaviour:
After reverting an inventory adjustment that set the product's physical quantity to 0, the package contains two lines for the same product with quantities 1 and -1.
This is inconsistent because a package should not contain a product with a negative quantity.
The package should be restored to its original state and contain only the expected positive quantity.
## Root cause:
When the user reverts the move line, `action_revert_inventory` is called. This method creates the revert move and then marks that move as done at [1].
Marking the move as done subsequently marks all related move lines as done at [2]. During this process, the system first unreserves the quantity from the virtual location / inventory adjustment and then removes the quantity from that location (resulting in a -1 quantity move line at that location). This is performed through `_synchronize_quant`, which is responsible for synchronizing the physical inventory with the move line at [3].
The `_synchronize_quant` method uses the move line's `package_id` when updating the corresponding quant at [4]. As a result, `_update_available_quantity` creates a new quant with the following values at [5]:
```
{
'product_id': 1,
'location_id': 14,
'lot_id': stock.lot(),
'package_id': 1,
'owner_id': res.partner(),
'in_date': datetime.datetime(2026, 6, 22, 12, 42, 11),
'quantity': -1.0,
}
```
This creates a quant with a negative quantity that is linked to the package because `package_id` is set on the newly created quant. Consequently, the move line with the negative quantity becomes associated with the package.
[1]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_move_line.py#L1016-L1035
[2]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_move.py#L1956 [3]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_move_line.py#L662-L666
[4]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_move_line.py#L678-L687
[5]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_quant.py#L1130-L1143
## Solution:
Remove the source `package_id` when creating revert moves for inventory adjustment locations.
When an inventory adjustment sets a product's quantity to 0, the adjustment is completed without a destination package, meaning the product is effectively removed from the package. Therefore, the corresponding revert move should not retain the package as its source. Keeping the package as the source is inconsistent because package information should not exist on a virtual inventory adjustment location, and the original inventory adjustment removes the product from the package (there is no destination package).
By removing the source `package_id` from the revert move, the system avoids creating negative quants associated with the package during quant synchronization. This also ensures that, after the inventory adjustment is reverted, the quantities of products inside the package are restored correctly and match their state prior to the adjustment.
opw-6285739
Forward-Port-Of: odoo/odoo#273632
Forward-Port-Of: odoo/odoo#271440This update corrects a visual issue where the background color of the account type selection dropdown remained in light mode when dark mode was enabled. The change ensures the dropdown's background color matches the overall dark mode theme, improving the user experience and visual consistency. This fix was implemented to maintain a polished and professional appearance across all Odoo environments.
Original PR description
Steps to reproduce: - Install `account` module - Enable dark mode - Open `view_account_form` to create a record - On the Accounting page, open type dropdown - The dropdown background remains in light mode This commit applies $dropdown-bg on `o_field_account_type_selection` as in odoo/odoo@0cd148eb389078c896aaa719af5733d05377fd1c Forward-Port-Of: odoo/odoo#274098 Forward-Port-Of: odoo/odoo#271352
This update fixes an issue where template tasks were incorrectly counted in task views and notebooks. The change ensures that task counts accurately reflect only real subtasks, improving the clarity and usability of project management within the Odoo system. This ensures accurate reporting and task management.
Original PR description
Steps to Reproduce --- - Create a normal parent task with one normal sub-task and one template sub-task. - Open the parent task form view and observe the Sub-tasks stat button count and notebook tab,…
Steps to Reproduce --- - Create a normal parent task with one normal sub-task and one template sub-task. - Open the parent task form view and observe the Sub-tasks stat button count and notebook tab, check the subtask view as well. - Create a template parent task with one normal sub-task and one template sub-task, then repeat the same checks. Issue --- - Task templates are handled like regular subtasks in the subtask count, notebook, and subtask view, without taking the parent task type into account. Current Behaviour --- - For a normal parent task, both the normal sub-task and the template sub-task are counted and shown in the opened subtask view and notebook. - For a template parent task, the same filtering is applied, even though template subtasks should remain accessible in that context. Expected Behaviour --- - For a normal parent task, only real sub-tasks should be counted and shown in the subtask view and notebook, and on the project kanban card. - For a template parent task, template subtasks should remain available in the subtask view and notebook according to the parent template context. - In the project kanban card, tasks must not be counted when their parent task is a template, even if the child task itself is not a template. Fix --- - Apply template-aware filtering to subtask counting,project kanban task count and subtask view behavior, depending on whether the parent task is a normal task or a template task. task-5966684
This update fixes an issue where expense accounts weren't being correctly applied during Point of Sale transactions. Now, when a sale is made without invoicing, the system accurately maps expense accounts based on the fiscal position or product category, ensuring accurate financial reporting. This improves the reliability of financial data generated from Point of Sale.
Original PR description
**Steps to reproduce:** - Make a product with a category - In the category, make the inventory valuation to automated - Set the income and expense account - Set a cost for the product - Make a fiscal…
**Steps to reproduce:** - Make a product with a category - In the category, make the inventory valuation to automated - Set the income and expense account - Set a cost for the product - Make a fiscal position and set it as default for the PoS - In the Account Mapping tab, map the income and expense to two other accounts - Go to the PoS - Make a sale for that product, without invoice - Close the session and in the backend check the session - Check the journal entries - The income account has been mapped to the fiscal position's - The outcome account stayed the same as in the category's **Why the fix:** When we invoice an order, the income and expense accounts are immediately updated, in a different place than if it has not been invoiced. At the session's closure, we update the accounts for every order that hasn't been invoiced. In this flow, the account mapping defined on the fiscal position was not applied, so we took the one defined on the product's category. The income account was already mapped as we need to do it earlier than the session closure, so it had already been set as the right one before our flow. For the expense account, we only need it at this specific time, so we can map it as the session's closure. We now map the account depending on the fiscal position if we are able to find one, otherwise, we use the category's default as we did before. opw-6171677 Forward-Port-Of: odoo/odoo#266700
This update corrects a previous error that triggered a user error message when generating invoices for Co-Contractant tax situations. The fix ensures that a note is only added to the invoice when the Co-Contractant tax amount is zero, aligning with standard fiscal practices. This improves invoice accuracy and user experience.
Original PR description
We were raising a UserError because we were putting the note even if the tax amount was different from 0. But in fact, it can be normal to have 0% cocontractant tax and normal rate at the same time on an invoice, which would have the fiscal position Co-Contractant. So remove these UserError, but only apply the note when the tax amount is 0 opw-6302806 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274117 Forward-Port-Of: odoo/odoo#268899
This update ensures that taxes and order totals are accurately displayed when customers select in-store pickup for international orders. Previously, the system incorrectly applied VAT, leading to inaccurate checkout summaries. This fix automatically recalculates taxes and updates the checkout summary to match the selected pickup location.
Original PR description
Backport of : https://github.com/odoo/odoo/pull/269057 to V18 When an international customer selects an in-store pickup location, the order's fiscal position changes to the fiscal position matching…
Backport of : https://github.com/odoo/odoo/pull/269057 to V18 When an international customer selects an in-store pickup location, the order's fiscal position changes to the fiscal position matching the pickup warehouse. However, the order-line taxes and checkout summary are not recomputed immediately. **Steps to reproduce:** 1. Configure a French company and website. 2. Configure a product priced at 100 ( just an example , any price will do ) EUR excluding 20% French VAT. 3. Configure an export fiscal position removing VAT for Japan. 4. Configure an international delivery method. 5. Configure an in-store pickup method with a warehouse located in France. 6. Checkout using a Japanese delivery address. 7. Select the international delivery method. 8. Switch to pickup in store. **Current behavior:** - The order fiscal position changes to the French fiscal position. - Product-line taxes and the checkout summary remain based on the export fiscal position. - French VAT only appears later on the payment step. - Switching back to international delivery can similarly leave stale totals. **Expected behavior:** - Selecting the French pickup location immediately applies French VAT. - Switching back to international delivery immediately removes French VAT. - Totals displayed during delivery selection match the payment-step totals. **Cause:** The Click & Collect flow explicitly recomputes `fiscal_position_id` when selecting or leaving an in-store pickup location, but it does not recompute the order-line taxes and prices. Additionally, the pickup-location route does not return updated order-summary values, so the checkout page cannot refresh its displayed totals. **Solution:** - Recompute taxes and prices when the in-store fiscal position changes. - Restrict the recomputation to draft website orders. - Return the updated order summary after selecting a pickup location. - Refresh the checkout summary using the returned values. **Tests cover:** - Japanese delivery with export fiscal position and no VAT. - Switching to a French pickup location immediately applying 20% VAT. - Switching back to international delivery removing VAT. - Delivery-step totals matching payment-step recomputation. - Pickup-location route returning updated summary values. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269086
11 changes
New functionality added to Odoo
This update introduces a new 'Profitability' field to account analytic lines, enabling a clearer breakdown of revenue and loss within the Analytic Report. This enhancement provides greater visibility into profitability by categorizing individual line items, improving financial analysis and reporting.
Original PR description
[IMP] account: group analytic items by profitability This commit add a new field 'Profitability' on the account analytic line model, this will allow to visually split analytic line items in 2 categories: 'Revenue' and 'Loss' in the Analytic Report task-4959636
This update adds support for French e-invoicing requirements, specifically UBL, CII, and Factur-X formats. It includes new profiles to comply with French regulations for B2B transactions, ensuring accurate and compliant invoice generation for French customers.
Original PR description
Add French variations for UBL, CII, and Factur-X formats to support France's mandatory e-invoicing requirements. Add support for French Peppol EAS `0225` (FR:CTC) in EAS mappings/selections. These profiles are required for compliance with French B2B e-invoicing regulations: - UBL/CII: EN16931 (standard) and EXTENDED-CTC-FR (extended French) - Factur-X: BASIC WL, EN16931, and EXTENDED The different profiles allow handling varying levels of invoice complexity as required by French tax authorities. Task : 4603737
Resolved issues and error corrections
This update corrects a visual inconsistency in the website's accordion controls. A previous change caused the accordion's color to appear differently when expanded versus collapsed. This fix ensures a consistent and correct color display for all accordion states, improving the overall user experience.
Original PR description
In commit[1] we restyled the accordion snippets, removing the background-image to use oi-icons instead. However due to selector specificty, the rule was taking priority. This :not is actually wrong since we want the color to apply as well when the accordion is collapsed (else you have 2 different colors between the collapsed uncollapsed state) task-6361379 [1]: f26a1535b96c728e4360d94c0c06de138a6b1b3f --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where the quantity displayed for kit products in the Point of Sale picking process was incorrect. The fix ensures that the correct quantity, based on the kit's components, is accurately reflected, leading to more precise inventory management. This improves order fulfillment accuracy for kit products.
Original PR description
**Steps to reproduce:** - Create a product A, tracked by lots - Create a kit product, include a component A - Change the UoM to 0.5 - Go to the PoS, order this kit product - Also order the component…
**Steps to reproduce:** - Create a product A, tracked by lots - Create a kit product, include a component A - Change the UoM to 0.5 - Go to the PoS, order this kit product - Also order the component A, with a quantity of 2 - Pay for it, ask for an invoice - Go to the created picking - The Demand column is correctly computed and is 0.5 - The Quantity column is wrong and is 2 **Why the fix:** When getting the data from https://github.com/odoo/odoo/blob/e0d84c7fbb270d0d1f82572daefa96c2978d3785/addons/point_of_sale/models/stock_picking.py#L283 we always get the component's line, as the move's product is the component, even if it used to be the kit product's move. This is because when exploding a kit's moves, it gets the kit's component as a product instead of keeping the kit product. This was introducing a weird behavior because we took the quantity from the component line, and not from the kit line, meaning the kit would always have the same quantity as the component. We now check if the move is actually a kit product's move, and if it is we adapt the qty to correct one by fetching the correct line's qty, and adapting it with the correct UoM. Changing the line in itself would not work, as the kit itself is not tracked by lots, so we would not enter https://github.com/odoo/odoo/blob/e0d84c7fbb270d0d1f82572daefa96c2978d3785/addons/point_of_sale/models/stock_picking.py#L284 and the move line would not be correctly created. opw-6153000 Forward-Port-Of: odoo/odoo#262551
This update corrects a previous error that displayed an invoice note even when the tax amount was not zero. The change allows for proper handling of invoices with varying tax rates, reflecting the Co-Contractant's fiscal position. This ensures accurate invoice generation and avoids unnecessary error messages.
Original PR description
We were raising a UserError because we were putting the note even if the tax amount was different from 0. But in fact, it can be normal to have 0% cocontractant tax and normal rate at the same time on an invoice, which would have the fiscal position Co-Contractant. So remove these UserError, but only apply the note when the tax amount is 0 opw-6302806 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268899
This update resolves an issue where tests related to account_edi_ubl_cii were failing due to an outdated VAT number. Replacing the invalid VAT with a valid one ensures consistent test results across different environments, improving the reliability of our system.
Original PR description
The previous Belgian VAT is rejected by newer versions of `python-stdnum`. Replace it with a valid VAT so the test behaves consistently across environments.
This update fixes an issue where users with access to multiple companies were only appearing as interviewers for jobs within their default company. The change ensures that users with access to multiple companies can be selected as interviewers for job positions across all their allowed companies, improving recruitment efficiency.
Original PR description
Issue: ---------------------------------------- A user allowed in multiple companies will only show as an interviewer in job positions from its default company. Steps to reproduce: ---------------------------------------- - Configure a user with multiple allowed companies (A and B) - Set the user's default company to A - Create or open a job position belonging to company B. - Try to add the user as an interviewer Cause: ---------------------------------------- To compute `allowed_user_ids` we group the users by `company_id` (i.e. the default company), so the allowed companies are ignored. Solution: ---------------------------------------- Group the users by `company_ids`, the aggregate then separates the companies in case they're a recordset. opw-6314373 Forward-Port-Of: odoo/odoo#273602
This update resolves a test failure related to certificate generation. The Odoo system relies on a specific version of the cryptography library, and an older version caused issues with X25519 keys. By skipping the X25519 issuer test when the library is outdated, the system continues to function correctly without disrupting certificate creation.
Original PR description
CertificateBuilder.public_key() rejects X25519 keys before cryptography 36.0.0, and Odoo pins 3.4.8 for python < 3.12, so test_is_issued_by errored on runbot. Skip the X25519 case when the lib can't build it. https://cryptography.io/en/latest/changelog/#v36-0-0 Runbot Error: https://runbot.odoo.com/odoo/runbot.build.error/941306 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
This update corrects a bug where the Peppol demo mode wasn't correctly applied to databases that had previously been neutralized. Previously, the system defaulted to production mode, leading to incorrect document registration. Now, the demo mode is automatically set when a neutralized database receives the account_peppol module, ensuring accurate Peppol network interactions.
Original PR description
When Peppol is installed on a database that was already neutralized (ex: a staging database where the feature is enabled after the neutralization happened), the account_peppol.edi.mode parameter is not set: data/neutralize.sql only runs at neutralization time, not when the module is installed afterwards. The demo/ data that also sets this parameter is not loaded on databases without demo data (real production/staging databases). As a result, _get_peppol_edi_mode() falls back to 'prod' and the neutralized database registers and sends documents against the live Peppol network. Steps to reproduce: - Neutralize a database on which Peppol is not installed yet - Install the account_peppol module - Open the Peppol settings / registration wizard: the mode is Production instead of Demo Force the demo mode in the pre_init_hook when the database is neutralized, mirroring data/neutralize.sql opw-6307710 Forward-Port-Of: odoo/odoo#273019
This update ensures that leave hours are calculated accurately when employees use calendars with multiple defined time slots. Previously, the system struggled to handle complex calendar schedules, leading to incorrect leave duration calculations. This fix resolves this issue, guaranteeing accurate leave tracking based on defined calendar hours.
Original PR description
Define the correct hours in the leaves if the calendar has defined dates (`date_from` and `date_to`) Use case example: - Create a calendar and define on Friday (Morning: from 08:00 to 13.00,…
Define the correct hours in the leaves if the calendar has defined dates (`date_from` and `date_to`) Use case example: - Create a calendar and define on Friday (Morning: from 08:00 to 13.00, Afternoon: from 19:00 to 21:00) with date_to=2025-01-01. - Define another specific Friday (Morning: from 09:00 to 14.00, Afternoon: from 17:00 to 20:00) in the same calendar with date_from=2025-01-01. - Create an employee and define the calendar created for him/her. - Create a leaves for the employee and select a Friday (2025-05-02). - The start hour of the leave must be 2025-05-02 09:00:00 - The end hour of the leave must be 2025-05-02 20:00:00   Please @pedrobaeza can you review it? @Tecnativa TT56218 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254249 Forward-Port-Of: odoo/odoo#208378
This update resolves a bug that caused errors when processing payments with withholding taxes in Argentina. Specifically, the system now correctly handles 0% withholding taxes and prevents the deletion of withholding lines during payment resets. This ensures accurate tax calculations and payment processing for Argentinian businesses.
Original PR description
**Steps to reproduce:** - Install Accounting and l10n_ar_withholding - Switch to an Argentinian company (e.g. (AR) Responsable Inscripto) - Create a 0% Payment Withholding tax: * Tax Type: Customer…
**Steps to reproduce:**
- Install Accounting and l10n_ar_withholding
- Switch to an Argentinian company (e.g. (AR) Responsable Inscripto)
- Create a 0% Payment Withholding tax:
* Tax Type: Customer Payment Withholding
* Amount: 0.00 %
* Add an account for the tax distribution lines
- Create an invoice with a tax
- Confirm the invoice
- Pay the invoice:
* Withholdings:
- Add a line with the created 0% Payment Withholding tax
- Add a line with another Payment Withholding tax
- Create Payment
- Go to the payment
**Issue 1:**
When clicking on the first withholding line, a JS error is raised due to a missing index (i.e. currency_id).
**Cause 1:**
One of the fields has an aggregate sum function applied on it (i.e. amount_currency).
As it is a monetary field, the corresponding currency field is required in the view.
**Issue 2:**
When resetting the payment to draft, the withholding line with the 0% tax is deleted.
As the withholding table is not editable, it is not possible to add the line again.
**Cause 2:**
When the payment is reset to draft, the state of the associated journal entry is also set to draft and a "_sync_dynamic_lines" is triggered, which remove tax lines having a zero amount during the process.
**Solution 2:**
Keep all the lines with a Customer Payment Withholding tax as it is not possible to add a withholding line in the payment afterwards.
opw-6298058
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr3 changes
Resolved issues and error corrections
This update corrects formatting issues with numbers in various languages, including Indian languages and Burmese, ensuring correct decimal separators and grouping symbols. It addresses inconsistencies in number formatting to improve the user experience for international customers and users.
This update resolves an issue where Nilvera invoices occasionally got stuck in an 'Unknown' status. The fix ensures Odoo continuously polls Nilvera for the latest invoice status, preventing delays in reporting and reconciliation. This improves the reliability of e-invoice processing with Nilvera.
Original PR description
## Short fix summary:
Nilvera reports `Unknown` as a normal, transient `StatusCode` value (their own e-Archive API docs
list the enum as `unknown`/`waiting`/`succeed`/`error`) right after a document is sent, before their
daily batch resolves the final status. But `_cron_nilvera_get_invoice_status`'s search domain only
matches `l10n_tr_nilvera_send_status in ('waiting', 'sent')`, so once an invoice lands on `unknown` it
is never polled again — even after Nilvera later resolves the real status on their side. This adds
`unknown` to that domain so these invoices keep getting polled until Nilvera reports a final status.
task-6328589
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update fixes a formatting issue with numbers displayed in Portuguese (pt_PT) and Hindi (hi_IN) languages within Odoo. It ensures numbers are grouped correctly according to international standards – three digits for Western countries and two digits after the first three for India – improving readability and accuracy. This change ensures consistent and appropriate number formatting for our users in these regions.
Original PR description
Currently the number grouping for Portuguese and Hindi is missing. Number grouping is used to separate long numbers in logical groups to make then easier to read. In Western countries, the grouping is usually done in groups of three digits (e.g. `1,000,000` instead of `1000000`), while in India, the grouping is done in groups of two digits after the first three digits (e.g. `10,00,000` instead of `1000000`). Source: https://www.unicode.org/cldr/charts/48/by_type/numbers.number_formatting_patterns.html#24a93b3d14ba17b2 All languages will be revised in a follow-up `master` PR. [task-6320391](https://www.odoo.com/odoo/project.task/6320391)