Daily updates from Odoo
Friday, September 26, 2025
38 changes · saas-18.3
Enhancements to existing features
Point of Sale now avoids loading large lists of product option values until they are actually needed. This reduces startup delays for stores with complex product catalogs while keeping product options linked correctly.
Original PR description
Before this commit, when loading PoS, all product template attribute value (ptav) IDs linked to a product attribute were loaded. This caused performance issues when attributes had a large number of values, even though they were not needed at that stage. With this commit, the values are no longer preloaded, since the reverse fields in ptav and ptal are fetched when needed, ensuring they can still be linked correctly without degrading performance. opw-5006818 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225600 Forward-Port-Of: odoo/odoo#224497
Restaurant point-of-sale users can now retry kitchen receipt printing when a printer issue causes a failure. The retry action only sends the receipt to printers that failed previously, avoiding duplicate prints on printers that already succeeded.
Original PR description
Before this commit: = - There was no option to retry printing kitchen receipts if a printer failed. After this commit: = - Users can now manually retry printing kitchen receipts that failed due to printer issues. - The `Retry` button targets only the printers that previously failed, ensuring other successful prints are not repeated. Task: 4717776
This update improves how the web interface reports certain automation errors by including the full error trace when available. This helps support and development teams find the root cause faster, reducing time spent diagnosing vague failure messages.
Original PR description
Because it only embeds the error message, and because it ultimately gets `console.error`-ed, an error during a `run()` function is currently extremely unhelpful e.g.
Cannot read properties of undefined (reading 'ownerDocument')
might be all you get. And despite what one might assume, browsers (or at least chrome) don't seem to chain stacktraces when using `{cause}`, so even printing stacktraces on `console.error` does not yield useful information, the stacktrace point to `performAction` instead of a useful location.
So use the `Error#stack` if it's available. In chrome that includes both the error message and the full stack, so a formatted error message is unnecessary. Fall back on a formatted error message if the error has no stack for some reason.
Forward-Port-Of: odoo/odoo#227169Resolved issues and error corrections
Fixed an issue in Brazilian electronic invoicing where confirming several invoices at the same time could cause the process to fail. This helps accounting teams process batches of invoices more reliably and reduces manual retries.
Original PR description
opw-5107516 Forward-Port-Of: odoo/enterprise#95511
Fixed an issue where membership products could disappear from invoice line search after the product's purchase option was disabled. This keeps membership invoicing workflows consistent and avoids confusion when editing draft invoices.
Original PR description
**Steps to Reproduce:** 1. Create a new membership product from the Membership module. 2. Open any partner and go to the Membership page. 3. Click on Buy Membership and select the created product. 4.…
**Steps to Reproduce:**
1. Create a new membership product from the Membership module.
2. Open any partner and go to the Membership page.
3. Click on Buy Membership and select the created product.
4. Click on Invoice Membership.
5. Open the newly created draft invoice.
6. From the invoice line, open the product form (via the internal link).
7. Disable the Can be Purchased option and return to the invoice using breadcrumbs.
8. Add a new line in the invoice and search for the same product by its name.
**Observation:**
1. When Can be Purchased is enabled on the product, the product appears in the invoice line search.
2. When Can be Purchased is disabled, the product no longer appears in the search.
**Issue:**
In the product field domain defined in
https://github.com/odoo/odoo/blob/9ba5b41ef0252f4421ff6cdcd7c047b7c53706f4/addons/account/views/account_move_views.xml#L1022-L1029 the `default_move_type` context is `null`.
As a result, only the condition `[('purchase_ok', '=', True)]` is applied in the `name_search` domain.
**Solution:**
Pass the proper context value in the invoice action, ensuring the domain evaluates correctly and the product remains searchable.
**Note:**
The domain used in the following field
https://github.com/odoo/odoo/blob/9ba5b41ef0252f4421ff6cdcd7c047b7c53706f4/addons/account/views/account_move_views.xml#L1022-L1029
is evaluated by a following JavaScript function
https://github.com/odoo/odoo/blob/9ba5b41ef0252f4421ff6cdcd7c047b7c53706f4/addons/web/static/src/core/py_js/py_interpreter.js#L483-L489
rather than on the Python backend. Because the domain logic depends on dynamic
context evaluation performed client-side, there is no straightforward way to
retrieve or test the domain arguments dynamically within the `name_search`
method on the server. As a result, it is not feasible to write automated test
cases for this specific domain filtering scenario in the backend.
opw-5028789
Forward-Port-Of: odoo/odoo#225230This fixes paid order search in the Point of Sale so staff only see orders from the current register setup or its trusted related setups. It prevents unrelated paid orders from appearing, reducing confusion and helping teams keep sales data separated correctly.
Original PR description
Before this commit, when searching paid orders in the PoS UI, orders from other configs could appear even if they were not part of the trusted configs or the same PoS config. This commit ensures that only orders related to the current PoS configuration (or its trusted configs) are loaded and displayed. opw-5083747 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227709
Fixes an issue in bank reconciliation where, when several bank lines were reconciled at once, an exchange difference entry could be attached to the wrong line. This helps keep accounting records accurate for multi-line reconciliations involving currency differences.
Original PR description
When selecting multiple lines in the bank rec widget (reconcile button), it could happen that one of those lines have a exchange diff move linked to it. In this case, the exchange move id was placed on the first line all the time which could be wrong. This commit will change the use of indexes to use the reconciled line of the exchange diff move. no task id --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures bank reconciliation assigns exchange difference entries to the correct selected line when multiple lines are reconciled together. It reduces the risk of accounting records being linked to the wrong transaction, improving accuracy in multi-currency reconciliation workflows.
Original PR description
When selecting multiple lines in the bank rec widget (reconcile button), it could happen that one of those lines have a exchange diff move linked to it. In this case, the exchange move id was placed on the first line all the time which could be wrong. This commit will change the use of indexes to use the reconciled line of the exchange diff move. no task id
Barcode receipt users will now see quality checks only for items they have actually picked. This prevents unnecessary or confusing checks from appearing for products with zero processed quantity, making warehouse quality control more accurate.
Original PR description
_______________________________________ ## Short functional explanation of the error On barcode, when an item isn't picked, when clicking on quality checks, the quality check for the unpicked item…
_______________________________________ ## Short functional explanation of the error On barcode, when an item isn't picked, when clicking on quality checks, the quality check for the unpicked item will still show. ## Reproduction Steps 1. Go to Quality and create a Quality point by clicking on Quality Control. Click on new, set a title and put 2 products in the field Product. In operation, select Receipt. 2. Go to Inventory and click Receipts. 3. Click New. Fill the Receive From field, and add 2 products. Set the demand field to 2 for example. 4. Click on Mark as Todo. 6. Go to Barcode. Click on Operations, the Receipts, and click on the latest Receipt you created. 7. For one product, click on the +2 button. For the other one, leave it at 0. Then, click on Quality Check. ### Expected behavior Only the quality check for the item that has been picked should show. ### Unexpected behavior Both quality checks show. ## Origin of the issue The behavior of the code is different when we perform the operations in backend compared to when we perform them in barcode. Indeed, for the regular flow in Inventory, in ```check_quality()```, we also retrieve the checks linked to a move line that hasn't been picked: https://github.com/odoo/enterprise/blob/c09a5cbc2450ec32b0ad3985fa2d4e5e2fcd3d71/quality_control/models/stock_picking.py#L44-L58 Which isn't the intended flow for barcode. Thus, we have to change this behavior and take into account the environment. __ opw-5010764
Users now see a clear “Device disconnected” message when the Belgian POS blackbox device is unplugged or loses connection. This avoids a vague unknown error and helps staff understand and resolve the issue faster.
Original PR description
When the blackbox is being disconnected the user gets "unknown blackbox error" instead of "Device disconnected" explicit message. This PR removes this vague error message introduced in https://github.com/odoo/enterprise/pull/93468 Forward-Port-Of: odoo/enterprise#95489
This fixes an issue where borders added to images in email marketing were missing when recipients viewed the email. Image styling is now preserved more reliably, helping sent emails match the design created by the user.
Original PR description
Problem: When adding a border to an image and sending an email, the border is not visible in the received email. Solution: Ensure a `border-style` is set if missing, otherwise keep the existing one. Steps to reproduce: - Open email marketing. - Add an image snippet. - Add a border to the image. - Send the email. - The received image has no border. opw-5004824 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223867
Preparation ticket printing now handles order notes consistently, even when multiple kitchen printers are configured. This prevents printing failures caused by different note formats, helping restaurant staff receive complete kitchen tickets reliably.
Original PR description
Normalize getStrNotes() to handle multiple note formats (JSON array string, array, plain string) and avoid crashes when printing preparation tickets to multiple printers. Steps to reproduce:…
Normalize getStrNotes() to handle multiple note formats (JSON array string, array, plain string) and avoid crashes when printing preparation tickets to multiple printers.
Steps to reproduce:
-------------------
* Configure two preparation printers for a pos_restaurant with food categorie.
* Create an order with a note in that restaurant.
* Send the order to the kitchen.
> Observation:
The second printer fails to print the ticket with an (uncaught) JSON parse error (Unexpected token), while the first prints correctly.
Why the fix:
------------
`getStrNotes()` assumed notes were always JSON strings like [{"text":"...","colorIndex":0}]. In practice, notes can be plain strings or already-parsed arrays depending on the update path and last printed changes.
The function now:
- returns joined texts for arrays,
- tries to parse JSON strings and joins texts if it’s an array,
- falls back to the raw string if parsing fails. This makes note rendering stable across printers and prevents the error, ensuring tickets are printed consistently.
opw-5029870When no receipt printer is connected, online self-order payments now send orders to the preparation display before opening the browser print dialog. This prevents staff from missing or waiting on paid orders because an unattended print popup blocked the process.
Original PR description
Steps to reproduce: ------------------- 1. Enable self orderdering, and set an online payment method 2. Open 3 tabs: the main PoS one, the self order one, and the preparation display one (we have to…
Steps to reproduce: ------------------- 1. Enable self orderdering, and set an online payment method 2. Open 3 tabs: the main PoS one, the self order one, and the preparation display one (we have to setup the prep display too) 3. In the self order tab, make an order and pay for it Observe that in the main tab, a receipt modal (window.print) appears, and the order is not sent to the payment display (on the third tab) until we either dismiss or accept the printing popup on the main tab. Reason: ------- If there is no printing device connected, we fallback to printing the receipt with `window.print`; this operation blocks the execution of the code that follows it, in our case sending the order to the preparation display, until we either dismiss or confirm the printing popup. Now if the user is not paying attention to the main tab (only looking at the preparation display for instance), the order will not appear in the prep display. Fix: ---- In the case of fallbacking to web printing, we execute the print in a `setTimeout`, so to not block the code that comes after it. opw-5039685
This update prevents two users or sessions from creating separate invoices for the same Point of Sale order at the same time. If invoicing is already underway, the user sees an error, and if an invoice already exists, Odoo opens it instead of creating another one.
Original PR description
This fix prevents multiple users from generating separate invoices for the same POS order simultaneously. Steps to reproduce: 1. Create a new POS order. 2. Open two tabs (or two POS sessions). 3. Generate an invoice in the first tab. 4. Immediately try to generate an invoice in the second tab. 5. Two invoices will be generated. With this fix: - If a user attempts to generate an invoice while another is already in progress, an error message is shown. - If the invoice has already been generated, the existing invoice view is opened instead of creating a duplicate. opw-5004504 Forward-Port-Of: odoo/odoo#223845
Users with view-only access can now mark or unmark documents as favorites using keyboard shortcuts without seeing an access error. This makes the shortcut behavior consistent with the standard favorite button and avoids interruptions for document viewers.
Original PR description
steps to reproduce =================== - Select a document where you have viewer permission. - Try to toggle the favorite through a hotkey. - Access Error when toggling favorite. Technical =========== - To maintain compatibility with stable versions and avoid changing the return type of the existing method, created the helper method, which will call `toggle_favorited` as we need to handle it for multiple records. After this commit ================== - This commit handles the accessError for shortcut flow. As in 18.3 we already have documents_favorite widget https://github.com/odoo/enterprise/pull/82639 which will work for manually favoriting the document, but it is not handling the shortcut flow. Task-4910326 Forward-Port-Of: odoo/enterprise#89928
This fixes an issue in the Timesheet Attendance report query that could cause database errors during upgrades. By correctly identifying the employee field, affected upgrade processes can complete as expected without this report blocking them.
Original PR description
In the affected query, the variable "employee_id" is undefined in the scope where it is used. This leads postgres to interpret it as a variable with default type VARCHAR and to the impossibility to compare it against an integer. We just qualify the variable name so it now works as expected. Failing upgrade requests: [3103245](https://upgrade.odoo.com/odoo/request/3103245) [3121291](https://upgrade.odoo.com/odoo/request/3121291) Fixes https://github.com/odoo/odoo/pull/192434/commits/c97ecfa7fc091f763329af589b69db2292931163 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225401
The self-order mobile test now cancels only orders that are still in draft status. This prevents test failures caused by trying to cancel completed or paid orders, improving reliability without changing customer-facing behavior.
Original PR description
Before this commit: = - Previously, `test_self_order_mobile` set all orders to cancel, causing errors with finalized orders (e.g., paid orders from demo data). After this commit: = - Only draft orders are cancelled, preventing errors and ensuring correct test behavior. Runboat Error: 224197
This fix prevents an earlier manufacturing operation from incorrectly changing to “In progress” after a later backordered operation is completed. It keeps work order statuses accurate, reducing confusion for production teams tracking manufacturing progress.
Original PR description
In this bug, in backorder created for later work opertions, the `state` of initial operation is changed to `progress` after, the backorder is `done`. To produce the bug: 1- Create a Bill of Materials with at least two operations at two work centers 2- Create a manufacturing order and confirm it. 3- Complete the first operation and edit the quantity on the second operation so there is a backorder for the remaining quantity 4- In the second work order, the first operation initially appears as `Cancelled`. Once the second operation is completed, it will change to `In progress`. opw-4931653 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222075
Bill Matching now treats individual contacts and their parent companies consistently when matching purchase orders with vendor bills. This prevents an error that blocked users from matching bills when both documents used the same individual contact linked to a company.
Original PR description
**Issue** When both a Purchase Order and a Vendor Bill are created using the same individual contact linked to a company, Bill Matching fails with a traceback. **Steps to Reproduce** 1. Create an…
**Issue** When both a Purchase Order and a Vendor Bill are created using the same individual contact linked to a company, Bill Matching fails with a traceback. **Steps to Reproduce** 1. Create an individual contact and link it to a company. 2. Create a Purchase Order with the individual as a vendor. 3. Create a Vendor Bill with the same individual as the vendor. 4. Try to perform Bill Matching. 5. A `ValueError: Expected singleton: res.partner(...)` is raised. Video for reference: https://drive.google.com/file/d/1qVnPLpk8jyMTKz-6AVLSaN2nVVeWiF4y/view **Root Cause** Purchase Orders store the partner exactly as selected (the individual contact), while Vendor Bills are normalized internally to the parent company (`commercial_partner_id`). This creates a mismatch in the Bill Matching logic, where records reference both the individual and the company, leading to an invalid recordset and the singleton error. **Fix** Always normalize vendors to their `commercial_partner_id` during Bill Matching. This ensures that both Purchase Orders and Vendor Bills consistently reference the same partner, avoiding mismatches between individual contacts and their parent company. Opw-5050339 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226130
The Belgian EC Sales List XML export now correctly includes the month or quarter when opened from the VAT Return page. This prevents incomplete XML files and helps businesses submit compliant tax reports without manually reselecting the period.
Original PR description
**Issue** When accessing the EC Sales List report via the smart button from the VAT Return page, downloading the XML without explicitly selecting a period omits the <Month> element—even though a…
**Issue** When accessing the EC Sales List report via the smart button from the VAT Return page, downloading the XML without explicitly selecting a period omits the <Month> element—even though a month is visibly preselected. **Steps to Reproduce** 1. Install the Accounting module and Belgium localization. 2. Go to the Accounting dashboard. 3. Open the VAT Return via the "Miscellaneous Operations" section. 4. Click the smart button to access the EC Sales List report. 5. Use the gear icon to export the XML. 6. Observe that the XML <Period> section only includes the <Year>—the <Month> is missing. **Root Cause** If no period is explicitly selected, the report uses a period_type of "tax_period". However, this value was not handled when generating the XML, so the logic to include the \<Month> or \<Quarter> elements skipped it. As a result, only the \<Year>, which is always included, was rendered. **Fix** Extend the handling of tax_period to derive the period from the company’s tax periodicity settings and adjust the filter accordingly. This ensures that the generated XML always includes the \<Month> or \<Quarter> element, in addition to \<Year>, whenever the report is based on a tax period. Opw-4702613 Forward-Port-Of: odoo/enterprise#89290
The website SEO dialog now ignores dynamic template images that users cannot edit. This prevents broken image icons from appearing in the image optimization area on pages such as appointments and courses, making SEO guidance clearer and less confusing.
Original PR description
**Issue:** In the SEO dialog, under the `Images Optimization` section, broken images are displayed due to the inclusion of non-editable dynamic template images. This issue has been observed on the appointment and course pages. **Steps to reproduce:** 1. Go to the `Appointment` page on the website. 2. Go to `Site` settings present in the header > `Optimize SEO`. 3. Notice under the `Images Optimization` section, the broken image icon. See [screencast](https://drive.google.com/file/d/1EZTF2FY1ljj6S2PLwwt42Vht1IdVC3aK/view) Exclude non-editable dynamic template images from the SEO dialog's `Images Optimization` section. Users cannot modify their `alt` attributes, so including them serves no purpose.
Dark mode display issues were fixed in Point of Sale and Appointments so icons and text remain easy to see. This improves readability and consistency for users working with darker interface settings.
Original PR description
In this commit: ------------------- - Added a dark mode color for the star icon. - Changed the text color to white in light mode, which is reflected as black in dark mode. This fixes the issue of the text not being properly visible in dark mode. task:4943078
New users can now load demo data in the Attendance app without running into a permissions error. This makes onboarding and testing smoother for teams setting up Attendance for the first time.
Original PR description
Currently, an error occurs when a new user tries to load demo data in the ``Attendance`` module. Steps to reproduce: --- - Install ``hr_attendance`` module (without demo data) - Create NEW user >…
Currently, an error occurs when a new user tries to load demo data in the ``Attendance`` module.
Steps to reproduce:
---
- Install ``hr_attendance`` module (without demo data)
- Create NEW user > Login with new user
- Open ``Attendance`` and Click ``Load Demo Data``
Traceback:
---
```
AccessError
You are not allowed to create 'Resource Working Time' (resource.calendar) records.
This operation is allowed for the following groups:
- Administration/Settings
Contact your administrator to request access if necessary.
ParseError
while parsing /home/odoo/src/odoo/saas-18.1/addons/hr_attendance/data/scenarios/hr_attendance_scenario.xml:5, somewhere inside <record id="resource_calendar_std_38h" model="resource.calendar" forcecreate="1">
<field name="name">Standard 32 hours/week (4 work days, friday free)</field>
<field name="company_id" eval="False"/>
<field name="hours_per_day">8</field>
<field name="attendance_ids" eval="[(5, 0, 0), (0, 0, {'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}), (0, 0, {'name': 'Monday Lunch', 'dayofweek': '0', 'hour_from': 12, 'hour_to': 13, 'day_period': 'lunch'}), (0, 0, {'name': 'Monday Afternoon', 'dayofweek': '0', 'hour_from': 13, 'hour_to': 17, 'day_period': 'afternoon'}), (0, 0, {'name': 'Tuesday Morning', 'dayofweek': '1', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}), (0, 0, {'name': 'Tu...
ValueError
ParseError('while parsing /home/odoo/src/odoo/saas-18.1/addons/hr_attendance/data/scenarios/hr_attendance_scenario.xml:5, somewhere inside\n<record id="resource_calendar_std_38h" model="resource.calendar" forcecreate="1">\n <field name="name">Standard 32 hours/week (4 work days, friday free)</field>\n <field name="company_id" eval="False"/>\n <field name="hours_per_day">8</field>\n <field name="attendance_ids" eval="[(5, 0, 0), (0, 0, {\'name\': \'Monday Morning\', \'dayofweek\': \'0\', \'hour_from\': 8, \'hour_to\': 12, \'day_period\': \'morning\'}), (0, 0, {\'name\': \'Monday Lunch\', \'dayofweek\': \'0\', \'hour_from\': 12, \'hour_to\': 13, \'day_period\': \'lunch\'}), (0, 0, {\'name\': \'Monday Afternoon\', \'dayofweek\': \'0\', \'hour_from\': 13, \'hour_to\': 17, \'day_period\': \'afternoon\'}), (0, 0, {\'name\': \'Tuesday Morning\', \'dayofweek\': \'1\', \'hour_from\': 8, \'hour...
```
This error occurs because the new user has not been granted administrative rights.
This commit resolves the issue by granting the user superuser rights.
sentry-6110523247
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#195714This fixes an issue that prevented newly created users from loading sample data in the Appraisal app. The change ensures the demo data setup runs with the needed permissions, so users can explore the app without encountering an error.
Original PR description
Currently, an error occurs when a new user tries to load demo data in the `Appraisal` module. Steps to reproduce: --- - Install `hr_appraisal` module (without demo data) - Create NEW user > Login…
Currently, an error occurs when a new user tries to load demo data in the `Appraisal` module.
Steps to reproduce:
---
- Install `hr_appraisal` module (without demo data)
- Create NEW user > Login with new user
- Open `Appraisal` and Click `Load Demo Data`
Traceback:
---
```py
ParseError: <record id="calendar_event_appraisal_1" model="calendar.event" forcecreate="1">
<field name="user_id" ref="base.user_admin"/>
<field name="name">Appraisal of Emma Granger</field>
<field name="partner_ids" eval="[(6,0,[ref('hr.work_contact_sj'), ref('hr.work_contact_mw'), ref('hr.work_contact_eg')])]"/>
<field name="start" eval="(DateTime.now() + relativedelta(months=1)).strftime('%Y-%m-%d 07:00:00')"/>
<field name="stop" eval="(DateTime.now() + relativedelta(months=1)).strftime('%Y-%m-%d 09:00:00')"/>
<field name="res_model_id" ref="hr_appraisal.model_hr_appraisal"/>
<field name="res_model">hr.appraisal</field>
<field name="res_id" ref="hr_appraisal.hr_appraisal_1"/>
</record>
ValueError: ParseError('while parsing /home/odoo/odoo/enterprise/hr_appraisal/data/scenarios/hr_appraisal_scenario.xml:561, somewhere inside\n<record id="calendar_event_appraisal_1" model="calendar.event" forcecreate="1">\n <field name="user_id" ref="base.user_admin"/>\n <field name="name">Appraisal of Emma Granger</field>\n <field name="partner_ids" eval="[(6,0,[ref(\'hr.work_contact_sj\'), ref(\'hr.work_contact_mw\'), ref(\'hr.work_contact_eg\')])]"/>\n <field name="start" eval="(DateTime.now() + relativedelta(months=1)).strftime(\'%Y-%m-%d 07:00:00\')"/>\n <field name="stop" eval="(DateTime.now() + relativedelta(months=1)).strftime(\'%Y-%m-%d 09:00:00\')"/>\n <field name="res_model_id" ref="hr_appraisal.model_hr_appraisal"/>\n <field name="res_model">hr.appraisal</field>\n <field name="res_id" ref="hr_appraisal.hr_appraisal_1"/>\n </record>') while evaluating
'action = model._load_demo_data()'
```
This error occurs because the new user has not been granted administrative rights.
This commit resolves the issue by granting the user superuser rights.
sentry-6110523247
Forward-Port-Of: odoo/enterprise#93461Scanning a package in the Barcode app now correctly converts quantities when the package and delivery line use different units of measure. This prevents under-recording delivered quantities, such as treating 10 kg as 10 g instead of 10,000 g.
Original PR description
Manual forward port of https://github.com/odoo/enterprise/pull/90878 **Problem:** When scanning a package with a different UoM than the barcode line, the conversion is not made. **Steps to…
Manual forward port of https://github.com/odoo/enterprise/pull/90878 **Problem:** When scanning a package with a different UoM than the barcode line, the conversion is not made. **Steps to reproduce:** - Enable the "Packages" setting; - Create a new storable product and set kg as its UoM; - In the inventory tab, add "g" in the packagings - Click on the on hand smart button and select update quantity - Add a new line; - In the package column create a new package; - Set a quantity of 10 kg; - Create a delivery and select your product; - Set a demand on 10000 and select g as the UoM; - Mark as todo; - Open the delivery in the Barcode app; - Scan the package. **Current behavior:** The quantity on the line is now 10 / 10000 g **Expected behavior:** It should be 10000 / 10000 g **Cause of the issue:** https://github.com/odoo/enterprise/blob/4c9fa9dc010958710d848fbcb3241b17ea7205ca/stock_barcode/static/src/models/barcode_picking_model.js#L1500-L1505 remaining_qty is expressed in the uom of the quant so it will be 10 but qty_needed is expressed in the uom of the line is it will be 10000. qty_used beeing the minimum of those two it will be 10. **Fix:** To define how much quantity to take from the package, we convert the line's quantity by using the package's UoM. Then, when we add this quantity to the line's quantity, we re-convert it by using the line's UoM. opw-4860064
Fixes an accounting display issue where cash basis journal item lines could show '/' instead of the actual posted journal entry name. This helps accountants see accurate journal entry references in transaction lists after payment-based tax entries are created.
Original PR description
### Issue: In the list view of Journal Items, cash basis lines show a `move_name` of '/' event if the move is posted and has a name. ### Steps to reproduce: - Activate Cash Basis in the accounting…
### Issue: In the list view of Journal Items, cash basis lines show a `move_name` of '/' event if the move is posted and has a name. ### Steps to reproduce: - Activate Cash Basis in the accounting settings - Create a tax with "Tax Exigibility" set "Based on Payment" - Set the "Cash Basis Transition Account" to "Current Assets" - Activate reconciliation on "Current Assets" - Create an invoice with this tax, confirm - In the dashboard, click on Bank and new - Set the name of the invoice as the label, and the amount of the invoice as amount - Save & Close - Go in Accounting > Transactions > Journal Items - The lines created for the cah basis entry display '/' in the column "Journal Entry" ### Cause: This issue is linked to the order in which things are done in `_set_next_sequence`: the fields triggered by the sequence field are added in `self.env.transaction.tocompute` then the sequence is computed and assigned. When `_set_next_sequence()` is called from [`_create_tax_cash_basis_moves()`](https://github.com/odoo/odoo/blob/849e4a87178d8c8588b75e3f7d9073d6a78326f9/addons/account/models/account_partial_reconcile.py#L649-L654) this order is problematic as `account.move.line.move_name` will be computed and removed from `self.env.transaction.tocompute`. So it will not be updated when the sequence is assigned in `account.move.name`. The callstack is something like this: - `_set_next_sequence()` calls `_locked_increment()` to compute the sequence - `_locked_increment()` calls `flush_recordset()` which will call `_recompute_recordset()` to recompute all fields - `_compute_invoice_date_due()` needs the field `needed_terms` triggering `_compute_needed_terms()` - `_compute_needed_terms()` needs `invoice_line_ids` - the fetch on `account.move.line` is ordered by `move_name` - So `_compute_related()` is triggered for `move_name` and `account.move.line.move_name` is removed from `self.env.transaction.tocompute` Then `_locked_increment()` returns the sequence, it gets assigned as the move name and `move_name` is never updated because it's not in `self.env.transaction.tocompute`. This doesn't occur in other flows (like calling `action_post()`) because the value of `needed_terms` is read from the cache. ### Solution: Swap the order in which things are done in `_set_next_sequence()`: first compute and assign the sequence and then add the triggered fields in `self.env.transaction.tocompute` so that they are computed afterwards. It seems more logic that way: we change the `_sequence_field` then mark all fields that will be impacted in `tocompute`. opw-5056938
This fix ensures cash basis journal item lines show the proper journal entry name instead of a placeholder slash. It protects accounting users from confusing entries in journal item lists and adds test coverage to prevent the issue from returning.
Original PR description
This commit adds a test for the [change made in community](https://github.com/odoo/odoo/pull/225558). ### Issue: In the list view of Journal Items, cash basis lines show a `move_name` of '/' event if…
This commit adds a test for the [change made in community](https://github.com/odoo/odoo/pull/225558). ### Issue: In the list view of Journal Items, cash basis lines show a `move_name` of '/' event if the move is posted and has a name. ### Steps to reproduce: - Activate Cash Basis in the accounting settings - Create a tax with "Tax Exigibility" set "Based on Payment" - Set the "Cash Basis Transition Account" to "Current Assets" - Activate reconciliation on "Current Assets" - Create an invoice with this tax, confirm - In the dashboard, click on Bank and new - Set the name of the invoice as the label, and the amount of the invoice as amount - Save & Close - Go in Accounting > Transactions > Journal Items - The lines created for the cah basis entry display '/' in the column "Journal Entry" ### Cause: This issue is linked to the order in which things are done in `_set_next_sequence`: the fields triggered by the sequence field are added in `self.env.transaction.tocompute` then the sequence is computed and assigned. When `_set_next_sequence()` is called from [`_create_tax_cash_basis_moves()`](https://github.com/odoo/odoo/blob/849e4a87178d8c8588b75e3f7d9073d6a78326f9/addons/account/models/account_partial_reconcile.py#L649-L654) this order is problematic as `account.move.line.move_name` will be computed and removed from `self.env.transaction.tocompute`. So it will not be updated when the sequence is assigned in `account.move.name`. The callstack is something like this: - `_set_next_sequence()` calls `_locked_increment()` to compute the sequence - `_locked_increment()` calls `flush_recordset()` which will call `_recompute_recordset()` to recompute all fields - `_compute_invoice_date_due()` needs the field `needed_terms` triggering `_compute_needed_terms()` - `_compute_needed_terms()` needs `invoice_line_ids` - the fetch on `account.move.line` is ordered by `move_name` - So `_compute_related()` is triggered for `move_name` and `account.move.line.move_name` is removed from `self.env.transaction.tocompute` Then `_locked_increment()` returns the sequence, it gets assigned as the move name and `move_name` is never updated because it's not in `self.env.transaction.tocompute`. This doesn't occur in other flows (like calling `action_post()`) because the value of `needed_terms` is read from the cache. ### Solution: Swap the order in which things are done in `_set_next_sequence()`: first compute and assign the sequence and then add the triggered fields in `self.env.transaction.tocompute` so that they are computed afterwards. It seems more logic that way: we change the `_sequence_field` then mark all fields that will be impacted in `tocompute`. opw-5056938
UAE invoice reports no longer show the same amount information twice when tax-included pricing is enabled. This keeps printed proforma and tax invoices clearer and avoids confusion for customers and accounting users.
Original PR description
**Step to reproduce:** - install account module with localization "UAE" - go to Settings > Tax Included - create a invoice (make sure a tax is applied) - print any invoice (Proforma or Tax)…
**Step to reproduce:**
- install account module with localization "UAE"
- go to Settings > Tax Included
- create a invoice (make sure a tax is applied)
- print any invoice (Proforma or Tax)
**Observation:**
- the amount is being displayed twice in the Amount column.
**Cause:**
- A change was introduced in 18.0 to add additional column right after Amount
column, [1] in l10n_ae module
- Another commit [2] in saas-18.3 introduces same column in main account module
- hence we have two columns printing same information
**Fix:**
- Removed and fixed a faulty xpath from view, as after commit [2]
base layout provides same logic
[1] https://github.com/odoo/odoo/commit/fe68fa30b18f90411043fc6e2314fd376ddaed0c
[2] https://github.com/odoo/odoo/commit/1bf232c22f430d282aaadd858c5e61fed12f4da6
**Before:**
<img width="774" height="146" alt="image" src="https://github.com/user-attachments/assets/a9eb6af2-81b3-4989-bf6e-6676eafe10f8" />
**After:**
<img width="813" height="143" alt="image" src="https://github.com/user-attachments/assets/fb019516-de7d-4dd3-b7dd-3fd14322b031" />
opw-4976410
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThe Time Off calendar now shows the selected employee’s own working schedule instead of the schedule of the person viewing it. This prevents confusion when managers review employees with different days off or working patterns.
Original PR description
Steps to reproduce: - In the Employee app, select an employee with a different working schedule than yours - Click on the "Time Off" smartbutton - Switch from Kanban to Calendar view - The displayed working schedule is yours and not the employee's (easier to see if you and the employee have different days off) Reason: The employee_id field in the context used by the Python method was null instead of an ID, which caused the Python method to default to not use the employee's working schedule but the working schedule of the user viewing it. How it was fixed: By using a different field already present in the context, the employee's ID is correctly retrieved and used to display the calendar. Task ID: 4987732
Orders placed through self-order or kiosk flows with online payment now appear on the preparation display only after the payment is confirmed. This prevents staff from preparing unpaid orders while still ensuring paid orders reach the preparation display, including when customers leave through an alternate payment portal route.
Original PR description
pos_*= pos_online_payment_self_order_preparation_display, pos_self_order_iot Before this commit, if an online payment method was assigned to a self or a kiosk, the order was displayed on the preparation display before the payment was confirmed. After this commit, the order is no longer displayed on the preparation display until the payment confirmation. Community PR: https://github.com/odoo/enterprise/pull/87173 Backport of https://github.com/odoo/odoo/pull/87173, with additional logic to ensure the order is correctly sent to the preparation display even if an exit route is used in the payment portal Forward-Port-Of: odoo/enterprise#95312
Orders placed through self-order or kiosk flows with online payment are now held back from the preparation display until payment is confirmed. This prevents staff from preparing unpaid orders while still ensuring confirmed orders reach the kitchen display, including when customers exit through the payment portal.
Original PR description
pos_*= pos_online_payment, pos_online_payment_self_order, pos_self_order Before this commit, if an online payment method was assigned to a self or a kiosk, the order was displayed on the preparation display before the payment was confirmed. After this commit, the order is no longer displayed on the preparation display until the payment confirmation. Enterprise PR: https://github.com/odoo/enterprise/pull/95312 Backport of https://github.com/odoo/odoo/pull/213493, with additional logic to ensure the order is correctly sent to the preparation display even if an exit route is used in the payment portal --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228189
The AI field picker now prevents the same field from being selected multiple times and clearly marks fields that are already selected. Long field paths also wrap correctly, making them easier to remove and improving day-to-day usability.
Original PR description
before this commit: When you press Enter in the field picker, it will always pick the same field again, even if it is not visible. After this commit: A field can only be selected once, and it stays visible in the list. Added a visual check to show that the field is already selected.
Online shop stock availability now accounts for kit products already in the cart when they share components with other products. This prevents customers from seeing outdated available quantities or attempting to buy unavailable stock after adding either a kit or its component to the cart.
Original PR description
### Steps to reproduce: - In the settings website > Shop: - Disable `Out-of-Stock: Continue Selling`. - Enable `Show Available Qty` if below 5 units. - Create 2 storable products published on the…
### Steps to reproduce:
- In the settings website > Shop:
- Disable `Out-of-Stock: Continue Selling`.
- Enable `Show Available Qty` if below 5 units.
- Create 2 storable products published on the website:
- COMP, put 1 unit in stock.
- KIT with bom of type Kit using 1 x COMP.
- With a private window go to the shop.
- Add 1 x COMP or KIT to the chart.
#### > This is not reflected on the available quantity in stock of the other product
### Cause of the issue:
The availability on the website is computed from the product availability using the `free_qty` fetched because of this override: https://github.com/odoo/odoo/blob/d358542c9159f325b4e2ff184ed1f5cdb6b8c5a9/addons/website_sale_stock/controllers/variant.py#L10-L13 from which the cart quantity of the product itself is deduced before re-render:
https://github.com/odoo/odoo/blob/d358542c9159f325b4e2ff184ed1f5cdb6b8c5a9/addons/website_sale_stock/static/src/js/variant_mixin.js#L49-L51 https://github.com/odoo/odoo/blob/d358542c9159f325b4e2ff184ed1f5cdb6b8c5a9/addons/website_sale_stock/static/src/js/variant_mixin.js#L83-L86 While the `free_qty` is correctly computed from kit products based on the component availability:
https://github.com/odoo/odoo/blob/d358542c9159f325b4e2ff184ed1f5cdb6b8c5a9/addons/mrp/models/product.py#L211-L221 The qties in the virtual cart quantities are not recomputed base on kits.
opw-4889956
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#228537
Forward-Port-Of: odoo/odoo#222945This fix ensures the latest restaurant point-of-sale order changes are saved before sending them to the kitchen printer or preparation display. It prevents outdated-order errors when staff add items, leave a table, and later return to send the updated order.
Original PR description
Before this commit, if an order had no changes and no preparation display was active, adding items to the order in the restaurant PoS and then returning to the tables would sync the order to the server and mark it as not dirty. As a result, reopening the order and clicking the order button to send it to the preparation display or printer would not sync the updated changes. This caused inconsistencies and errors. Steps to reproduce: 1. Open a table, place an order, and send it to the kitchen printer 2. Add more products but instead of placing the order, go back 3. Re-enter the table, place the order, and send it 4. When placing another order, the error "Order Outdated" appears This commit fixes the syncing logic to ensure that last changes are properly synced, avoiding the "Order Outdated" error. opw-5097566 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227824
Project users can no longer create new task stages from the task list when they do not have the required permissions. This keeps project workflow setup controlled by the right roles and prevents accidental or unauthorized changes to task stages.
Original PR description
Steps to reproduce: - Go to a project - Open the task list view - Select a task - In the `Stage` field, attempt to create a new stage Issue: - Project users were able to create new task stages from…
Steps to reproduce: - Go to a project - Open the task list view - Select a task - In the `Stage` field, attempt to create a new stage Issue: - Project users were able to create new task stages from the task list view, despite not having the required permissions. Cause: - The `_default_user_id` method assigns the current user as the owner `user_id` of a new stage only when `default_project_id` is not present in the context. As a result, the method returned the current user’s ID, unintentionally making them the owner of the stage. This allowed project users to bypass the intended access rules and create new stages. Solution: - Use the `no_create` option for users outside the project manager group to prevent them from creating new stages. - Updated the `stage_id` field in the task list view to explicitly include `default_project_id` in the context, ensuring proper access control of that stage. task-4628666 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228627 Forward-Port-Of: odoo/odoo#206407
Rating forms no longer show stray “by” or “on” text when publisher comments or related details are missing. This keeps rating records cleaner and avoids confusing users after comments are removed.
Original PR description
Steps to Reproduce: 1. Navigate to a rating record form view 2. View ratings without publisher comments 3. Notice confusing 'by on' text fragments appearing Current Behavior: - 'by on' text shows even when there's no comment or publisher information - Text fragments remain visible after comments are removed Expected Behavior: - 'by' and 'on' text should only appear when there's actual content to display - Proper conditional visibility based on comment presence Changes Made: - Added conditional visibility to rating form view text elements - Improved XML structure for better maintainability - Fixed persistent text display issues when comments are removed --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Changing a blog tag color now correctly updates existing blog posts that use that tag. This ensures visitors see the latest tag styling on blog pages without waiting for old cached content to refresh.
Original PR description
Steps to reproduce: - Go to the /blog page - See that some posts use some tags - Go to Configuration > Tags - Change the color of an existing tag - Go back to the /blog page => The color of the tag is not updated for existing posts using it. This is a t-cache issue, which unfortunately is difficult to fix in stable (as it would require modifying multiple nodes in qweb). As a workaround, and knowing that the t-cache system was fully removed in 19.0 at [1], this fixes the bug with a hack: on tag update, make a dummy update to the related blog posts already using it. Tag updates should be quite rare anyway. [1]: https://github.com/odoo/odoo/commit/1cf06a5688e6aa80175d5a28a83b639d0eb925a7 task-4045724 Forward-Port-Of: odoo/odoo#228428
Documentation and clarification updates
This update adds new members to the Adhoc corporate Contributor License Agreement record. It keeps Odoo's contribution and legal documentation current so accepted contributions remain properly covered.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228593 Forward-Port-Of: odoo/odoo#226715