Skip to content

[19.0] [REF] stock_account: stock valuation report by lot - #129

Draft
ThomasBinsfeld wants to merge 299 commits into
19.0from
19.0-stock_valuation_report_by_lot_tbi
Draft

[19.0] [REF] stock_account: stock valuation report by lot#129
ThomasBinsfeld wants to merge 299 commits into
19.0from
19.0-stock_valuation_report_by_lot_tbi

Conversation

@ThomasBinsfeld

Copy link
Copy Markdown
Member

DO NOT MERGE

thle-odoo and others added 30 commits July 31, 2026 12:18
Ensure that the methods called in the XML files are correct.

Task-6411877
*:mrp_subcontracting_purchase

Issue before this commit:
========================
- In inter-warehouse transfers with multi-step delivery and in  multi-step
manufacturing flows, demand moves were not counted in the monthly demand.

- Also, direct transfers to customer and subcontracting locations generated from
orderpoint were also not counted correctly.This resulted in lower monthly demand
values than the actual demand and could lead to inaccurate purchase planning.

Steps to Reproduce:
=========================
- Install purchase_stock module and enable multi-step routes.
- Set the Outgoing Shipments in the warehouse to 2-step/3-step.
- Create a second warehouse and configure it to resupply from another warehouse.
- Create a storable product and assign a vendor.
- Create an orderpoint for the product in the second warehouse, set the route to
  the warehouse resupply route, and trigger the replenishment.
- Go to Purchase → Create RFQ for the vendor and open the Catalog
Observation:
The replenishment transfer demand is not correctly counted in the monthly demand

Cause of the issue:
=========================
- In [PR](odoo#244180), the monthly demand move
domain was updated to filter out intermediate customer delivery moves using
move_dest_ids.origin_returned_move_id. However, inter-warehouse replenishment
delivery moves also have move_dest_ids linked to receipt moves of the other
warehouse, but origin_returned_move_id is not set since they are not return move
Because of this, these valid demand moves were incorrectly excluded from the
monthly demand computation.
- Also, in multi-step inter-warehouse flows, delivery moves stay in the waiting
state since it waits for another operation, so they were also not counted.
Additionally, orderpoint-triggered moves use a fixed midday scheduled time,
and since monthly demand was computed using the current timestamp as the limit
date, same-day moves could be excluded if checked before midday.

After This Commit:
=========================
- The monthly demand move domain was updated to correctly count inter-warehouse,
manufacturing, and subcontracting resupply demand moves while still avoiding
inflated demand from intermediate moves. The move state domain was also updated
to include waiting moves in multi-step flows, and the limit date now uses the
full current day so same day moves are counted correctly.

Enterprise PR: odoo/enterprise#115944
TaskID-5490137

closes odoo#262435

Signed-off-by: William Henrotin (whe) <whe@odoo.com>
…irms

**Issue**
Confirming a SO that generates a batch of MOs from a BoM with a
batch size could lead to creating an invalid number of pickings: all the
MOs end up sharing a single picking instead of getting one each.

**Steps to reproduce**
- Use 2-step manufacturing
- Create a storable product with the MTO + Manufacture routes
- Add a BOM that has a batch size of 10 that consumes one component
- Create and confirm a SO of 100 units of that product
-> 10 MOs are created, but each one points to the same "Pick Components" transfer instead of getting its own.

**Cause**
This commit dd6ee07 batches the confirm of productions:
https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/mrp/models/stock_rule.py#L120
thus `assign_picking` is called in batches:
https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/mrp/models/mrp_production.py#L1653
https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1736-L1737
https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1550-L1556
since, the `reference_ids` are the same for each MO/stock.move (they all come from the same procurement):
https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1712-L1713

Consequently, all the moves end up in the same recordset `moves`:
https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1527
Creating only one picking:
https://github.com/odoo/odoo/blob/b51dc298fd63d9586d0b8d7cff59764b0dee5cae/addons/stock/models/stock_move.py#L1577

opw-6403427

closes odoo#279179

Signed-off-by: Lancelot Semal (lase) <lase@odoo.com>
When an internal recipient receives an Out of Office (OOO)
notification, the resulting `mail.message` record has
`partner_ids` populated with the recipient partner ID,
while `outgoing_email_to` is set to `False`.

When a second internal user emails the OOO user within the 4-day window,
`_notify_thread_with_out_of_office` excutes a search domain with an OR condition:
`'|', ('partner_ids', 'in', recipient.ids), ('outgoing_email_to', '=', email_to)`

Because `email_to` is `False` for internal partners, `('outgoing_email_to', '=', False)`
evaluated to `True` against the first recipient's message record.
Consequently, the search falsely determined that the second recipient was
already notified, suppressing OOO replies for all subsequent contacts
across the 4-day window.

Proposed solution:
We resolve this by dynamically constructing recipient sub-domains conditionally
depending if `recipient` or `email_to` are set.
We also extend `test_routing_with_out_of_office` with a corresponding test case.

How to reproduce:
1. Set up a DB with at least 3 users (User A, User B, User C).
2. Configure User A to be out of office (in user preferences)
3. Go to any chatter/mail.thread while logged as User B and tag User A
in a log note. -> triggers OOO message
4. Log as User C, tag User A in a log note.
-> BUG: no OOO message because the "4 day" check falsely believes that
User C already received a OOO from User A

OPW-6110300

closes odoo#277880

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
**Issue**
The height is not correctly computed in the picking form when editing product description.

**Steps to reproduce**
- Create a delivery for a product
- Add a description to it
- Click on editing the descriptio
-> Observe that the description is partially hidden because the widget height is incorrectly computed

**Cause**
Since commit odoo@e4f4171, `useProductAndLabelAutoresize` no longer assigns a height to the widget root.

The corresponding widget is `MoveProductLabelField`, which extends `ProductNameAndDescriptionField`:
https://github.com/odoo/odoo/blob/91b59f285248c120fe9e3e5f6b6f086ea7be2837/addons/stock/static/src/views/picking_form/stock_move_product_label.js#L5
It uses `useProductAndLabelAutoresize`:
https://github.com/odoo/odoo/blob/91b59f285248c120fe9e3e5f6b6f086ea7be2837/addons/product/static/src/product_name_and_description/product_name_and_description.js#L54-L56
**Solution**
Explicitly add a div around the product display and description to still use the `Autoresize`

closes odoo#271564

Signed-off-by: Maxime Noirhomme (noma) <noma@odoo.com>
Steps to reproduce the bug:
- Install point_of_sale
- Open the POS frontend and create a new product from the register
- Add it to the order, then open its product info popup and edit it
    - Rename it and change its price
- Confirm the edit dialog
- Click on the (renamed) product again to add it to the order

Problem:
On runbot the tour test_product_create_update_from_frontend
(point_of_sale/tests/test_frontend.py, MobileTestUi) intermittently times
out waiting for the orderline to show the edited product name/quantity/
price combination.

editProduct()'s onSave callback in pos_store.js closed the edit dialog
via act_window_close right after firing this.data.read("product.template",
...) and this.data.searchRead("product.product", ...), without waiting for
either call to resolve. When the dialog closes before those RPCs land, the
in-memory product record used by canBeMergedWith() (pos_order_line.js) to
decide how to merge/create the next orderline can still hold the stale
price, so re-clicking the product right after editing produces an
orderline that never matches the expected quantity/price.

Solution:
Make onSave async and await both this.data.read() and
this.data.searchRead() before closing the dialog, so the reactive store is
guaranteed to hold the updated product data before the user (or the tour)
can interact with the product again.

runbot-223630

closes odoo#279496

X-original-commit: 364b959
Signed-off-by: Adrien Guilliams (adgu) <adgu@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
The government has held off the `shipToGSTIN` changes until further notice.
https://services.gst.gov.in/services/advisoryandreleases/read/668

Hence, this commit reverts those changes.

task-6431622

ref - odoo#266388

closes odoo#279553

X-original-commit: f3c748e
Signed-off-by: Josse Colpaert (jco) <jco@odoo.com>
Before this commit, the default einvoice format was changed only when
the partner was french and had a vat number. We want ubl_21_fr only if
the partner is fr and is on the annuaire. If the partner is on peppol
we want ubl_bis3.

task-6303174

closes odoo#278158

X-original-commit: 215a514
Signed-off-by: de Wouters de Bouchout Jean-Benoît (jbw) <jbw@odoo.com>
Signed-off-by: Maximilien La Barre (malb) <malb@odoo.com>
When running `ŧest_free_reservation`, it could happen on very rare
occasions that both moves would be created at a different second. In
such cases, the test would fail.

Since we want to test the case with *exact* same dates, we can't use
`assertAlmostEqual` which is usually better for dates. Instead, we
freeze the time for the duration of the creation / assignation.

runbot-944453

closes odoo#279565

X-original-commit: 45c4ed5
Signed-off-by: Stéphane Diez (snd) <snd@odoo.com>
Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
When an image is start-aligned, if a list is defined after it, its
bullets/numbers/checkboxes are rendered on top of the image.

This commit makes the bullets rendered after the image.

Steps to reproduce:
- Edit a website page
- Drop a text page
- Insert an image with `/image`
- Align image to the left
- Insert a bullet list or a numbered list or a checkbox list with some
indented entries

=> Some bullets were rendered on top of the image

Additionally, the start-align is neutralized inside list lines because
other approaches do not provide a satisfactory layout - and break
further situations.

task-6116437

closes odoo#279394

X-original-commit: a88e7c7
Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
Signed-off-by: Benoit Socias (bso) <bso@odoo.com>
Description of the issue this commit addresses:

The settlement tour expects an invoice named with the year 2026. On time-shifted
test instances, invoices use a later year, so the tour cannot find the invoice
and fails at the settlement selection step.

Desired behavior after this commit is merged:

This commit matches settlement invoices using the stable journal prefix, so the
tour works regardless of the year in which it runs.

runbot-[242206](https://runbot.odoo.com/odoo/error/242206)

closes odoo#279659

X-original-commit: 2c7da6f
Signed-off-by: Stéphane Vanmeerhaeghe (stva) <stva@odoo.com>
Signed-off-by: Thomas Becquevort (thbe) <thbe@odoo.com>
…nvoices / vendor bills.

Currently, Peppol product detection relies strictly on barcode or default_code matching,
which fails when vendors use their own codes.

Accurate product identification is essential before running the predictive model (for taxes/accounts)
and is a strict prerequisite for Purchase Orders matching to function correctly.

This commit makes the product matching relies on the Vendor Product Code as the first priority
( SellersItemIdentification or StandardItemIdentification or BuyersItemIdentification )

task-6171251

closes odoo#262801

Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
Ensure combo prices are computed in the backend.

closes odoo#279652

Signed-off-by: Stéphane Vanmeerhaeghe (stva) <stva@odoo.com>
…nsion

The global "message" event listener registered by pttExtensionHookService
reads data.from without checking that data is defined first. Any
same-window, same-origin postMessage sent by an unrelated browser
extension (a very common content-script <-> injected-script pattern) can
carry `data === undefined`, which crashes with:

  TypeError: Cannot read properties of undefined (reading 'from')

This surfaces as an uncaught client error on any page with Discuss
loaded after some time, unrelated to what the user is doing — the
push-to-talk extension itself does not need to be installed to trigger
it, since the crash happens before checking whether the message
actually originated from that extension.

Fix: use optional chaining (data?.from) so unrelated same-origin
messages are safely ignored instead of crashing.

X-original-commit: f13fcad
Part-of: odoo#279645
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
closes odoo#279645

X-original-commit: 4409037
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
closes odoo#278716

X-original-commit: b0e209c
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
…ests

Backport of [1].

Builder image tests were flaky in full-suite runs because earlier tests
left slow requests pending. Bogus snippet thumbnails, obsolete modify_image
mock data, and made-up attachment URLs triggered expensive website 404
rendering and starved the browser connection pool.

Avoid rendering missing thumbnails, use data URIs or existing static images
in fixtures, return the current modify_image response shape, and give the
CORS test image explicit dimensions.

[1]: odoo@ec5cc6a

closes odoo#279564

X-original-commit: 9964e7c
Signed-off-by: Francois Georis (fge) <fge@odoo.com>
Portal subscribe task can create tb because the task was archived
before unsubscribing.

opw-6397850

closes odoo#279596

X-original-commit: 495c1cd
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
Signed-off-by: Mohammadmahdi Alijani (malj) <malj@odoo.com>
A return coming back from the customer must always decrease the
delivered quantity of a sale order line, even when it is not linked
to its original delivery (no origin_returned_move_id and its
picking has no return_id)

These unlinked returns are created through a negative procurement,
example: when the ordered quantity is reduced below the delivered one.

Steps to reproduce:
- Confirm a sale order of 10 and deliver the 10
- Cancel the order and reset it to draft
- Reduce the line quantity from 10 to 4
- Re-confirm: the pull rule generates a return of 6 with to_refund
  set but no origin_returned_move_id nor picking.return_id
- Validate that return

Before: delivered stays at 10. After: delivered is 4.

opw-6345628

closes odoo#279494

X-original-commit: 1dcfb81
Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
When a format is applied on an unsplittable node, removing it from a
wider selection does not dare to touch that format to ensure it won't be
split.
Because of this, it becomes impossible to remove the format on such
nodes.

This commit slightly adapts the logic by so that instead of stopping
when encountering an unsplittable node, it keeps looking higher in the
hierarchy where the format is actually defined.

Steps to reproduce:
- Go to a "To do" note
- Select a word
- Apply a style (underscore, strikethrough...)
- Type "odoo.com"
- Press space to turn it into a link
- Select the whole line
- Try to remove the style

=> The style was not removed from the link.

task-6322596

closes odoo#279511

X-original-commit: e01b007
Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
Signed-off-by: Benoit Socias (bso) <bso@odoo.com>
…product

Steps to reproduce:
- Enable the ZUGFeRD (or Factur-X) e-invoicing format on a German customer.
- Create a sale order for that customer, confirm it, create an invoice with
  a down payment.
- Confirm and send the invoice to generate the PDF/XML.
- Validate the XML (e.g. on portinvoice.com): it is rejected because the
  invoice line is missing the mandatory ram:Name field, only
  ram:Description is present.

Cause of the issue:
a down payment invoice line created from a sale order
no longer carries a product_id: it only has a free-text.

The Factur-X/CII export template rendered ram:Name directly from line.product_id.name
with no fallback. For a line without a product, this produced an empty
ram:Name element, which cleanup_xml_node then stripped entirely from the
XML, leaving only ram:Description.

Solution:
Fall back to the line's name when there is no product

opw-6391121

closes odoo#279562

X-original-commit: d33f16d
Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
Signed-off-by: Amzil Ayoub (amay) <amay@odoo.com>
Steps to reproduce:
Use the real testing credentials
Make sure the invoice sequence is not generated on the real testing credentials

1. Create an invoice with overseas partner
2. Create ewaybill

Error from the portal:
`[372] Invalid or Blank Consignee Ship-to State Code`

It is currently a flaw in the government portal because in
Government portal there is no option for the Other country (99)
for Ship to state code and only option for Other Teritory(97)

It is because in reality, it should the port ship to state code
but there cases where goods can be transfered to nearby country
i.e. Bangladesh, Nepal where good can taken by road from India

In that case the state code should be 97

task-6431082

X-original-commit: 52d0ab6
Part-of: odoo#279888
Signed-off-by: Josse Colpaert (jco) <jco@odoo.com>
Signed-off-by: Harsh Modi (hamo) <hamo@odoo.com>
Steps to reproduce:
Use the real testing credentials
Create a SEZ partner
Create an invoice and ewaybill
Select the type of Ewaybill as Export Tax Invoice

We get error code-450
which clearly states, `450 For outward-export ewaybill, To GSTIN has to be either URP or SEZ`

closes odoo#279888

X-original-commit: e791baa
Signed-off-by: Josse Colpaert (jco) <jco@odoo.com>
Signed-off-by: Harsh Modi (hamo) <hamo@odoo.com>
Needed by linked PR.

closes odoo#279778

Task-id: 6438820
Related: odoo/enterprise#126378
Signed-off-by: Stéphane Vanmeerhaeghe (stva) <stva@odoo.com>
…tions

Steps to reproduce:
1. Create a sales order.
2. Confirm or cancel the order.
3. Share the quotation link.
4. Open the quotation from an incognito window or the customer portal.

Issue:
- A 'Quotation Viewed by Customer' notification is sent even though the document
  is no longer an active quotation.

Fix:
- Only send the notification while the order is in quotation or quotation sent
  state.

opw-6419364

closes odoo#279775

X-original-commit: f13c4e8
Signed-off-by: Shrey Mehta (shrm) <shrm@odoo.com>
This commit fix the regex used in `street_split` to be
more complient.

Before: address format was "street_name street_number - street_number2"

Now, street_number can be in front of street_name.

Format is also less strict, allowing multiple numbers in the street_name
without skipping the building number.

task-6317758

closes odoo#279777

X-original-commit: bf88dff
Related: odoo/enterprise#126377
Signed-off-by: Florian Gilbert (flg) <flg@odoo.com>
Signed-off-by: Igor Bertrand (igbe) <igbe@odoo.com>
rhe-odoo and others added 29 commits August 13, 2026 07:02
… multiple devices

When using multiple devices sharing draft orders, a race condition can happen where one device reuses another device's empty synced draft order. This leads to duplicate UUIDs, which triggers automatic order merging in `sync_from_ui` on the server and clears the table association.

To prevent this:
- Filter out synced orders (`!order.isSynced`) in `getEmptyOrder()`, `createOrderIfNeeded()`, and `setTable()` when looking for reusable empty orders.
- This ensures each terminal only reuses its own locally created, unsynced empty orders, guaranteeing unique UUIDs per device session.

closes odoo#269551

Task-id: 6296661
Signed-off-by: David Monnom (moda) <moda@odoo.com>
closes odoo#281707

X-original-commit: 2c8ed64
Signed-off-by: John Laterre (jol) <jol@odoo.com>
…amped

closes odoo#281871

X-original-commit: 126b5bd
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
closes odoo#280754

Signed-off-by: Florian Gilbert (flg) <flg@odoo.com>
Problem:
`isVisibleTextNode` fails to check the space visibility in case it is
preccedded with a `feff`.

Cause:
The final check uses `visibleCharRegex` on the preceding node, which
excludes zero-width chars like `feff`. But `feff` is not whitespace,
so it shouldn't make the adjacent space collapse either.

Solution:
Check for non-whitespace instead of visibility on the preceding node.

task-6397398

closes odoo#282061

X-original-commit: 6a1cd7d
Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
Signed-off-by: Walid Sahli (wasa) <wasa@odoo.com>
Issue:
```
In [14]: receiver._get_peppol_proxy_endpoint('/2/get_services')
Out[14]: '/api/peppol//2/get_services'

In [15]: receiver._get_peppol_proxy_endpoint('2/get_services')
Out[15]: '/api/peppol/2/get_services'
```

this raises:
```bash
[ERROR] odoo.addons.account_peppol_response.models.account_edi_proxy_user
Auto registration of peppol services for module: account_peppol_response failed on the user: ***, with exception: Invalid signature for request. This might be due to another connection to odoo Access Point server. It can occur if you have duplicated your database
```

OPW-6431279

closes odoo#282119

X-original-commit: 8401ffb
Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
Signed-off-by: Victor Miguel Armenta Carrillo (vmac) <vmac@odoo.com>
When edit_translations is set, convert_to_record wraps translated
terms in branding spans. Related (non-stored) fields re-read that
already-wrapped value and ran the same wrapping again, producing
nested spans.
Only wrap terms for stored fields so related Html inherits the
source branding unchanged. Also keep data-oe-translation-state in
HTML safe_attrs so sanitization does not strip it.

closes odoo#282063

X-original-commit: 060f1f2
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Chong Wang (cwg) <cwg@odoo.com>
`test_orderpoint_activity_portal_context_leak` assumes that running the
orderpoint will trigger a procurement exception. However, depending on
which modules are installed (e.g., when `purchase_stock` is absent), standard
stock rules for the test warehouse destination location can succeed in
generating stock moves rather than raising an error.

Deactivate all matching destination stock rules on the test warehouse prior
to running procurement so the orderpoint is guaranteed to fail.

runbot-941316

closes odoo#281297

X-original-commit: c7d6c18
Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
Signed-off-by: Pierre Paridans (app) <app@odoo.com>
X-original-commit: bf05bb0
Part-of: odoo#282021
Signed-off-by: Krzysztof Magusiak (krma) <krma@odoo.com>
Odoo intentionally leaves Pillow's WebP decoder unloaded, but URL imports
used Pillow directly to validate image dimensions. This rejected valid WebP
images even though Odoo's image fields support them.

Validate downloaded images with ImageProcess so WebP and other formats share
the same identity and IMAGE_MAX_RESOLUTION checks without enabling the
decoder or duplicating format-specific logic.

closes odoo#282021

X-original-commit: cd36852
Signed-off-by: Krzysztof Magusiak (krma) <krma@odoo.com>
Current behaviour:
In the Calendar view (day/week/month scale), when the user's timezone
observes a DST transition that starts exactly at local midnight (e.g.
Africa/Cairo, since 2023), the day column right after the transition
gets the wrong weekday name, duplicating the previous day's name.
For ex. it renders "... THU THU FRI ..." instead of
"... THU FRI SAT ...", for the week surrounding April 30th 2027.

To fix this we add 1 hour to the Date before reading its weekday/day from
it, mirroring the workaround FullCalendar itself adopted for
this same bug. It has no effect on any ordinary day (adding 1h to a
correct local midnight stays within the same calendar day), and it
cannot overshoot into the next day since no real-world DST gap exceeds
that margin.

Note: This is a known bug (fullcalendar/fullcalendar#7633),
fixed in FullCalendar v6.1.17, a major version ahead of the v4.4.0,
so the fix can't be applied directly without a full library
upgrade.

opw-6370140

closes odoo#280210

X-original-commit: eeab54a
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Signed-off-by: Achraf Ben Azzouz (abz) <abz@odoo.com>
… count

Issue:
The internal chatter logs were being counted as regular comments in the blog.

Steps to reproduce:
Create a website with a blog.
Create a page for the blog and activate comments.
While editing go into blog post.
Send a log in the chatter, and the blog will show one more message than it should.

Cause:
Both logs and comments have the same type: 'Comment' and when doing the
counting of comments we used this broader type, encompassing all of them.

Fix:
Distinguish them based on being internal or not.

closes odoo#270998

Signed-off-by: Jérémy Kersten <jke@odoo.com>
Steps:
- Install `account_peppol` module.
- Set `Peppol` compatable country and related details
- Go to my/account page.

Issue:
- Peppol related details always displayed on `my/account` page
even though user select different invoice sending method like:
`By Email`.

Casue:
- selector to manage visibility of Peppol related details in
`my/account` is wrong and because of that those fields always
display. Probably because odoo#195764 and
backport of this odoo#198327 merged at
same time.

Fix:
- Update selector to fix this

X-original-commit: bf01085
Part-of: odoo#282132
Signed-off-by: Sven Führ (svfu) <svfu@odoo.com>
Signed-off-by: Kartik Chavda (kcv) <kcv@odoo.com>
Steps:
- Install `account_peppol` module.
- Set `Peppol` compatible country and related details.
- Go to my/account page.
- Set some wrong Peppol value for `Peppol e-Address (EAS)`,
`Peppol Endpoint` and `Electronic format`

Issue:
- Not able to save those details without any error message on
address page and getting error on console `Cannot read properties
of undefined (reading 'classList')`.

Casue:
- In this PR odoo#190312 when adapting
portal page we set not existing fields in `invalid_fields` details
and because of that it can't find related fields on address page
and don't allow to save details without raising proper error
message.

Fix:
- Updated `invalid_fields` values to properly target them

X-original-commit: 7385dde
Part-of: odoo#282132
Signed-off-by: Sven Führ (svfu) <svfu@odoo.com>
Signed-off-by: Kartik Chavda (kcv) <kcv@odoo.com>
…address

closes odoo#282132

X-original-commit: c8244b9
Signed-off-by: Sven Führ (svfu) <svfu@odoo.com>
Signed-off-by: Kartik Chavda (kcv) <kcv@odoo.com>
Behavior before:
When uploading an animated GIF to fields utilizing image responsive sizing
or cropping (such as employee avatars or product images), no downscaling or
cropping occurs for sub-variants like 'image_128' or 'image_1024'. The
responsive fields replicate the exact file size and data footprint of the
original large image, leading to heavy storage overhead and unnecessary
frontend asset loading.

Behavior after:
Animated GIF images scale down and crop correctly to match requested
responsive dimensions and aspect ratios. Sub-variants take up significantly
less space in the filestore, matching proportional dimensions without
dropping or stripping the underlying animation loop. Large images that are
smaller than requested boxes are safely left un-upscaled to maximize
database deduplication.

Root Cause:
Historically, a legacy safeguard bypassed GIF resizing and cropping because
older versions of the Pillow library did not gracefully handle multi-frame
sequential image buffers. As a result, standard 'image.crop()',
'image.thumbnail()', or 'image.resize()' implementations would flatten
multi-frame animated sequences down into a single, static first frame or
throw dimension/mode mismatches during save operations.

Fix:
Intercept the image processing pipeline when encountering an asset identified
as a GIF where 'is_animated' evaluates to True. Implemented a unified,
in-place multi-frame helper routine (`_apply_gif_operation`) using PIL's
'ImageSequence.Iterator' to cleanly step through, normalize to a uniform color
mode (RGBA), duplicate, and modify each animation frame individually.

This single helper handles sequential workflows for both 'crop' and 'thumbnail'
operations while preserving individual frame duration arrays and native loop
metadata. Both 'resize' and 'crop_resize' leverage this logic to achieve
precise dimensions cleanly.

Crucially, upscaling (expanding) is intentionally unsupported for animated GIFs.
Forcing a low-resolution, 256-color indexed animation to stretch beyond its
native dimensions forces heavy color dithering across every single frame. This
breaks the sequential LZW pattern compression, causing the resulting file sizes
to skyrocket catastrophically. The logic utilizes thumbnail boundaries to
completely block this expansion, protecting the filestore from accidental bloat.

Benchmark:

--------------------------------------------------------------------------
| GIF size    | Variant          | Size Before (KB)   | Size After (KB)   |
|-------------|------------------|--------------------|-------------------|
| (2.5MB)     | image_1024       | 2475.87            | 2475.87           |
|             | image_128        | 2475.87            |  257.93           |
|-------------|------------------|--------------------|-------------------|
| (3.8MB)     | image_1024       | 3724.93            | 3724.93           |
|             | image_128        | 3724.93            |  463.62           |
|-------------|------------------|--------------------|-------------------|
| (442KB)     | image_1024       |  432.49            |  432.49           |
|             | image_128        |  432.49            |   36.14           |
|-------------|------------------|--------------------|-------------------|
| (3.6MB)     | image_1024       | 3491.98            | 3491.98           |
|             | image_128        | 3491.98            | 1728.25           |
|-------------|------------------|--------------------|-------------------|

opw-6232841

closes odoo#281857

X-original-commit: d9fae40
Signed-off-by: Aurélien van Delft (avd) <avd@odoo.com>
Signed-off-by: Hammad Arif (arih) <arih@odoo.com>
Shop product lookup and facet computations used different searchable fields. In particular, facets searched raw website_description HTML, so CSS tokens could match a large part of a catalog even when the displayed result set was small.

Use one shared field list for product lookup and facets, replace internal and raw website descriptions with the eCommerce description.

opw-6391984

closes odoo#280720

Signed-off-by: Youssef El Fatihi (yoelf) <yoelf@odoo.com>
When creating a MO For a product with no variant, it will add an on apply on variant componant,
even if only one of it's attribute has a values that match with the product on the mo.

Steps to reproduce:
-------------------
* Create a Product with two never attributes (att1 and att2)
* Add values to both attributes
* Create a BOM with components with apply on variant for every possibility:
  - component att1 val1, att2 val1, apply on variant: att1 value 1 att2 value1
  - component att1 val1, att2 val2, apply on variant: att1 value 1 att2 value2
  - component att1 val2, att2 val1, apply on variant: att1 value 2 att2 value1
  - ...
* Add mto and manufacture to the product
* Create and confirm a SO for the product variant att1 value 1 and att value 2
-> On the MO every component that as at least one of the values will be present.

Observation:
-------------
When confirming the SO it will call action_confirm.
Since we are in mto, it will create a procurement order of the manufacture type and will create a MO.
When creating the workorder, it will call explote on the bom to know all the components:
https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/mrp/models/mrp_production.py#L626
Each line that does not respect the apply on variant condition will be ignored:
https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/mrp/models/mrp_bom.py#L450-L451
it will retrieve the line if at least one value from any attribute match:
https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/mrp/models/mrp_bom.py#L623-L626

opw-6293259

closes odoo#271351

Signed-off-by: Stéphane Diez (snd) <snd@odoo.com>
Issue:
---
When you apply pricing on product variant form, pricing is instead
applied on product template.

Steps to reproduce:
1- Open a product variant.
2- From prices tab, add a pricelist rule. Save the variant.
3- Re-open pricelist rule. As you see, the variant is not set.

Cause & Fix:
---
This is because `applied_on` is changed to `1_product` when
`display_applied_on` is set to `1_product`.

However, `display_applied_on` is also set to `1_product` when item
is created from variant. We can check that case using
`default_product_id`.

opw-6421193

closes odoo#280303

Signed-off-by: Mohammadmahdi Alijani (malj) <malj@odoo.com>
Steps to reproduce:
- make a few sales in the PoS and refund one of them
- close the session
- select all those orders, including the refund, and create a
  consolidated invoice

Issue:
The invoice is refused with "You cannot validate an invoice with a
negative total amount. You should create a credit note instead.", while
the total of the selected orders is positive.
If a cash rounding method is set on the PoS config, no error is raised
but the posted document is a credit note carrying a rounding line equal
to twice the order total (a credit note of 20.00 with a 40.00 "Rounding"
line for sales of 10.00 + 20.00 and a refund of 10.00).

Cause:
_prepare_invoice_vals picked the move type from the presence of a refund
in the group instead of its net amount: any group holding an order with
is_refund set, or a negative amount_total, became an 'out_refund'.
_get_invoice_lines_values then negates the quantities of every order
whose direction differs from the move type, so the sales end up as
negative lines of a credit note and the document totals -20.00 instead
of +20.00. account.move refuses to post it.
When invoice_cash_rounding_id is set, the cash rounding line is computed
to bring the document back to a total valid for its type, so it absorbs
the whole sign error and the wrong credit note is posted silently.

Fix:
Choose the move type from the net amount_total of the group, as was done
up to saas-18.3, and keep is_refund only as the tie-break when that net
is zero so a lone zero-total refund still gives a credit note. The sign
handling of the lines is unchanged: it already keys on each order's own
direction, which is what makes a sale a negative line of a credit note
and a refund a negative line of an invoice.

opw-6452996

closes odoo#281703

Signed-off-by: Manu Vaillant (manv) <manv@odoo.com>
Steps to reproduce:
- Create a "Buy 2 Get 1 free" program whose rule and reward cover three
  products having the same price
- In the PoS, add one unit of each of the three products
  -> one free product is given
- Add three more units of the second product, 6 units in total

Issue:
Only one free product is given instead of two, the order total is 50
instead of 40.

Cause:
`_updateRewardLines` deletes the reward lines and re-applies each claimed
reward. Beforehand it merges the claims having the same reward and the
same price, which is the case for two free products of the same price
even when they were claimed for two different products. The merged claim
keeps the `_reward_product_id` of the first line only, with a quantity of
two. On re-application, `_computeUnclaimedFreeProductQty` only counts in
`available` the quantity of that single product, since the other lines
are counted only while a reward line is still in the order and they have
all just been deleted. It therefore returns 1 and the second free
product is lost.

Fix:
Only merge claims that were made for the same free product. Gift
card/ewallet claims have no `_reward_product_id` and claims of a reward
having a single reward product all share the same one, so both keep
being merged as before.

opw-6430385

closes odoo#282052

Signed-off-by: Manu Vaillant (manv) <manv@odoo.com>
Issue:
---
Authorize payment tokenization doesn't work.

Steps:
1- Setup authorize payment provider.
2- Using portal page, add a new payment method for the user.

The created payment method is not saved.

Cause:
---
The issue was introduced in efc2788.
Before that, we were calling `_tokenize` before voiding the tx.
In that PR, the `_tokenize` call was moved to `_process()`, after
`_apply_updates()`.
So now what happens is that we void the tx, then call `_tokenize()`.
Inside tokenize we try to create a customer profile, which fails
because the tx is already voided.

Fix:
---
We can fix it by calling `_tokenize()` once before voiding the tx.

The redundant tokenize call inside the general payment tx `_process`
is rendered ineffective by two safeguards:
1- There is a check for `tx.tokenize`, which neutralizes double
tokenization:

https://github.com/odoo/odoo/blob/fffd987cc98d1ea0cd04e24dda2ed8b64a219cdc/addons/payment/models/payment_transaction.py#L754-L755
https://github.com/odoo/odoo/blob/fffd987cc98d1ea0cd04e24dda2ed8b64a219cdc/addons/payment/models/payment_transaction.py#L893-L896

2- If `token_id` is already set, no token value is returned:

https://github.com/odoo/odoo/blob/fffd987cc98d1ea0cd04e24dda2ed8b64a219cdc/addons/payment_authorize/models/payment_transaction.py#L237-L243

opw-6426847

closes odoo#281014

Signed-off-by: Mohammadmahdi Alijani (malj) <malj@odoo.com>
Steps to reproduce
---
1. Create and confirm a sale order.
2. Create a down payment invoice on it and post it: the down payment line reads "Down Payment (ref: INV/... on ...)".
3. Open that invoice and use Reverse and Create Invoice, then post the newly created draft down payment invoice.
4. Open the sale order: the down payment line has lost its reference and now reads only "Down Payment", and that empty label also carries over to the down payment section when generating the final invoice.

Issue
---
The down payment line description is built by `_get_downpayment_description`, which only produces the "Down Payment (ref: ... on ...)" label when exactly one customer invoice is linked to
the down payment `sale.order.line`, guarded by `len(invoice) == 1`.

https://github.com/odoo/odoo/blob/3a5f7431effd4b2b2eb8ce3eed81aaba42fcd8ea/addons/sale/models/sale_order_line.py#L484-L509

Reverse and Create Invoice runs `account.move.reversal.modify_moves`, which copies the reversed invoice with `include_business_fields=True`, so the copied line keeps its `sale_line_ids` and the new draft invoice is attached to the very same down payment line as the reversed original.

https://github.com/odoo/odoo/blob/3a5f7431effd4b2b2eb8ce3eed81aaba42fcd8ea/addons/account/wizard/account_move_reversal.py#L142-L149

That down payment line then references two `out_invoice` moves (the reversed one and the re-issued one), so `len(invoice) == 1` is false and the label silently falls back to the bare "Down Payment", losing the reference that the final invoice's down payment section reuses. Going back to the sale order to raise a fresh down payment instead creates a new line, which keeps a single invoice and is why the slower flow is unaffected. The `len(invoice) == 1` guard was introduced in ba95460. Discarding the reversed invoice (`payment_state == 'reversed'`) leaves the active re-issued invoice as the single match, so its reference is shown again; when the only linked invoice is itself reversed, the fallback keeps displaying it so existing descriptions are preserved.

opw-6353384

closes odoo#277802

Signed-off-by: Amr Ahmed (amahm) <amahm@odoo.com>
We still have cases of people being confused by the fact that they
send their invoices, reset it to draft, change something, then
re-sending.
Of course, the re-sending does not send on peppol, as it's already sent.
It's more confusing than anything else.
Prevent it if they're sent and not in error
task-6459869

closes odoo#281847

X-original-commit: 895e5ed
Signed-off-by: Sven Führ (svfu) <svfu@odoo.com>
Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
Before this commit, deleting a record leaves its id in the relations of
a record deleted before it in the same update, and reading one of those
relations hands out an entry for a record that is gone.

This happens because an update takes a deleted record out of the
relations that hold it, but forgets it as soon as it is deleted.
However, deleting a record is what queues the deletion of the records it
holds: `channelMembers` carries `onDelete: (r) => r.delete()`, so the
members of a thread are deleted once the thread is already forgotten,
and their ids stay in its `onlineMembers`.

This commit fixes the issue by keeping the records deleted by an update
known until it ends.

`RHD_QUEUE` has nothing left to run then, so this commit also removes it
and deletes the record where the update takes it out of the store.

closes odoo#282307

X-original-commit: 7a9c0f1
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Before this commit, the test "Shows warning badge on mic/camera on
non-granted permission in meeting conversations" failed on runbot, on
19.0:

Failed to find 1 of "button[title='Turn camera on']" (Timeout of 10
seconds). Found 0 instead.

This happens because the mock server numbers a new record with the
highest id of the model plus one, so a record created right after the
last one is deleted takes its id back. Joining another call leaves the
meeting call first, and the session of the new call carries the id of
the one just left. Leaving broadcasts
"discuss.channel.rtc.session/ended" for that id, and under load it
lands after the join: the client reads it as its own session being
closed and ends the call it has just joined.

This commit numbers the records of a model with a counter, started
above the ids its definition gives, as a database sequence does, so a
notification about a deleted record can no longer name a live one.

https://runbot.odoo.com/odoo/error/945965

closes odoo#282297

X-original-commit: d517393
Signed-off-by: Julien Mougenot (jum) <jum@odoo.com>
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Before this commit:

- From the Product Screen, users could only reprint the last order change, while
  from the Ticket Screen, they could reprint all previous order changes one by
  one.

After this commit:

- Users can now reprint the entire order as an order change directly from both
  the Product Screen and the Ticket Screen.

Task-6230594

closes odoo#266070

Signed-off-by: David Monnom (moda) <moda@odoo.com>
Before this commit, the hoot test "keep banner for messages received
while scrolled up" failed at random on runbot:

```
Failed to find 1 of ".o-mail-Thread-banner:has(:text('1 new message'))"
(Timeout of 10 seconds). Found 0 instead.
```

This happens because the test waits for the scroll position it sets in
the DOM only, while the thread copies that position to the record on the
scroll event, one animation frame later. Bob's message can arrive in
between, when the record still says "bottom": the counter the banner
reads stays frozen at 0 and the message is marked as read on arrival, so
the banner never shows.

This commit waits until the record holds that position before posting.

https://runbot.odoo.com/odoo/error/945967

closes odoo#282332

X-original-commit: d6483e8
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
@acsonefho
acsonefho force-pushed the 19.0-stock_valuation_report_by_lot_tbi branch from ac026f6 to 1f6ae3e Compare August 14, 2026 12:17
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.