Skip to content

viindoo#65

Open
odoochain wants to merge 176 commits into
odoochain:19.0from
Viindoo:19.0
Open

viindoo#65
odoochain wants to merge 176 commits into
odoochain:19.0from
Viindoo:19.0

Conversation

@odoochain

Copy link
Copy Markdown
Owner

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

davidtranhp and others added 24 commits April 15, 2026 19:35
* [I18N] account*: fix i18n

Forward-Port-Of: #1196

* Update vi.po

---------

Co-authored-by: quyen <[email protected]>
Co-authored-by: Roy Le <[email protected]>
…260512_01

Merge from upstream 19 20260512 01
…260519_01

Merge from upstream 19 20260519 01
Currently, error occurs when user removes date on Accrued Expense Entry wizard.

Steps to replicate:
- Install `purchase` and `accountant` with demo.
- Open any Purchase Order > Click on cog menu > Accrued Expense Entry.
- Remove value from `date` and click else where.

Error:
```
  File '/home/odoo/odoo19/community/addons/account/wizard/accrued_orders.py', line 67, in _compute_reversal_date
    if not record.reversal_date or record.reversal_date <= record.date:
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<=' not supported between instances of 'datetime.date' and 'bool'

```

Cause:
- As the user removed value from `date`, [here] `record.date` is received as
  False.
- As a result the comparison `record.reversal_date <= record.date` causes this
  error to occur.

Solution:
- Added a conditional check for `date` before the date comparison.

[here]: https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/account/wizard/accrued_orders.py#L67

No ID

closes odoo#265997

X-original-commit: 9a17bf1
Signed-off-by: Julien Alardot (jual) <[email protected]>
Signed-off-by: Bhavya Ashesh Nanavati (bhna) <[email protected]>
…te and checkmark

In this commit :
- Show "Processing..." text while payment finalization is running
- Show animated success checkmark and "Amount Paid" once processing completes
- Remove warning notification when clicking during processing
- Extract shared checkmark animation into reusable template
- Update tour tests to verify the success state

Task:6246377

closes odoo#267635

Signed-off-by: David Monnom (moda) <[email protected]>
When a calendar event has multiple attendees, `_get_contact_details_description` picks the first non-organizer partner from a set-based recordset to render under "Contact Details" in the event description. The recordset is built from `partner_ids_from_attendees`, a set whose iteration order depends on Python's hash seed, so the displayed contact is effectively random and not controllable from the UI.

Restrict the "Contact Details" block in `_get_contact_details_description` to events with exactly one non-organizer attendee (1-on-1 meetings). For group meetings the block is omitted entirely, since any single attendee picked from a larger group is arbitrary by construction.

Steps to reproduce:
1. Go to Calendar > New
2. Add 3+ attendees (e.g. Alice, Bob, Charlie)
3. Save the event
4. Check the Notes tab in the event form

=> One random attendee's contact info appears under "Contact Details"

opw-6035192

closes odoo#258901

Signed-off-by: Thibault Delavallee (tde) <[email protected]>
**Step to reproduce**
Reproducible in single app

The "name" field make this assertion fails:
```
self.assertRecordValues(sale_order.order_line[0], [{
            "product_id": no_variant_product_tmpl.product_variant_id.id,
            "name": 'No Variant\nAttribute: Value 1',
```
**Observation**
The name will not be the same depending which app are installed, purchase_product_matrix, changes the name of the product if there is a attribute value of a never variant:
https://github.com/odoo/odoo/blob/f399f99d4e0e562d25e1de32336e8d6a55199b9b/addons/purchase_product_matrix/models/purchase.py#L168-L174
Which will be passed to the purchase_order_line:
https://github.com/odoo/odoo/blob/f399f99d4e0e562d25e1de32336e8d6a55199b9b/addons/purchase/models/purchase_order_line.py#L630-L634
that will pass the information to the sale order:
https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/sale_purchase_inter_company_rules/models/purchase_order.py#L114
https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/sale_purchase_inter_company_rules/models/purchase_order.py#L125-L126

**Additional information**
Since this [commit](odoo@b8ebb26#diff-5684edced9bdfc98021a85de4c6cdf691ea7add74e56ab50334a1d7db9ef4224R90) product_no_variant_attribute_value_ids was directly added in the purchase module.

breaking commit : odoo/enterprise@bf286a0
runbot-242362

closes odoo#268016

Signed-off-by: Steve Van Essche <[email protected]>
Steps to reproduce:
- In the settings enable: Multi-Steps Routes
-  Set your warehouse to manufacture in 2 steps (pick then manufacture).
- Create a final product (FP) with a BOM in flexible consumption:
  - 2 x COMP (lot tracked)
- Put a lot for 6 units in of COMP in stock
- Create and confirm an MO for 5 units of FP
- Set the quantity producing on the MO to 1, requiring 2 of the 6
  available units of COMP
- Validate the MO and create a backorder for the remaining quantity.
> The consumed qty on the main MO is of 0 units rather than 2.

Cause of the issue:

Since the component is tracked, and since the pbm move was backordered,
the move quantity will not be automatically set when setting the
`qty_producing`:
https://github.com/odoo/odoo/blob/a1bcd917846493d08dd02b63e6110078ff5156a3/addons/mrp/models/mrp_production.py#L1405-L1411
And in particular, the move is not picked as it would if the product was
untracked or if the pbm move was not backordered:
https://github.com/odoo/odoo/blob/a1bcd917846493d08dd02b63e6110078ff5156a3/addons/mrp/models/mrp_production.py#L1421-L1427
And, since the move will not be picked at any other point in this flow,
the move will be unreserved during the `button_mark_done`:
https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L2216
https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L1895-L1896
https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L1901

opw-6128575

closes odoo#269235

Signed-off-by: William Henrotin (whe) <[email protected]>
…ition & pricelist

Self-order showed one price on product cards / product page and another
after adding to the order, when a preset fiscal position (e.g. take-out)
changed taxes. The UI used template-only pricing and sometimes skipped
fiscal position on tax computation.

Steps to reproduce:
-------------------
* Create a fiscal Position (e.g. takeout)
* Create a Taxe for that Fiscal Positions replacing the default Taxe (e.g. 0%)
* Create a pricelist with a formula increasing the price
    by the same % as default Taxe (e.g. 15%)
* Enable Self-Ordering for a Restaurant
* In the takeout Presets, set our Pricelist and Fiscal Positions
* Open the Mobile Menu of the Restaurant and add a product that has variants (e.g Pizza VG)
> Observation:
Price on product selection is different from price in cart

Why the fix:
------------
We now make self-order use the same rules as an actual order:
default variant for template-only display, pricelist from pos.order first
(what setPreset and the session already maintain), fiscal position from the order
or the preset everywhere taxes are derived, and correct tax inputs on the product page
(price, pricelist, fiscalPosition, variant).
Order line tax preparation now uses that same order-or-preset fiscal position, so remapped taxes
apply to lines the same way they apply to the prices shown while browsing.

opw-6120097

closes odoo#261535

Signed-off-by: Stéphane Vanmeerhaeghe (stva) <[email protected]>
* Open a new record form (the `onchange` RPC is cached).
* Open a second new record form (it uses the cached `onchange` RPC).
* Save the record before the `onchange` RPC returns.

Before this commit, a race condition caused an error to be raised. When
`web_save` is executed, it updates the record configuration with the new
`resId` without reloading the view. When the pending `onchange` RPC finally
returns, the cache callback misinterprets the data as a `web_read` result
instead of an `onchange` result due to the updated ID, triggering a crash.

Now, the callback safely does nothing if the resId has changed since
the request was sent.

runbot-243200

closes odoo#269394

X-original-commit: 61e8c42
Signed-off-by: Aaron Bohy (aab) <[email protected]>
Issue
When setting the partial deductibility percentage to 99%
on a vendor bill line, the system incorrectly treats it
as 100% deductible and completely ignores the
non-deductible part

Additionally, changing the deductibility percentage on a
line with taxes does not trigger an update of the
non-deductible tax journal items, leaving the private
part taxes unchanged

Cause
In the tax recomputation mechanism, `float_compare`
was wrongly configured with `precision_rounding=2`
instead of `precision_digits=2` when checking the
`deductible_amount` field

This rounding error caused 99.00 to be evaluated as
equal to 100.00, skipping the creation of the
non-deductible line

Furthermore, `_sync_tax_lines` relies on
`get_base_line_tracked_fields` to detect modifications
that require a tax recalculation

This tracked field list only included price, quantity,
and discount. Modifying the deductibility percentage
did not trigger any sync, preventing the non-deductible
tax lines from adjusting

Fix
To fix the synchronization, `deductible_amount` is added
to the tracked fields for invoices. This straightforward
approach is preferred here for simplicity
However, a more restrictive condition may be needed for
example only check it on lines with taxes

Steps to reproduce
- Install `account`
- Create a Vendor Bill  (Price: 1000$, Taxes: 15%, Professional %: 50)
- Check the Journal Items tab to see the Private Part line at 500$ debit and Private Part (taxes) line at 75$ debit
- Change the Professional % field on the invoice line to 75
Before the fix, the Private Part (taxes) line remains at 75$ debit
- Change the Professional % field on the invoice line to 99
Before the fix, the private part lines completely disappear instead of adapting to 1%

opw-6245909

closes odoo#269385

X-original-commit: 1769341
Signed-off-by: Olivier Colson (oco) <[email protected]>
Signed-off-by: Corentin Heinix (cohe) <[email protected]>
After Unicode slug support was introduced in odoo@926e45a, `/`
characters started being silently removed instead of treated as
slug boundaries.

As a result:
    "foo/bar" -> "foobar"

while it should instead generate:
    "foo/bar" -> "foo-bar"

This restores the previous behavior by treating each non word character
as separators normalized to `-`.

task-6219984

closes odoo#269371

X-original-commit: 60eed35
Signed-off-by: Francois Georis (fge) <[email protected]>
Signed-off-by: Julien Castiaux (juc) <[email protected]>
Before this commit, when high number of partners were loaded in the POS,
searching for a partner was slow. The main issue was that all of the
filtered partners based on the search query were being rendered, while
in reality, if a query returns lots of results, the search query is not
refined enough and the user is likely to type more characters to narrow
down the search. So in this commit, we limit the number of rendered
partners to 200, which is a reasonable number of results to display and
does not cause performance issues.

Moreover, the debounce time of the search input has been increased from
100ms to 500ms to further reduce the number of times the search function
is called while the user is typing.

opw-6215958

closes odoo#268658

X-original-commit: c2063ba
Signed-off-by: Adrien Guilliams (adgu) <[email protected]>
Signed-off-by: Pedram Bi Ria (pebr) <[email protected]>
Loading assets bundles into an iframe requires the iframe to be
connected (present in the DOM) at time of insertion.

However, it can happen that iframes are removed from the DOM before
all their assets have loaded in. In these instances, errors
from failed bundle loads will turn into tracebacks.

This is generally not an issue in Chromium-based browsers as iframes
do not fire a load event if they are disconnected; however, in
Gecko-based browsers, this can happen. As such, mass_mailing users
using Firefox currently receive a systematic traceback, as the CSS
file "mass_mailing.assets_inside_builder_iframe.css" will not load.

Steps to reproduce:
- Use Firefox (or a Gecko-based browser)
- Open a new mailing
- Select the Events theme and make an edit (add a space...)
- Save the mailing
- Wait for 23 seconds

The bug may be non-deterministic.

Fix:

Errors during the iframe load process will no longer bubble up if their
iframe is disconnected when the error occurs.

task-6293998

closes odoo#269324

Signed-off-by: Damien Abeloos (abd) <[email protected]>
Co-authored-by: Damien Abeloos <[email protected]>
Commit odoo/odoo@1789308 introduced a new way to check for sequence gaps
in account moves.

Forward-ported revisions of this change include this early return to
avoid some queries (and the inner method is itself there to prevent
some costlier queries). If the move has no name (or the default '/'),
there is no sense in checking for gaps anyhow - it has no number at all.

In addition, calling `_get_sequence_format_param` instead of
`_get_next_sequence_format` avoids queries (since it is obtained from
the journal and cached, and not checking the previous move every time)
as well.

Task-5253768

closes odoo#269239

Signed-off-by: William André (wan) <[email protected]>
The media list snippet forces the image to fill the height of its row. The
image column carries align-self-stretch and the image carries h-100, so when
the text next to the image is longer than the image is tall, the row grows to
fit the text and the image is stretched to that height (and cropped through
object-fit: cover). The longer the text, the more the image is distorted.

Drop h-100 from the image and align-self-stretch from its column in the
s_media_list snippet and in the mass_mailing_themes templates that reuse it.
With no forced height the image keeps its natural aspect ratio and the row
height follows its content, so the image is laid out next to the text instead
of being stretched to match it.

Steps to reproduce:
1. Open Email Marketing and create a new mailing.
2. Select the Blogging template for the mail body.
3. In a media item, replace the text next to an image with a very long paragraph.

=> The image is stretched and cropped to match the height of the text.

Ticket [link](https://www.odoo.com/odoo/project.task/5117571)
opw-5117571

closes odoo#268675

X-original-commit: dd6b007
Signed-off-by: Damien Abeloos (abd) <[email protected]>
Signed-off-by: Mohamed Jemai (mojem) <[email protected]>
In recent versions of PyPDF, modifying a `PageObject` directly from a
`PdfFileReader` instance triggers a `PageObject.replace_contents`
deprecation warning. As identified in the pypdf library's architecture
updates (specifically PR odoo#3638 [^1] and PR odoo#3669 [^2]), a reader's page
is intended to be read-only. Mutating it directly (e.g., using
`mergePage` or `compressContentStreams`) before attaching it to a writer
can break internal object references and cause `NullObject` errors.

This commit resolves the warning by inverting the order of operations to
ensure we only mutate writable objects. The fix implements the following
flow:
1. Add the unmodified source page directly to the `PdfFileWriter`.
2. Retrieve the newly created, writable output page.
3. Apply `mergePage` and `compressContentStreams` exclusively to the
   writer's copy of the page.

[^1]: py-pdf/pypdf#3638
[^2]: py-pdf/pypdf#3669

closes odoo#269229

X-original-commit: 4327a94
Related: odoo/enterprise#119968
Signed-off-by: Christophe Monniez (moc) <[email protected]>
Signed-off-by: Pierre Paridans (app) <[email protected]>
Steps to reproduce:
- Install the hr_timesheet module
- Create a user without HR access rights
- Create a timesheet
- Log in with the above user
- Open the kanban view

Issue:
   Instead of showing the employee's avatar, a placeholder image
   is displayed.

Reason:
    The user does not have access to the hr.employee model.

Fix:
    In this commit, if the user does not have access to hr.employee,
    we fetch the image from the hr.employee.public model.

closes odoo#269416

Task: 4461272
X-original-commit: 0630051
Signed-off-by: Xavier Bol (xbo) <[email protected]>
Signed-off-by: Prakash Prajapati (ppr) <[email protected]>
Issue:
----------------------------------------
When in a negative timezone, the "Back on ..." text in discuss shows the day before.

Steps to reproduce:
----------------------------------------
- Change the timezone of the user to "America/Toronto" for example
- Have an employee currently on leave until tomorrow
- Open discuss to chat with this employee
- The "Out of Office until..." shows today's date

Cause:
----------------------------------------
When calling `toLocaleString()` without a timezone specified in the options, the date is converted to local time (in the browser's timezone).

Here `leave_date_to` is just a date, `deserializeDateTime()` converts it to a timestamp, so the same day at 0am.
Then if the timezone is negative, the timestamp becomes an hour the previous day when calling `toLocaleString()`. The format we give `DateTime.DATE_MED` doesn't include hours, so we just display the previous date.

Solution:
----------------------------------------
Add `timeZone:"UTC"` in the options to avoid the timezone conversion.

opw-6252040

closes odoo#268886

X-original-commit: 8c4608c
Signed-off-by: Abdelrahman Mahmoud (amah) <[email protected]>
Signed-off-by: Mathieu Coutant (mcou) <[email protected]>

@odoochain odoochain left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why

robinengels and others added 5 commits June 11, 2026 14:16
When finishing a repair order a stock valuation entry is created for the
product used. If you then make a quotation and invoice it another
stock valuation entry would be created for the same product.

Steps to reproduce:
-------------------
* Create a category using FIFO and real time valuation
* Create a product using this category and set it's cost to 5€
* Set some on hand quantity for the product
* Create a repair order and add the product with the "Add" option
* Finish the repair order
> Observation: At this point you should have a valuation entry in the
  accouting app
* From the repair order create a quotation and invoice it
> Obesrvation: If you check the accounting entries again you will see
  a second valuation entry

Why the fix:
------------
When checking if the line is eligible for valuation we make sure that if
it is linked to a repair order, this repair order should not have any
accounting entries linked to it.

opw-5429996

closes odoo#254468

Signed-off-by: William Henrotin (whe) <[email protected]>
Validating a `pos.order` creates a stock move in inventory.
However, when configuring reports to automatically print on
validation, the print job wasn't triggered from the pos.

We added a way to retrieve report actions and execute them.

closes odoo#239084

Task: 5392414
Signed-off-by: Yaroslav Soroko (yaso) <[email protected]>
Issue:
When work entries are generated from Attendances, a worked-time time off created by the Indian sandwich rule can overlap a public holiday and generate duplicate work entries for the same day.

Steps to reproduce:
- Create an employee with Work Entry Source set to Attendances
- Use a flexible working schedule on the employee
- Configure a public holiday on a scheduled day with work entry type (Paid time off)
- Create a time off type with Count as set to Worked Time
- Generate time off for the period so the public holiday entry exists (maybe a day before and a the public holiday and the day after)
- Open Payroll > Work Entries (Observe the date of the public holiday will have more than 8h entry)

Cause:
In `_get_version_work_entries_values()`, calendar leaves are split by `hr_holidays` `time_type` into:
- leaves: absences and public holidays
- worked_leaves: worked-time time off For attendance-based contracts, both sets were turned into work entries without removing overlap between a public holiday and a worked-time leave on the same period. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L222-L226

For non-flexible calendar:
Public holidays and worked-time leaves are both clipped to the static working schedule (e.g. 8h per working day). overlap was kept in both result sets. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L260

For flexible calendar:
The one-day intervals are kept as the actual interval (often 00:00-23:59 for a public holiday). The worked-time on that day is schedule-shaped (e.g. 8h). Subtracting intervals on a full-day public holiday left a 16h fragment instead of removing the public holiday entry. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L242-L249

Solution:
We need to make regular leaves take priority over worked-time leaves, compute the real regular leave intervals first, then remove those intervals from the worked-time leave intervals before work entries are created:
- for fully flexible employees, subtract regular leaves from worked leaves;
- for flexible calendars, keep one-day regular leaves as is and subtract them from worked-time leaves
- for non-flexible attendance-based calendars, clip regular leaves on the static schedule, then subtract them from worked-time leaves clipped on the same schedule.

This means that when a sandwich worked-time leave overlaps a public holiday, the public holiday consumes that period first. The overlapping part is then removed from `real_worked_leaves`, so no second worked-time entry is generated for the same public holiday period.

opw-6237163

---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr

closes odoo#268527

Related: odoo/enterprise#119530
Signed-off-by: Abdelrahman Mahmoud (amah) <[email protected]>
When archiving or unarchiving bank accounts, salary distribution map is not recomputed.

Task-6180142

closes odoo#262255

Signed-off-by: Yannick Tivisse (yti) <[email protected]>
Bug introduced in: e2efdf7

Steps to reproduce: Clear the Warehouse field (set it to False) Create a
purchase order Set "Deliver To" to the operation type with no warehouse
Add any product Confirm the PO → TypeError is raised

Steps to reproduce the bug:
- Have at least 2 warehouses
- Go to Inventory > Configuration > Operation Types > Receipts
    - Clear the Warehouse field (set it to False)

- Create a purchase order:
    - Set "Deliver To" to the operation type with no warehouse
    - Add any product
    - Try to confirm the PO

Problem:
A traceback is triggered:
```   return self.parent_path.startswith(other_location.parent_path)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: startswith first arg must be str or a tuple of str, not bool```

`_get_final_location_record` computes `wh_stock_loc` from
`picking_type_id.warehouse_id.lot_stock_id`. When `warehouse_id`
is False (a valid configuration, operation types can be detached from
any warehouse), `lot_stock_id` short-circuits to False instead of an
empty recordset.

Solution:
guard the _child_of call with not wh_stock_loc. When the
picking type has no warehouse, wh_stock_loc is falsy and there is
nothing to compare against, so the method falls back to
default_location_dest_id (the only destination available).

opw-6032018

closes odoo#269049

X-original-commit: 518d36f
Signed-off-by: William Henrotin (whe) <[email protected]>
Signed-off-by: Djamel Touati (otd) <[email protected]>
Waleed Elgamal and others added 30 commits June 18, 2026 10:05
Steps to reproduce:
1. Open the Project application and open any project.
2. Filter the tasks by milestone (milestone deadlines appear as expected in the kanban view).
3. Open any task form view.
4. Click the browser's back button (or simply refresh the page while on the task kanban view).

Issue:
Milestone deadline dates disappear from the task Kanban cards and headers after navigating back or reloading.

Why this happens:
When hitting the browser back button or refreshing, the web client's router state recovery workflow executes
(`loadRouterState` -> `loadState` -> `doAction` -> `_executeActWindowAction`).
During this flow, `_getActionParams` checks if it can reuse the cached `lastAction`. However, due to a safety condition
introduced in commit ab26f95 to prevent embedded action showing across different projects, the router falls back to
generating a fresh action request via `state.action`.

This forces `_loadAction` to fetch the action definition from the database. Because the original base action window
`act_project_project_2_project_task_all` lacks the `display_milestone_deadline` key inside its default context dictionary,
the reloaded view is rendered without the flags required by the frontend to display milestone deadlines.

opw-6283514

closes odoo#269781

Signed-off-by: Xavier Bol (xbo) <[email protected]>
Before this commit:

- When a syntax highlighting block contained a scrollbar, hovering over the
  scrollbar displayed a text cursor. This was misleading because the text cursor
  suggests text interaction, while the scrollbar is only used for scrolling.

After this commit:

- The default cursor is now shown when hovering over the scrollbar, avoiding
  this confusion.

task- 6295899

closes odoo#269728

Signed-off-by: David Monjoie (dmo) <[email protected]>
Let's consider an auto-install module `A` having 2 dependencies, one to
`base` and the second to custom module `B`.

  If module `B` is not present in the addons path (i.e is unknown),
during a new database initialization module `A` would still be marked
as `to install`.

This commit ensures that if an auto-install module has a missing
dependency, it will not be marked as `to install`.

closes odoo#270678

X-original-commit: 54a18dd
Signed-off-by: Chong Wang (cwg) <[email protected]>
Signed-off-by: Xavier Alt (xal) <[email protected]>
Steps to reproduce:
- Go to the Link Tracker page
- Generate a first tracked link
- Click on the button to start editing the code
- Click on "create another tracker"
- Generate a second tracked link
=> When you access the screen to see/edit the tracked link url, the
buttons "ok" and "cancel" are already present. Clicking on "ok" display
a traceback.

To fix this issue, this commit also cancels edition when clicking on
"create another tracker".

task-4531974

closes odoo#270628

X-original-commit: 5e62ad4
Signed-off-by: Francois Georis (fge) <[email protected]>
Signed-off-by: Romaric Moyeuvre (romo) <[email protected]>
…e vendors

**Issue**
Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error
when creating an RFQ approval request.

**Steps to reproduce**
- Have two companies A and B and two users u1 and u2
- user u2 only have access to company A
- With user u1:
	- Create two vendors v1 and v2 without any company assigned
	- Create vendor pricelists for a product for each vendor and assign the company A to the pricelist
- Add the company B for the vendor v2
- With user u2:
	- Open approval application
	- Try to create an approval for an RFQ for that product (the vendor v1 will be automatically selected)
	- Save it
-> An access error is thrown

**Cause**
Saving the approval request computes `has_no_seller`, which calls `_select_seller`:
https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/views/approval_product_line_views.xml#L9
https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L32
https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L62-L70
Which filtered the right seller
https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L759
By preparing the sellers:
https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L721
https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L712
Please note that `self.seller_ids` contains both sellers (even v2)
By filtering the suppliers:
https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_supplierinfo.py#L104-L105
But at that point, one of the supplier in `self`, can be accessed, thus an access error is thrown while
trying to access its associated `partner_id`.

opw-6203910

closes odoo#270707

X-original-commit: aed1619
Related: odoo/enterprise#120941
Signed-off-by: William Henrotin (whe) <[email protected]>
Signed-off-by: Maxime Noirhomme (noma) <[email protected]>
Printing the images no longer works in Firefox due to it not respecting
the script tags that are written with document.write. Therefore we need
to construct the page manually through the newer JS style with
createElement. However it was also quite clear that this function could
be improved and therefore I simply refactored it to keep the code to a
minimum.

opw-6287367
After commit 3cbaad4,
the theme manifest is now looked up to find addon snippets for the
configurator. However, during an upgrade, if a website is configured
with a third-party/custom theme whose code is not present in the
addons path, `Manifest.for_addon()` returns `None` and
`_generate_primary_snippet_templates` raises an `AttributeError`:
```py
2026-06-16 03:27:47,155 24126 INFO db_4367932 odoo.modules.loading: loading website/views/new_page_template_templates.xml
2026-06-16 03:27:47,803 24126 WARNING db_4367932 odoo.modules.module: module theme_prime: manifest not found
2026-06-16 03:27:47,845 24126 WARNING db_4367932 odoo.modules.loading: Transient module states were reset
2026-06-16 03:27:47,846 24126 ERROR db_4367932 odoo.registry: Failed to load registry
2026-06-16 03:27:47,846 24126 CRITICAL db_4367932 odoo.service.server: Failed to initialize database `db_4367932`.
Traceback (most recent call last):
  File "/home/odoo/src/odoo/19.0/odoo/tools/convert.py", line 605, in _tag_root
    f(rec)
  File "/home/odoo/src/odoo/19.0/odoo/tools/convert.py", line 273, in _tag_function
    _eval_xml(self, rec, env)
  File "/home/odoo/src/odoo/19.0/odoo/tools/convert.py", line 197, in _eval_xml
    result = method(*args, **kwargs)
  File "/home/odoo/src/odoo/19.0/addons/website/models/ir_module_module.py", line 704, in _generate_primary_snippet_templates
    theme_addons = theme_manifest.get('configurator_snippets_addons', {})
AttributeError: 'NoneType' object has no attribute 'get'
```
We also get the missing manifest logs right before the error.

TBG-2781

[`_generate_primary_snippet_templates`]: https://github.com/odoo/odoo/blob/19.0/addons/website/models/ir_module_module.py#L700

closes odoo#270217

Signed-off-by: Benjamin Vray (bvr) <[email protected]>
When validating a POS order containing a product tracked by lots, an
error about duplicate lot numbers is raised if the lot name can be read
as a GS1 barcode (e.g. "10156": "10" is the GS1 Application Identifier
for Batch/Lot) while the company uses a GS1 nomenclature and the Barcode
app is installed.

Steps to reproduce:
-------------------
* Install Barcode, POS and Inventory, enable lots & serial numbers
* Set the barcode nomenclature to "Default GS1 Nomenclature"
* Create a product tracked by lots and a lot named "10156" (any name
  starting with "10"), set an on-hand quantity for it with this lot
* On the "PoS Orders" operation type, enable both "Create New" and
  "Use Existing ones" for lots/serial numbers
* In POS, sell the product with lot "10156" and validate the order

> Observation:
The order fails to validate with a duplicate lot number error: the
search for existing lots does not find lot "10156", so the POS tries to
create it again and hits the unique constraint on stock.lot.

Why the fix:
------------
With stock_barcode installed, `stock.lot._search` preprocesses any
domain on `name` with `_preprocess_gs1_search_args` so that scanned GS1
barcodes can match lot records. The lot names sent at order validation by `_create_production_lots_for_pos_order` are real lot names coming from
the order lines, not scanned barcodes, but "10156" is decomposable
as a valid GS1 lot ("10" + "156"), so the search domain
became `('name', '=', '156')` and missed the existing lot. Skip the GS1
preprocessing in that search with the existing `skip_preprocess_gs1`
context key, as already done in `product` and `stock`.

opw-6274744

closes odoo#269787

Signed-off-by: Stéphane Vanmeerhaeghe (stva) <[email protected]>
Since [1], studio binary fields uploaded through a form store their filename.

Due to the condition of [1], this behaviour is restricted to manual fields, which limits the usage of those fields in standard and is particularly problematic when Saas modules that use this feature are migrated to Python.

Given that a more appropriate condition has already been added in [2], it should no longer be necessary to restrict this feature to manual fields.

This commit removes that restriction to allow standard binary fields to store their filename when uploaded through a form.

[1] odoo@0e2f3b1
[2] odoo@1bcab2f

closes odoo#270702

X-original-commit: 6feedc1
Signed-off-by: Krzysztof Magusiak (krma) <[email protected]>
Added the states of Tajikistan to align with official
ISO 3166-2 standards. In addition change the address
format of the country to show state name instead of
state code.

task-6237595

Part-of: odoo#269091
Signed-off-by: Khumam Alzagim (alkh) <[email protected]>
Added the states of Turkmenistan to align with official
ISO 3166-2 standards. In addition change the address
format of the country to show state name instead of
state code.

task-6237707

Part-of: odoo#269091
Signed-off-by: Khumam Alzagim (alkh) <[email protected]>
Added the states of Kyrgyzstan to align with official
ISO 3166-2 standards. In addition change the address
format of the country to show state name instead of
state code.

task-6237473

Part-of: odoo#269091
Signed-off-by: Khumam Alzagim (alkh) <[email protected]>
Added the states of Armenian to align with official
ISO 3166-2 standards. In addition change the address
format of the country to show state name instead of
state code.

task-6237440

Part-of: odoo#269091
Signed-off-by: Khumam Alzagim (alkh) <[email protected]>
Added the states of Kazakhstan to align with official
ISO 3166-2 standards. In addition change the address
format of the country to show state name instead of
state code.

task-6237284

closes odoo#269091

Signed-off-by: Khumam Alzagim (alkh) <[email protected]>
…counted twice

**Steps to reproduce**

- Create an attribute A, of type always, with 2 values, one should have an extra price
- Create an attribute B, of type never, with 2 values
- Create a product that has both those attributes
- Create a combo with that product with both values for A
- Go to the PoS and order that combo with the value that has an extra price for A
- The extra price is added

**Why the fix:**

For variants of type always, a product is
created, meaning we can chose which products of
this variants to have in our combo.

As we can chose this, it means that we can and
should chose the extra price on the combo creation
page, not on the attribute page.

It does not make sense to take the attribute
extra price into account, as we do not take
the unit price of combo items into account,
so this extra price should be set on the combo
page and we should ignore the attribute's extra
price if the type is "always".

The variants are then considered as different
products, as they should in this case.

If the type of the attribute is never, we can't
chose which one gets an extra price on the
combo page, so we should still take the
attribute's extra price in this situation,
as we have no other way to set it.

We need to have both an always and a never
attribute in order to reproduce this bug
because if we only have "always" values,
the configuration of the combo item is
bypassed and is undefined, so **attribute_value_ids**
will be undefined in this code and we
won't get any value for the extra price
in this code: https://github.com/odoo/odoo/blob/c09e8b2fc24ee75495fc947924e29cf5c601506f/addons/point_of_sale/static/src/app/models/utils/compute_combo_items.js#L44-L49
We now ignore the attribute's extra price
if it's type is always, otherwise, it the
behavior stays the same.

opw-6262431

closes odoo#270625

X-original-commit: b84750e
Signed-off-by: Stéphane Vanmeerhaeghe (stva) <[email protected]>
Signed-off-by: Arthur Nanson (artn) <[email protected]>
In the combo configurator dialog, a combo item's `extra_price` and the
`price_extra` of `no_variant` attributes are stored in the company
currency but were serialized to the front-end without conversion. With a
foreign-currency pricelist, the popup added them 1-to-1 to the
already-converted base price, so the displayed total didn't match the
price computed on the sale order line.

Convert both extras via `currency._convert()` before sending them to the
front-end, so the popup matches the order line.

Closes odoo#119701

closes odoo#269905

X-original-commit: 7d0278a
Signed-off-by: Louis Tinel (loti) <[email protected]>
The feature introduced in odoo/enterprise#78429 allows users to detach
attachments from moves, primarily to facilitate the regeneration and
re-sending of outgoing XMLs (e.g., sales invoices) without needing to
delete the original attachment.

However, detaching should not apply to incoming XML attachments on bills
that originate from EDI import, as these attachments are the received
source document and are never regenerated by the system. Detaching them
inadvertently prevents their inclusion in bulk XML exports.

An exception exists for Italy: businesses need to send Tax Integration XMLs
back to the SdI. In this specific case, detaching the Tax Integration XML
is appropriate and ensures the bulk export finds the latest, correct attachment.

opw-5062132

closes odoo#267892

X-original-commit: 66b4395
Signed-off-by: Thomas Becquevort (thbe) <[email protected]>
Website forms allow submitting messages to many different models, e.g.
creating a task, sending an email, etc. Upon sending an email we want
to check the signature of the request. This should be done when the
email_to field is set but also when the email_cc and email_bcc is set.

opw-6110064
When loading products in the POS, both the sale price and the cost were
converted to the POS currency using `currency_id`. However a product
stores its sale price and its cost in two potentially different
currencies: `currency_id` (company currency, falling back to the main
company) and `cost_currency_id` (company currency, falling back to the
current company).

opw-6297452

closes odoo#269829

Signed-off-by: Stéphane Vanmeerhaeghe (stva) <[email protected]>
The sales details report computes a line discount as
`original_price - price_subtotal_incl`. On a refund line the quantity is
negative, so `original_price` is negative, while `price_subtotal_incl`
is stored positive. Subtracting the two then inflates the discount
instead of cancelling it, understating "discount_amount" by
`2 * price_subtotal_incl` for every refunded discounted line.

opw-6281752

closes odoo#270592

Signed-off-by: Stéphane Vanmeerhaeghe (stva) <[email protected]>
…ents' update

This commit adapts the code to prevents appointment invitations from being sent if the
appointment status is neither "booked" nor "request".

For more information about the issue, see the enterprise PR.

Enterprise PR: odoo/enterprise#114304

Task-6139036

closes odoo#260073

Related: odoo/enterprise#114304
Signed-off-by: Renaud Thiry (reth) <[email protected]>
**Steps to reproduce**
- Install planning
- Switch to English (UK) and change the "First day of the week" to
Sunday in the technical settings
- Have an employee with a flexible schedule with a total of 40h/week,
average 8h/day
- In the planning app, after creating a shift to display the employee
in the gantt view, notice that when hovering over the progress bar on
the left, 48 worked hours are expected for the current week, which is
more than what is defined in the employee's calendar

**Cause**
The displayed week, starting on Sunday, could accumulate more hours
than the weekly cap due to the Sunday being part of another week with
the locale default first day (Monday).

opw-6110395

closes odoo#259600

Signed-off-by: Xavier Bol (xbo) <[email protected]>
Description:

Processing batch payments for multiple invoices triggers the
`_increase_rank` method across numerous partners. Previously,
this could lead to Out-Of-Memory (OOM) errors in databases
with extensive partner hierarchies (parent/child relationships),
primarily due to cascaded writes triggered by
`_commercial_sync_to_descendants`.

This commit optimizes the rank increment process, significantly
reducing both memory consumption and execution time.

Benchmark:

| Partner Count | Time Before | Time After | Memory after |
|---------------|-------------|------------|--------------|
| 191,946       | 2 min       | 47s        | 111 Mb       |
| 393,509       | OOM         | 1 min 45   | 216 Mb       |

Reference:
opw-5152687

closes odoo#259334

Signed-off-by: Piryns Victor (pivi) <[email protected]>
The aim of this commit is to allow module unrelated to auth_oauth to
import fragment_to_query_string.

Task-id: 6071808
Part-of: odoo#270834
Related: odoo/enterprise#121019
Signed-off-by: Julien Castiaux (juc) <[email protected]>
The aim of this commit is to make `fragment_to_query_string` JUC
compliant by:
  - documenting the behavior
  - clarifying the code
  - reducing possible side effect
  - testing the behavior
  - add a route to be able to test it manually

closes odoo#270834

Task-id: 6071808
Related: odoo/enterprise#121019
Signed-off-by: Julien Castiaux (juc) <[email protected]>
Steps to reproduce:
- Open a slide of a course in non fullscreen mode (website).
- Go to the comments tab and add a comment in the chatter.
- The comments count does not change in the tab.
- Another way to see the incorrect counter is to add a note in the slide form
view (backend).

Before this change, `website_slides` used `website_message_ids` to calculate the
 comments. Since odoo#138233 the old portal chatter has been replaced with the mail
chatter and the way messages are displayed on the portal has changed. For
example notes are no longer considered portal messages and also deleted messages
 should not be displayed or counted as such.

This change ensures that comments calculations are based on a domain that
considers those changes meaning that comments will be synced with the
actual number of available comments.

closes odoo#270800

X-original-commit: 34f63f7
Signed-off-by: Sébastien Theys (seb) <[email protected]>
Signed-off-by: Maryam Kia (maki) <[email protected]>
**Problem:**
Valuation account for luxembourg is currently 60761 Merchandise
which is incorrect because it's an expense account.
We should rather use a current asset account like
301 Inventories of raw materials

**Steps to reproduce on a fresh db:**
- create a new db with modules stock_account and accountant
(without demo data)
- On the 'fiscal localization setting' set the package
as 'Luxembourg' and save
- ativate the automatic accounting setting

**Current Behavior:**
The 'stock valuation account' appearing below
the automatic accounting setting is :
60761 Merchandise

**Expected behaviour:**
It should be 301 Inventories of raw materials

closes odoo#270048

X-original-commit: 24a71ac
Signed-off-by: Yolann Sabaux (yosa) <[email protected]>
Signed-off-by: Pierre-Louis Hance (plha) <[email protected]>
…ct rewards

Steps to produce:
- Install `website_sale_loyalty`.
- Go to `Website > ecommerece > Loyalty > Discount & Loyalty`.
- Create a new discount & loyalty program > set program type as `promotions`.
- Under Rewards, select Free Shipping as the reward type.
- Create a product with a price of 1000 and publish it.
- Add the product to the cart from the website.
- Observe that free shipping is automatically applied on cart.
- Attempt to remove the free shipping reward from the cart.

Issue:
- Free shipping (and similarly, free product rewards) cannot be removed
  from the cart once applied.

Root cause:
- At [1], the website_sale_loyalty_delete context is only passed when the reward
  type is discount. As a result, For free shipping and free product rewards, the
  context is not set. At [2], the order line is removed, but the reward is not
  added to disabled_auto_rewards. The `_auto_apply_rewards` method runs
  immediately afterward, detects the missing reward, and re-applies it
  automatically.

Fix:
- Since there are three reward types (discount, free shipping, and free product)
 , the condition restricting the context to only discount rewards should be
  removed.

[1]: https://github.com/odoo/odoo/blob/5e90858fa91348f6aa33b4f8a246e77fbb8ea63f/addons/website_sale_loyalty/models/sale_order.py#L179
[2]: https://github.com/odoo/odoo/blob/5e90858fa91348f6aa33b4f8a246e77fbb8ea63f/addons/website_sale_loyalty/models/sale_order_line.py#L15-L23

opw-6159288

closes odoo#270959

X-original-commit: 3300d88
Signed-off-by: anko-odoo <[email protected]>
Signed-off-by: Krishna Arvindkumar Patel (krip) <[email protected]>
…260615_01

Merge from upstream 19 20260615 01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.