Thursday, October 9, 2025
75 changes
12 changes
Resolved issues and error corrections
Stripe payments now handle currencies like the Ugandan shilling that use special decimal rules in Stripe. This prevents valid orders from being sent with the wrong amount and rejected at checkout.
Original PR description
Steps: - Activate the 'UGX' currency. - Make a sale order with amount 100 with 'UGX' currency - Try to pay that order (100 USh) using card Issue: - stripe throws the following error - > 'The Checkout Session's total amount must convert to at least 50 cents. 1.00 USh converts to approximately €0.00.' - Hence 100 USh sent was identified as 1 USh by stripe. This confirms issue with decimals and currency mapping. Cause: - 'UGX' is zero-decimal currency but stripe identify it as two-decimal. Fix: - Update mapping for such special currency cases for stripe that don't follow general rules opw-5075707 Forward-Port-Of: odoo/odoo#227688
This fixes an issue where some nested website product description text could not be translated when using multiple languages. Businesses can now maintain complete localized shop content, improving consistency for international customers.
Original PR description
Scenario: - enable second language on website - go to /shop/1 and try to translate description_ecommerce Result: this is not translatable Cause: Since at least…
Scenario:
- enable second language on website
- go to /shop/1 and try to translate description_ecommerce
Result: this is not translatable
Cause:
Since at least b455ea85853dfc19ed01e33986ad270cf80ee5d6 the
contenteditable attribute in ContentEditablePlugin is not set on an
element if it has a contenteditable ancestor.
TranslationPlugin disable all editable nodes containing editable nodes.
So with this combination, if we had a node for example:
```
<div class="oe_editable" data-oe-model="product.template" data-oe-id="1"
data-oe-field="description_ecommerce" data-oe-type="html">
<div>
<span class="oe_editable" data-oe-model="product.template"
data-oe-id="1" data-oe-field="description_ecommerce">
test
</span>
</div>
</div>
```
the contenteditable was added to the parent div.oe_editable, but was
removed by TranslationPlugin so the "test" text was not translatable.
Fix: move the code that adds data-oe-readonly class in the
after_setup_editor_handlers so it is run before contenteditable
attributes are set.
opw-5128618The vendor on-time rate report now shows purchase delivery data even when ordered products do not have a product category. This restores the graph on vendor records and gives purchasing teams a complete view of supplier delivery performance.
Original PR description
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and…
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and validate the generated receipt. 5-In the vendor form view, click the On-time Rate smart button → no graph is visible. **Issue:** https://github.com/odoo/odoo/blob/77b3956ed5635d79ae8dc19423140dc6a10098f1/addons/purchase_stock/report/vendor_delay_report.py#L46-L50 ``` The On-time Rate graph is not displayed in the Vendor Delay report. ``` **Cause:** - From version 18.2, `categ_id` was removed as a required field. The report query still uses an inner join on `categ_id`, which excludes products without a category and prevents data from being generated. - Commit which make `categ_id` non require - https://github.com/odoo/odoo/pull/166323/commits/b039caecbeb04057fbccb1cc88d03a4946f88e8e **Solution:** - Replace the inner join with a left join so that products without a `categ_id` are also included in the report (with null values when the category is not set). **opw** - 4991367 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230388 Forward-Port-Of: odoo/odoo#225557
This update ensures the right domestic fiscal position is selected for companies in the UAE, Italy, Mexico, and Cambodia. This helps apply the correct domestic taxes and removes a duplicate Italian setup that could cause confusion or incorrect tax behavior.
Original PR description
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the…
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the following localizations: **AE** Sequences are added making Dubai the domestic fiscal position. However this needs to be improved to automatically prioritize the fiscal position based on the company's state. **IT** (l10n_it_edi_doi) An additional domestic fiscal position was mistakenly added. The correct domestic FP is defined in it's dependency module l10n_it. The duplicate FP is removed. **MX** Sequences are added **KH** Sequences are added No Task - l10n's identified by the fiscal position checks in `test_all_l10n` 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#230654
This fixes several display issues when opening a single bank statement line from a reconciled entry. The reconciliation screen now restores the summary when filters are cleared, avoids expanding unrelated lines, hides an irrelevant Statement button for single-line views, and opens the ledger using the correct journal context.
Original PR description
When you open a statement line from a reconciled move, it opens the bank reconciliation widget with only the selected statement line, which is unfolded by default. However, there are a few issues with this behavior, which are fixed in this commit: 1 - When entering the bank reconciliation widget, the initial line is unfolded. If you remove the filter, all the other lines become unfolded as well. This should not be the case; only the original line should remain unfolded. 2 - By default, the statement summary line is hidden. When the filter is removed, the summary remains hidden. We now ensure the summary is displayed again when the filter is cleared. 3 - The Statement button on the statement line (which is meant to create a new statement) doesn't make any sense when there is only one line. It is now hidden in this case. task-5108118 Forward-Port-Of: odoo/enterprise#95558
Gantt group headers now keep their sticky behavior even when the timeline has many or wide columns. This improves usability, especially on mobile screens, by preventing headers from stretching beyond the visible page area.
Original PR description
Gantt group headers could stop being sticky because their width was fixed based on the number and size of columns. Even though they were set to position: sticky, oversized headers could no longer remain aligned when scrolling, as they extended beyond the viewport and were constrained by the document width. This was especially noticeable on mobile, where group headers are often wider than the screen. The fix applies a max-width style to these headers, capping their size to the available space so they remain sticky without overflowing the document. task-4970992 Forward-Port-Of: odoo/enterprise#96612 Forward-Port-Of: odoo/enterprise#96015
The appraisal skills list now allows horizontal scrolling again on mobile devices. This makes the justification field and add/remove buttons accessible, so employees and managers can complete appraisal skill updates from smaller screens.
Original PR description
Horizontal scrolling has been disabled on the appraisal skills list. An unwanted side effect of that is that the justification field along with the add and remove buttons are not visible on mobile. This PR re-enables the scrolling and removes some dead css. task-5001344 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230310 Forward-Port-Of: odoo/odoo#222161
This fix ensures nested website content, such as product eCommerce descriptions, can be translated correctly when multiple languages are enabled. It prevents editable translation areas from being disabled too late, improving the translation experience for website managers.
Original PR description
Scenario: - enable second language on website - go to /shop/1 and try to translate description_ecommerce Result: this is not translatable Cause: Since at least…
Scenario:
- enable second language on website
- go to /shop/1 and try to translate description_ecommerce
Result: this is not translatable
Cause:
Since at least https://github.com/odoo/odoo/commit/b455ea85853dfc19ed01e33986ad270cf80ee5d6 the
contenteditable attribute in ContentEditablePlugin is not set on an
element if it has a contenteditable ancestor.
TranslationPlugin disable all editable nodes containing editable nodes.
So with this combination, if we had a node for example:
```
<div class="oe_editable" data-oe-model="product.template" data-oe-id="1"
data-oe-field="description_ecommerce" data-oe-type="html">
<div>
<span class="oe_editable" data-oe-model="product.template"
data-oe-id="1" data-oe-field="description_ecommerce">
test
</span>
</div>
</div>
```
the contenteditable was added to the parent div.oe_editable, but was
removed by TranslationPlugin so the "test" text was not translatable.
Fix: move the code that adds data-oe-readonly class in the
after_setup_editor_handlers so it is run before contenteditable
attributes are set.
opw-5128618Fixes an issue where choosing “Remote” as a job location on a website job application could trigger an error. The Remote option is restored in the location dropdown so users can edit job postings without interruption.
Original PR description
Steps to reproduce: 1. Go to Website → Jobs. 2. Open any job application. 3. Change the Job Location to the option "Remote". 4. A traceback occurs. Before this commit: When selecting a job location, initially no Many2One field is selected, that's why no many2oneid is find. which results in a null value being returned. This caused a traceback error After this commit: The "Remote" option is explicitly included in the dropdown, restoring the previous behavior.
The attendance process now checks whether an employee had an active contract before marking them absent for a missed check-in. This prevents employees from being incorrectly flagged as absent before their contract start date, improving payroll and attendance accuracy.
Original PR description
To register absence, the cron looks for all employees that did not check in the previous day. However, it was not checking if the employee was in contract for that day. This commit fixes the issue by adding a check on the contract date start. task-4987428
Fixes receipt printing for Italian point-of-sale setups using fiscal printers when the receipt screen is skipped. This ensures customers still receive the correct fiscal receipt for the completed sale, avoiding missed printouts and printer errors.
Original PR description
This PR fixes two related bugs happening when printing a receipt with the Italian Fiscal printer First, before this PR, if the option to skip the receipt screen was ticked, then the receipt would…
This PR fixes two related bugs happening when printing a receipt with the Italian Fiscal printer First, before this PR, if the option to skip the receipt screen was ticked, then the receipt would never print. This was caused by the printing logic being implemented on the receipt screen instead of on the pos itself. steps to reproduce: 1. install l10n_it_pos 2. configure one pos 3. configure the IT printer 4. select to skip the receipt screen (print automatically) 5. open the pos 6. make a sale => no ticket printed and the chrome console shows a printer error With this new verison the printing logic was moved to the pos so that printing of fiscal receipts with the italian fiscal printer works, even when receipt screen is skipped. This put to light another potential bug related to how the `order` variable was treated. Before this PR, the printReceipt logic in the module would not pass the order to be printed. This can become a problem upon context changes, where `pos.get_order()` does not return the completed order, but a newly created one. This can for example happen when skipping the receipt screen with the option to "print automatically" (iface_print_auto). After this PR, we keep order as an argument, so we always print the last completed order and not a newly created one. opw-4882480 Forward-Port-Of: odoo/enterprise#95985 Forward-Port-Of: odoo/enterprise#91412
This fixes a survey issue where respondents who entered a comment as their answer in certain multiple-choice questions were incorrectly told the question was unanswered. It also strengthens validation so single-choice questions cannot receive multiple answers, improving data quality and reducing confusing survey behavior.
Original PR description
Issue: When answering a question with a comment in multiple choice with roaming activated for the survey, the UI will display a warning message that says the question requires an answer. Cause: The backend creates a skipped record if none of the pre-created answers is chosen. Solution: Don't create a skipped record if a comment counts as an answer and a comment is provided. Added validation of input and unittests Task-5062984 Forward-Port-Of: odoo/odoo#226022
18 changes
Resolved issues and error corrections
Fixes an issue where users could see an error message after successfully reconciling the last available batch payment in the bank reconciliation widget. The reconciliation itself worked, but the confusing traceback interrupted the workflow; this change keeps the screen stable when no batch payments remain.
Original PR description
1 change
Resolved issues and error corrections
This fixes an issue where confirming a batch transfer could lose barcode scanning settings. Warehouse users can now scan locations such as WH-Stock after creating a batch without the scan being incorrectly split into individual characters.
Original PR description
5 changes
Resolved issues and error corrections
This fix prevents invoices from failing during tax calculation when no external tax is found for a customer's ZIP code. The system now safely treats missing manual tax details as empty, allowing users to continue computing taxes without interruption.
30 changes
Resolved issues and error corrections
Fixes an issue where Time Off list view header buttons, such as New Group, did not respond properly unless they were approve or refuse actions. This helps managers complete Time Off and allocation workflows from list, calendar, and Gantt views without blocked or ignored actions.
Original PR description
**Issue** When clicking header buttons other than approve/refuse in Time Off list view, the actions are not processed correctly. **Steps to Reproduce** 1. Navigate to Time Off > Management > Time Off or Allocations 2. Switch to List view 3. Click on New Group button 4. Action is not executed properly **Root Cause** Previously, handleViewButtonClick only processed approve/refuse actions and ignored other header button actions. Now, non-leave actions are correctly forwarded to the default handler. Task ID: 5062846 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
7 changes
Resolved issues and error corrections
Stripe payments now use the right amount conversion for currencies like the Ugandan shilling that Stripe treats differently from standard currency rules. This prevents valid customer payments from being rejected or sent with the wrong value.
Original PR description
Steps: - Activate the 'UGX' currency. - Make a sale order with amount 100 with 'UGX' currency - Try to pay that order (100 USh) using card Issue: - stripe throws the following error - > 'The Checkout Session's total amount must convert to at least 50 cents. 1.00 USh converts to approximately €0.00.' - Hence 100 USh sent was identified as 1 USh by stripe. This confirms issue with decimals and currency mapping. Cause: - 'UGX' is zero-decimal currency but stripe identify it as two-decimal. Fix: - Update mapping for such special currency cases for stripe that don't follow general rules opw-5075707 Forward-Port-Of: odoo/odoo#227688
2 changes
Resolved issues and error corrections
Inventory barcode scanning now correctly accepts different products that happen to use the same serial number in GS1 barcodes. This prevents an error that previously stopped the second product from being added to an inventory count.
Original PR description
**PROBLEM** When scanning two gs1 barcode with the same serial number, but for different products there is an error and the 2nd product is not added to the inventory count. **STEP TO REPRODUCE** 1. install stock_barcode 2. activate the gs1 barcode and select the default gs1 nomenclature. 3. scan the following barcode - 01000000000001232180085 (product barcode: 0000000000123, serial: 80085). - 01000000000000482180085 (product barcode: 0000000000048, serial: 80085). 4. there is an unexpected error notification, and the 2nd product line isn't added. **CAUSE** In _processBarcode (barcode_model.py), we only check if: - there is already a line with serial tracking with a non-null qty - this line serial number is the same serial number that we are scanning **FIX** We should also verify if the product from the lines we are checking, and the line we want to create are the same. [opw-5076045](https://www.odoo.com/odoo/project/49/tasks/5076045)
…batch In the bank reconciliation widget, after reconciling the last batch payment, a traceback will be shown to the user. Steps to reproduce: - Create and confirm a customer payment - Create a batch…
…batch
In the bank reconciliation widget, after reconciling the last batch payment, a traceback will be shown to the user.
Steps to reproduce:
- Create and confirm a customer payment
- Create a batch payment including the above payment (ensure this is the only batch payment available for reconciliation)
- Open Bank reconciliation widget
- Create a Bank transaction to reconcile with the batch payment
- Add the batch payment and click "Validate"
Issue: Reconciliation succeeds, but a traceback will be shown:
```
OwlError: The following error occurred in onWillUnmount: "Cannot set properties of undefined (setting 'exportState')"
Error
at wrapError (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11557:23) (/web/static/lib/owl/owl.js:2685)
at onWillUnmount (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11626:34) (/web/static/lib/owl/owl.js:2754)
at BankRecBatchPaymentsRenderer.setup (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:217012:9) (/account_accountant_batch_payment/static/src/components/bank_reconciliation/batch_payments_list_view.js:11)
at new ComponentNode (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11305:28) (/web/static/lib/owl/owl.js:2433)
at http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:14948:28 (/web/static/lib/owl/owl.js:6076)
at BankRecEmbeddedListController.slot7 (eval at compile (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:14679:20), <anonymous>:128:32) (/web/static/lib/owl/owl.js:5807)
at callSlot (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11922:37) (/web/static/lib/owl/owl.js:3050)
at Layout.template (eval at compile (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:14679:20), <anonymous>:39:10) (/web/static/lib/owl/owl.js:5807)
at Fiber._render (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:10655:38) (/web/static/lib/owl/owl.js:1783)
at Fiber.render (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:10647:18) (/web/static/lib/owl/owl.js:1775)
Caused by: TypeError: Cannot set properties of undefined (setting 'exportState')
at BankRecBatchPaymentsRenderer.saveSearchState (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:217039:32) (/account_accountant_batch_payment/static/src/components/bank_reconciliation/batch_payments_list_view.js:38)
at BankRecBatchPaymentsRenderer.<anonymous> (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11571:26) (/web/static/lib/owl/owl.js:2699)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11400:24) (/web/static/lib/owl/owl.js:2528)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode._destroy (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11404:23) (/web/static/lib/owl/owl.js:2532)
at ComponentNode.beforeRemove (http://127.0.0.1:8982/web/assets/debug/web.assets_web.js:11534:18) (/web/static/lib/owl/owl.js:2662)
```
This occurs because we want to hide the Batch Payments tab from the reconciliation widget when no more batches are available for reconciliation but the `saveSearchState` still expects the batch payments to be defined in the view.
opw-4830466
Forward-Port-Of: odoo/enterprise#96598Stripe payments now handle currencies like the Ugandan shilling that use different decimal rules in Stripe than in standard currency settings. This prevents valid payments from being rejected or sent with the wrong amount, improving checkout reliability for affected currencies.
Original PR description
Steps: - Activate the 'UGX' currency. - Make a sale order with amount 100 with 'UGX' currency - Try to pay that order (100 USh) using card Issue: - stripe throws the following error - > 'The Checkout Session's total amount must convert to at least 50 cents. 1.00 USh converts to approximately €0.00.' - Hence 100 USh sent was identified as 1 USh by stripe. This confirms issue with decimals and currency mapping. Cause: - 'UGX' is zero-decimal currency but stripe identify it as two-decimal. Fix: - Update mapping for such special currency cases for stripe that don't follow general rules opw-5075707 Forward-Port-Of: odoo/odoo#227688
Tables pasted from tools like Google Docs now keep the expected formatting and structure in Odoo's HTML editor. This prevents invisible or incomplete tables and makes pasted content easier to edit reliably.
Original PR description
### Purpose of this PR: - Ensure that pasted table elements get the standard classes: `table, table-bordered, and o_table.` - When content is pasted from other source (e.g., Google Docs inside iframe), attribute nodes coming from another JavaScript context do not match the `Attr` prototype of the current context. Use `item.nodeType === Node.ATTRIBUTE_NODE` instead of `instanceof Attr` to detect attribute nodes. - Insert a base container into empty `<td>` elements when pasting tables from external sources. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230425 Forward-Port-Of: odoo/odoo#230208
The bank reconciliation widget now keeps existing invoice matches when users choose a write-off account that has a default tax. This prevents matched bills from disappearing during reconciliation, reducing rework and avoiding confusion for accounting users.
Original PR description
In the Bank reconciliation widget, users can click a button to set the account to write off the remaining balance. However, if the chosen account has a default tax set, the widget will lose any existing matches with invoices. Steps to reproduce: - Have an account with a default tax - Create a bill with a total - Create a bank statement for a greater amount - Open the bank reconciliation widget - In the created statement, first add the bill, then click 'Set Account,' and choose the account with tax Issue: Bill matching will be lost. This occurs because we remove and recreate the matching line, but we don't keep the line to be reconciled. opw-5002624
Fixes a checkout issue where valid promotions or coupons could be removed because the storefront and payment confirmation used different time zones or timing. This helps prevent paid orders from getting stuck as unconfirmed and ensures expired coupon discounts are removed before payment is finalized.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a database with GeoIP enabled; 2. have a promotion program that gives a discount on a specific product; 3. use a VPN to browse /shop from California…
Versions -------- - 17.0+ Steps ----- 1. Have a database with GeoIP enabled; 2. have a promotion program that gives a discount on a specific product; 3. use a VPN to browse /shop from California before 7:00 UTC; 4. add the product to your cart; 5. go to checkout; 6. pay for the order. Issue ----- Order cannot be confirmed due to incomplete payment. Cause ----- The `_frontend_pre_dispatch` method of `website` adds a timezone value to the context based on the request's `geoip`. This context value then gets used to find applicable loyalty programs via `Date.context_today`, and applies them to the order. Then after payment was initiated, the order gets validated again using server time (UTC), which now considers the applied program expired, and removes the reward before confirming the order. Consequently, with the discount removed, the paid amount no longer matches the order total, thus the order remains unconfirmed. Solution -------- If the order has a confirmed transaction, use its `create_date` to verify loyalty expiration dates. For time zone, instead of `Date.context_today`, using whatever `tz` value is in the context, use a helper function which retrieves the current day in the company's timezone. For website orders, if defined, use the eCommerce salesperson's time zone instead. Also fix an issue where expired coupon lines weren't getting removed from the order. opw-4765873 opw-4781346 opw-4939268 Forward-Port-Of: odoo/odoo#229749 Forward-Port-Of: odoo/odoo#222428
Product searches in Point of Sale now show all relevant matches instead of stopping at an exact match. This helps cashiers find similar or related products more reliably, reducing missed items during checkout.
Original PR description
The POS search only returned products with an exact match (when existing), ignoring other relevant products that partially matched the search string. Steps to reproduce: 1. Create a product "TEST" - Create a variant with attributes value including "TEST" and "OTHER". 2. Create a second product "TEST 2". 3. Open the POS. 4. Search for "TEST". 5. Only "TEST" is shown; "TEST 2" is missing, even with "Search more". To align with the behavior introduced in v18, I’ve removed the exact match condition, as it no longer appears necessary due to the absence of fuzzy search. I’ve also adjusted the logic to perform the search on `product.product` instead of `product.template`. opw-4958141 Forward-Port-Of: odoo/odoo#221520
This fix prevents an error when saving a manufacturing order after changing the duration of a work order that has not yet been scheduled. It ensures only scheduled work orders are used to calculate production start and finish dates, improving reliability for manufacturing teams using work orders.
Original PR description
**Steps to reproduce:** 1. In Settings, enable "Work Orders". 2. Create a product with a BOM that has 2 operations: op1 and op2. 3. Create and confirm an MO for 1 unit. 4. Start op1 and change the…
**Steps to reproduce:** 1. In Settings, enable "Work Orders". 2. Create a product with a BOM that has 2 operations: op1 and op2. 3. Create and confirm an MO for 1 unit. 4. Start op1 and change the Real Duration of op2. 5. Try to save. **Issue:** - Traceback : `'<' not supported between instances of 'datetime.datetime' and 'bool'` **Cause of the issue:** Starting the first operation launches a call of the `button_start` method creating a `resource.calendar.leaves` to set on the `leave_id` of this first operation: https://github.com/odoo/odoo/blob/97a70e71c32ea6183f87fd5eb558b32bcbd2d231/addons/mrp/models/mrp_workorder.py#L630-L641 Then, setting the duration of the second operation from the form view of the MO and saving triggers a call of the write of the MO containing the `[Command.update(op_2.id, new_duration)]` as vals.This, in turn, calls `_plan_workorders`: https://github.com/odoo/odoo/blob/97a70e71c32ea6183f87fd5eb558b32bcbd2d231/addons/mrp/models/mrp_production.py#L939-L942 while the first operation has a set `leave_id` but the second do not However, the `min` operator will be applied to both the set and the unset values, comparing a `boolean` with a `datetime`: https://github.com/odoo/odoo/blob/97a70e71c32ea6183f87fd5eb558b32bcbd2d231/addons/mrp/models/mrp_production.py#L1581-L1588 **Solution:** Only workorders with a `leave_id` (i.e., those planned in work-center schedule) should be considered when computing MO `date_start` and `date_finished`. Workorders without a `leave_id` are not yet scheduled and therefore should not influence MO start and end dates. As both `date_start` and `date_finished` of a workorder are related to the `leave_id` record. As per `mrp_workorder._compute_dates`, these dates reflect the work-center scheduling (`leave_id.date_from` and `leave_id.date_to`). https://github.com/odoo/odoo/blob/6a075fa3c090920499ccbd5fe673819da7e3f95e/addons/mrp/models/mrp_workorder.py#L250-L260 Therefore, when computing MO dates, it logically follows that only workorders with an assigned `leave_id` should be used. This avoids mixing unscheduled operations (`leave_id = False`) with scheduled ones, preventing invalid comparisons and ensuring accurate production timing. **opw-5068080** Forward-Port-Of: odoo/odoo#226436
This fixes an issue where French POS order integrity hashes could be created before all order details were finalized. The change helps prevent valid orders from being incorrectly flagged as altered during compliance checks.
Original PR description
Description of the issue/feature this PR addresses:
Starting from version 18.0, inalterability hashes in the FR localization are sometimes calculated with incomplete data, leading to incorrect `l10n_fr_hash`. Related orders are then wrongly flagged as altered when running the POS Inalterability Check.
Current behavior before PR:
When you post a POS order and a related draft order exists, Odoo updates the existing order with the new vals. Because `{'state': 'paid'}` is amongst the new vals, it triggers the generation of the `l10n_fr_hash` before the order is fully processed. For instance, the hash will be generated before a new payment line is added for change with `_process_payment_lines()`.
Desired behavior after PR is merged:
The hash should be generated at the end of the order processing, with the final write in `action_pos_order_paid()`.
Forward-Port-Of: odoo/odoo#226032Fixes an issue where opening a shared employee profile link could display an error when the profile contained private information. Users now receive a clearer message and can be redirected to the public employee list, reducing confusion and improving reliability.
Original PR description
Sharing a link of an employee profile containing private info generated a traceback. Permissions had to be applied to the private field. I've also put a more explicit error message that allows the user to get redirected to the public employee list. I couldn't find a way to get the employee id from the url before the generic permission warning comes in. Thus I had to resort to redirecting to the general public employees list. Other tracebacks may happen each time a private field without the corresponding groups is put in the xml. Thus I added a test to prevent us from doing that again. Forward-Port-Of: odoo/odoo#229611 Forward-Port-Of: odoo/odoo#228623
Installing the POS Settle Due module now applies its required products to every point-of-sale configuration, including those with active sessions. This prevents checkout issues when staff need to settle dues, take deposits, or settle invoices in POS.
Original PR description
Before this commit, when the module pos_settle_due was installed, the special products (settle due, deposit, settle invoice) were only set on the POS configurations that did not have any open session. This could lead to issues when trying to use these products in a POS session of a configuration that did not have them set. Now, the special products are set on all POS configurations when installing the module. Community PR: https://github.com/odoo/odoo/pull/229074
This fix prevents essential point of sale products, such as discounts, tips, and settlement items, from being deleted or archived. It helps avoid checkout and configuration issues caused by missing required products.
Original PR description
Before this commit, it was possible to delete or archive some products even if they were special for the pos (discount, tips, settle, etc.). This commit adds a mechanism to prevent this and reduce the risk of errors linked to missing products in the pos. Enterprise PR: https://github.com/odoo/enterprise/pull/95789 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Releasing an unused restaurant table no longer leaves behind a pointless draft order. Orders already sent to the kitchen are still cancelled properly to keep kitchen records accurate, while unused orders are removed entirely.
Original PR description
Steps to reproduce: ------------------------- - Install POS restaurant. - Open any table to order. - Release the table. Issue: ------- - A draft order is created without purpose or use. Cause: --------- - On releasing the table we were not deleting the order, we were just cancelling the order even if it's not useful. Fix: ----- - We have called a proper function to manage the conditions like - If the order is sent to kitchen it will cancel the kitchen ticket to avoid inaccuracy kitchen side and already recorded on server so it will be cancelled and if the order was not sent to kitchen than there is no need of the order so will be removed totally. - We have corrected condition to send order in kitchen as `last_order_preparation_change` will always have some keys with blank values but we need to send data based on the lines changed in lopc. task: 4774814
This fix ensures a Spanish 0% VAT tax for services outside the EU is reported as not subject to VAT instead of as an export in Modelo 303. It also corrects the refund sign for the related service tax, helping Spanish VAT returns reflect these transactions more accurately.
Original PR description
The s_iva_e tax (IVA 0% Extracomunitaria (Servicios)) is configured as no_sujeto_loc, but is reported as "Exportacion" in modelo 303. There might have been the idea that we need a tax for services that are just a complement to some goods, but this tax is not used that way in practice. So, it is better to treat it as a duplicate of the s_iva_ns tax (Not Subject To VAT (services)) where we also see that the refund sign was wrong. opw-5079297 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#230383 Forward-Port-Of: odoo/odoo#229752
Fixes Italian fiscal printer receipts so they print automatically even when the POS is configured to skip the receipt screen. The update also ensures the correct completed sale is printed, avoiding missing or incorrect fiscal receipts for businesses using Italian POS compliance features.
Original PR description
This PR fixes two related bugs happening when printing a receipt with the Italian Fiscal printer First, before this PR, if the option to skip the receipt screen was ticked, then the receipt would…
This PR fixes two related bugs happening when printing a receipt with the Italian Fiscal printer First, before this PR, if the option to skip the receipt screen was ticked, then the receipt would never print. This was caused by the printing logic being implemented on the receipt screen instead of on the pos itself. steps to reproduce: 1. install l10n_it_pos 2. configure one pos 3. configure the IT printer 4. select to skip the receipt screen (print automatically) 5. open the pos 6. make a sale => no ticket printed and the chrome console shows a printer error With this new verison the printing logic was moved to the pos so that printing of fiscal receipts with the italian fiscal printer works, even when receipt screen is skipped. This put to light another potential bug related to how the `order` variable was treated. Before this PR, the printReceipt logic in the module would not pass the order to be printed. This can become a problem upon context changes, where `pos.get_order()` does not return the completed order, but a newly created one. This can for example happen when skipping the receipt screen with the option to "print automatically" (iface_print_auto). After this PR, we keep order as an argument, so we always print the last completed order and not a newly created one. opw-4882480 Forward-Port-Of: odoo/enterprise#95985 Forward-Port-Of: odoo/enterprise#91412
This update prevents Chrome on iOS from automatically changing certain text on Odoo pages in a way that could disrupt the interface. It helps keep screens stable and usable for affected mobile users, especially on Chrome iOS versions where the browser behavior reappeared.
Original PR description
Chrome iOS wraps some text nodes (like measures, email...) with a `<chrome_annotation>` tag, which breaks OWL rendering. This commit works around it by adding the (undocumented) `<meta name="chrome"…
Chrome iOS wraps some text nodes (like measures, email...) with a `<chrome_annotation>` tag, which breaks OWL rendering. This commit works around it by adding the (undocumented) `<meta name="chrome" content="nointentdetection">` tag to disable this Chrome behavior. The tag has to be set before the onDOMContentLoaded event to be taken into account. Note: Looks like this behavior was present in Chrome iOS 127 and disabled afterward (because it already had issues) but it appeared again in version 140-141. References: - https://issues.chromium.org/issues/353650041 - https://issues.chromium.org/issues/388718411 - https://stackoverflow.com/questions/78207646/how-do-i-disable-chrome-annotation-tags - https://stackoverflow.com/questions/78575970/prevent-auto-detection-of-phone-numbers-in-chrome-mobile - https://stackoverflow.com/questions/78725191/stop-chrome-ios-auto-detecting-numbers-followed-by-letter-m-as-metre-units-an - https://github.com/solidjs/solid/issues/2235 opw-4969197 Forward-Port-Of: odoo/odoo#230081
Adyen payment requests now include extra checkout details required by some payment methods, such as Klarna. This helps prevent affected transactions from failing when country information and order line items are needed to complete payment.
Original PR description
Some payment methods eg. Klarna require 'country code' and 'line items' in order to process the transaction. opw-5077617 Forward-Port-Of: odoo/odoo#230292
The manufacturing Bill of Materials overview now avoids showing a planning error when the maximum producible quantity cannot fit into the long-term work center schedule. Instead, it falls back to the requested quantity, allowing users to open the overview and continue replenishment planning normally.
Original PR description
### Steps to reproduce: 1. Install mrp + purchase 2. Create a new product (A) 1. Add the Buy route on the product 2. Add a vendor line on the Purchase tab 3. Set the quantity on hands to 2000 3.…
### Steps to reproduce: 1. Install mrp + purchase 2. Create a new product (A) 1. Add the Buy route on the product 2. Add a vendor line on the Purchase tab 3. Set the quantity on hands to 2000 3. Create a second product (B) with manufacturing route 4. Create a BoM for this product (B) 1. Add the product (A) as the component with 1 quantity 2. Create a new operation with a duration of 600:00 5. On the product B's page, click Replenish 1. Put 10 quantities to replenish 2. Select the manufacturing route and confirm 6. Go to the BoM and open the BoM overview 7. 'Impossible to plan. Please check the workcenter availabilities.' https://github.com/user-attachments/assets/58697fd9-4e3e-4df6-98e1-5de7e8759715 ### Before this commit: When opening the BoM overview, if the producible quantity for this BoM exceed the quantity we can plan in the 700 following days, an error is displayed. ### After this commit: If the quantity producible cannot be planned, we retry automatically with the requested quantity. opw-5031724 Forward-Port-Of: odoo/odoo#229745 Forward-Port-Of: odoo/odoo#227433
Emails sent from Odoo could fail when they included an attached email file containing accented or other non-English characters. This fix makes those attachments handled correctly, improving reliability for users sharing email conversations through the system.
Original PR description
The previous fix for `message/rfc822` attachments forced binary encoding (`cte='binary'`) to comply with RFC 2046. However it also introduced a new issue: emails containing `.eml` attachments with…
The previous fix for `message/rfc822` attachments forced binary encoding (`cte='binary'`) to comply with RFC 2046. However it also introduced a new issue: emails containing `.eml` attachments with non-ASCII characters could not be serialized ### Steps to reproduce 1. Send an email via the chatter with a `.eml` file attached containing non-ASCII characters (e.g., "é") in its body. The sending of that email will fail with a `UnicodeEncodeError` error ### Cause Commit 6197233ef1611ddd974cfdb06ae2568e4af369de attempted to fix an issue where `.eml` (`message/rfc822`) attachments were not RFC-compliant. It did this by forcing the `Content-Transfer-Encoding` to `binary` for the raw byte content of the attachment. While this worked for simple ASCII attachments, it failed for attachments containing non-ASCII characters. When Python's `email` library later tried to serialize the entire message, it treated the attachment's content as an opaque binary blob. It did not understand the character encoding within that blob, leading to a `UnicodeEncodeError` during the final serialization process. ### Fix Instead of attaching the raw bytes, we now: * Parse `.eml` contents using `email.parser.BytesParser`, producing a proper `Message` object. * Attach the parsed message directly, letting the email library handle correct encoding and transfer settings automatically. opw-4655868 Forward-Port-Of: odoo/odoo#230384 Forward-Port-Of: odoo/odoo#223790
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and…
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and confirm - Scan WH-Stock #### > The scan fails considering you scanned each letter independently. ### Cause of the issue: When the barcode is scanned a call of the split barcode will be launched to split the barcode in multiple barcodes according to the `barcode_separator_regex` present in the config: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_model.js#L613-L632 The issue lies in the fact that even thought the is `barcode_separator_regex` was conrrectly populated at the onWillStart of the mainComponent: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L97 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_picking_model.js#L36-L38 It was reset by the batch confirmation here: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L123-L135 because this part of the config is not meant to be returned by the private method `_get_barcode_data` but rather by public complete version `get_barcode_data`: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L91-L98 Now, since no `barcode_separator_regex` was provided to our new config, each character will be considered to be considered as an independent barcodes and the `WH-Stock` barcode will not match any location. opw-5062331 Forward-Port-Of: odoo/enterprise#94056
Original PR description
Currently, an error occurs when computing taxes for an invoice. **Error:** `KeyError: 'manual_tax_amounts'` **Cause:** When a user clicks the `Compute Tax` button, the system calculates the tax for…
Currently, an error occurs when computing taxes for an invoice.
**Error:**
`KeyError: 'manual_tax_amounts'`
**Cause:**
When a user clicks the `Compute Tax` button, the system calculates the tax for that invoice, including the `manual_tax_amount` [1]. However, if no tax is found for a given customer ZIP code, the `tax_values_list` becomes empty [2]. As a result, `manual_tax_amounts` in the base line also becomes empty.
Later, when the system tries to fetch the `manual_tax_amounts` key from extra_tax_data, it raises a KeyError [2], because the key no longer exists.
Additionally, the condition in [3] indicates that there is no guarantee that the `manual_tax_amounts` key will always be present in the base_line.
**FIX:**
This commit ensures that if the manual_tax_amounts key does not exist, an empty dictionary {} is used instead. This prevents the KeyError from occurring during tax computation.
[1]- https://github.com/odoo/enterprise/blob/b17b6b4e5ca3085d831fc763457496b5c5b639c5/account_external_tax/models/account_external_tax_mixin.py#L155-L163
[2]- https://github.com/odoo/enterprise/blob/a51aee8f6e8bce2aa699d3199d6723495464a762/account_external_tax/models/account_external_tax_mixin.py#L88
[3]- https://github.com/odoo/odoo/blob/241c170dbece8c1652db9ca1aa935b2106ede532/addons/account/models/account_tax.py#L1330
sentry-6919182805
Forward-Port-Of: odoo/enterprise#96401Gantt group headers now keep the right size so they remain visible and aligned while users scroll. This prevents oversized headers from breaking the sticky behavior, especially on smaller mobile screens.
Original PR description
Gantt group headers could stop being sticky because their width was fixed based on the number and size of columns. Even though they were set to position: sticky, oversized headers could no longer remain aligned when scrolling, as they extended beyond the viewport and were constrained by the document width. This was especially noticeable on mobile, where group headers are often wider than the screen. The fix applies a max-width style to these headers, capping their size to the available space so they remain sticky without overflowing the document. task-4970992 Forward-Port-Of: odoo/enterprise#96612 Forward-Port-Of: odoo/enterprise#96015
Quality checks for products tracked by serial number now correctly remain failed when the check is failed from a receipt. This prevents defective items from being incorrectly marked as passed, improving inventory and quality control accuracy.
Original PR description
Serial number tracked product are marked as pass even when they fail a move_line type of check. ### Steps to reproduce: * Create a product tracked by serial number * For this product create a control…
Serial number tracked product are marked as pass even when they fail a move_line type of check. ### Steps to reproduce: * Create a product tracked by serial number * For this product create a control point: - Control per quantity - Operations : Receipts * Create a receipt for this product * Mark the receipt as Todo * Start the Quality check from the receipt, without using the smart button. * Fail the Quality check * The Quality check still passes ### Issue: When validating a quality check and it fails: https://github.com/odoo/enterprise/blob/d48228127c239e45938551d9bbac734afab8b31a/quality_control/wizard/quality_check_wizard.py#L84-L92 I will not go through the standard process with show_faillure_message where the user can select failed_qty, it directly goes to confirme_fail>_move_to_failure_location: https://github.com/odoo/enterprise/commit/49149580d34ec5583559fa0288356fec6cb2c514#diff-2ffdc2ffc25417076b580b772447514c7e9d8b3e2d2fff2d3100721eb5ccbaf4L455-R457 In our case since failed_qty is still at 0 this new condition transfer the quality check to pass. In the case of serial numbers, the quality check is done one by one, the failed_qty can be retrived from check.move_line_id.quantity opw-5015266 Forward-Port-Of: odoo/enterprise#92966
When an employee contract is signed, the selected company car is now reliably recorded in the employee history even if the value was already present on the contract version. Offer summaries also show the selected car and bike names, making compensation details clearer for HR and employees.
Original PR description
As when signing the employee contract, the version related to that contract is already created and we just set the version active, the value of the car does not change, so the tracking is not triggered and it's not added into the chatter. This PR force the car_id and ordered_car_id to be tracked by adding the initial value the employee precommit tracking values, before the version is activated (so before the employee get the new values from the newly active version). Also, this PR adds the selected car and bike names to the offer summary. Task-4962922 Forward-Port-Of: odoo/enterprise#90915
The Time Off screens now correctly open the group request wizard from list, calendar, and Gantt views. This ensures managers can create group time off requests without the button failing or being ignored.
Original PR description
See https://github.com/odoo/odoo/pull/226574 **Issue** - When clicking header buttons other than approve/refuse in Time Off list view, the actions are not processed correctly. - Added New Group Time Off to calendar and gantt view **Steps to Reproduce** 1. Navigate to Time Off > Management > Time Off or Allocations 2. Switch to List view 3. Click on New Group button 4. Action is not executed properly **Root Cause** Previously, handleViewButtonClick only processed approve/refuse actions and ignored other header button actions. Now, non-leave actions are correctly forwarded to the default handler. Task ID: 5062846 Forward-Port-Of: odoo/enterprise#95153
This fixes Nuvei payment handling so customers who return from the payment page without completing payment are not blocked by missing notification data. It also validates amounts correctly for Nuvei methods such as Webpay that require whole-number amounts, improving successful payment processing.
Original PR description
Since https://github.com/odoo/odoo/pull/163860, all notifications from providers are checked to see that they have the correct currency and amount in their flow before processing the notification. However, this has two issues with Nuvei: 1. The process when a customer hits "Go back" on the payment page instead of paying does not send any notification data. As such trying to compare these values will not work. 2. Certain payment methods within Nuvei use different decimal precision than the currencies on odoo. Webpay must always be in whole values even for USD, as such, we need to pass the correct number of precision digits to the validation method otherwise Webpay will never be able to go through. opw-5108631 Forward-Port-Of: odoo/odoo#230159
This fixes Brazilian Avalara tax calculations for service invoices so discounts are not subtracted twice. Businesses using this localization should see more accurate tax amounts on discounted service lines, reducing billing and compliance discrepancies.
Original PR description
Confusingly, Avalara's service API already accounts for the discount in lineNetFigure, whereas their goods API does not. In <saas-18.4 this was handled by _l10n_br_get_line_total(), but it got lost in the big refactor in saas-18.4 [1]. [1] https://github.com/odoo/enterprise/pull/82623 opw-5147143 Forward-Port-Of: odoo/enterprise#96585
Fixed an issue where computing taxes on an invoice could fail when no external tax was found for a customer's ZIP code. The system now safely continues with empty manual tax data, helping users complete invoice tax calculations without interruption.
Original PR description
Currently, an error occurs when computing taxes for an invoice. **Error:** `KeyError: 'manual_tax_amounts'` **Cause:** When a user clicks the `Compute Tax` button, the system calculates the tax for…
Currently, an error occurs when computing taxes for an invoice.
**Error:**
`KeyError: 'manual_tax_amounts'`
**Cause:**
When a user clicks the `Compute Tax` button, the system calculates the tax for that invoice, including the `manual_tax_amount` [1]. However, if no tax is found for a given customer ZIP code, the `tax_values_list` becomes empty [2]. As a result, `manual_tax_amounts` in the base line also becomes empty.
Later, when the system tries to fetch the `manual_tax_amounts` key from extra_tax_data, it raises a KeyError [2], because the key no longer exists.
Additionally, the condition in [3] indicates that there is no guarantee that the `manual_tax_amounts` key will always be present in the base_line.
**FIX:**
This commit ensures that if the manual_tax_amounts key does not exist, an empty dictionary {} is used instead. This prevents the KeyError from occurring during tax computation.
[1]- https://github.com/odoo/enterprise/blob/b17b6b4e5ca3085d831fc763457496b5c5b639c5/account_external_tax/models/account_external_tax_mixin.py#L155-L163
[2]- https://github.com/odoo/enterprise/blob/a51aee8f6e8bce2aa699d3199d6723495464a762/account_external_tax/models/account_external_tax_mixin.py#L88
[3]- https://github.com/odoo/odoo/blob/241c170dbece8c1652db9ca1aa935b2106ede532/addons/account/models/account_tax.py#L1330
sentry-6919182805
Forward-Port-Of: odoo/enterprise#96401The Time Off screens now correctly process the New Group action from list, calendar, and Gantt views. This lets managers create grouped time off requests without the button failing or being ignored.
Original PR description
See https://github.com/odoo/odoo/pull/226574 **Issue** - When clicking header buttons other than approve/refuse in Time Off list view, the actions are not processed correctly. - Added New Group Time Off to calendar and gantt view **Steps to Reproduce** 1. Navigate to Time Off > Management > Time Off or Allocations 2. Switch to List view 3. Click on New Group button 4. Action is not executed properly **Root Cause** Previously, handleViewButtonClick only processed approve/refuse actions and ignored other header button actions. Now, non-leave actions are correctly forwarded to the default handler. Task ID: 5062846
The purchase reporting view now correctly includes purchase order lines for products that do not have a category. This restores the vendor On-time Rate graph so purchasing teams can assess vendor delivery performance even when product category data is missing.
Original PR description
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and…
**Steps to reproduce:** 1-Install the purchase_stock module. 2-Create a Purchase Order with a new vendor. 3-In the Purchase Order line, add a product without a category. 4-Confirm the order and validate the generated receipt. 5-In the vendor form view, click the On-time Rate smart button → no graph is visible. **Issue:** https://github.com/odoo/odoo/blob/77b3956ed5635d79ae8dc19423140dc6a10098f1/addons/purchase_stock/report/vendor_delay_report.py#L46-L50 ``` The On-time Rate graph is not displayed in the Vendor Delay report. ``` **Cause:** - From version 18.2, `categ_id` was removed as a required field. The report query still uses an inner join on `categ_id`, which excludes products without a category and prevents data from being generated. - Commit which make `categ_id` non require - https://github.com/odoo/odoo/pull/166323/commits/b039caecbeb04057fbccb1cc88d03a4946f88e8e **Solution:** - Replace the inner join with a left join so that products without a `categ_id` are also included in the report (with null values when the category is not set). **opw** - 4991367 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230388 Forward-Port-Of: odoo/odoo#225557
Vendor credit notes matched to purchase orders now show the correct positive quantity when reversing over-billed purchase lines. This helps avoid confusing refund quantities and supports more accurate purchase billing records.
Original PR description
Steps to reproduce:- - Create a Purchase Order with Product A(invoicing policy: received quantities) and Quantity 3. - Create Vendor Bill with Product A and Quantity 3 and match it with the PO. - Receive only 2 on PO. - Now on PO, Quantity: 3, Received:2, Billed:3 - Create a Vendor Credit Note for that partner, add an empty line and save. - Click on PO Matching at the top. - Select line from Vendor Credit Note and line from PO, click match. Problem: In Vendor Credit Note Quantity: -1 (which should be 1) Before this commit: When credit note values are prepared from purchase order, quantity to invoice on purchase order is set as quantity on credit note. After this commit: When credit note values are prepared from purchase order, inverse(-ve) of quantity to invoice on purchase order is set as quantity on credit note. task-4975200 Forward-Port-Of: odoo/odoo#230487 Forward-Port-Of: odoo/odoo#221203
Customer statement emails sent from child invoice contacts now include the correct PDF details instead of an empty attachment. The Customer Statement button is also hidden when there are no transactions or no amount due, reducing confusion for accounting users.
Original PR description
**Steps to reproduce:** 1. Go to Accounting > Customers > create a company with child contact (invoice) (both having name and email). 2. Create an invoice with the child contact as customer and…
**Steps to reproduce:** 1. Go to Accounting > Customers > create a company with child contact (invoice) (both having name and email). 2. Create an invoice with the child contact as customer and confirm it. 3. Go to the child contact and open the Customer Statement smart button. 4. Download the PDF → data is shown correctly. 5. Send the statement → the attachment in the sent mail is empty. **Issue:** - When sending customer statements via email from a child contact, the generated PDF attachment contains no data, showing empty amounts and transactions. - Additionally, the "Customer Statement" button was still visible even when the total due was zero. **Cause:** - The button visibility condition checks for `total_due == 0.0 and not has_moves`, which didn’t properly cover all use cases. **Solution:** - Update button visibility condition to: `invisible="not has_moves or total_due == 0"` ensuring it is hidden when there are no moves or the total due is zero. **opw-5009182** Forward-Port-Of: odoo/enterprise#95356 Forward-Port-Of: odoo/enterprise#93162
The AI assistant now handles incomplete grouped search requests more safely when the language model leaves out required grouping or summary fields. This prevents terminal errors and keeps the chat experience stable for users making business data queries.
Original PR description
Currently, an error occurs when no groupby property is found in LLM response while trying to search records through the AI agent in the chat. Steps to replicate: - Install ai_app and sale_management.…
Currently, an error occurs when no groupby property is found in LLM response
while trying to search records through the AI agent in the chat.
Steps to replicate:
- Install ai_app and sale_management.
- Setup gemini key.
- In the systray click on AI icon.
- Type in:
`read group in res partner`
or
`read group in partners groupby None`
- Error will occur in terminal.
(If the error doesnt occur the first time, spam the above given prompt.)
Error:
`ValueError: TypeError("'NoneType' object is not iterable") while evaluating
"ai['result'] = record._ai_tool_read_group(model_name, domain, groupby, aggregates, having, offset, limit, order)"`
Cause:
- As the LLM response didnt incude groupby it was passed on as None to the orm,
which caused the `'NoneType' object is not iterable` at the line [1].
- The groupby was set `None` through line [2], the loop sets every param that
is not in the instance as None i.e. Every value that is in `ai_tool_schema`
but not received in LLM response is set as `None`.
Solution:
- The method `_ai_tool_read_group` now safely handles cases where `groupby` or
`aggregates` (similar error occurs when aggregates is none at [3]) are None.
- Fields are assigned default values before calling the method `_read_group`.
[1]: https://github.com/odoo/odoo/blob/c034fed2eeb194961af7e1b3c60203141784acf2/odoo/orm/models.py#L1919
[2]: https://github.com/odoo/enterprise/blob/7e6fe07512b7d897cf6315d45e6a1004e48ef45e/ai/utils/tools_schema/validators.py#L51
[3]: https://github.com/odoo/odoo/blob/c034fed2eeb194961af7e1b3c60203141784acf2/odoo/orm/models.py#L1923
sentry-6912361256This fix ensures the correct domestic fiscal position is selected for several country localizations, which helps apply the right local taxes. It adjusts fiscal position ordering for the UAE, Mexico, and Cambodia, and removes a duplicate Italian domestic fiscal position that could cause incorrect selection.
Original PR description
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the…
Since the fiscal position sequence is used to determin the domestic fiscal position, and hence, the domestic taxes - it is important to properly sequence the fiscal positions. This commit fixes the following localizations: **AE** Sequences are added making Dubai the domestic fiscal position. However this needs to be improved to automatically prioritize the fiscal position based on the company's state. **IT** (l10n_it_edi_doi) An additional domestic fiscal position was mistakenly added. The correct domestic FP is defined in it's dependency module l10n_it. The duplicate FP is removed. **MX** Sequences are added **KH** Sequences are added No Task - l10n's identified by the fiscal position checks in `test_all_l10n` 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#230654
This fix ensures outgoing stock movements are properly included when Odoo calculates product quantities in strict mode. Businesses should see more accurate inventory availability figures in affected stock workflows.
Original PR description
### Issue: Commit ba54310a11d2b702753d4b9b028a62dd00a91467 has altered the location domain for quantities computations. However, the `dest_loc_domain_out` has not been correctly replaced: https://github.com/odoo/odoo/blob/f173c738b1adcf85a80eb641ad307b7cccf17294/addons/stock/models/product.py#L319 Since the returned value used to be negated and is not anymore. This results in out moves being ignored by the `_compute_quantities` in `strict` mode. opw-4997982 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229734 Forward-Port-Of: odoo/odoo#229304
The Point of Sale customer details screen now shows only the information needed for checkout and related POS work. This reduces clutter for staff and helps avoid errors caused by back-office-only fields appearing in the POS interface.
Original PR description
Before this commit: ==================== The POS frontend used the main backend form view of res.partner, which displayed all partner details. Many of these fields and buttons were irrelevant for the POS and occasionally caused errors or tracebacks due to backend-specific features being exposed. After this commit: =================== The POS frontend now displays a simplified partner form with only the essential fields required for POS operations. Unnecessary backend details are hidden to improve usability and prevent potential errors. Task-5103953
Gantt group headers now keep the right size so they remain visible and aligned while users scroll. This prevents oversized headers from breaking the sticky behavior, especially on smaller mobile screens.
Original PR description
Gantt group headers could stop being sticky because their width was fixed based on the number and size of columns. Even though they were set to position: sticky, oversized headers could no longer remain aligned when scrolling, as they extended beyond the viewport and were constrained by the document width. This was especially noticeable on mobile, where group headers are often wider than the screen. The fix applies a max-width style to these headers, capping their size to the available space so they remain sticky without overflowing the document. task-4970992 Forward-Port-Of: odoo/enterprise#96612 Forward-Port-Of: odoo/enterprise#96015
This fix improves how Swiss payroll recalculates payslip issues, helping ensure payroll warnings and related checks stay accurate after changes. It reduces the risk of outdated or incorrect payslip information affecting payroll review and accounting workflows.
Original PR description
task-5150492
Adding a combo product to the online shop cart no longer fails when its related combo choice was deleted. This prevents shoppers from encountering an error at checkout and keeps the cart flow working for affected products.
Original PR description
Currently, an error occurs when a user adds a combo product to the cart. Steps to Reproduce [video](https://drive.google.com/file/d/1m-zxaIsrIzogeLun_Dj92Hb37-S9g9dO/view?usp=sharing): - Install the…
Currently, an error occurs when a user adds a combo product to the cart. Steps to Reproduce [video](https://drive.google.com/file/d/1m-zxaIsrIzogeLun_Dj92Hb37-S9g9dO/view?usp=sharing): - Install the `website_sale` module. - Create a product of type `combo` and add a `combo choice`. - Go to the `combo choices` and delete `that combo choice`. - Go to the `website` > `Shop` and add that product to the `cart`. `ValueError: min() arg is an empty sequence` This error occurs after this [commit](https://github.com/odoo/odoo/pull/198070/files), When user creates a combo product, adds its related combo choice, and then deletes that combo choice, adding the product to the cart causes the system to check the quantities of the order line [1]. Since there is no sale combo choice for that product, the combo line becomes empty and raises an error[2]. This commit ensures combo choice quantities are checked only if they exist. [1]- https://github.com/odoo/odoo/blob/df05ae6d9af6abdfd67c49ac7a4d01762472bfc3/addons/website_sale/controllers/cart.py#L189 [2]- https://github.com/odoo/odoo/blob/df05ae6d9af6abdfd67c49ac7a4d01762472bfc3/addons/website_sale/models/sale_order.py#L621 sentry-6924112987 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Shared employee profile links that include private information now show a clearer access message instead of causing an error. Users are redirected to the public employee list, and extra checks help prevent similar permission issues from returning.
Original PR description
Sharing a link of an employee profile containing private info generated a traceback. Permissions had to be applied to the private field. I've also put a more explicit error message that allows the user to get redirected to the public employee list. I couldn't find a way to get the employee id from the url before the generic permission warning comes in. Thus I had to resort to redirecting to the general public employees list. Other tracebacks may happen each time a private field without the corresponding groups is put in the xml. Thus I added a test to prevent us from doing that again. Forward-Port-Of: odoo/odoo#230390 Forward-Port-Of: odoo/odoo#228623
Quality checks for serial-number tracked products now correctly stay failed when an item fails inspection during receipt processing. This prevents defective tracked items from being incorrectly marked as passed, improving inventory quality control accuracy.
Original PR description
Serial number tracked product are marked as pass even when they fail a move_line type of check. ### Steps to reproduce: * Create a product tracked by serial number * For this product create a control…
Serial number tracked product are marked as pass even when they fail a move_line type of check. ### Steps to reproduce: * Create a product tracked by serial number * For this product create a control point: - Control per quantity - Operations : Receipts * Create a receipt for this product * Mark the receipt as Todo * Start the Quality check from the receipt, without using the smart button. * Fail the Quality check * The Quality check still passes ### Issue: When validating a quality check and it fails: https://github.com/odoo/enterprise/blob/d48228127c239e45938551d9bbac734afab8b31a/quality_control/wizard/quality_check_wizard.py#L84-L92 I will not go through the standard process with show_faillure_message where the user can select failed_qty, it directly goes to confirme_fail>_move_to_failure_location: https://github.com/odoo/enterprise/commit/49149580d34ec5583559fa0288356fec6cb2c514#diff-2ffdc2ffc25417076b580b772447514c7e9d8b3e2d2fff2d3100721eb5ccbaf4L455-R457 In our case since failed_qty is still at 0 this new condition transfer the quality check to pass. In the case of serial numbers, the quality check is done one by one, the failed_qty can be retrived from check.move_line_id.quantity opw-5015266 Forward-Port-Of: odoo/enterprise#92966
Fixed a survey issue where people who answered certain multiple-choice questions with a comment could still be told the question was unanswered. This improves survey completion reliability and adds safeguards to prevent invalid multiple answers on single-choice questions.
Original PR description
Issue: When answering a question with a comment in multiple choice with roaming activated for the survey, the UI will display a warning message that says the question requires an answer. Cause: The backend creates a skipped record if none of the pre-created answers is chosen. Solution: Don't create a skipped record if a comment counts as an answer and a comment is provided. Added validation of input and unittests Task-5062984 Forward-Port-Of: odoo/odoo#226022
Fast checkout could leave printed receipts empty, and in restaurant workflows it could cause an error when printing. This fix ensures the receipt screen uses the correct current order so customers receive complete receipts reliably.
Original PR description
pos*: pos_event_iot, l10n_it_pos Steps to reproduce: - Enable a one-click payment method. - Create and validate an order using fast validation. - On the receipt screen, print the order receipt. Issue: - The printed receipt is empty (no order details). - In restaurant mode, a traceback occurs when printing the receipt. Fix: - Use the receipt screen’s `currentOrder` reference instead of fetching the order directly from the POS instance. Task-5093060 Related: https://github.com/odoo/odoo/pull/227621
This fixes an issue where users working with Indian localization could not create a new company contact from a CRM lead when entering a GSTIN. The change prevents an invalid contact type from being used during PAN entity creation, allowing the contact save process to complete normally.
Original PR description
Currently, with Indian localization, creating a contact from a CRM lead raises an error. **Steps to Reproduce:** 1) Install CRM,l10n_in (with Demo) 2) Switch to IN Company 3) Navigate to CRM> Click…
Currently, with Indian localization, creating a contact from a CRM lead raises an error. **Steps to Reproduce:** 1) Install CRM,l10n_in (with Demo) 2) Switch to IN Company 3) Navigate to CRM> Click on 'New' 4) For **Contact** value click on 'Search more'>'New'. 'Create contact' wizard will open and set the following values >- Set contact as 'Company' >- Set 'GSTIN' (e.g 22AAFCH6738N1Z8) 5) Click Save Error: `ValueError: Wrong value for l10n_in.pan.entity.type: 'contact'` Root Cause: since [this commit](https://github.com/odoo/odoo/pull/214189/commits/c943637ef4aef740b97abaf1852ceb6fdfcd55bb), the field `l10n_in_pan_entity_id` at [1] was changed from `char` to `Many2one` which depends on the field `type` in the `l10n_in_pan_entity` as shown at [2]. Now following the above steps, the type of the partner is set as 'contact' from [3], which is not available at [2], raising an error. Fix: Updated the context value before creating a record for Pan Entity. [1]- https://github.com/odoo/odoo/blob/b81d119fae5f5194334cee94bacffefeb1cd8c6e/addons/l10n_in/models/res_partner.py#L27-L35 [2]- https://github.com/odoo/odoo/blob/b81d119fae5f5194334cee94bacffefeb1cd8c6e/addons/l10n_in/models/l10n_in_pan_entity.py#L15-L27 [3]- https://github.com/odoo/odoo/blob/b81d119fae5f5194334cee94bacffefeb1cd8c6e/addons/crm/views/crm_lead_views.xml#L454 sentry-6916949666
Fast validation in Point of Sale now keeps the correct order linked to the receipt screen. This prevents empty printed receipts, restaurant printing errors, and unintended new orders in some checkout flows.
Original PR description
Steps to reproduce: - Enable a one-click payment method. - Create and validate an order using fast validation. - On the receipt screen, print the order receipt. Issue: - The printed receipt is empty (no order details). - In restaurant mode, a traceback occurs when printing the receipt. - In retail mode, an unwanted new order is created. Fix: - Prevent the creation of a new floating order during fast order validation. Task-5093060 Related: https://github.com/odoo/enterprise/pull/96695
This fixes a problem that prevented Mexican electronic invoices from being cancelled because the certificate key was sent in a format rejected by providers. Businesses using Mexican localization can now cancel CFDI invoices reliably again.
Original PR description
### Steps to reproduce 1. Install `l10n_mx_edi` with demo data 2. Switch to the ESCUELA KEMPER URGATE demo company 3. Create an invoice to the INMOBILARIA CVA demo partner 4. Send the invoice CFDI 5.…
### Steps to reproduce 1. Install `l10n_mx_edi` with demo data 2. Switch to the ESCUELA KEMPER URGATE demo company 3. Create an invoice to the INMOBILARIA CVA demo partner 4. Send the invoice CFDI 5. Request cancellation of the CFDI 6. The cancellation fails with the error 'invalid passphrase'. ### Analysis When calling `_finkok_cancel`, `_solfact_cancel`, or `_sw_cancel`, one of the API call parameters is the `pem_key` of the certificate given by the SAT. Before 19.0, the PEM key was in an unencrypted format. Since f88f8258ead, `env['certificate.key'].pem_key` is encrypted. According to Finkok's API documentation, the private key should be encrypted using DES when given as a SOAP parameter. https://wiki.finkok.com/home/webservices/ws_cancelacion/cancel However, in testing, encrypting the private key using DES seems to be rejected by Finkok. Solucion Factible and SwSapien don't indicate in their documentation whether and how the private key should be encrypted. ### Solution We send the private key unencrypted, as was already the case before 19.0. opw-5137549
Opening a single bank statement line in reconciliation now behaves more consistently: clearing the filter no longer expands every line, and the statement summary returns as expected. The update also hides an irrelevant statement creation button when only one line is shown and fixes an error when opening the general ledger from this view.
Original PR description
When you open a statement line from a reconciled move, it opens the bank reconciliation widget with only the selected statement line, which is unfolded by default. However, there are a few issues with this behavior, which are fixed in this commit: 1 - When entering the bank reconciliation widget, the initial line is unfolded. If you remove the filter, all the other lines become unfolded as well. This should not be the case; only the original line should remain unfolded. 2 - By default, the statement summary line is hidden. When the filter is removed, the summary remains hidden. We now ensure the summary is displayed again when the filter is cleared. 3 - The Statement button on the statement line (which is meant to create a new statement) doesn't make any sense when there is only one line. It is now hidden in this case. task-5108118 Forward-Port-Of: odoo/enterprise#95558
This fix adds the extra order details some Adyen payment methods need, such as country code and line items. It helps customers complete payments with options like Klarna instead of having transactions fail during processing.
Original PR description
Some payment methods eg. Klarna require 'country code' and 'line items' in order to process the transaction. opw-5077617 Forward-Port-Of: odoo/odoo#230292
This fix prevents Chrome on iOS from automatically changing certain text on Odoo pages in a way that could disrupt the web interface. It helps keep screens rendering correctly for users browsing Odoo from affected Chrome iOS versions.
Original PR description
Chrome iOS wraps some text nodes (like measures, email...) with a `<chrome_annotation>` tag, which breaks OWL rendering. This commit works around it by adding the (undocumented) `<meta name="chrome"…
Chrome iOS wraps some text nodes (like measures, email...) with a `<chrome_annotation>` tag, which breaks OWL rendering. This commit works around it by adding the (undocumented) `<meta name="chrome" content="nointentdetection">` tag to disable this Chrome behavior. The tag has to be set before the onDOMContentLoaded event to be taken into account. Note: Looks like this behavior was present in Chrome iOS 127 and disabled afterward (because it already had issues) but it appeared again in version 140-141. References: - https://issues.chromium.org/issues/353650041 - https://issues.chromium.org/issues/388718411 - https://stackoverflow.com/questions/78207646/how-do-i-disable-chrome-annotation-tags - https://stackoverflow.com/questions/78575970/prevent-auto-detection-of-phone-numbers-in-chrome-mobile - https://stackoverflow.com/questions/78725191/stop-chrome-ios-auto-detecting-numbers-followed-by-letter-m-as-metre-units-an - https://github.com/solidjs/solid/issues/2235 opw-4969197 Forward-Port-Of: odoo/odoo#230081
This fixes an issue that prevented Viva payment webhook verification from finding the correct point-of-sale payment method. Businesses using Viva payments can now verify the webhook successfully and avoid related server errors during setup.
Original PR description
Steps to reproduce:
1. Configure a Viva payment method
2. Copy the webhook URL and attempt to configure it on viva.com
3. Click the 'Verify' button to confirm the webhook is functioning
EXPECTED BEHAVIOUR:
- The webhook verifies successfully
ACTUAL BEHAVIOUR:
- An error message is displayed, and the Odoo server also logs an error
In the commit cc60da3, an optimisation was added to domain searches that subtly changed the behaviour. In particular, in the case where a domain is written like such:
```python
env['pos.payment.method'].search([('company_id.id', '=', company_id)])
```
The `company_id` variable is no longer implicitly converted from `str` to `int`. In the `pos_viva_com` controller, we were relying on this conversion as the parameter is passed to the method as a string.
To fix this, we now explictly cast the variable to `int`.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prFixed an issue where employees could not edit personal information in the salary configurator when the website editing component was not installed. The change restores access to the underlying input fields, ensuring salary package configuration remains usable in affected setups.
Original PR description
Before this commit, when website was not installed (or more precisely html_builder), the salary configurator was not editable anymore due to ::before section that took the whole page. This was due to the changes made in https://github.com/odoo/odoo/pull/229554/. The style rule regarding relative positioned sections was move from html_editor to html_builder as this was a more website specific (or html_builder specific) rule. The fix should then be done in modules that used that rules but that does not depends on html_builder. The commit applies relative position to the personal info section ans force the ::before to let the pointer go through it to access underlying inputs. Task-5154145
This fix ensures recruitment offer simulations use the correct company when calculating available salary benefits. As a result, benefit values are properly updated instead of relying on the default first company.
Original PR description
in this commit, fixes issue when open simulation page
through recruitment offer values of benefits not updated.
issue:
get only default first company while triggering get
white list method.
task-4929771
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-prSalary simulation pages opened from recruitment offers now use the correct company context when loading benefit values. This prevents benefits from being shown with defaults from the wrong company, helping recruiters and candidates see accurate offer details.
Original PR description
in this commit, fixes issue when open simulation page through recruitment offer values of benefits not updated. issue: get only default first company while triggering get white list method. task-4929771
This change prevents certain template attributes from being automatically translated when they are used to pass internal website parameters. It avoids a server error when editing translations on pages such as the online shop, improving reliability for multilingual websites.
Original PR description
Scenario: enable second language on website, go to /shop, edit
translation => error 500 is shown with error:
SyntaxError: invalid syntax (<>, line 1)
Cause: since eb6e88a25050fff2bd09317739dd51ba451450df parameters are set
on the t-call tags, but this can conflict with attribute tag that are
translatable. In the case of /shop, there is:
<t t-call="website_sale.search" placeholder="placeholder"/>
that is transformed to:
<t t-call="website_sale.search"
placeholder="<span data-oe-model=...>placeholder</span>"/>
but this is an invalid value, t-call attribute should only be translated
if they have the suffix .translate and should not be auto-translated.
opw-5121074This fixes an issue where cash basis journal entries could appear without their journal item number after posting an invoice. The change ensures the correct information is saved during numbering, improving accounting list accuracy and reducing confusion during review.
Original PR description
The name field of `account.move` became protected, which prevents the correct computation of the `move_name` field on `account.move.line`. As a result, move_name is not set for cash basis (CABA) journal items. The problem stems from flushing of whole recordset in the `_locked_increment` of sequence_mixin. This **PR** modifies the flush and allows only required fields to be flushed. Steps to reproduce (Runbot, v18): 1. Post an invoice that creates a CABA entry 2. Open the journal items list view 3. Number (move_name) is empty for the CABA-related lines **opw**-4747878
This fix ensures cash basis journal item lines show the correct journal entry name instead of a placeholder slash. It improves accounting list views by keeping related entry names in sync after sequence numbers are assigned.
Original PR description
Backport of #225558 to 18.0. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixed an issue where scanning two GS1 barcodes with the same serial number for different products caused an error and prevented the second item from being added. Inventory counts now correctly distinguish serial numbers by product, reducing scan interruptions and missing count lines.
Original PR description
**PROBLEM** When scanning two gs1 barcode with the same serial number, but for different products there is an error and the 2nd product is not added to the inventory count. **STEP TO REPRODUCE** 1.…
**PROBLEM** When scanning two gs1 barcode with the same serial number, but for different products there is an error and the 2nd product is not added to the inventory count. **STEP TO REPRODUCE** 1. install stock_barcode 2. activate the gs1 barcode and select the default gs1 nomenclature. 3. scan the following barcode - 01000000000001232180085 (product barcode: 0000000000123, serial: 80085). - 01000000000000482180085 (product barcode: 0000000000048, serial: 80085). 4. there is an unexpected error notification, and the 2nd product line isn't added. **CAUSE** In _processBarcode (barcode_model.py), we only check if: - there is already a line with serial tracking with a non-null qty - this line serial number is the same serial number that we are scanning **FIX** We should also verify if the product from the lines we are checking, and the line we want to create are the same. [opw-5076045](https://www.odoo.com/odoo/project/49/tasks/5076045) Forward-Port-Of: odoo/enterprise#96430
This fixes an issue where appointments could fail when booking with staff members who have flexible working hours. Businesses can now use appointment types limited to work hours without blocking valid bookings for flexible-schedule employees.
Original PR description
In the community branch, resource.calendar has a method, _attendance_intervals_batch, that can cause a bug if someone attempts to book an appointment with a staff member that has a flexible schedule. But it is used for many things besides booking appointments, and it works correctly for those other things. So, conditional logic was introduced there with a block you should only enter into if an appointment is currently being booked. To facilitate that, a flag signaling that an appointment is being booked, booking_apt=True, gets passed down through many of the methods that get called in the process of booking an appointment. Solves ticket 5094795
Appointments can now be booked correctly for resources using flexible working hours. The fix prevents valid booking slots from being wrongly rejected, avoiding unexpected 404 errors during online scheduling.
Original PR description
Steps to reproduce: 1. Create a resource with a "Working Time" calendar set with flexible hours 2. Create an appointment with this resource 3. Go to the website and try to book an appointment with…
Steps to reproduce: 1. Create a resource with a "Working Time" calendar set with flexible hours 2. Create an appointment with this resource 3. Go to the website and try to book an appointment with this resource 4. Error 404 not found. When booking appointments with resources that have flexible calendars, the system returns a 404 error during slot validation. The issue occurs in `_check_appointment_is_valid_slot` (appointment controller) which validates that a slot is still available before allowing booking. This validation calls `_unavailable_intervals_batch` (resource.calendar) to check resource availability. For flexible resources, `_unavailable_intervals_batch` generates inverted time intervals (e.g., start=18:30, end=18:00) which causes the overlap check to fail incorrectly, making valid slots appear unavailable. This regression was introduced when the distinction between "fully flexible" (no calendar) and "flexible" (calendar with flexible_hours=True) was added. The check was only applied for fully flexible resources, leaving regular flexible resources broken. Solution: Skip unavailable interval computation for both `_is_fully_flexible()` and `_is_flexible()` resources, since flexible resources by definition have no fixed unavailable periods. opw-5026825 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale now correctly applies quantity-based pricelist rules when the same lot-tracked product is split across multiple lots. This prevents customers from missing eligible discounts simply because inventory was selected from different lots.
Original PR description
**PROBLEM** Pricelist rules based on a minimum quantity does not work well with lot tracked product, when the quantity is splitted between multiples lots. For example, if you take 2 product from lot…
**PROBLEM** Pricelist rules based on a minimum quantity does not work well with lot tracked product, when the quantity is splitted between multiples lots. For example, if you take 2 product from lot A, and 3 product from lot B, a rule defining the price for a minimum quantity of 5 will not trigger (it should). **STEP TO REPRODUCE** 1. install pos 2. create a lot tracked product 3. create a pricelist rule for the product, with a price based on min qty 4. from the pos, order the min qty but split it accross multiple lots 5. price will not takethe rule into account **CAUSE** Order line of lot tracked products are never merged. The quantity used to compute if a pricelist trigger is the quantity of each line individually. **FIX** For lot tracked product, to determine the price of a line, we parse find all corresponding lines and add their quantities together. Then we update all of their prices. To know if we should take into account a line, we verify if they would have been merged, if their product wasn't lot tracked. **REMARK** Ideally, their would be a way to merged order line of lot tracked product, while being able to edit the quantity taken from each lot directly from the pos. From now, order line doesn't work well with multiple lots, and it would require unstable change on the db. opw-4751920 Forward-Port-Of: odoo/odoo#219110
This fixes a validation error that could block confirmation of sales orders for made-to-order manufactured products when mandatory analytic plans are enabled. The system now carries the analytic distribution from the sales order line into the related manufacturing order, preserving required accounting details and allowing the order flow to continue.
Original PR description
## Issue: Confirming a Sale Order for a product with MTO + Manufacturing routes fails (Validation Error) when Analytic Accounting is enabled and an Analytic Plan is mandatory ## Cause: The…
## Issue:
Confirming a Sale Order for a product with MTO + Manufacturing routes fails (Validation Error) when Analytic Accounting is enabled and an Analytic Plan is mandatory
## Cause:
The analytic_distribution is first validated one time for the Sale Order line
When the MO will is created later, the `_compute_analytic_distribution()` function in `mrp_account` is triggered
Since no `account.analytic.distribution.model` is defined, the analytic_distribution field is recomputed as {}
This trigger a second validation, which fails because `{}` is invalid when an analytic plan is mandatory
## Steps to reproduce:
- Enable Analytic Accounting and Multi-Step Routes in Settings
- In Accounting > Configuration > Analytic Accounting > Analytic Plans set Projects as Mandatory
- Unarchive the MTO route
- Create a Product with MTO + Manufacturing routes
- Create a Sale Order for this product and set an Analytic Distribution for Projects
- Confirm the SO to get the Validation Error
opw-4863498