Skip to content

Merge from upstream 17 20260512 01#1218

Open
royle-vietnam wants to merge 49 commits into
Viindoo:17.0from
royle-vietnam:merge_from_upstream_17_20260512_01
Open

Merge from upstream 17 20260512 01#1218
royle-vietnam wants to merge 49 commits into
Viindoo:17.0from
royle-vietnam:merge_from_upstream_17_20260512_01

Conversation

@royle-vietnam
Copy link
Copy Markdown
Collaborator

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

loco-odoo and others added 30 commits April 28, 2026 07:37
When clicking on the extra menu item, a Bootstrap dropdown is displayed
with a transition. Because this transition takes time, it can lead to
undeterministic behavior especially in tests. For example, if a tour
clicks on the extra menu item and then clicks on the "Site" button in
the navbar, the dropdown transition may still be in progress. This can
cause the "Site" dropdown to close prematurely.

runbot-240955

closes odoo#261179

Signed-off-by: Francois Georis (fge) <fge@odoo.com>
Problem:
During an `onchange` call, if a field is defined in the `fields_spec` with a `limit` attribute, the `fetch` method doesn't respect it, and will fetch all records satisfying the domain. In certain circumstances, this leads to slow requests.

Solution:
Enforce the `limit` when fetching if it is present.

Steps to reproduce:
- Have a product with many quant records
1. Open a picking for this product in Barcode
2. Change the lot/serial

The frontend will send an `onchange` request that includes `product_stock_quant_ids` in the `fields_spec` (with default `limit` 40). Odoo will fetch all quants for this product regardless of the limit, and the request will take a while to resolve.

Benchmark:
# of quants | Before | After
17193 | ~9s | ~400ms

opw-6041705

closes odoo#259983

Signed-off-by: Krzysztof Magusiak (krma) <krma@odoo.com>
Before this commit:
Partner was searched using contains on the name, which could match
unrelated partners with similar names (e.g. 'Global Tech' matching
'Global Technologies Ltd').

After this commit:
- Partner retrieval now uses an exact name match to avoid incorrect
  matches caused by partial name search.
- The search limit is set to 1 to ensure a consistent result when multiple
  partners are found.

Technical:
- Replaced 'ilike' with '=ilike' in the name search domain.

task-5485563

closes odoo#250309

Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
**Problem**
Before this commit, the email address typed in the signup form was not
validated, allowing arbitrary strings to be used as email addresses.
Additionally, the form was missing the recommended `autocomplete`
attributes [1].

**Steps to reproduce**
1. Enable "free sign up" ("Settings"->"Website"->"Customer Account")
2. While signed out, navigate to "/web/signup"
3. Enter an invalid email address->No validation is triggered.

**Fix**
1. `AuthSignupHome._prepare_signup_values` already checked for missing
   fields and not-matched passwords, raising an `UserError` that is
   later caught and rendered in an error box on the web page. After this
   commit, the same method also validates the password against the regex
   `odoo.tools.single_email_re`. Note that `_prepare_signup_values` is
   also used when resetting password, but the email validation only
   happens during signup.
2. The email field type in the template `auth_signup.fields` is set to
   `email` to enable built-in browser validation, and appropriate
   `autocomplete` attributes are added to the form.

[1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/autocomplete

task-6094631

closes odoo#258967

Signed-off-by: Francois Georis (fge) <fge@odoo.com>
The unit test is tagged `-standard` and `database_breaking` because
it was leaving left overs in the database.

Using an `HttpCase` over a `BaseCase` solves that issue
in addition to make the code way simpler.

We want to resurrect this unit test class because we plan to add
another unit test in that class for a bug fix.

closes odoo#261743

Signed-off-by: Walravens Mathieu (wama) <wama@odoo.com>
closes odoo#261658

Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
To reproduce:
-Activate Peppol
-Activate selfbilling on your purchase journal
-Create a Vendor Refund
-Generate the UBL
=> The InvoiceTypeCode is 389, meaning it's considered a selfbilling invoice, not a selfbilling credit note.
The issue is that we never put the document type of credit_note for selfbilling documents as it wasn't expected.
invoice was, due to a else encompassing invoices and bills.
Also add a handle demo to be able to create selfbilling documents in demo mode.

opw-6132226

closes odoo#260941

Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
Before this commit, voice message tests don't wait until the voice
player is drawn before resolving the corresponding promise. This may
lead to race conditions.

This commit fixes the issue by properly `await`ing the completion of the
asynchronous code before resolving the promise.

closes odoo#261795

Signed-off-by: Louis Wicket (wil) <wil@odoo.com>
Issue:
- When a user without access rights tries to view their profile,
  a permission error is raised.
- Issue pr: odoo#254162

Fix:
- Added `employee_country_code` to SELF_READABLE_FIELDS in `res.users`.

closes odoo#255260

Signed-off-by: Abdelrahman Mahmoud (amah) <amah@odoo.com>
**PROBLEM**
When importing an invoice, we don't want to round the discounts, to avoid
discrepancy between the subtotal computed by Odoo, and the subtotal of the file we import.
To do this, we change the decimal precision of discount to 100 digits when importing files.
However, float_round wasn't built with this in mind, in float round, we add a small epsilon to fix some rounding issue.
This small epsilon changes the amount of the discount (50.0 -> 0.5000000000004) and this changes the subtotal.

**STEP TO REPRODUCE**
1. Install l10n_edi_it.
2. Change the VAT number of IT Company to 05098540288 (to match the one on the file to import).
3. Import the file present in the bug ticket.
4. Notice the subtotal of the line doesn't match what's in the invoice.

opw-6046324

closes odoo#256037

Signed-off-by: Paolo Gatti (pgi) <pgi@odoo.com>
Steps to reproduce:
1. Install Invoicing and Studio
2. Go the Journal Entries list view
3. Enter Studio mode
4. Go to View, and Enable Mass Editing

The following traceback is raised:
```py
Field 'company_id' used in domain of python field 'journal_id' (
(company_id and ['|', ('company_id', '=', False), ('company_id', 'parent_of', [company_id])] or ['|', ('company_id', '=', False), ('company_id', 'parent_of', [''])]) + ([('id', 'in', suitable_journal_ids)])) is restricted to the group(s) base.group_multi_company.
```

Now that the list view is editable, there is a check being performed on
the `journal_id`'s company and domain. However, those fields aren't
present in the view, thus OWL is unaware of their values and cannot
properly apply the `journal_id`'s check_company, nor domain. By adding
those two fields as `column_invisible`, the error is fixed.

opw-6119955

closes odoo#260954

Signed-off-by: Paolo Gatti (pgi) <pgi@odoo.com>
Steps to reproduce:
- Create a storable product "P1" with UoM set to KG
- Update on-hand quantity to 1 KG
- Create a delivery order for 100g of P1 and validate it
- Click the Return button

Problem:
The return wizard displayed 100 KG instead of 0.1 KG.

The `uom_id` field on `stock.return.picking.line` is a non-stored related
field pointing to `product_id.uom_id`. The quantity was taken directly from
the stock move (expressed in the move's UoM) without being converted to the
product's UoM before being passed to the wizard.

Solution:
Convert the quantity from the move's UoM to the product's UoM.

opw-6113515

closes odoo#262069

Signed-off-by: Tiffany Chang (tic) <tic@odoo.com>
In Discuss, the function used to sort partners prioritizes those whose
email addresses start with the search terms. However, due to an error in
the programming of the corresponding condition, this check could never
be true.

This commit adjusts the condition so that it behaves as expected.

closes odoo#262583

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
…t fallback to responsible_ids

Issue:
When ('both','By Employee's Approver and Time Off Officer') is selected on a new HR Leave Type  it does not fall back to the responsible_ids or “Notify HR”.

Steps:
1) Setup a neutralized outgoing mail server
2) install hr_holidays
3) make a new hr.leave.Type (Approval) with ('both','By Employee's Approver and Time Off Officer') and select a 'Notified Time Off Officer'(responsible_ids)
4) select an emplyee with a reelated user and remove the coach, manager, and responsible 'Time Off'.
5) save
6) Sign in as the employee, make a time off request under the new Type
7) No email

Fix:
Add a conditional with the lowest priority to fall back to responsible_ids

opw-6101637

closes odoo#261853

Signed-off-by: Romain Carlier (romc) <romc@odoo.com>
When receiving a Peppol/UBL XML file containing an embedded PDF via an
email alias, the PDF is not extracted and attached to the resulting
vendor bill.

Steps to reproduce:
- Set up a BE Company
- Configure an incoming mail server
- Set up an email alias for the Vendor Bill journal
- Receive a Peppol XML with embedded PDF via alias
- Check the created Bill

Issue:
PDF has not been extracted from the xml
This occurs because the received xml is set as main attachment for the
record and in this case we skip extraction

opw-6075250

closes odoo#262047

Signed-off-by: Antoine Boonen (aboo) <aboo@odoo.com>
Currently, error occurs when user tries to merge a mailing list.

Steps to replicate:
- Install `mass_mailing`.
- Open Email Marketing > Mailing Lists > Mailing Lists and switch to list view.
- Select a single record and from cog menu Click merge.

Warning:
```
odoo.http: Record does not exist or has been deleted.
(Record: mailing.list(6,), User: 2)

```

Cause:
- When the user clicks Merge, the `mailing.list.merge` form opens and
  `default_get()` is executed to populate defaults.
- At this point, `src_list_ids` is added to res in a structured format like
  `[(6, 0, ids)]` [1].
- Later, `res.get('src_list_ids')` is reused and assigned to `src_list_ids` [2].
- Taking `src_list_ids[0]` [3] returns `(6, 0, ids)`, and its first element `6`
  is incorrectly treated as a record ID and assigned to `dest_list_id`.
- This leads to an attempt to access a record with ID 6, which does not exist,
  causing the error.

Solution:
- Instead of reading `src_list_ids` back from res after it has been set, we
  initialize and reuse local variables (src_list_ids, active_ids) at the
  beginning of the method.

- This avoids relying on transformed values in res and ensures that
  `dest_list_id` is computed using a consistent and valid list record IDs.

[1]: https://github.com/odoo/odoo/blob/21877c09863222a237fe99334787ac46935dcca4/addons/mass_mailing/wizard/mailing_list_merge.py#L20-L22

[2]: https://github.com/odoo/odoo/blob/21877c09863222a237fe99334787ac46935dcca4/addons/mass_mailing/wizard/mailing_list_merge.py#L24

[3]: https://github.com/odoo/odoo/blob/21877c09863222a237fe99334787ac46935dcca4/addons/mass_mailing/wizard/mailing_list_merge.py#L26

sentry-7447326420

closes odoo#262466

Signed-off-by: Florian Charlier (flch) <flch@odoo.com>
Bug introduced in: odoo@c5f0e56

Steps to reproduce the bug:
- Create a BoM with more than 40 components
- Create a manufacturing order with this BoM

Problem:
Only the first 40 components are taken into account and their moves are created; the remaining ones are not created.

opw-6186544

closes odoo#262692

Signed-off-by: Adrien Widart (awt) <awt@odoo.com>
**Steps to reproduce:**
- Go to Email Marketing app
- Create a mailing campaign
- Set its recipients to Contact
- Upload a file in Settings > Attach a file
- Click on the test button to send a test mail to any mail
- Go to the first contact record
- Related attachment appears in the chatter

**Issue:**
Before 18.2, messages created for testing were ignored
by the Chatter as they were empty (and not unlinked).

But if an attachment was provided, it was linked to the
test message and not deleted afterwards (which means
it shows up in the record chatter).

**Fix:**
Ensure the related messages are unlinked at the same time as
the test mail in `send_mail_test` by setting `is_notification`
to False to trigger the `unlink` logic and remove the related
attachments at the same time.

backport of: odoo@526b3d7

opw-6168632

closes odoo#262152

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Some Peppol emitters carry the supplier VAT in
cac:PartyIdentification/cbc:ID instead of the BIS3-standard
cac:PartyTaxScheme/cbc:CompanyID. The import then extracted no
VAT, the partner auto-creation not available (needs name+vat)
and invoice.partner_id stayed empty. As a side effect, when
the XML also carried a PayeeFinancialAccount, the bank account
creation crashed with a NOT NULL violation on partner_id.

Fall back on cac:PartyIdentification/cbc:ID when cbc:CompanyID
is empty, so the partner is found (or auto-created) and
the bank account is properly linked.

Steps to reproduce:
- Create a XML with the supplier VAT only in cac:PartyIdentification/cbc:ID
and a cac:PayeeFinancialAccount/cbc:ID.
- Upload on a purchase journal: import fails, the bill stays
    empty with an error in chatter.
- With the fix: partner auto-created, bill filled, bank
    linked.

opw-6148974

closes odoo#261933

Signed-off-by: Claire Bretton (clbr) <clbr@odoo.com>
A tax exemption reason code that does not pass the peppol validation was added
in the xml generation in this task-id-5905176
task-id-none

closes odoo#262810

Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
Steps to Reproduce:

- write on ir.model.data to modify noupdate.
- _lookup_xmlids still returns the old noupdate value.

Example:
In [1]: imd = self.env['ir.model.data']

In [2]: xml_id = self.env['ir.model.data'].search([], limit=1)

In [3]: imd._lookup_xmlids([xml_id.complete_name], self.env[xml_id.model])
Out[3]: [(18603, 'auth_signup', 'action_send_password_reset_instructions', 'ir.actions.server', 149, False, 149)]

In [4]: xml_id.write({'noupdate': not xml_id.noupdate})
Out[4]: True

In [5]: imd._lookup_xmlids([xml_id.complete_name], self.env[xml_id.model])
Out[5]: [(18603, 'auth_signup', 'action_send_password_reset_instructions', 'ir.actions.server', 149, False, 149)]

In [6]: imd.flush_model()

In [7]: imd._lookup_xmlids([xml_id.complete_name], self.env[xml_id.model])
Out[7]: [(18603, 'auth_signup', 'action_send_password_reset_instructions', 'ir.actions.server', 149, True, 149)]

Issue:

- _lookup_xmlids is returning values from ir.model.data executing an SQL query w/o flushing.

Fix:

- Add flushing in _lookup_xmlids.

closes odoo#262791

Signed-off-by: Chong Wang (cwg) <cwg@odoo.com>
Steps to reproduce:

* Enable multiple languages
* Go to Sale Order Templates and create a new template
* Add a product line, then click the translate button on the description field
* A confusing validation error appears for missing `sale_order_template_id`

Issue:

* Instead of highlighting the missing required fields on the sale order template
  form view, it raises a misleading validation error on `sale_order_template_id`

Cause:

* `useTranslationDialog` always attempts to save the passed record directly.
  In O2M list views, the field can belong to a nested relational record, so the
  correct behavior is to save the root record instead.

Affected Version: 17.0

closes odoo#262755

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
…rses

Expected Behaviour:
Contacts enrolled in common courses should not be merged and the merge
should fail.

Steps to reproduce:
1- Go to one of the courses
2- Add two attendees to the course
3- Go to Contacts App
4- Select the two attendees you added to the course
5- Try merging the two contacts

Actual Behaviour before the Fix:
Contacts enrolled in common courses are getting merged and the common
courses are kept in the destination contact.

Behaviour with the Fix:
Contacts enrolled in common courses are blocked from being merged and an
error message is shown to the user saying that the reason the merge is
blocked is a duplicate course.

opw-5417223

closes odoo#244500

Signed-off-by: Florian Charlier (flch) <flch@odoo.com>
When multiple rescue sessions existed for a POS config, calling
`open_opened_rescue_session_form` raised a ValueError ("Expected
singleton") because `.id` was accessed on a multi-record set.

Now opens a filtered list view titled "Rescue Sessions" when multiple
open rescue sessions are found, and a direct form view when there is
only one.

opw-6184661

closes odoo#262829

Signed-off-by: David Monnom (moda) <moda@odoo.com>
Steps to reproduce:
- Install the sale_project module
- Create a sale order based on milestones
- Create the project from the order
- Open the project, click the three dots, and open a milestone

Issue:
Users are unable to open milestones and get an access error.

Cause:
Users in `sales_team.group_sale_salesman`  lack read access to the related
`sale.order.line`, causing an AccessError when `sale_line_id` is accessed
during the computation of `product_uom_qty`.

Fix:
Compute `product_uom_qty` using `sudo()` to bypass record rule restrictions.

task-5477304

closes odoo#245392

Signed-off-by: Maxime de Neuville (mane) <mane@odoo.com>
The tax rate(`amount`) for code 32 was mistakenly set to '11.0'. To properly
align with the official Norwegian tax rates, it needs to be updated to '11.11'.

Related Enterprise PR: odoo/enterprise#110792

task-6033027

closes odoo#258390

Related: odoo/enterprise#110792
Signed-off-by: Florian Gilbert (flg) <flg@odoo.com>
Some UBL invoices we receive both have a node CustomizationID signifying
that it's a bis3 and a UBLVersionID 2.1 (which should be illegal).
We don't block malformed bis3 invoices.
But we should try to guess that it's a bis3 if it has the perfect
customization.
We can keep the fallback in case it's an unknown bis3 format.

closes odoo#263285

Signed-off-by: Laurent Smet (las) <las@odoo.com>
pro-odoo and others added 19 commits May 7, 2026 15:52
odoo/o-spreadsheet@79ef1d87e8 [REF] lint: enforce braces for all control statements [Task: 6140827](https://www.odoo.com/odoo/2328/tasks/6140827)

closes odoo#263263

Signed-off-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
Co-authored-by: Florian Damhaut (flda) <flda@odoo.com>
Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com>
Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com>
Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com>
Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com>
Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com>
Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com>
Co-authored-by: Rémi Rahir (rar) <rar@odoo.com>
Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com>
Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
Steps to reproduce
-----
- Modules: Sale, Purchase, Mrp, Accounting
- Enable automatic accounting & anglo-saxon valuation
- Create an AVCO Product category (AVCO automatic valuation)
- Create a Kit product storable & AVCO
    - Kit bom
    - Comp as a component (storable & AVCO)
- Settings > Decimal Accuracy > Product Price > set to 4 digits
- Purchase 3 units of Comp at 3.3333 piece & validate reception
- Make 2 sales for 1 unit of Comp each & validate both delvieries
- Create a SO for 1 Kit and 1 Comp & confirm
- Create & confirm invoice
- Go to the delivery, force quantity on the component and try to validate
    delivery

> Error message: "You are trying to reconcile some entries that are already
    reconciled."

/!\ Fun(?) fact: this error doesn't occur if the order of the moves is inverted.

Cause
-----
When the purchase delivery is validated, a stock valuation layer is created for
3 units with a value of 10. As they are sold individually, these 3 units
generate a valuation layer for 3.33 per unit summing to 9.99.

When we validate the last delivery, the 0.01 difference is detected and an
adjustment is made on the valuation layer in `_prepare_out_svl_vals`.

However this adjustment is made for the product when the invoice line concerns
the kit. As a result, the first reconciliation fails and the line is added to
the list to be reconciled later.

Then, when handling the line for COMP2, it will successfully reconcile the lines
while it is still in the pool to be reconciled, resulting in an error when
attempting to reconcile it later.

This is caused by `_stock_account_anglo_saxon_reconcile_valuation` where the
`product_stock_moves` only contains the kit move when called with the kit
product as argument, but it contains both moves when called with the component
itself as argument. This leads to the same AML being reconciled twice.

https://github.com/odoo/odoo/blob/f0b9f4c234cd0101f5cb259e58620e1cf65bb2b7/addons/stock_account/models/account_move.py#L222-L225

-----
Ticket:
opw-5722072

closes odoo#258013

Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
Before this commit, creating an invoice with an Early Payment Discount (EPD) as a payment term
could cause the schematron validation of the generated invoice to fail when an invoice line
had a 0% tax.

The issue was caused by generating two TaxSubtotal nodes for the same TaxCategory (0%, exemption
code 'E'):
- one for the 0% VAT
- one for the EPD discount applied to the total amount

However, Peppol requires a single VAT breakdown (TaxSubtotal) per VAT category (in this case: E)

Additionally, when VAT was set to 0%, the allowance charge TaxSubtotal incorrectly used 'S'
as a hardcoded tax category code.

Another issue (rare, but could happen) is that we group the epd taxes only by percent.
If we have 2 tax details with the same percent but different tax category, we would substract
the the combined (for both tax categories) EPD amount from both.

This commit fixes the 3 issues.

task-5900496

closes odoo#254199

Signed-off-by: Sven Führ (svfu) <svfu@odoo.com>
**Problem:**
When a branch user with no access to the parent company tries to create a
transaction for a parent company's journal with a foreign currency set, this
will raise an access error.

**Steps to Reproduce:**
- Make a branch of "My Company (San Francisco)"
- Set user "Marc Demo" to only have access to the branch
- Add a new bank journal set to "EUR" currency
- Switch to Marc Demo
- Try to add a transaction in the new bank journal

**Root Cause:**
When a transaction is created, Odoo determines the amount in company currency
by converting it from the foreign currency. The method to convert currency uses
"with_company()" to use the company's rates, but the allowed companies of the
branch user does not have access to the parent company, causing an access
error.

**Solution:**
Call the currency conversion with sudo() to ensure access to the relevant
companies.

opw-6186901

closes odoo#263425

Signed-off-by: Paolo Gatti (pgi) <pgi@odoo.com>
… SOL

Steps to reproduce:
---------------------------------------
1. Install the `sale_timesheet_margin` module
2. Create a product as follows:
    * Type: Service
    * Invoicing Policy: Prepaid/Fixed Price
    * Create on order: Nothing
    * Cost: Add some cost to the product (e.g., 30)
3. Create and Confirm Sale Order with Product (Add Cost field in SOL from the
optional field)
4. Now add a new Sales Order Line (SOL) with the same product

Observation:
---------------------------------------
The cost of the recently created Sales Order Line (SOL) is 0.0, which is not
correctly calculated based on the product's cost.

Issue:
---------------------------------------
The `_compute_purchase_price` method has a filter (`service_non_timesheet_sols`)
that excludes certain sale order lines from the parent's purchase price
computation. When a new sale order line is added to an already confirmed sale
order (state='sale'), the new line inherits the parent SO's state immediately.
That means, the new line matches the filter criteria and gets excluded from
parent computation. The `purchase_price` is never calculated from the product's
`standard_price`

Solution:
---------------------------------------
The added condition, like  EITHER:
1. Has timesheets recorded (`sol.timesheet_ids` is truthy) → Preserve existing
cost
2. OR product has NO standard price (`not sol.product_id.standard_price`) → Use
timesheet-based costing

Code intentionally skips the computation of `service_non_timesheet_sols` lines
to preserve existing values

opw-5351724

closes odoo#253860

Signed-off-by: Joyal Patel (pajo) <pajo@odoo.com>
Configuration:
- Costing method: FIFO, automated valuation
- Multi-currency: PO in a foreign currency (e.g. EUR), company currency USD
- Two different exchange rates: one active at bill date, one at receipt date
- Bill posted before any goods are received

Steps to reproduce:
- Set EUR as a secondary currency with two different rates:
    - Rate 1 on January 1st:  1 EUR = 1 USD
    - Rate 2 on January 8th:  1 EUR = 2 USD
- Create a PO in EUR for 20 units @ 10,000 EUR
- Post the vendor bill dated January 3rd (rate 1 applies: 1 EUR = 1 USD)
- Receive 10 units on a date after January 8th and create a backorder
- Receive the remaining 10 units from the backorder on the same date
- Inspect the stock valuation layers and interim account journal entries
  for both receipts

Prior to this commit:
  The two receipts, identical in quantity, date, and PO price, would produce
  different unit costs in USD. The backorder receipt would be incorrectly
  valued due to a wrong exchange rate being used when computing `receipt_value`
  in `_get_price_unit()`.

  Receipt 2 (backorder):
    SVL 1 value:          $100,000 USD
    Converted to EUR at receipt date (1 USD = 0.5 EUR):
    receipt_value       = $100,000 × 0.5     =  50,000 EUR  (wrong rate)
    total_invoiced_value                     = 200,000 EUR
    remaining_value     = 200,000 - 50,000   = 150,000 EUR
    remaining_qty       = 20 - 10            =        10
    price_unit          = 150,000 / 10       =  15,000 EUR
    Converted to USD at bill date (1 EUR = 1 USD):
    price_unit                               =  $15,000 USD
    SVL value           = $15,000 × 10       = $150,000

  This bug only affects backorder receipts. The first receipt always gets
  `receipt_value = 0` (no prior SVLs exist), so the problematic conversion
  never runs.

After this commit:
  `receipt_value` is now computed using `_get_currency_convert_date()` instead
  of `layer.create_date`. This ensures `receipt_value` and
  `total_invoiced_value` are both expressed in EUR at the same reference rate.

  Receipt 2 (backorder):
    SVL 1 value:          $100,000 USD
    Converted to EUR at bill date (1 EUR = 1 USD):
    receipt_value       = $100,000 × 1.0     = 100,000 EUR  (correct rate)
    total_invoiced_value                     = 200,000 EUR
    remaining_value     = 200,000 - 100,000  = 100,000 EUR
    remaining_qty       = 20 - 10            =        10
    price_unit          = 100,000 / 10       =  10,000 EUR
    Converted to USD at bill date (1 EUR = 1 USD):
    price_unit                               =  $10,000 USD
    SVL value           = $10,000 × 10       = $100,000

  Both receipts now produce identical unit costs regardless of exchange rate
  differences between bill date and receipt date.

closes odoo#262577

Opw: 5426718
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
* Before: the manufactured quantity on product use the planned quantity

* After: Use actual produced quantity

closes odoo#261438

Signed-off-by: William Henrotin (whe) <whe@odoo.com>
## Issue
When creating a job application with a new email address, a `res.partner`
is created with both its name and email set to the email address, even
if a `partner_name` is provided.

## Steps to reproduce
1. Install *Recruitment* (`hr_recruitment`) and *Contacts* (`contacts`)
2. In Recruitment, create a job application:
    - Any Subject
    - Name N
    - Email E
3. Save the job application
4. Go to Contacts
5. **The partner created from the job application has both its name and
email set to the Email E used to create the job application.**

## Cause
The `_inverse_partner_email` passes the email address to `find_or_create`
to create the new res.partner:

https://github.com/odoo/odoo/blob/fc58ff23f491a2063b10ffcd6393a08b90dc7975/addons/hr_recruitment/models/hr_applicant.py#L317-L324

This method is implemented to parse both a name and an email address in
the same string.

https://github.com/odoo/odoo/blob/fc58ff23f491a2063b10ffcd6393a08b90dc7975/odoo/addons/base/models/res_partner.py#L937-L945

We can thus provide both the `partner_name` and the `email_from` to the
method to create a user with a name and an email address properly set.

opw-6111598

Part-of: odoo#260296
Signed-off-by: Bertrand Dossogne (bedo) <bedo@odoo.com>
In multiple tests, the partner created and used for testing is named
*"Test ..."*, which makes it appear far down the alphabetically ordered
list of partners in the POS. This causes an issue in tours when there are over
100 partners existing at once, as only 100 partners are loaded at a time
in the POS' list of partners.

https://github.com/odoo/odoo/blob/e7345340efbd66473da70ccf6680181b158047ce/addons/point_of_sale/models/pos_config.py#L845-L865

In such cases, the desired test partner is not loaded by default, and
thus has to be found by clicking the *Search More* button at the end of
the list in the POS. As this behavior depends on the amount of partners
created, an easier way to work around this issue is to rename the test
partners for them to appear higher up in the list.

closes odoo#260296

Signed-off-by: Bertrand Dossogne (bedo) <bedo@odoo.com>
This reverts commit fcb80cc.
As discussed in [1], the change may break existing customizations or
workflows using non-email logins.

[1]: odoo#258967

task-6094631

closes odoo#263589

Signed-off-by: Francois Georis (fge) <fge@odoo.com>
The sum of individual line extension amounts in UBL/CII exports can
sometimes differ from the total expected amount due to cumulative
rounding differences.

Steps to reproduce:
- Configure rounding to Round Globally
- Have a Belgium company setup
- Have a customer with Peppol enabled
- Create an invoice with many lines where each line amount
  have multiple decimals before rounding (product price
  precision raised to 4, fixed tax with 4 decimals)
- Confirm the invoice

Issue:
Discrepancy between line totals and the document total in the XML,
leading to validation failure
`[BR-CO-10]-Sum of Invoice line net amount (BT-106) = Σ Invoice line net
amount (BT-131)`

Analysis:
When generating e-invoice, we calculate the total line extension amount
from unrounded line amounts.
However, the sum of line rounded values may not equal the rounded sum
of the raw values.
This change tracks the expected rounded sum and compares it to the
actual accumulated sum. If a delta exists, it is distributed across
the lines to ensure the XML is consistent.
Minimalistic backport of d66c299

opw-5871638

closes odoo#263061

X-original-commit: fa0a4e7
Signed-off-by: Laurent Smet (las) <las@odoo.com>
Steps:
Create a task inside any project.
Create a sub-task under that parent task.
Open the sub-task and remove the project (clear the project field).
Look at the status bar at the top of the form view.

Issue:
The status bar is displayed twice (both the Project stages and Personal stages
are visible simultaneously).

Cause:
When the project field is cleared from a sub-task in the UI, conflicting
visibility rules or residual stage data can cause the status bar widget to
render twice.

Fix:
To resolve this, an `onchange` event is added to the `project_id` field. If the
user removes the project from a sub-task, the system now instantly falls back to
the parent task's project and sets `display_in_project = False`. This syncs the
frontend UI with the intended backend behavior, preventing the interface from
entering the broken state and removing the duplicate status bars.

task-6033970

closes odoo#255319

Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
The Issue:
The frontend Kanban view enforces a strict 12-color limit using a
modulo 12 mathematical rule (which calculates the remainder after
dividing by 12).

When the frontend receives our high backend IDs (20-24), it runs this
modulo math (e.g., 23 % 12) to force them into the allowed limit,
converting them into the remainders: IDs  8, 9, 10, 11 and 0.

Because stylesheet was still searching for the original high
numbers (20-24) instead of these modulo results, the custom colors
were completely ignored by the browser.

The Fix:
Updated the stylesheet to target the actual modulo-computed classes
(.oe_kanban_color_8 through 11 and 0). Mapped these classes to their correct
 variables (-success, -info, -warning, -danger, -primary) and
fixed the left border styling so the colors render properly.

task-6064106

closes odoo#256023

Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
Issue:
---

Steps to reproduce:
1- Create a `Discount Code` program.
2- In SO, use `Coupon Code` wizard and use the code.
3- After available rewards are shown, discard the wizard.
4- Re-apply the code.

Validation Error: The promo code is already applied.

As the reward is not applied, this is functionally confusing.
At this point We can see the reward only inside the rewards wizard
view.

If we allow re-apply the code in case no reward line is created for the
`rule.program_id`, we can still see the reward by re-applying the same
code, without any side effects.

opw-6164198

closes odoo#261950

Signed-off-by: Mohammadmahdi Alijani (malj) <malj@odoo.com>
Steps to reproduce:
-------------------
* Install l10n_pe_pos
* Switch to PE company
* Create a pos
* Enable shipping later for that pos
* Open the pos
* Make an order
* Create a new customer inside the pos, fill in all information
* Go to pay the order
* Select the ship later option
* valdiate
> Popup, incorrect address for shipping

Why the fix:
------------
This.pos.cities is a list containing the id of the city and the name string.
For the PE loca we were only setting the city_id field when creating a customer
and not city. Which is the required field when checking addresses.

opw-6070005

closes odoo#257569

Signed-off-by: Stéphane Vanmeerhaeghe (stva) <stva@odoo.com>
@viinbot
Copy link
Copy Markdown

viinbot commented May 12, 2026

@royle-vietnam Viindoo Test Suite has failed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.