Skip to content

[IMP] website: improve design of new s_whatsapp snippet#5164

Closed
anso-odoo wants to merge 10000 commits into
masterfrom
master-whatsapp-snippet-chdh-anso
Closed

[IMP] website: improve design of new s_whatsapp snippet#5164
anso-odoo wants to merge 10000 commits into
masterfrom
master-whatsapp-snippet-chdh-anso

Conversation

@anso-odoo
Copy link
Copy Markdown

@anso-odoo anso-odoo commented May 13, 2026

This PR:

  • Sets Brand colors
  • Ensures dark mode compatibility
  • Ensures keyboard navigation
  • Refines focus and active states
  • Refines sizings
  • Removes unused classes
  • Renames generic class names (e.g: chatbox -> wa-chatbox)
  • Adapts snippet screenshot for the preview
Before After
Screenshot 2026-05-13 at 17 19 35 Screenshot 2026-05-13 at 17 18 27

task-6113374

gawa-odoo and others added 30 commits May 11, 2026 12:00
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#263646

X-original-commit: b575bdc
Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
Before this commit, the "Back on X" text below chats of people that
are away was only displayed in non-compact sidebar.

This comes from `xpath` that targets only the non-compact sidebar.

This commit fixes the issue by adding the `xpath` for the compact
sidebar.

Task-6197362

closes odoo#263634

X-original-commit: 6d2f606
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
# How to reproduce
- Create product #1 & #2
- Create a SO
- Add a section to that SO
- Go to the catalog
- Ensure the section is selected, then add product #1 followed by #2

# The problem
The orders of the product are reversed. #2 is before #1 in the SO

# Cause
Clicking on the Add button will trigger an RPC call to "/product/catalog/update_order_line_info"
that will endup adding a new sale order line :
https://github.com/odoo/odoo/blob/c7f05ae216de64d1f8e76e332bc6dd9cf11ce657/addons/sale/models/sale_order.py#L2222-L2227

To determine the sequence of this new order line, we call `_get_new_line_sequence`.
Since a section_id is given, the new order line is inserted right after, before any
product under the same section :
https://github.com/odoo/odoo/blob/c7f05ae216de64d1f8e76e332bc6dd9cf11ce657/addons/account/models/product_catalog_mixin.py#L59-L63

opw-6175704

closes odoo#263611

X-original-commit: ee3aa07
Signed-off-by: Zachary Vanvlasselaer (zavan) <zavan@odoo.com>
Issue before this commit:
The XML export for branch companies incorrectly identified the branch
as the sender, even when a Peppol parent company was configured.

Steps to reproduce the issue:
1. Download Accounting, Contacts and l10n_be
2. Create a branch for a Belgium company
3. Enable Peppol sending on the parent company
4. Enable Peppol sending on the branch company using the parent company
endpoint
5. Switch to branch company
6. Create a customer invoice in the branch company using a customer who
is on the Peppol network (meaning insert a valid VAT number and then
verify button in the Accounting tab)
7. Confirm and send the invoice via Peppol
8. Download the resulting xml file and check the
"AccountingSupplierParty" nodes. It contains the data of the branch and
not the ones of the parent company

Cause of the issue:
The EDI export logic was fetching the supplier data directly from the
invoice's company record without checking for a delegated Peppol parent
company, ignoring the hierarchical relationship defined in the settings.

Reason to introduce the fix:
This fix ensures that the AccountingSupplierParty in the UBL/CII file
correctly reflects the parent company's data when applicable.

opw-6030526

closes odoo#263784

X-original-commit: eb228d6
Signed-off-by: Sven Führ (svfu) <svfu@odoo.com>
The session id rotates softly every 3 hours

For some features, the mobile app sometimes does requests
"outside" of the mobile app, through a webview for instance,
and if the session rotation interval is reached at that moment,
it rotates the session and the `set-cookie`
instruction setting the new session cookie is received by the
webview only, it's not propagated back to the mobile app.

Then, this could lead for the user to be logged out of the mobile app
if the soft automatic session rotation happens at the very unfortunate
moment the request through that webview happens.

For instance, the mobile app uses a webview to download attachments.
If the session rotation happened during that request, the mobile
app doesn't receive the `set-cookie` header and doesn't receive the new
session id, leading for the user to be logged out of the mobile app.

This revision aims to provide an option for the mobile app
to temporary skip the session rotation for a specific request,
such as the requests done through the webview during downloads.

This option to be able to disable the rotation is not a security threat:
If an attacker passes that header to disable the interval session
rotation, he would avoid the session to be changed every 3 hours,
but if he wouldn't he would still receive the new session id
every 3 hours.
The session rotation is for legitimate user / computer to rotate their session
every 3 hours so that in case of data leak of their browser cookies,
there is a chance the session cookie is already no longer valid when published
on the public web. Legitimate users have no benefit using this option header
to disable the rotation.

closes odoo#263654

X-original-commit: cd830d3
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
Previously, computing warning_employee_rate fetched all analytic lines
associated with projects.task_ids to check if any employee
lacked a sale_order_line in project.sale.line.employee.map.

This approach had two major flaws:
	1- Iterating over all accessible tasks is highly inefficient for
	large projects, especially since many tasks do not even have
	associated analytic lines.

	2- Fetching analytic lines blindly by task_id could pull in lines
	linked to a completely different project_id adding performance issues.

**Solution**:
Since the compute method for the `project_id` field for the `account.analytic.line`
model is making sure that the field `project_id` equal the project
for the task, then we can remove the domain matching for the `task_id`.

We now can replace the `_read_group` with a simple SQL query, filtering out
the unmapped projects directly.

The benchmark done below was on a database that had around $10^7$ analytic lines,
2K `project_sale_line_employee_map` records and $10^6$ tasks with the top 80
projects in terms of the number of `analytic.lines` + projects that had the most
records in the `project_sale_line_employee_map`.

| Before | After |
| :--- | :--- |
| 33.0s | 170.0ms |

closes odoo#263726

X-original-commit: 365d986
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
Before:
The project kanban card's dropdown menu included a `Duplicate` button. Because
this button was placed where it could be easily clicked by accident, and because
it instantly created a new project without any confirmation warning, users were
unintentionally creating duplicate projects.

After:
The `Duplicate` action link is removed from the
`project.project.kanban` view menu template. This prevents accidental
duplications from the kanban view.

closes odoo#255732

Task-id: 6043499
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
pos*: point_of_sale, pos_adyen, pos_online_payment, pos_razorpay,
pos_stripe, pos_viva_com

This commit makes the necessary adaptations to the changes done in
the enterprise commit that adds pos_sale_planning and
pos_sale_renting_planning modules.

task-id: 6192655
Enterprise PR: odoo/enterprise#116714

closes odoo#263480

Signed-off-by: David Monnom (moda) <moda@odoo.com>
…rd kanban

Before this commit, the project updates kanban view used a horizontal
"kanban-list" layout designed for a right-side panel that no longer exists.

This commit redesigns the kanban view as standard vertical cards showing
name, progress bar, task stats with color-coded warnings, date, status
bubble, and user avatar. All related dead JS/SCSS code is removed.
The list view's unnecessary custom js_class is also removed.

task-5993686

closes odoo#256785

Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
This commit hides the “View Task” button from To-Do notification emails sent to
portal users. Since portal users do not have access to view To-Dos, the button
is no longer displayed for them.

task-4908548

closes odoo#235747

Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
Steps to Reproduce:
Click on configure on one of the job positions having a recruiter assigned
Remove the recruiter from the form
Now try to go to Settings App > Manage Users. (You will stuck with an error)
Navigate to users using the menu, and open Mitchell Admin → He is no longer an employee.

Bug Cause:
In HrJob.write(), when recruiter_id changes, the code attempts to update ongoing applications' recruiter by writing:
    application_ids.recruiter_id.user_id = job.recruiter_id.user_id

This traverses the relational chain and writes user_id directly on the existing recruiter employee record instead of reassigning the recruiter on the applications. When recruiter_id is cleared, job.recruiter_id.user_id resolves to False, effectively setting user_id = False on the previous recruiter's hr.employee record,
breaking the link between the employee and their user account.

Bug Solution:
Directly reassign recruiter_id on the ongoing applications instead of mutating the employee's user_id:
application_ids.recruiter_id = job.recruiter_id

closes odoo#263800

Task: 6102209
X-original-commit: 3c426c2
Signed-off-by: Abdelrahman Mahmoud (amah) <amah@odoo.com>
Add a `persistToStorage` flag to `logPosMessage` that mirrors critical
IndexedDB errors to `localStorage["pos_idb_errors"]` in addition to the
posLogger. This ensures error traces are preserved even when the
IndexedDB daemon itself is unavailable.

opw-6150816

closes odoo#263802

X-original-commit: d4476d6
Signed-off-by: David Monnom (moda) <moda@odoo.com>
Signed-off-by: Pedram Bi Ria (pebr) <pebr@odoo.com>
``cls._inherit`` is only for definition model classes. registry model
classes shouldn't use this attribute.

```
class A1:
    _name = 'a'

self.env.registry['a']._inherit == ['base']

class B2:
    _name = 'b'
    _inherit = ['b', 'c']

class A2:
    _inherit = ['a', 'b']

self.env.registry['a']._inherit == ['a', 'b']

class A3:
    _inherit = 'a'

self.env.registry['a']._inherit == ['a']
```

`self.env.registry['a']._inherit` is always used wrongly outside of the
framework.

closes odoo#260982

Related: odoo/enterprise#114817
Related: odoo/upgrade#10028
Related: odoo/upgrade-util#419
Signed-off-by: Chong Wang (cwg) <cwg@odoo.com>
…ters

Before this Commit:
In graph rendering, `formatValue()` delegates to widget formatters
(e.g., formatPercentage), which call `extractOptions()` (from formatFloat).
That function directly accesses `attrs.digits`, assuming `attrs` is defined.

Here, `extractOptions()` could be called without `attrs`, leading to a
traceback when accessing `attrs.digits`.

This commit ensures `attrs` is always defined when calling extractOptions(),
avoiding the crash.

task-6023555

closes odoo#263813

X-original-commit: e94231e
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Signed-off-by: Neel Ajitbhai Shah (nees) <nees@odoo.com>
Before, the "Show weekends" button was disabled directly in the XML.
Now the logic is handled in JS, making it easier to change or update
in the future.

task-5164096

closes odoo#234094

Related: odoo/enterprise#98649
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
Issue:
---
In `tax included` companies, the down payment section is not correctly
calculated.

Steps to reproduce:
- Configure selected company's field account_price_include to be "tax_included"
- Create a sales order
- Create 1 or more down payment invoices for the SO and confirm
- Create a final invoice that pays for the rest of it
- On this final invoice where the down payment(s) are also listed, click on the preview button

Current behavior:
- The down payment section's total is the sum of the subtotal

Expected behavior:
- The down payment section's total should be the sum of the totals

Justification:
---
The amounts included in the invoice report are dependent on the
`company_price_include` field in `res.partner`. If tax_excluded,
subtotals are listed. If `tax_included`, totals are listed.
There was a mismatch between the entries and the section total;
the section entries could have the total as the amount while
the section's sum would be in terms of subtotals.

Fix:
---
On stable we can still rely on `section_subtotal` but set its
amount to total instead of subtotal in case of `tax_included`.

However, this fix is not stable as there is a xpath on `t-set`
expression in `l10n_ar`.
To avoid breaking the views, we can re-set the `section_subtotal`
in the next lines.
This would still cause issues as it will replace the overridden
logic in the `l10n_ar` implementation.
To prevent that issue, we can re-set the `section_subtotal` only
if the value is the same as `get_section_subtotal`, which means
we are in the main implementation and it's safe to re-set the value.

opw-6127615

closes odoo#263379

X-original-commit: 21923af
Signed-off-by: Thomas Becquevort (thbe) <thbe@odoo.com>
Signed-off-by: Mohammadmahdi Alijani (malj) <malj@odoo.com>
**Problem:**
When printing an invoice in English (LTR report) with a product
whose name contains Arabic text and parentheses (e.g.,
لوحة توزيع كهربائية 100 أمبير (شنايدر )), the brackets appear
in the wrong position in the generated PDF.

**Steps to reproduce:**
1. Create a product named: لوحة توزيع كهربائية 100 أمبير (شنايدر )
2. Create an invoice with that product
3. Print the invoice PDF in English
4. Observe the brackets are misplaced in the description column

**Current behavior:**
Parentheses appear detached from the Arabic word they enclose,
floating at the wrong end of the text.

**Expected behavior:**
Parentheses correctly wrap the enclosed Arabic text.

**Cause of the issue:**
Odoo's report CSS sets `direction: ltr` on elements that are
ancestors of the line description span. When CSS `direction: ltr`
targets the same element as `dir="auto"`, wkhtmltopdf's WebKit
engine lets the CSS rule win, keeping the paragraph base direction
as LTR. The Unicode BiDi algorithm then resolves parentheses
(neutral characters) using LTR as the base direction, misplacing
them.

**Fix:**
Placing `dir="auto"` directly on the `<span>` that renders the
line description — rather than the parent `<td>` — avoids the
CSS override. wkhtmltopdf then detects the first strong character
(Arabic) and uses RTL as the base direction for that span,
allowing the BiDi algorithm to correctly position the brackets.

opw-5884712

closes odoo#259614

X-original-commit: 1fad0cc
Related: odoo/enterprise#114157
Signed-off-by: Josse Colpaert (jco) <jco@odoo.com>
Signed-off-by: Youssef Maaouia (yoma) <yoma@odoo.com>
Steps to reproduce:
- Install Contacts and Accounting
- Create a branch company
- Switch to the branch company

Issue:
In the partner form, "Payment Method" field doesn't propose the methods
coming from the parent company.
Same issue on the account move form.
However, in the payment wizard opened from an invoice, the payment
methods from the parent company are available.
The behavior should be consistent.
The payment methods from the parent company should be available from
a branch company.

opw-6001573

closes odoo#261120

X-original-commit: fbdac50
Signed-off-by: Josse Colpaert (jco) <jco@odoo.com>
Version:
- saas-19.3

Steps to reproduce:
- Install the Time Off module
- Go to Settings → Time Off Types
- Click on “Allow Negative”

Issue:
- The form layout for Time Off Type is broken

Cause:
- Before this PR: odoo#249288 , the Allow Negative
  field was inside a <group> tag.
- After the PR, it was moved inside a <div>.

Fix:
- Updated the class based on the new structure to fix the layout

Task-6127402

closes odoo#263823

X-original-commit: 6f02249
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
Prior to this commit, the `compute` method was getting all the projects
that had missing employee sale order line mappings through an SQL query.

The result of the query is supposed to be a tuple but was treated as an
array of `Integer` ids causing trouble while browsing and then later
writing the value for the field.

Since the field `warning_employee_rate` is not used in the views we can
assume that the warning will be `False` for all projects and remove this field
later on Master.

closes odoo#263877

X-original-commit: 862b007
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
According to Decree 70/2025/NĐ-CP, validated e-invoices in Vietnam can
no longer be "canceled" in the system. They must instead be handled via
"Adjustment" or "Replacement" invoices to maintain a proper audit trail.

This commit hides the cancel button on the invoice form view for the
Vietnamese EDI localization.

Task-6150505

closes odoo#262145

Related: odoo/upgrade#10087
Signed-off-by: Jonathan Andika (jand) <jand@odoo.com>
Set tax closing entry to False by default for WHT taxes,
as WHT uses separate payable accounts (PND forms)
and does not require closing entries.

task-6146195

closes odoo#263573

X-original-commit: 0b85718
Signed-off-by: Nicolas Viseur (vin) <vin@odoo.com>
Signed-off-by: Jonathan Andika (jand) <jand@odoo.com>
**Steps to reproduce:**
* Go to Accounting App.
* Open the Journals list view (Configuration > Accounting > Journals).
* Click on the "Action" (cog) menu.

**Observed behavior:**
* The "Import records" option is completely missing.

**Cause:**
* In PR 242277, `create="False"` was added to the `account.journal` list view
  to hide the "New" button, intentionally redirecting users to use the journal
  creation wizard instead.
* However, Odoo's standard `base_import` framework evaluates the XML
  architecture of the view (`config.viewArch.getAttribute("create")`). Because
  `create="False"` was set on the view, the framework automatically hid the
  `Import records` action menu item, assuming importing was entirely restricted.

**Fix:**
* Remove `create="False"` from the XML view architecture so the `base_import`
  framework evaluates it correctly and displays the "Import records" action.
* Introduce a custom `js_class` (`list_no_create`) for the journal list
  view. By explicitly setting `this.activeActions.create = false` inside the
  controller's `setup()` lifecycle method, we can safely hide the inline "New"
  button on the UI layer without interfering with the backend XML architecture
  evaluation.

opw-6132990

closes odoo#263976

X-original-commit: 5b5222b
Signed-off-by: Paolo Gatti (pgi) <pgi@odoo.com>
Signed-off-by: Raj Bhuva (bhra) <bhra@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#263942

X-original-commit: c67f2e4
Signed-off-by: Maxime de Neuville (mane) <mane@odoo.com>
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
Signed-off-by: Nikhil Joransingh (njor) <njor@odoo.com>
Problem:
Sponsor logos were broken on the event sponsor footer cards after [1], even
when `image_128` / `image_512` were set. The QWeb image widget generated
a `srcset` including larger sizes (`image_1024`, `image_1920`) that do not
exist on `event.sponsor`, allowing browsers to pick invalid URLs.

Cause:
The template renders `sponsor.image_128` with the generic image widget, which
auto-generates a `srcset` from the image family. Without restricting it, larger
nonexistent variants are included.

Solution:
Set `t-options` with `"preview_image": "image_128"` in the sponsor footer template
to limit `srcset` to existing variant and ensure valid image URL is selected.

[1]: odoo@36e680f

Task-6079695

closes odoo#263916

X-original-commit: 6bd2de2
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Signed-off-by: Yagnik Parmar (yagp) <yagp@odoo.com>
Problem/Context:
- ETA receiver address was only using partner.street field, causing street2 information to be dropped in generated JSON payloads.

What Changed:
- Street and street2 fields are now concatenated with a single space in the receiver address.
- Added regression test to verify the concatenated street value is correctly generated.

task-6133587

closes odoo#263964

X-original-commit: 64b7497
Signed-off-by: Florian Gilbert (flg) <flg@odoo.com>
Signed-off-by: Adnan Sabbir (adns) <adns@odoo.com>
### Contains the following commits:

odoo/o-spreadsheet@4f00b68bc9 [REL] 19.4.0-alpha.4 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@dd07fc7b0c [FIX] package: husky should run at post install [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@7d7e6ead84 [FIX] workflow: fix the tag definition [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@49c0890579 [FIX] Workflow: fix missing permission to use OpenID Connect [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@cd18e7a27a [FIX] workflow: Split the workflow in parallel jobs [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@5616fbe642 [IMP] named ranges: add support of xlsx import/export [Task: 5462359](https://www.odoo.com/odoo/2328/tasks/5462359)
odoo/o-spreadsheet@857d43fc03 [FIX] composer: remove forced reflow in content editable [Task: 6199661](https://www.odoo.com/odoo/2328/tasks/6199661)
odoo/o-spreadsheet@447b131d18 [FIX] evaluation: error handling on vectorize function [Task: 6009255](https://www.odoo.com/odoo/2328/tasks/6009255)
odoo/o-spreadsheet@15165504ce [FIX] chart: remove masterChartConfig from ScatterChartRuntime [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@87aec758a2 [IMP] charts: add bubble chart [Task: 5262905](https://www.odoo.com/odoo/2328/tasks/5262905)
odoo/o-spreadsheet@8389c44909 [IMP] link: change shortcut [Task: 6179942](https://www.odoo.com/odoo/2328/tasks/6179942)

Part-of: odoo#263931
Signed-off-by: Rémi Rahir (rar) <rar@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>
Task: 6179942
Part-of: odoo#263931
Signed-off-by: Rémi Rahir (rar) <rar@odoo.com>
Part-of: odoo#263931
Signed-off-by: Rémi Rahir (rar) <rar@odoo.com>
### Contains the following commits:

odoo/o-spreadsheet@4f00b68bc9 [REL] 19.4.0-alpha.4 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@dd07fc7b0c [FIX] package: husky should run at post install [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@7d7e6ead84 [FIX] workflow: fix the tag definition [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@49c0890579 [FIX] Workflow: fix missing permission to use OpenID Connect [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@cd18e7a27a [FIX] workflow: Split the workflow in parallel jobs [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@5616fbe642 [IMP] named ranges: add support of xlsx import/export [Task: 5462359](https://www.odoo.com/odoo/2328/tasks/5462359)
odoo/o-spreadsheet@857d43fc03 [FIX] composer: remove forced reflow in content editable [Task: 6199661](https://www.odoo.com/odoo/2328/tasks/6199661)
odoo/o-spreadsheet@447b131d18 [FIX] evaluation: error handling on vectorize function [Task: 6009255](https://www.odoo.com/odoo/2328/tasks/6009255)
odoo/o-spreadsheet@15165504ce [FIX] chart: remove masterChartConfig from ScatterChartRuntime [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)
odoo/o-spreadsheet@87aec758a2 [IMP] charts: add bubble chart [Task: 5262905](https://www.odoo.com/odoo/2328/tasks/5262905)
odoo/o-spreadsheet@8389c44909 [IMP] link: change shortcut [Task: 6179942](https://www.odoo.com/odoo/2328/tasks/6179942)

closes odoo#263931

Signed-off-by: Rémi Rahir (rar) <rar@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>
Yetso and others added 26 commits May 15, 2026 16:17
The notification message when the user doesn't have enough credits used
to say "-> Buy more credits". We reword it to "-> Buy".
Also the "-> buy" wasn't vertically aligned.

Task-6128791

closes odoo#263348

Related: odoo/enterprise#116623
Signed-off-by: Ricardo Gomes Rodrigues (rigr) <rigr@odoo.com>
Before this commit, when making a payment on a Stripe terminal, the only
way to cancel the payment was from the POS interface. In the self order
kiosk, it was impossible to cancel the payment.

After this commit, a cancel button will appear on the payment terminal
for both POS and kiosk Stripe payments.

task-6166789

closes odoo#264728

X-original-commit: 79b981e
Signed-off-by: Yaroslav Soroko (yaso) <yaso@odoo.com>
Signed-off-by: Max Whale (mawh) <mawh@odoo.com>
Steps to reproduce:
1) Select the Treehouse theme from the website editor
2) Add a product to the cart and proceed to payment
3) Complete the payment and reach the confirmation page

Issue:
- The payment success alert message is not displayed properly
  and appears compressed in height.

opw-5976602

closes odoo#263956

X-original-commit: 2f66ace
Signed-off-by: Lina Eweis (liew) <liew@odoo.com>
This commit stabilizes the tour flow by ensuring the sliding panel is
fully closed before proceeding to the next step.

Issue:
The tour steps selects a shape, which triggers [hideSlidingPanel]. That
function focuses a `BuilderButton` after a timeout.

This introduced a race condition: if the timeout executes before the
tour interacts with the `OverlayButtons`, the overlay gets hidden due to
the `focusin` event registered on the builder (outside the iframe) [1],
which ultimately hides the overlay buttons.

The issue made the tour undeterministic following commit [2], which
removed several intermediary steps between the shape selection and the
failing step.

Fix:
Wait for the sliding panel to fully close before continuing the tour
flow.

[hideSlidingPanel]: https://github.com/odoo/odoo/blob/saas-19.3/addons/html_builder/static/src/core/building_blocks/builder_sliding_panel.js#L73-L81
[1]: https://github.com/odoo/odoo/blob/saas-19.3/addons/html_editor/static/src/core/selection_plugin.js#L265
[2]: odoo@fa328f4

runbot-242702

closes odoo#260947

Signed-off-by: Francois Georis (fge) <fge@odoo.com>
Before this commit:
The thread loading error showed a plain text error and a basic retry link.

After this commit:
The error state shows a emoji, keeps the failure reason visible and adds a
fa-refresh icon before Try again.

closes odoo#263839

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Event tickets show a struck-through original price even when a "Fixed
Price" pricelist rule is applied, making it incorrectly appear as a
discount. This is inconsistent with eCommerce shop behavior.

Steps to reproduce
------------------

1. Create an event with a paid ticket (e.g., 100 EUR).
2. Create a pricelist with a "Fixed Price" rule for that ticket (e.g.,
   80 EUR).
3. Open the event registration page.
4. The 100 EUR appears struck-through next to 80 EUR.

Cause
-----

Odoo's website only shows a struck-through original price
for discount rules, not fixed price rules. By design, a fixed price
replaces the original rather than reducing it. However, the event
registration page used a simplified check: it compared the final price
to the original and assumed any difference was a discount. This ignored
the rule type, incorrectly flagging fixed price rules as discounts.

Fix Rationale
-------------

A new helper method on the event ticket model now queries
the applied pricelist rule to determine if it qualifies as a discount.

opw-5993477

closes odoo#264753

X-original-commit: 9cd3771
Signed-off-by: Séna Serge Nshimiyimana (sesn) <sesn@odoo.com>
When merging pages with pypdf, the resulting content is uncompressed. A
compression pass should be done right after to reduce the resulting file
size.

Additionally, this helps alleviate a memory leak in PyPDF2 where
resources in the merged page are not properly released. Newer versions
of pypdf (>=3.15.4) do not have this leak but still see benefits in the
output file size.

In practice the CPU overhead is negligible, and we actually see a speed
increase in cases with high memory usage.

Benchmark
Printing 400 page annual report
|      |Print Time|Peak Memory|Output File|
|------|----------|-----------|-----------|
|Before|142s      |3.6GB      |103MB      |
|After |127s      |0.4GB      |5MB        |

opw-6148786

closes odoo#264779

X-original-commit: bbedf18
Related: odoo/enterprise#117483
Signed-off-by: Lou Habert (loha) <loha@odoo.com>
Signed-off-by: Junqi Wu (juwu) <juwu@odoo.com>
Since `write` is often done record by record because the values written
are different on all lines, the call to `action_undo_reconciliation` is
acually not batched. Even if there is nothing to do, some queries are
still done to make sure that there is nothing to do...

closes odoo#264788

X-original-commit: 83c120e
Signed-off-by: de Wouters de Bouchout Jean-Benoît (jbw) <jbw@odoo.com>
Signed-off-by: William André (wan) <wan@odoo.com>
During validating, the domain validation may trigger a
search on the comodel to ensure the domain is valid.

After [1], the validation still performs the search with Domain
True [here] because it ``search_domain`` is override because of
[comodel_domain] is False with ``Domain.True`` to handle this
checking if already ``search_domain`` is False or not

```
Traceback (most recent call last):
  File "/home/odoo/src/odoo/saas-19.3/odoo/service/server.py", line 1643, in preload_registries
    registry = Registry.new(dbname, update_module=update_module, install_modules=config['init'], upgrade_modules=config['update'], reinit_modules=config['reinit'])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/odoo/src/odoo/saas-19.3/odoo/tools/func.py", line 67, in locked
    return func(inst, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/odoo/src/odoo/saas-19.3/odoo/orm/registry.py", line 224, in new
    load_modules(
  File "/home/odoo/src/odoo/saas-19.3/odoo/modules/loading.py", line 467, in load_modules
    load_module_graph(
  File "/home/odoo/src/odoo/saas-19.3/odoo/modules/loading.py", line 222, in load_module_graph
    load_data(env, idref, mode, kind='data', package=package)
  File "/home/odoo/src/odoo/saas-19.3/odoo/modules/loading.py", line 61, in load_data
    convert_file(env, package.name, filename, idref, mode, noupdate=kind == 'demo')
  File "/home/odoo/src/odoo/saas-19.3/odoo/tools/convert.py", line 716, in convert_file
    convert_xml_import(env, module, fp, idref, mode, noupdate)
  File "/home/odoo/src/odoo/saas-19.3/odoo/tools/convert.py", line 815, in convert_xml_import
    obj.parse(doc.getroot())
  File "/home/odoo/src/odoo/saas-19.3/odoo/tools/convert.py", line 686, in parse
    self._tag_root(de)
  File "/home/odoo/src/odoo/saas-19.3/odoo/tools/convert.py", line 639, in _tag_root
    raise ParseError(msg) from None  # Restart with "--log-handler odoo.tools.convert:DEBUG" for complete traceback
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
odoo.tools.convert.ParseError: while parsing /home/odoo/src/enterprise/saas-19.3/ai/security/security.xml:4
Invalid domain ['|', ('attachment_id.public', '=', True), ('attachment_id.res_access_read', '=', True)]: Cannot search, too many attachments

View error context:
'-no context-'
```

[here]: https://github.com/odoo/odoo/blob/4561e703128963d566a16ab1356c7ef12e44256a/odoo/addons/base/models/ir_attachment.py#L643
[1]: odoo#260753
[comodel_domain]: https://github.com/odoo/odoo/blame/afca863b750ec58f5414a5d47e2e2a64e3eba598/odoo/orm/domains.py#L1440-L1442

upg-4248693
opw-6182400

X-original-commit: e7d0151
Part-of: odoo#264795
Signed-off-by: Krzysztof Magusiak (krma) <krma@odoo.com>
Signed-off-by: Sanchit Gupta (sagu) <sagu@odoo.com>
during opening menu if field is comodel with ``ir.attachment``
it do fail on checking description  field is groupable while
``res_access_read`` search do call because big database can have
more attachment. So it will equal with search limit which is used.

To fix,

Value error is raised to prevent blocking

```
41237-('website_sale.menu_orders_orders', 645, 'Website > eCommerce > Orders > Orders', 1041):
41238- Traceback (most recent call last):
41239-   File "/tmp/tmpci4qg_2w/migrations/base/tests/test_mock_crawl.py", line 344, in crawl_menu
41240-    self.mock_action(action_vals)
41241-   File "/tmp/tmpci4qg_2w/migrations/base/tests/test_mock_crawl.py", line 357, in mock_action
41242-    return self.mock_act_window(action)
41243-           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41244-   File "/tmp/tmpci4qg_2w/migrations/base/tests/test_mock_crawl.py", line 441, in mock_act_window
41245-    views = get_views(
41246-            ^^^^^^^^^^
41247-   File "/home/odoo/src/odoo/saas-19.3/addons/mail/models/mail_thread.py", line 489, in get_views
41248-    res = super().get_views(views, options)
41249-          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41250-   File "/home/odoo/src/enterprise/saas-19.3/web_studio/models/models.py", line 10, in get_views
41251-    result = super().get_views(views, options=options)
41252-             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41253-   File "/home/odoo/src/enterprise/saas-19.3/web_studio/models/ir_ui_view.py", line 52, in get_views
41254-    return super().get_views(views, options)
41255-           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41256-   File "/home/odoo/src/odoo/saas-19.3/odoo/addons/base/models/ir_ui_view.py", line 2947, in get_views
41257-    result['models'][model] = {"fields": self.env[model].fields_get(
41258-                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
41259-   File "/home/odoo/src/enterprise/saas-19.3/web_studio/models/ir_model.py", line 77, in fields_get
41260-    return super().fields_get(allfields, attributes=attributes)
41261-           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41262-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/models.py", line 2637, in fields_get
41263:    description = field.get_description(self.env, attributes=attributes)
41264-                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41265:   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/fields.py", line 933, in get_description
41266-    value = value(env)
41267-            ^^^^^^^^^^
41268-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/fields.py", line 989, in _description_groupable
41269-    model._read_group_groupby(Query(model).table, groupby)
41270-   File "/home/odoo/src/odoo/saas-19.3/addons/analytic/models/analytic_mixin.py", line 145, in _read_group_groupby
41271-    return super()._read_group_groupby(table, groupby_spec)
41272-           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41273-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/models.py", line 2080, in _read_group_groupby
41274-    sql_expr = field.join(table, only_ids=True).id
41275-               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41276-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/fields_relational.py", line 1773, in join
41277-    coquery = comodel._search(codomain, bypass_access=self.bypass_search_access)
41278-              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41279-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/models.py", line 4778, in _search
41280-    sec_domain = sec_domain.optimize_full(self_sudo)
41281-                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41282-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 470, in optimize_full
41283-    return self._optimize(model, OptimizationLevel.FULL)
41284-           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41285-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 484, in _optimize
41286-    previous, domain = domain, domain._optimize_step(model, next_level)
41287-                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41288-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 677, in _optimize_step
41289-    children = self._flatten(child._optimize(model, level) for child in self.children)
41290-               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41291-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 632, in _flatten
41292-    for child in children:
41293-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 677, in <genexpr>
41294-    children = self._flatten(child._optimize(model, level) for child in self.children)
41295-                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41296-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 484, in _optimize
41297-    previous, domain = domain, domain._optimize_step(model, next_level)
41298-                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41299-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 1033, in _optimize_step
41300-    domain = opt(self, model)
41301-             ^^^^^^^^^^^^^^^^
41302-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 1450, in _optimize_any_domain_at_level
41303-    domain = domain._optimize(comodel, level)
41304-             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41305-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 484, in _optimize
41306-    previous, domain = domain, domain._optimize_step(model, next_level)
41307-                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41308-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 677, in _optimize_step
41309-    children = self._flatten(child._optimize(model, level) for child in self.children)
41310-               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41311-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 632, in _flatten
41312-    for child in children:
41313-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 677, in <genexpr>
41314-    children = self._flatten(child._optimize(model, level) for child in self.children)
41315-                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41316-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 484, in _optimize
41317-    previous, domain = domain, domain._optimize_step(model, next_level)
41318-                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41319-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 1020, in _optimize_step
41320-    domain = self._optimize_field_search_method(model)
41321-             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41322-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 1096, in _optimize_field_search_method
41323-    raise original_exception
41324-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/domains.py", line 1059, in _optimize_field_search_method
41325-    computed_domain = field.determine_domain(model, operator, value)
41326-                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41327-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/fields.py", line 1999, in determine_domain
41328-    return determine(self.search, records, operator, value)
41329-           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41330-   File "/home/odoo/src/odoo/saas-19.3/odoo/orm/fields.py", line 85, in determine
41331-    return needle(records, *args)
41332-           ^^^^^^^^^^^^^^^^^^^^^^
41333-   File "/home/odoo/src/odoo/saas-19.3/odoo/addons/base/models/ir_attachment.py", line 478, in <lambda>
41334-    search=lambda self, operator, value: self._search_res_access('read', operator),
41335-                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41336-   File "/home/odoo/src/odoo/saas-19.3/odoo/addons/base/models/ir_attachment.py", line 645, in _search_res_access
41337-    raise UserError(self.env._("Cannot search, too many attachments"))
41338- odoo.exceptions.UserError: Cannot search, too many attachments
41339-
```

closes odoo#264795

X-original-commit: 837bbdb
Signed-off-by: Krzysztof Magusiak (krma) <krma@odoo.com>
Signed-off-by: Sanchit Gupta (sagu) <sagu@odoo.com>
When optizing `('searchable_bool_field', 'in', [True, False])`, the
optimization for the tautology is called after the search method. We
should do it before as this case may not be handled by implementations
which always expect `'in'/'not in', [True]`.

closes odoo#264853

X-original-commit: 7a67274
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Krzysztof Magusiak (krma) <krma@odoo.com>
When trying to spawn new workers, we may fail to detect changes because
of timeouts. Ignore errors as `check_registries` is there to spawn new
workers and should not prevent the server from working.

X-original-commit: 48b8d22
Part-of: odoo#264794
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Krzysztof Magusiak (krma) <krma@odoo.com>
When the registry fails to load, don't log the error when the query
timeouts. The error is already raised and will be handled or logged
appropriately.

closes odoo#264794

X-original-commit: 1669c19
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Krzysztof Magusiak (krma) <krma@odoo.com>
Before this commit, passing record to DiscussAvatar requires to
pass the named prop. For example:

```xml
<DiscussAvatar member="member"/>
<DiscussAvatar channel="channel"/>
<DiscussAvatar user="user"/>
<DiscussAvatar t-if="channel or persona" channel="channel" persona="persona"/>
```

This commit simplifies passing of props to simply `record`:

```xml
<DiscussAvatar record="member"/>
<DiscussAvatar record="channel"/>
<DiscussAvatar record="user"/>
<DiscussAvatar t-if="channel or persona" record="channel or persona"/>
```

This makes it easier to see the mandatory prop and the optional props
for customization, and also makes it easier to add newer records we
support by just adapting the appropriate colored getters that maps
`record` to the appropriate typed record.

closes odoo#264304

Related: odoo/enterprise#117223
Signed-off-by: Thanh Son Dodeur (tso) <tso@odoo.com>
Steps to reproduce:
- Install Accounting and Expenses

- Create an expense:
  * Category: [any]
  * Total: [any]
  * Employee: [create or select one without a bank account]
  * Paid by: Employee (to reimburse)
- Submit
- Post Journal Entries (in Purchases journal)
- Create another expense, submit it and post its journal entries

- Go to the bills list
- Select both bills created from the expenses
- Click on "Pay" and then on "Create Payments"

Issue:
A traceback is raised while creating a payment.

Cause:
In the values used to create the payment, "partner_bank_id" is
an empty "res.partner.bank" recordset instead of False, which
leads to a SQL error because the type of the value is invalid.

opw-6206315

closes odoo#264842

X-original-commit: 2291f0d
Signed-off-by: Ali Alfie (alal) <alal@odoo.com>
Signed-off-by: Anh Thao Pham (pta) <pta@odoo.com>
closes odoo#264865

Signed-off-by: Krzysztof Magusiak (krma) <krma@odoo.com>
Validating an MO while env.company differs from mo.company_id read
company-dependent fields (product.standard_price, product.cost_method)
in the wrong company: raw moves are valued at 0 and the finished move's
price_unit collapses, so the MO ends up with no valuation.

Steps to reproduce:
1. User with access to companies A and B.
2. Product whose standard_price is set in A only.
3. Confirm an MO of company A.
4. Validate it while env.company is B.
  -> Raw + finished moves stored with value 0.

opw-6205741

closes odoo#264785

X-original-commit: a81166e
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Louis Gobert (loug) <loug@odoo.com>
_set_tracking does write(is_storable=bool(tracking)) without
looking at type. A service template imported manually with
tracking='none' thus flips to is_storable=True.

Restrict the inverse to consu templates.

Steps to reproduce:
- Import a CSV with type=service,tracking=none
- You will visually see the Quantity on Hand field on the form view

opw-6203593

closes odoo#264760

X-original-commit: fb88989
Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
Signed-off-by: Louis Gobert (loug) <loug@odoo.com>
In order to work properly, a comparison function must be anti-symmetric,
that is, if compareFn(a, b) gives -1, then compareFn(b, a) should be 1.

In the case of sortChannels, whenever c1.displayName is undefined, it
falls back to comparing ids, but no such behavior is implemented when
c2.displayName is missing, breaking the antisymmetry property. This flaw
in the comparison function can potentially lead to infinite loops.

This commit solves the issue, explicitly handling both c1.displayName
and c2.displayName, in an antisymmetric fashion.

closes odoo#264711

X-original-commit: a73194d
Signed-off-by: Louis Wicket (wil) <wil@odoo.com>
…nt between credit note and original invoice

**STEP TO REPRODUCE**
1. Create an invoice and send it to jofatora.
2. Create a credit note for the invoice, send it to jofatora.
3. Sending the credit note will fail with the following error:
`Request failed: {"EINV_RESULTS":{"status":"ERROR","INFO":[],"WARNINGS":[],"ERRORS":[{"type":"ERROR","status":"ERROR","EINV_CODE":"invoice-persist","EINV_CATEGORY":"Invoice","EINV_MESSAGE":"invoice: Credit invoice buyer info does not match the original invoice"}]},"EINV_STATUS":"NOT_SUBMITTED","EINV_SINGED_INVOICE":null,"EINV_QR":null,"EINV_NUM":null,"EINV_INV_UUID":null}`

**CAUSE**
In `account_edi_xml_ubl_21_jo.py` if the document is a credit note (`is_refund`), we fill the customer party with some default value.
However, the documentation states that the credit note customer party should have the exact same values as the original invoice.

opw-6183573

closes odoo#264880

X-original-commit: d8d8b78
Signed-off-by: Khaled Fahmy (khfa) <khfa@odoo.com>
…ny logo

Currently an error is generated when the user tries to choose theme during
configure the website after set the logo of the company.

Steps to produce an error
- Initilalize DB and set Logo (e.g. [1])
- Install a website and build a website with click `Let's do it`
  and all input your choice
- The error occurs when finally choosing the theme

Error:`UnicodeDecodeError:
'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte'`

This issue occurs because assigning the existing company logo using
`company.logo` returns a `LocalBinaryFile` object instead of raw bytes
after the recent refactor changes with [2]. Attempting to decode this
`LocalBinaryFile` object causes the error.

This commit fix the above issue by using `BinaryBytes(company.logo.content)`,
which returns the expected raw bytes required to set the website logo
from the company logo.

[1]: https://odoocdn.com/openerp_website/static/src/img/assets/png/odoo_logo.png
[2]: odoo@41fe2eb

Sentry- 7475955377

closes odoo#264832

X-original-commit: a07d501
Signed-off-by: Francois Georis (fge) <fge@odoo.com>
Signed-off-by: ANSARI MAHAMADASIF (maan) <maan@odoo.com>
@anso-odoo anso-odoo force-pushed the master-whatsapp-snippet-chdh-anso branch from a1e4144 to dbe3e2a Compare May 18, 2026 06:55
@anso-odoo anso-odoo changed the base branch from master-whatsapp-snippet-chdh to master May 18, 2026 06:58
@anso-odoo anso-odoo closed this May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet