Daily updates from Odoo
Friday, July 3, 2026
350 changes
8 changes
Enhancements to existing features
This update ensures the font style for general customer notes in Point of Sale matches the font used for line customer notes. This improves the visual consistency of sales receipts and enhances the overall user experience for customers.
Original PR description
We updated the general customer note font to match the line customer note's one. task-6294200 Forward-Port-Of: odoo/odoo#271344 Forward-Port-Of: odoo/odoo#270060
Resolved issues and error corrections
This update resolves a recurring issue in the Odoo presence subscription test, which previously failed due to timing dependencies. By removing a batching delay, the test now reliably logs every subscription call, ensuring consistent and accurate test results. This improves the stability of the Odoo system.
Original PR description
Since [1], the `subscribe to presence channels according to store data` test is sometime failing as it heavily depends on timings. This commit removes the `OUTGOING_BATCH_DELAY` in order to remove batching. This way, we can ensure every call to `subscribe` is actually logged instead of guessing how they will be batched. runbot-941301,941304,941303 [1]: https://github.com/odoo/odoo/pull/272199 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 checkout process displayed outdated information due to caching issues. Specifically, toggling the 'extra info' step caused stale data to be served. The fix ensures that the checkout steps are refreshed whenever this step is enabled or disabled, improving the customer experience.
Original PR description
The next and previous checkout steps are cached for each current step. This is beneficial as the query doesn't change and is repetitive for every customer going through the checkout process. However, one exception was overlooked: the extra info step, which can be enabled or disabled via the HTML editor. Toggling it changes the result independently from the cache key/query, so a stale value is served. Invalidate the cache whenever the extra info step is enabled or disabled. runbot-939605
A recent issue in the mass mailing functionality caused crashes when opening emails. This fix resolves a problem where complex QWeb node structures (specifically `t-if` and `t-out` combinations) were causing errors. This ensures mass mailings open correctly and reliably in Email Marketing.
Original PR description
Prior to this commit, if a `<t>` node had children, the function evaluating if they should be displayed inline or not would crash. How to reproduce: - send a mass_mailing with qweb instructions: a `t-if` node containing a `t-out` - open the mass_mailing after it was sent (in readonly) Issue: - crash when opening the mass mailing (in Email Marketing) task-6250450 Forward-Port-Of: odoo/odoo#273818 Forward-Port-Of: odoo/odoo#266663
This update resolves an issue where editing lot IDs on tracked products caused incorrect quantity updates within the stock management system. The fix ensures that lot assignments accurately reflect available quantities and correctly adjusts reservations, improving the reliability of stock tracking. This impacts users managing lot-based inventory.
Original PR description
### Issue: Editing the `lot_ids` of a move of a `lot` tracked product from the picking form view leads to wildly unexpected results. This happens only with tracking by `lot` not by serial. ###…
### Issue:
Editing the `lot_ids` of a move of a `lot` tracked product from the picking form view leads to wildly unexpected results. This happens only with tracking by `lot` not by serial.
### Concrete Issue 1:
1. In the settings Enable "Lots and serial numbers", "Storage Locations"
2. Create a storable product P tracked by lots
3. Create and confirm a delivery for 5 units of P
4. Set the quantity of the move to 5 from the Form picking view > save
5. Create and set 2 lots: LOT1, LOT2 on the serial numbers field
6. Save
#### > The quantity of the move has been updated to 2, only the first lot is set and it has been for this quantity of 2
### Concrete Issues 2 and 3:
1. In the settings Enable "Lots and serial numbers", "Storage Locations"
2. Create a storable product P tracked by lots
3. Update the onhand quantity of P:
- 1 units of LOT001 in Shelf1
- 2 units of LOT001 in Shelf2
- 2 units of LOT002 in Stock
4. Create and confirm a delivery for 5 units of P
5. Remove LOT002 from the Serial numbers in the Form picking view > save
#### > The quantity of the move is updated to 1 (only the 1 unit of LOT001 from Shelf2 is kept)
5'. Remove LOT002 and put it back
#### > The quantity is updated from 5 to 2 if you save, only LOT001 is kept.
### Cause of the issue:
The `_onchange_lot_ids` and `_set_lot_ids` methods have been tailored to work appropriately only with `serial` tracking, updating the quantities considering a 1 to 1 quantity, lot matching:
https://github.com/odoo/odoo/blob/c9715982134220aa8fa525d0cf6a8d47eaeb6ed6/addons/stock/models/stock_move.py#L623-L645
However, for lot tracked product the situation is much more subtle to handle.
### Behavior after the fix:
Editing the `lot_ids` on tracked products should adapt the reservation following these rules:
- Existing move lines with a valid lot or lot name should be kept unchanged.
- Removing a lot should delete its related move lines and adjust the move quantity accordingly.
- Each newly assigned lot must be linked to at least one move line of the move.
If the move is expected to bypass reservation (e.g. receipts, final move of a production,...):
- Assignment should be performed, in priority, on an existing free move line.
- If no suitable free move line exists, a new move line should be created with the largest possible quantity that does not cause the total assigned quantity to exceed the move demand.
- If such a quantity cannot be assigned, the new move line should be created with a quantity of 1 in the product.uom_id.
If the move is expected to be reserved (e.g. internal transfer, deliveries,...):
- Each new lot should be assigned from an existing quants with the maximum available quantity to satisfy at best the remaining demand.
- If no available quantity can be assigned from existing quants, the lot should be assigned a minimum quantity of 1 in product.uom_id.
### Additional note on the fix:
Since move that do bypass reservation use a different detailed operation view relying on lot_names form move line rather than lot_id from existing quants it is important to set both the `lot_name` as well as the `lot_id` on move lines for the changes to be visible in the detailed operations view.
### Note:
The current fix populated records on which the `label_production_view_pdf` report was tested (by the test_report) highlighting a template error:
https://github.com/odoo/odoo/blob/a73428187112b3948a11810abae2a3c82c9c7bcd/addons/mrp/report/mrp_production_templates.xml#L187
The value provided to the t-field being something else than a field but rather an or close between two fields.
opw-6173914
opw-5881661
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#272253
Forward-Port-Of: odoo/odoo#263037This update corrects a small issue where email notifications weren't being properly sent after a call activity was marked as complete. The change ensures that users receive the expected email updates, improving communication around call interactions. This fix was implemented as part of a broader update to how call activities are managed.
Original PR description
In [1], we removed `action_call_done` for call activity, and to use `action_feedback` to mark a call activity done like other activities. However, we forgot to assign `activity_mail_message_id` for later mail message update. Add this in `action_feedback`. [1]: 70ba1812812596e00509415cedcc8f4bdf6c6e37 COMPR: https://github.com/odoo/odoo/pull/267663 Forward-Port-Of: odoo/enterprise#122687 Forward-Port-Of: odoo/enterprise#118396
This update resolves a performance issue in the previous memory profiler, which significantly impacted Odoo's speed. The fix replaces the problematic tracemalloc system with a new heuristic approach that accurately tracks memory usage without slowing down the application. This results in faster and more reliable performance for Odoo users.
Original PR description
The previous memory profiler was causing a lot of performance issues. This is because tracemalloc tracks the allocations that happens at the python interpreter level by attaching to the cpython…
The previous memory profiler was causing a lot of performance issues. This is because tracemalloc tracks the allocations that happens at the python interpreter level by attaching to the cpython allocators. This first meant each allocation that happens through python has to go through a callstack while holding the GIL and preventing the thread and other threads from operating. This callstack does multiple things, first is walking the allocation back from the current frame up until the specified frame depth at the start of collection. The other is updating the internal object that keeps track of the allocations and what cause them up until now which degrades the performance even more when the allocator keeps running for a long time. Increasing the frame depth also means the partitioning becomes even more fragmented in the internal object and leads to higher memory usage. This in turns means lower performance as well. The issue becomes more evident when the overhead of tracemalloc blocks any execution even turning it off because the gil cannot be released until the full allocation execution happens. Currently this would happen on long enough requests or a high enough depth. Two PRs were made to try to address this issue. 1- https://github.com/odoo/odoo/pull/251950 : This PR tries the solution of having a lower frame depth but matching the frames based on a window of frames so that we can reconstruct an approximation of the flamegraph, for example: matching window of 2 frames 1 - > 2 - > 3 - > 4 2 - > 3 - > 4 - > 5 would mean that we would match frames 2 and 3 in both stack traces and append the first frame to the second callstack which would look like 1 - > 2 - > 3 - > 4 - > 5 Neverthless this was deemed to have too big of an assumption in the building heuristic. 2- https://github.com/odoo/odoo/pull/253120: This PR was supposed to be introducing memray as a profiler. Memray is the best tool for this usecase. First because it attaches on the native system allocation calls, and uses a file to append to on allocations. This solves both of the issues that we had in the beginning but the issue with memray is that it's an external tool that was deemed unnecessary to add. The final solution is this PR: The PR assumes a heuristic that in worker mode, a single worker handles one thread which mean that the process memory can be fully attributed to the request. The heuristic is also based that on a high enough sampling rate, the delta can be fully attributed to the current frame. This is a close enough approximation to know where to look but not what is the actual memory usage by line. Forward-Port-Of: odoo/odoo#273424 Forward-Port-Of: odoo/odoo#253604
A technical bug prevented the successful display of a notification after activating Peppol. This update corrects a validation error in the system's code that was triggered by a specific configuration, ensuring that users receive confirmation when Peppol is properly set up.
Original PR description
**Steps to reproduce:** * Install the **account_peppol** and **l10n_be** module. * Switch to BE Company. * Create and confirm a BE customer invoice. * Open the "Send & Print" dialog. * Activate…
**Steps to reproduce:**
* Install the **account_peppol** and **l10n_be** module.
* Switch to BE Company.
* Create and confirm a BE customer invoice.
* Open the "Send & Print" dialog.
* Activate Peppol (register as a Peppol participant) in developer mode and demo mode by clicking on `Why should you use it ?` on the banner in wizard.
**Observed behavior:**
* An Uncaught Promise OwlError trace is thrown on the screen: `TypeError: Cannot use 'in' operator to search for 'toString' in null`.
* The success notification indicating that Peppol was activated fails to appear.
**Cause:**
* Upon successful registration, the `peppol.registration` wizard triggers a client action to display a success notification via `display_notification`.
* The backend Python code explicitly passed `title=None` in the notification parameters, which is serialized to `null` in the JavaScript frontend.
* In previous versions (like 19.2), the `Notification` component's `title` prop validation was defined loosely as `{ type: [String, Boolean, { toString: Function }] }`. OWL did not strictly validate this shape, allowing `null` to pass through without error.
* In 19.3, the prop validation was updated to strictly enforce the object shape: `{ type: [String, Boolean, { type: Object, shape: { toString: Function } }] }`. Because JavaScript evaluates `typeof null` as `"object"`, the OWL validation schema now attempts to verify the shape by evaluating `'toString' in null`. Using the `in` operator on `null` is illegal in JavaScript and immediately crashes the application.
**Fix:**
* Replace `title=None` with `title=False` in the `_action_send_notification` method.
* This translates to `false` in the JavaScript frontend, which seamlessly satisfies the `Boolean` prop type validation for the OWL component and allows the notification to render safely without errors.
opw-6333224
Forward-Port-Of: odoo/odoo#2729743 changes
Enhancements to existing features
This update refines how employees' favorite projects are automatically selected on timesheets. Previously, a project was selected with fewer than 3 linked timesheets. Now, a project is only chosen if at least 3 of the employee's 5 most recent timesheets are associated with it, ensuring more accurate project association.
Original PR description
A favorite project is now selected only when at least 3 of the employee's 5 most recent timesheets are linked to it. task-6290859 Forward-Port-Of: odoo/odoo#273259
Resolved issues and error corrections
This update resolves a technical issue preventing AI Studio fields from functioning correctly in employee appraisal forms. The problem stemmed from the AI system incorrectly storing field data, leading to a type error. This fix ensures the AI system receives the expected list format for field data, resolving the error and restoring functionality.
Original PR description
**STEPS TO REPRODUCE** 1. Add an AI Studio field in the employee appraisal form view (can be a regular text field or other) 2. Add `employee_feedback` to the prompt using '/' 3. Click the AI button to populate the field 4. Error occurs: `TypeError: unsupported operand type(s) for +: 'OrderedSet' and 'list'` **CAUSE** In any model, the read function expects the argument `fields` to be a list. When using AI fields in Studio, the fields argument is stored as an OrderedSet instead of a list, causing errors when performing operations. opw-5954203 Forward-Port-Of: odoo/enterprise#120799
This update fixes an issue where the standard price of a product wasn't correctly calculated during subcontracting dropshipping transactions. The change ensures that the product's value is accurately updated based on the relevant moves, leading to correct billing and accounting. This resolves discrepancies in product pricing related to dropshipping and subcontracting processes.
Original PR description
*: mrp_subcontracting_{dropshipping, purchase} ### Steps to reproduce: - In the settings: Enable subcontracting, dropshipping - Create a storable dropshipped product FP with a set vendor for 5$ and…
*: mrp_subcontracting_{dropshipping, purchase}
### Steps to reproduce:
- In the settings: Enable subcontracting, dropshipping
- Create a storable dropshipped product FP with a set vendor for 5$ and subcontracting BOM: 1 X COMP. Value this product in avco perpetual
- Set the component to resupply subcontractor and standard price to 2$
- Create and confirm a sale order for 1 unit fo FP
- Validate the resupply to the subcontractor and then the dropship
> The FP standard price shoul dhave been updated to 5$ + 2$ = 7$
- Create and post a bill from the PO for 10$ rather than 5
#### > The FP standard price should have been updated to 11$ rather than 12$
Cause of the issue:
Posting the bill will call the `_set_value` method to re-evaluate the product in terms of the newly recorded `account.move`: https://github.com/odoo/odoo/blob/161715c850496d3683baa5d1600380470d0b5ff5/addons/stock_account/models/stock_move.py#L393-L395 Now, the issue is that due to our config, there are two relevant moves linked to the `order_line`: the final move of the subcontracted production (which `is_in`) and the dropship move going from the subcontractor to the customer. When it comes to the subcontracted move, it is appropriately valuated at 12$ by the `_get_value_from_account_move` because of this override which adds the components value via the extra cost since the move has a `production_id`:
https://github.com/odoo/odoo/blob/161715c850496d3683baa5d1600380470d0b5ff5/addons/mrp_subcontracting_purchase/models/stock_move.py#L14-L38 However, the dropship move will not add this extra cost (as no override sets it to have the same value as the subcontracted production it comes from) so that this move is valuated at 10$. This explains why the value of the avco product is then updated to 11$ since (12 + 10) /2 = 11
Note that the issue is not reproducible in the case of regular subcontracting since in that case the receipt from `subcontractor` to `stock` is not valuated.
opw-6318035
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#273137
Forward-Port-Of: odoo/odoo#27281321 changes
New functionality added to Odoo
This update adds Russian translations for the Chart of Accounts data within the Odoo localization module for Uzbekistan. Recognizing the widespread use of Russian in local accounting practices, this change expands Odoo's reach and improves adoption among Uzbek users. This supports a key market and enhances the overall user experience.
Original PR description
This change adds Russian translations for the Chart of Accounts data in the l10n_uz module. Standard practice is to enable only a country's official statutory language in localization modules However, the business reality of Central Asia particularly Uzbekistan justifies an exception: Russian is widely used in accounting practice there, and supporting it will significantly improve adoption among local users. task-6229114 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269320
Enhancements to existing features
This update adds Russian translations to key Uzbekistan reports (balance sheet and profit & loss) within the Odoo Enterprise system. This change supports the growing Uzbek market by aligning with local business practices and increasing adoption rates.
Original PR description
Uzbekistan's business environment requires Russian in addition to the official Uzbek language to ensure adoption. While localizations typically activate only statutory languages, Central Asian market realities justify this exception. task-6229114 -- I confirm I have signed the CLA and read the PR guidelines at [www.odoo.com/submit-pr](http://www.odoo.com/submit-pr) Forward-Port-Of: odoo/enterprise#120250
Resolved issues and error corrections
This update fixes a visual issue where the 'Unmatched' section of the timesheet grid appeared even when it contained only temporary 'away from keyboard' events. The change ensures the header only displays if there are actually visible entries, resulting in a cleaner and more professional timesheet view for users. This improves the overall user experience.
Original PR description
The Unmatched group's header renders even when its only entries are afk events, since those are filtered out at display time but still counted when checking if the group has content. With this PR, we first check if a group has visible content before displaying the header Task-6348666
This update fixes an error in the timesheet revenue reporting for prepaid services. Previously, the calculation was inaccurate due to rounding issues with delivered quantities, leading to incorrect revenue figures. The fix ensures accurate revenue reporting by using the correct per-unit rate, accounting for discounts and ensuring consistency across timesheet entries.
Original PR description
Steps to reproduce 1. Create a service product: Invoicing Policy = Prepaid/Fixed Price, Track Service = Timesheets, Unit of Measure = Days 2. Confirm a Sales Order with 2 days of that product at…
Steps to reproduce 1. Create a service product: Invoicing Policy = Prepaid/Fixed Price, Track Service = Timesheets, Unit of Measure = Days 2. Confirm a Sales Order with 2 days of that product at 800/day 3. Register 1 hour on the generated task 4. Open Timesheets > Reporting, add the "Timesheet Revenues" measure Issue `timesheet_revenues` in `timesheets.analysis.report` was computed per analytic line as `(SOL.price_subtotal / SOL.qty_delivered) * (unit_amount * sol_uom.factor / ts_uom.factor)` (https://github.com/odoo/odoo/blob/16f170619d9cc5fd86529a3f17e349da37607f73/addons/sale_timesheet/report/timesheets_analysis_report.py#L42-L44). `SOL.qty_delivered` is a stored float rounded to the day UoM precision (0.01d). For 1 hour timesheeted, qty_delivered = 1/8 = 0.125d rounds to 0.13d, so the formula yields (1600 / 0.13) × (1/8) = 1538.46 instead of the correct 100. Because `qty_delivered` is recomputed each time a timesheet is added, all existing rows shift their revenue figure with every new entry. Additionally, using `price_subtotal / qty_delivered` as the per-unit rate ignores any line discount: the rate derived from a discounted subtotal divided by a delivered quantity that differs from the ordered quantity is not the effective price per day. For prepaid lines, the effective per-unit rate is `price_subtotal / product_uom_qty` — the ordered quantity is stable and the subtotal already reflects any discount — multiplied by the timesheet hours converted to the SO line UoM. opw-6150555 Forward-Port-Of: odoo/odoo#272910 Forward-Port-Of: odoo/odoo#262524
This update corrects a restriction in the Italian electronic invoicing system (l10n_it_edi) that prevented multiple pension fund taxes from being applied to a single invoice line. The fix aligns with Italian regulations regarding pension fund taxes, ensuring accurate reporting for IT companies. This change avoids errors during invoice printing and sending.
Original PR description
### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi_withholding 2. Switch to IT company 3. Create 2 taxes with a Pension fund type set (in Advanced Options) 4. Create an invoice…
### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi_withholding 2. Switch to IT company 3. Create 2 taxes with a Pension fund type set (in Advanced Options) 4. Create an invoice and set on the same line the 2 taxes created 5. Click on send and print and see the error: Invoices must have at most one Pension Fund tax set per line. (even if it's not true) ### Cause of the issue: The following function check how many taxes we have per line but this limit is incorrect because it is accepted by the Italian electronic invoicing specifications to have also more than 1 tax. https://github.com/odoo/odoo/blob/bd095fe286930acc54d85bdf7f92af15569f5b82/addons/l10n_it_edi/models/account_move.py#L1268-L1273 ### Reference documentation: 1. [Art. 10 della Legge n. 183_2011, successivamente integrato dal D.L. n. 1_2012 (art. 9-bis)..pdf](https://github.com/user-attachments/files/29056003/Art.10.della.Legge.n.183_2011.successivamente.integrato.dal.D.L.n.1_2012.art.9-bis.pdf) 2. Following image: <img width="823" height="580" alt="estrattoEppi" src="https://github.com/user-attachments/assets/e79be16f-651e-467a-84f4-8400185ceea4" /> opw-6264685 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273040 Forward-Port-Of: odoo/odoo#269456
This update fixes an issue where overtime calculations were inaccurate when employees worked shifts that crossed midnight. The change ensures that all overlapping shifts are correctly considered when determining overtime hours, leading to more accurate payroll processing. This improves the reliability of overtime reporting.
Original PR description
Issue: ---------------------------------------- The overtime calculation ignores attendances overlapping midnight when creating an attendance on the day they overlap. Steps to reproduce:…
Issue:
----------------------------------------
The overtime calculation ignores attendances overlapping midnight when creating an attendance on the day they overlap.
Steps to reproduce:
----------------------------------------
- Have the standard 8 hours per day working schedule
- Use the default overtime ruleset:
- Quantity, per day, more than the contract
- Have no rule on weeks
- Create an attendance of 8+ hours overlapping midnight on a day:
- From 10pm to 10am (2h + 10h = 12h)
- Create another attendance on the day the first ended:
- From 2pm to 6pm (4h)
- The first attendance has 2h of overtime:
- 0h from the first worked day (from 10pm to midnight = 2 < 8)
- 2h on the next day (10h worked from midnight to 10am)
- The second attendance have 0h of overtime even though it should be 4h
- We only considered this attendance in the calculation, ignoring the 10h worked in the morning
Cause:
----------------------------------------
In `_update_overtime()` we create a domain to include all useful attendances in the calculation. As all rules are based on days, the domain will use the date of the attendance to get overlapping attendances. But the date of the attendance is the date of its `check_in` ([src](https://github.com/odoo/odoo/blob/4235b48c86077bd5bceb9e817cc45b2eec8697e8/addons/hr_attendance/models/hr_attendance.py#L91)). So when creating the second attendance, the domain only fetches attendance with their `date` on the same date as the `check_in` of the second one. This excludes the first one even though it overlaps on the same day.
Solution:
----------------------------------------
Don't use `date` but `check_in` and `check_out` in the domain to really get all attendances overlapping a day with an updated attendance.
As this domain was used on both `hr.attendance` and `hr.attendance.overtime.line`, we adapt it so it uses the correct fields (`time_start` and `time_stop`) from the overtime lines.
opw-6253777
Forward-Port-Of: odoo/odoo#272447This update corrects a technical issue that prevented proper log metadata retrieval in Odoo versions 19.0 and later. The fix ensures that the necessary argument is passed to the get_log_metadata function, resolving a problem that could have impacted log data access. This ensures consistent log functionality across all Odoo releases.
Original PR description
During the forwardport, it was missed that get_log_metadata needs an argument starting from 19.0. Forward-Port-Of: odoo/odoo#273694
This update resolves an issue where the package type selection wizard wasn't displayed when using the barcode 'put in pack' function. The fix ensures that the wizard appears correctly, allowing users to accurately define package types during the picking process, improving inventory accuracy.
Original PR description
### Steps to reproduce: - In the settings enable: Packages - On the operation type `Delivery Order` set "Set Package Type" - Create and confirm a delivery for 1 unit of a product P + reserve it - Got…
### Steps to reproduce: - In the settings enable: Packages - On the operation type `Delivery Order` set "Set Package Type" - Create and confirm a delivery for 1 unit of a product P + reserve it - Got to the barcode app to process the delivery - Scan your product and click "put in pack" #### > The put in pack wizard allowing you to set a package type on the new package does not pop up. ### Cause of the issue: As a general rule of thumb the wizard is suppose to be displayed when the option is enabled and when a package/package type is not already provided to the call: https://github.com/odoo/odoo/blob/5dbc448d336c7ff22803ae91d5014eb6d0a07234/addons/stock/models/stock_package.py#L332-L341 https://github.com/odoo/odoo/blob/5dbc448d336c7ff22803ae91d5014eb6d0a07234/addons/stock/models/stock_move_line.py#L1236-L1238 However an override was added to the barcode module so that the wizard is never displayed when the action is launched from the barcode app: https://github.com/odoo/enterprise/blob/673d449f38cd3eff27c44270c8f7edf91d0ecd02/stock_barcode/models/stock_move_line.py#L193-L196 The idea behind this override was that you could provide the package type id via scans and hence that is was not necessary. However, if you click directly on the put in pack button, the wizard still make sense and should therefore be displayed under the same conditions. opw-6325092 Forward-Port-Of: odoo/enterprise#122308
This update resolves an issue where server reloads triggered by file changes could cause the application to crash. The fix prevents a series of signals from interrupting the server's restart process, ensuring stability and preventing container downtime during reload operations. This improves the reliability of the Odoo server.
Original PR description
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP`…
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP` into `KeyboardInterrupt`, which `ThreadedServer.run()`'s wait-loop catches. The catch is too narrow — a reload `SIGHUP` can kill the process through **three** windows that all sit outside the wait-loop's `try/except`, so the exception escapes `run()`/`main()`. Under Docker's default `restart: no`, PID 1 dies and the container stays down. ### The three windows 1. **Teardown duplicate (exit 130).** One file change can emit several FS events; the FSWatcher's `if not odoo.phoenix:` dedup races across threads and fires more than one `SIGHUP`. The first begins the phoenix teardown; the second lands during `stop()` / `watcher.stop()` / `_reexec()` and `KeyboardInterrupt` escapes. 2. **Exec-gap (exit 129).** `os.execve()` resets caught signal handlers to their default disposition (`SIGHUP` terminates) but preserves `SIG_IGN`; a `SIGHUP` arriving after the exec but before the re-exec'd process re-installs its handler kills the process outright. 3. **Startup (exit 130).** In the re-exec'd process, a `SIGHUP` anywhere in the startup section that precedes the wait-loop — `start()`, `preload_registries()` **and** `cron_spawn()` — escapes `run()`. ### Reproducer (deterministic) Boot a `ThreadedServer` (`--workers 0`) on any initialised db, then signal PID 1 a few times in quick succession: ```bash docker exec <container> sh -c 'i=0; while [ $i -lt 8 ]; do kill -HUP 1; sleep 0.1; i=$((i+1)); done' ``` Unpatched the process exits 130 or 129. Patched it stays up after one clean phoenix reload. Verified live on 17.0 and 18.0: stock `server.py` dies; the patched `server.py` survives sustained bursts (20/20 across repeated reload cycles on each version); `SIGINT`/`SIGTERM` still exit 0. ### Fix Minimal, in `signal_handler` + `run()` + `_reexec()`; `SIGINT`/`SIGTERM` untouched; one new instance attribute, no new module globals: - **Teardown duplicate:** ignore a `SIGHUP` once `quit_signals_received` is set (a restart/shutdown is already pending; the re-exec reloads fresh code). - **Startup:** a per-instance `in_preload` flag marks the entire startup section (`start()` + `preload_registries()` + `cron_spawn()`); a `SIGHUP` there sets the phoenix flag + counter and returns instead of raising, so the wait-loop exits right after startup and runs the normal restart. - **Exec-gap:** `signal.signal(signal.SIGHUP, signal.SIG_IGN)` just before `os.execve` so a `SIGHUP` in the gap is dropped rather than terminating the process. ### Related - #21209 (merged) — introduced the phoenix flag; did not guard these windows. - #206898 (merged), #207930 (open) — PreforkServer reload. ### CLA Covered by Codeforward B.V.'s corporate CLA; #269240 adds me to its contributor list (pending merge). Forward-Port-Of: odoo/odoo#269247
This update resolves an issue that prevented users from correctly shortening task deadlines within the Gantt chart view. The problem occurred when a task had no successors, leading to an error during deadline calculations. This fix ensures that deadline adjustments, both extending and shrinking, now function reliably.
Original PR description
## Current behavior: In the Project's app, switch to Gantt chart's view, when changing the deadline of a single task by shrinking its right edge, the server throws `ValueError: max() iterable…
## Current behavior: In the Project's app, switch to Gantt chart's view, when changing the deadline of a single task by shrinking its right edge, the server throws `ValueError: max() iterable argument`` is empty when calling end_date = max(candidates.mapped(stop_date_field_name)). ## Steps to reproduce: 1. In version 19.0 and above, install Project app 2. Create a project and only 1 single task 3. Switch to Gantt chart view 4. Try changing the deadline of a task by dragging its right edge 5. Observe that extending the task's deadline by dragging to the right works fine, but shrinking the deadline by dragging to the left will cause server to throw RPC_ERROR: Odoo Server Error and ValueError: max() iterable argument is empty. ## Cause of the issue: - A task with NO successors will cause candidates gathered via dependency_inverted_field_name to be empty. - The empty candidates recordset then get called by max(candidates.mapped(stop_date_field_name)), which is the reason causing error message ValueError: max() iterable argument is empty. opw-6283566 Forward-Port-Of: odoo/enterprise#120375
This update streamlines the website forum editor by removing unnecessary toolbar features like headings and font options, and fixing a technical issue that prevented certain functions from working correctly. It ensures consistent styling and improves stability for the forum editor experience.
Original PR description
Description of the feature this PR addresses: - Remove unwanted toolbar features (heading, font_family, powerbuttons, undo/redo buttons) - Update toolbar styles in website_forum to keep them consistent - Fix table menu traceback by passing missing `localOverlayContainers` in `website_forum_wysiwyg` config task-6123698 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271571 Forward-Port-Of: odoo/odoo#263326
This update fixes an issue where the Intrastat report was incorrectly cropping the bill name, preventing full visibility of key information like the hyphenated identifier. The fix adjusts a regex pattern to now correctly handle hyphen characters in bill names, ensuring accurate reporting.
Original PR description
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Intrastat" - Create a product with Intrastat info - Create a bill: * Product: [the created Intrastat product] *…
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Intrastat" - Create a product with Intrastat info - Create a bill: * Product: [the created Intrastat product] * Intrastat Country: [any] * Intrastat Transport Mode: [any] - Confirm the bill - Make sure that the bill name contains a hyphen character (i.e. "-") For example, "BILL/2026-06/0001". Use the "Resequence" action from the bills list view if needed. - Go to "Accounting / Reporting / Audit Reports / Intrastat Report" - Expand the line to display the bill name **Issue:** The bill name is not fully displayed. It is cropped right before the hyphen character (i.e. BILL/2026). **Cause:** A regex is used to retrieve the bill name from the report line name, but it is only allowing "/" character. **Solution:** Just allow "-" character in addition. No other character is allowed to limit the risk of matching something that should not. opw-6299854 Forward-Port-Of: odoo/enterprise#120979
This update fixes an issue where images inserted into audit reports weren't appearing in the generated PDF documents. The change ensures images are properly rendered within the PDF, improving the quality and usability of reports. This resolves a visual discrepancy impacting report presentation.
Original PR description
Currently, when a user uses the `/file` command to insert an image into an audit report and exports the report to PDF, the image is omitted from the generated PDF. To improve the support of those blocks, we will pre-process the document and replace the embedded files that correspond to images with standard image elements before PDF generation. This will ensure that images are correctly rendered and displayed within the document's text flow in the exported PDF. Task [link](https://www.odoo.com/odoo/project.task/5115280) task-5115280 Forward-Port-Of: odoo/enterprise#121673
This update resolves an issue where invoices would remain open after a website sale order was paid through a payment provider. The fix ensures that payments are correctly assigned to invoices, preventing manual intervention needed to reconcile payments and invoices. This improves the accuracy of financial reporting.
Original PR description
Steps to reproduce --- 1. Pay a website sale order through a payment provider (the payment stays In Process). 2. Reconcile that provider payment with a bank statement line before invoicing. 3.…
Steps to reproduce --- 1. Pay a website sale order through a payment provider (the payment stays In Process). 2. Reconcile that provider payment with a bank statement line before invoicing. 3. Confirm the delivery and create the invoice for the order. Issue --- The invoice is posted but stays open: the linked payment is never assigned to it, even though its receivable line is still outstanding and is even offered in the invoice outstanding-credits widget. Reconciling the bank statement first fully matches the payment's liquidity line, so the payment moves to the 'paid' state while its receivable line stays open. At invoice posting, _post only auto-assigns payments still in the 'in_process' state, so a 'paid' payment is skipped and its receivable is left unreconciled, leaving the invoice open and requiring a manual intervention. The matched case was lost in 01b87f1230be, which split the former 'posted' state into 'in_process' (cash not matched) and 'paid' (cash matched) and mechanically renamed this filter to 'in_process' only, dropping the matched payments the old 'posted' used to cover. Restoring 'paid' fixes it while the existing not-reconciled guard still keeps failed payments out. https://github.com/odoo/odoo/blob/2b89d39f9329ac0fe7a2938595d1f6ee16dc2924/addons/sale/models/account_move.py#L115-L126 opw-6216259 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270315
This update fixes an issue where replacing website icons removed their styling classes (like rounded or shadow). The fix ensures that icons in the website builder retain their original visual styles, providing a more consistent and predictable user experience. This improves the visual quality of website content.
Original PR description
Issue: Replacing an icon removes style classes applied to the original icon, such as `rounded`, `rounded-circle`, `shadow`, or `img-thumbnail`. This issue was introduced by [commit], which stopped…
Issue: Replacing an icon removes style classes applied to the original icon, such as `rounded`, `rounded-circle`, `shadow`, or `img-thumbnail`. This issue was introduced by [commit], which stopped preserving image-specific classes when replacing an image with an icon. This behavior is appropriate in the backend editor, where icons do not support these styling options. However, the same logic also affected the website builder, where icons support the same styling options as images. As a result, these classes were unnecessarily removed when replacing an icon. Steps to reproduce: 1. Add an icon with style classes such as `rounded`, `rounded-circle`, `shadow`, or `img-thumbnail`. 2. Replace the icon. 3. Notice that the style classes are removed from the new icon. Fix: Preserve these style classes when replacing icons in the website builder, allowing the newly selected icon to retain the existing visual styling. [commit]: https://github.com/odoo/odoo/commit/8638dbc21a7a3ebb3c9cc195d2249b4eb5c264ab task-[6200832](https://www.odoo.com/odoo/project/974/tasks/6200832) Forward-Port-Of: odoo/odoo#265496
This update resolves a bug that prevented barcode scanning of packages containing multiple products when specific delivery settings were enabled. The fix removes a redundant check in the barcode scanning process, allowing packages to be correctly identified as result packages. This ensures accurate picking and inventory management.
Original PR description
### Steps to reproduce: - In the settings Enable: Multi-steps Routes, Packages - Put your warehouse in delivery in 2-steps - On the Pick operation type in the barcode tab disable: "Allow extra…
### Steps to reproduce: - In the settings Enable: Multi-steps Routes, Packages - Put your warehouse in delivery in 2-steps - On the Pick operation type in the barcode tab disable: "Allow extra products" - Create two storable products P1 and P2 - On P2 > On hand > Update Quantity > New - Create a new line in WH/Output with a package POOK for 1 unit - Create a new internal transfer for 1 unit of P1 using the pick operation type so that the picking goes WH/Stock -> WH/Output - Set the quantity of the move to 1 unit and go to the barcode app - Open the Pick > Scan WH-STOCK > Scan P1 > Scan POOK #### > An error is raised: This package contains extra products and extra products are not allowed on this operation. #### Expected behavior: The package should be set as result package. ### Cause of the issue: In the `_processPackage`, a check that is done to ensure that the package scan will not add extraproduct to the picking if this operation is not allowed: https://github.com/odoo/enterprise/blob/5e4c8ecb0c644e21755570ed59cd8f6e9f618c8a/stock_barcode/static/src/models/barcode_picking_model.js#L2024-L2035 Unfortunately, this check is done just before a possible usage of the package as package dest. And, in that case, since we do not try to add any product to the picking the check is irrelevant anyway. opw-6303969 Forward-Port-Of: odoo/enterprise#121789
This update corrects a bug where barcode scanning incorrectly displayed stock move quantities. The fix ensures that quantities are accurately converted to the stock move's UoM, resolving discrepancies between the barcode view and the actual stock levels. This improves the reliability of inventory tracking.
Original PR description
**Steps to reproduce:** - Install `stock` and `purchase` modules - Enable `Units of Measure and Packages` and `Storage Locations` from setting - Create a storable product with vendor purchase UoM set…
**Steps to reproduce:** - Install `stock` and `purchase` modules - Enable `Units of Measure and Packages` and `Storage Locations` from setting - Create a storable product with vendor purchase UoM set to "Pack of 6" - Create and confirm a Purchase Order with quantity 6 Units - Open the generated receipt - Update a move line in Detailed Operations: - Quantity: 1 - UoM: Pack of 6 - Save and open the Barcode view using smart button. - Increase quantity using "+" button by 1. - Exit barcode view without validating and refresh the receipt **Issue:** After refresh, the stock move quantity becomes 1 instead of 6, while the move line correctly shows 1 Pack of 6. **Cause:** https://github.com/odoo/enterprise/blob/2bfe0f32c0cec426fc7345ef716395146cc569ca/stock_barcode/static/src/components/main.js#L161-L162 - Exiting the barcode view triggers `__onExit()`, which forwards `reserved_uom_qty` and `qty_done` from move lines to `post_barcode_process()`. https://github.com/odoo/enterprise/blob/2bfe0f32c0cec426fc7345ef716395146cc569ca/stock_barcode/static/src/models/barcode_picking_model.js#L1885-L1898 This `post_barcode_process()` function triggers `_truncate_overreserved_moves()` https://github.com/odoo/enterprise/blob/2bfe0f32c0cec426fc7345ef716395146cc569ca/stock_barcode/models/stock_move.py#L56-L58 - During this flow, `_truncate_overreserved_moves()` updates the stock move quantity by taking the maximum of `qty_done` and `reserved_uom_qty`. However, it assigns this value directly to the move without converting it into the stock move UoM. - In this case, both values are 1 because the move line is UoM is "Pack of 6" Logically, 1 Pack corresponds to 6 units, but since the stock move UoM is in units, this conversion is skipped. As a result, the move quantity is incorrectly set to 1 instead of 6. https://github.com/odoo/enterprise/blob/2bfe0f32c0cec426fc7345ef716395146cc569ca/stock_barcode/models/stock_move.py#L52-L54 **Fix:** - Convert quantities coming from barcode processing into the stock move UoM before updating the move quantity, ensuring packaged UoM values are preserved correctly. ---- opw-5472598 Forward-Port-Of: odoo/enterprise#116022
This update resolves an issue where self-order kiosks weren't correctly generating receipts. The fix restores payment method data to the order response, ensuring that customers receive complete receipt information after settling their orders in the backend. This improves the user experience for self-service ordering.
Original PR description
Steps to reproduce: - Set up a kiosk with pay at counter - Order a product - Settle the order in backend - Go to my order on the self, try donwload the receipt - TB Issue: This commit https://github.com/odoo/odoo/pull/237553 removed the pos_payment_method from the _generate_return_values method. The fornt-end didn't had the necessary data to generate the receipt. Fix: Restore payment method in the _generate_return_values method. Task-6191379 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272607 Forward-Port-Of: odoo/odoo#263515
This update resolves an issue where the 'Remaining Extra Hours' value in the employee attendance summary was incorrectly displayed as 00:00 instead of a negative value. The fix adjusts the calculation to accurately reflect the remaining extra hours, ensuring consistency with other overtime values. This improves the clarity and accuracy of overtime reporting for employees.
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#273402
Forward-Port-Of: odoo/odoo#271272This update resolves a technical issue where clicking the logout button on the website preview triggered duplicate requests, resulting in a 'CSRF validation failed' error. Additionally, a test was updated to automatically enable the 'Free sign up' setting, eliminating the need for manual configuration and ensuring consistent test results.
Original PR description
### Commit 1: [FIX] website: prevent CSRF error by blocking duplicate form submission Before this commit: Clicking the logout button from the website preview triggered two simultaneous logout…
### Commit 1:
[FIX] website: prevent CSRF error by blocking duplicate form submission
Before this commit: Clicking the logout button from the website
preview triggered two simultaneous logout requests:
1. The browser performed the default form submission with a valid
`csrf_token`, destroying the session afterward.
2. During the same click event, `setupClickListener()` intercepted
the click using `closest('[action]')`, found the parent
`/web/session/logout` form, and triggered a second POST request
using `odoo.csrf_token`.
Since the session was already destroyed by the first request, the
second request resulted in a "CSRF validation failed" error.
This commit prevents the default form submission before triggering
the manual POST request, ensuring that only one request is sent.
Runbot-940403
--------------------------------------------------------------------------------------------------------------------------------
### Commit 2:
[FIX] website: enable free sign up setting in test_auth_forms_warning
Steps to reproduce:
1. Install any website related module (e.g. `website`, `website_event`).
2. Keep the default configuration and do not manually enable
'Free sign up' in Settings.
3. Run `test_auth_forms_warning`.
Before this commit: The test did not programmatically enable the
'Free sign up' setting. As a result, it failed unless a developer
manually navigated to the setting and enabled it beforehand.
After this commit: This commit explicitly enables the "Free sign up"
configuration during test execution, allowing public access to the
`/web/signup` page and ensuring the test passes without any manual
setup.
runbot-940394
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#272020This update fixes an issue where the standard price of a product wasn't correctly updated during subcontracting dropshipping transactions. The change ensures that the product's value is accurately calculated based on the relevant moves, leading to correct billing and accounting. This resolves a discrepancy in the final product value.
Original PR description
*: mrp_subcontracting_{dropshipping, purchase} ### Steps to reproduce: - In the settings: Enable subcontracting, dropshipping - Create a storable dropshipped product FP with a set vendor for 5$ and…
*: mrp_subcontracting_{dropshipping, purchase}
### Steps to reproduce:
- In the settings: Enable subcontracting, dropshipping
- Create a storable dropshipped product FP with a set vendor for 5$ and subcontracting BOM: 1 X COMP. Value this product in avco perpetual
- Set the component to resupply subcontractor and standard price to 2$
- Create and confirm a sale order for 1 unit fo FP
- Validate the resupply to the subcontractor and then the dropship
> The FP standard price shoul dhave been updated to 5$ + 2$ = 7$
- Create and post a bill from the PO for 10$ rather than 5
#### > The FP standard price should have been updated to 11$ rather than 12$
Cause of the issue:
Posting the bill will call the `_set_value` method to re-evaluate the product in terms of the newly recorded `account.move`: https://github.com/odoo/odoo/blob/161715c850496d3683baa5d1600380470d0b5ff5/addons/stock_account/models/stock_move.py#L393-L395 Now, the issue is that due to our config, there are two relevant moves linked to the `order_line`: the final move of the subcontracted production (which `is_in`) and the dropship move going from the subcontractor to the customer. When it comes to the subcontracted move, it is appropriately valuated at 12$ by the `_get_value_from_account_move` because of this override which adds the components value via the extra cost since the move has a `production_id`:
https://github.com/odoo/odoo/blob/161715c850496d3683baa5d1600380470d0b5ff5/addons/mrp_subcontracting_purchase/models/stock_move.py#L14-L38 However, the dropship move will not add this extra cost (as no override sets it to have the same value as the subcontracted production it comes from) so that this move is valuated at 10$. This explains why the value of the avco product is then updated to 11$ since (12 + 10) /2 = 11
Note that the issue is not reproducible in the case of regular subcontracting since in that case the receipt from `subcontractor` to `stock` is not valuated.
opw-6318035
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#273137
Forward-Port-Of: odoo/odoo#2728133 changes
Enhancements to existing features
This update ensures that restaurant users can now always access course management features, regardless of whether Course Allocation is enabled. A helpful message has also been added to guide users when creating new courses, improving the overall user experience.
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
Resolved issues and error corrections
This update resolves an issue where invoices would remain open after a website payment was processed and reconciled with a bank statement. The fix restores a previous system that correctly assigned payments to invoices, preventing manual intervention. This ensures invoices are accurately linked to payments, streamlining the accounting process.
Original PR description
Steps to reproduce --- 1. Pay a website sale order through a payment provider (the payment stays In Process). 2. Reconcile that provider payment with a bank statement line before invoicing. 3.…
Steps to reproduce --- 1. Pay a website sale order through a payment provider (the payment stays In Process). 2. Reconcile that provider payment with a bank statement line before invoicing. 3. Confirm the delivery and create the invoice for the order. Issue --- The invoice is posted but stays open: the linked payment is never assigned to it, even though its receivable line is still outstanding and is even offered in the invoice outstanding-credits widget. Reconciling the bank statement first fully matches the payment's liquidity line, so the payment moves to the 'paid' state while its receivable line stays open. At invoice posting, _post only auto-assigns payments still in the 'in_process' state, so a 'paid' payment is skipped and its receivable is left unreconciled, leaving the invoice open and requiring a manual intervention. The matched case was lost in 01b87f1230be, which split the former 'posted' state into 'in_process' (cash not matched) and 'paid' (cash matched) and mechanically renamed this filter to 'in_process' only, dropping the matched payments the old 'posted' used to cover. Restoring 'paid' fixes it while the existing not-reconciled guard still keeps failed payments out. https://github.com/odoo/odoo/blob/2b89d39f9329ac0fe7a2938595d1f6ee16dc2924/addons/sale/models/account_move.py#L115-L126 opw-6216259 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270315
This update corrects a technical issue preventing multiple pension fund taxes from being applied to a single invoice line in the Italian accounting module. The fix aligns with Italian electronic invoicing regulations that permit multiple tax types. This ensures accurate reporting and compliance for IT companies using the Odoo system.
Original PR description
### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi_withholding 2. Switch to IT company 3. Create 2 taxes with a Pension fund type set (in Advanced Options) 4. Create an invoice…
### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi_withholding 2. Switch to IT company 3. Create 2 taxes with a Pension fund type set (in Advanced Options) 4. Create an invoice and set on the same line the 2 taxes created 5. Click on send and print and see the error: Invoices must have at most one Pension Fund tax set per line. (even if it's not true) ### Cause of the issue: The following function check how many taxes we have per line but this limit is incorrect because it is accepted by the Italian electronic invoicing specifications to have also more than 1 tax. https://github.com/odoo/odoo/blob/bd095fe286930acc54d85bdf7f92af15569f5b82/addons/l10n_it_edi/models/account_move.py#L1268-L1273 ### Reference documentation: 1. [Art. 10 della Legge n. 183_2011, successivamente integrato dal D.L. n. 1_2012 (art. 9-bis)..pdf](https://github.com/user-attachments/files/29056003/Art.10.della.Legge.n.183_2011.successivamente.integrato.dal.D.L.n.1_2012.art.9-bis.pdf) 2. Following image: <img width="823" height="580" alt="estrattoEppi" src="https://github.com/user-attachments/assets/e79be16f-651e-467a-84f4-8400185ceea4" /> opw-6264685 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273040 Forward-Port-Of: odoo/odoo#269456
3 changes
Resolved issues and error corrections
This update ensures that several Odoo community add-ons (certificate, l10n_hr_edi, etc.) are correctly licensed under LGPL-3. Previously, these modules incorrectly used the enterprise license. This change aligns with the proper licensing for community-supported add-ons, clarifying legal obligations and ensuring compliance.
Original PR description
Before this commit, the license set on manifest of some modules uses the enterprise license instead of `LGPL-3` license since it is a community module. This commit changes the license to set `LGPL-3`. Fixes #205134 Forward-Port-Of: odoo/odoo#273690 Forward-Port-Of: odoo/odoo#273597
This update fixes an issue where the price of Point of Sale (POS) order lines wasn't correctly recalculated after a refund and quantity change. Specifically, when a refund was processed and the line quantity was adjusted, the price wasn't updated to reflect the fiscal position. This ensures accurate pricing and tax calculations during POS transactions.
Original PR description
When changing the quantity of a pos order line the fiscal position set on the order was not used when recomputing the line price and taxes. Steps to reproduce: ------------------- * Create a tax with 15% rate and another with 10% rate * Create a fiscal position that maps the 15% tax to the 10% tax * Setup a PoS to be able to use that fiscal position * Open the PoS, add a product with the 15% tax, set the fiscal position and validate the order * Refund the order in the backend and change the quantity of the line from -1 to 0 and back to -1. > Observation: The price is not the same as before Why the fix: ------------ The fiscal position was not applied when recomputing the line's price and taxes. opw-6253311 Forward-Port-Of: odoo/odoo#273366 Forward-Port-Of: odoo/odoo#270135
This update optimizes how Odoo forms respond to changes. Previously, opening a form triggered onchange methods multiple times for related field updates. This fix reduces redundant calls, leading to faster form loading and a smoother user experience. It's a small but important improvement for overall performance.
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#251813
2 changes
Resolved issues and error corrections
This update resolves a technical problem where web studio's technical names were incorrectly generating `x_studio_<type>_NaN` values. The fix ensures these names are generated correctly, preventing potential errors and improving the stability of the web studio functionality. This change ensures consistent and reliable technical naming conventions.
Original PR description
The PR #119993 introduced a bug leading to technical names being named `x_studio_<type>_NaN`. This commit fixes the issue. A `_NaN` increment is only possible if the increment reach int max size. task-6353814 Forward-Port-Of: odoo/enterprise#122594
This update corrects a warning in the planning module that occurred when trying to modify certain settings. The change ensures data restrictions are applied correctly, preventing potential issues with data integrity. This improves the stability and reliability of the system.
Original PR description
The `@api.constrains` decorator was listening to `company_id`, which is a readonly related field. This triggers an ORM warning ("parameter 'company_id' is not writeable").
Swapped the constraint trigger from `company_id` to `warehouse_id`. Since the company is fully dependent on the warehouse, this safely achieves the exact same trigger logic.
build: [940408](https://runbot.odoo.com/odoo/runbot.build.error/940408)
Forward-Port-Of: odoo/enterprise#1215846 changes
Resolved issues and error corrections
This update resolves an access error preventing PS users from opening the Preparation Display. A recent base module update requires 'write' access to server actions, which PS users lacked. The fix now directly opens the URL action, bypassing the previous server action and ensuring proper functionality for all user types.
Original PR description
A recent fix in the base module requires users to have "write" access on ao model to execute its server actions. commit: odoo/odoo@846eb51a02baaf2e4f6e6780f8d0ceb23322c38b Previously, the Preparation Display was opened through the server action `action_pos_preparation_display_kitchen_display`, which then redirected to the URL action `action_pos_preparation_display_bar_restaurant_filter_link`. However, PS users only have read access on `pos.prep.display`. As a result, executing the server action triggers an access error when opening the Preparation Display. This commit bypasses the intermediate server action and opens the URL action directly. Task-6311320
This update corrects an issue where EC Sales List returns were incorrectly consolidated for tax units. Now, each member entity within a tax unit generates its own return using its individual VAT number, ensuring accurate reporting and compliance with regulations. This change improves data accuracy and reduces the risk of reporting errors.
Original PR description
Issue: The EC Sales List return is currently generated under the tax unit VAT number, consolidating all member entities into a single declaration. Expected: The EC Sales List return must be generated individually per member entity, each under their own VAT number, even when those entities belong to a tax Unit. Fix: Apply tax unit only if report's multi company filter is `tax_units`. Ref: https://github.com/odoo/enterprise/blob/07e8aba8604319747a5925c83576095ce9a63f9e/account_reports/models/account_return.py#L316-L317 task-6069402
This update ensures PDF signatures maintain their original appearance by locking editable fields during the signing process. Previously, a flawed method of flattening fields altered the PDF's look. This change prioritizes a consistent user experience while a future upgrade to pypdf will enable true PDF field flattening.
Original PR description
Currently, we flatten fields in a naive way which does not handle many edge cases and can alter the PDF appearance for users. We could use pypdf to handle production-grade flattening, but Odoo's `pypdf` dependency (5.4.0) does not support native form field flattening (which was introduced in 5.8.0). To resolve this, rather than flattening, we lock the interactive fields so they are no longer editable while signing, which perfectly maintains the original appearance. In the future, when we support higher pypdf versions, we can truly flatten the PDF to provide a better user experience. task-6037759
This update fixes a stability issue in the payroll testing process. By using a separate, dedicated employee version for tests, we've eliminated interference from existing payroll data, ensuring more reliable test results. This improves the overall quality and consistency of our payroll system.
Original PR description
Use a dedicated employee/version for the percentage computation test instead of Rahul, whose existing payroll values affect copied version data. Define the test amounts in common and reuse `employee.version_id` in the test, so percentages are derived from amounts without changing payroll behavior. task-6340923
This update fixes an issue where expense authorizations were incorrectly flagged as declined due to MCC range mismatches. It now accurately checks MCC codes, preventing duplicate refusal messages and ensuring expenses are processed correctly. Related to previous issues opw-6185961 and opw-6288399.
Original PR description
# [FIX] hr_expense_stripe: Fix MCC ranges Context: Since 3e52d875 when receiving an authorization whose MCC fits in a range we would not find it in the search. This is logical yet we return an error before checking properly mcc codes with range included After this commit: This will also check that the authorization MCC exist if we don't directly find the range. We move the "not found" error after that check too The forgotten tests have been added into the overrides opw-6185961 opw-6288399 # [FIX] hr_expense_stripe: Fix double refusal of expenses Context: When an expense is created through a declined stripe authorization, the expense is refused twice, resulting in a duplicated refusal message After this commit: Do not refuse already refused expenses
This update resolves a crash in the Partner Ledger report when sending emails in companies using multiple currencies. The fix ensures the necessary database table is initialized before report generation, preventing a 'table not found' error. This ensures reliable email delivery for all users, regardless of their company's currency setup.
Original PR description
### Description of the issue this PR addresses Sending the **Partner Ledger** report by email in a multi-currency setup (several companies using different currencies) crashes the send wizard on…
### Description of the issue this PR addresses Sending the **Partner Ledger** report by email in a multi-currency setup (several companies using different currencies) crashes the send wizard on opening with: ``` psycopg2.errors.UndefinedTable: relation "account_currency_table" does not exist ``` ### Current behavior before PR To compute the recipients, `AccountPartnerLedgerReportHandler._get_report_send_recipients` runs `_get_query_sums`, whose SQL joins the currency table. In a multi-currency setup that table is a **temporary** table that must be created beforehand by `AccountReport._init_currency_table`. Every regular rendering entry point calls `_init_currency_table` before running currency-table queries, but the report-sending path does not, so the query fails on a missing `account_currency_table` relation. ### Desired behavior after PR is merged `_init_currency_table(options)` is called before running the query, so the temporary table exists. It is a no-op in mono-currency setups (early return in `_init_currency_table`), so mono-currency behavior is unchanged. ### Steps to reproduce 1. Have several companies using different currencies. 2. Select more than one of them in the company switcher. 3. Open **Accounting > Reporting > Partner Ledger**. 4. Click **Send by email** → the wizard crashes on opening. A regression test covering the multi-currency send-recipients path is included in `test_partner_ledger_report.py`.
3 changes
Resolved issues and error corrections
This commit addresses a minor issue with a test related to the l10n_it_edi_withholding module. The change ensures the test accurately reflects the functionality of a previously merged PR. This ensures the ongoing stability and reliability of the Italian tax reporting feature.
Original PR description
This commit just want to correct a test of a PR already merged. Original commit: 78ffb5a2e63401123e4506056493e52cf3e69953 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a performance issue in the Point of Sale system. Previously, fetching order data involved multiple, separate requests, which slowed down the system. The change combines these requests into one, resulting in faster order retrieval and a smoother user experience.
Original PR description
Issue: pos_self_order overrode getServerOrders() to add a separate loadServerOrders() call for it's own orders before delegating to super, resulting in up to an additional sequential RPCs on every order fetch. Fix: Extract the base query domain into a new overridable getServerOrdersDomain() method. Each module overrides it to OR in its own domain via Domain.or([super.getServerOrdersDomain(), extraDomain]), so all orders are fetched in a single RPC call instead of three. Task-6284860 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 optimizes a key function that checks for gaps in move sequence numbers, significantly reducing the time it takes to process updates. By narrowing the search and using more efficient techniques, the system now performs much faster, improving overall system responsiveness. This change addresses a performance bottleneck related to move updates.
Original PR description
The function _compute_made_sequence_gap is designed to determine if an updated move created a sequence gap. This is currently done with several performance issues. Firstly, the search domain simply…
The function _compute_made_sequence_gap is designed to determine if an updated move created a sequence gap. This is currently done with several performance issues.
Firstly, the search domain simply uses a min/max sequence number of the updated moves. However, we only ever need the sequence number that comes before each changed move.
Example:
Let's say we updated 3 moves.
Move A: sequence_number = 27
Move B: sequence_number = 235
Move C: sequence_number = 100342
The search domain then becomes:
('sequence_number', '>=', min(moves.mapped('sequence_number')) - 1),
('sequence_number', '<=', max(moves.mapped('sequence_number')) - 1),
('sequence_number', '>=', 26),
('sequence_number', '<=', 100341),
The search domain can now return up to 100315 moves! Since we then loop over each updated move (Move A,B,C) and check if the previous sequence number exists, we are never using 100312 of the records from the search.
Instead, we can compute what sequence numbers we are looking for ahead of time, and specifically search for those.
We can also convert this to a search_read to retrieve only sequence_number.
| | Two Moves 35,000 apart | 1000 sequential moves |
| --------- | ------ | ------ |
| Queries Before |129 | 4,300|
| Queries After | 24|4,291|
| Time Before |0.90 seconds |2.92 seconds|
| Time After | 0.11 seconds|2.69 seconds|
opw-63307311 change
Resolved issues and error corrections
This update corrects a technical issue that was causing a misleading error message when generating invoices with Co-Contractant tax rates. The fix ensures the note is only added to the invoice when the tax amount is zero, accurately reflecting the Co-Contractant's fiscal position and avoiding unnecessary alerts.
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