Daily updates from Odoo
Wednesday, May 14, 2025
62 changes
8 changes
Enhancements to existing features
The bank reconciliation search dialog now uses the expected ordering, matching the previous experience from the earlier version. Reference text sizing was also adjusted so longer references display more cleanly and are easier to read.
Original PR description
Adding the right context key to change the order like it was in the old bank rec widget of 18.2. Also correcting a css issues where the ref where too big no task id
Miscellaneous changes
Description ------------ For non-admin users, loading the default kanban view of the Appointment application triggers the compute method `_compute_appointment_counts`. This is quite slow as it calls an override of `_read_group`, which adds an elaborate domain for privacy in `_get_default_privacy_domain`. This patch optimizes domains to generate more efficient queries by: - Simplifying useless sub-queries of the form `fkey in (select id from comodel where id = X)` to `fkey in (X)` where
Original PR description
Description ------------ For non-admin users, loading the default kanban view of the Appointment application triggers the compute method `_compute_appointment_counts`. This is quite slow as it calls an override of `_read_group`, which adds an elaborate domain for privacy in `_get_default_privacy_domain`. This patch optimizes domains to generate more efficient queries by: - Simplifying useless sub-queries of the form `fkey in (select id from comodel where id = X)` to `fkey in (X)` where it makes sense (in `sudo` context) - Adding supporting indexes Benchmark ---------- On odoo.com, the time for a regular user to open the default kanban view of appointments is: | Before (hot) | After (hot) | Speedup | |--------------|-------------|---------| | 11s | 1.2s | 9.2x | Reference --------- task-4744275 Community PR: https://github.com/odoo/odoo/pull/207015 Forward-Port-Of: odoo/enterprise#83916
Before this commit, the test_automatic_invoice_token test would fail with the following traceback: FAIL: TestSubscriptionController.test_automatic_invoice_token Traceback (most recent call last): File "/data/build/enterprise/sale_subscription/tests/test_subscription_controller.py", line 157, in test_automatic_invoice_token subscription = self._portal_payment_controller_flow() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/data/build/enterprise/s
Original PR description
Before this commit, the test_automatic_invoice_token test would fail with the following traceback: FAIL: TestSubscriptionController.test_automatic_invoice_token Traceback (most recent call last):…
Before this commit, the test_automatic_invoice_token test would fail
with the following traceback:
FAIL: TestSubscriptionController.test_automatic_invoice_token
Traceback (most recent call last):
File "/data/build/enterprise/sale_subscription/tests/test_subscription_controller.py", line 157, in test_automatic_invoice_token
subscription = self._portal_payment_controller_flow()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/tests/test_subscription_controller.py", line 235, in _portal_payment_controller_flow
self.assertEqual(subscription.invoice_ids.sorted('id').mapped('state'), ['posted'])
AssertionError: Lists differ: ['posted', 'posted'] != ['posted']
First list contains 1 additional elements.
First extra element 1:
'posted'
- ['posted', 'posted']
+ ['posted']
The issue was detected when the test was running on the last day of the
month.
When we were not on the last day of the month, in the controller /my/subscriptions/<int:order_id>/transaction
invoice_to_pay was None because there was only once invoice already paid.
As a result, amount_to_invoice was 0.0 in this code:
amount_to_invoice = invoice_to_pay.amount_total if invoice_to_pay else order_sudo.amount_to_invoice
a tx with an amount equal to 0 would be created in the controller and
in payment_transaction.py, during the postprocess, a "partially paid tx" would be found as the amount would not match (2.3 and 0.0).
We prefer to fix the test by making sure an amount is set in the parameters of the controller. It will make the flow more coherent and realistic.
\# Explanation
When /my/subscriptions/<int:order_id>/transaction was called the second
time in the test, no amount kwarg was provided. As a result the
following line would be called in the controller:
amount_to_invoice = invoice_to_pay.amount_total if invoice_to_pay else order_sudo.amount_to_invoice
invoice_to_pay is always None and therefore the amount_to_invoice is
equal to order_sudo.amount_to_invoice
When we look,at _compute_amount_to_invoice, we have:
is_invoice_due = (
not order.last_invoice_date
or (order.next_invoice_date <= today and order.last_invoice_date <= today)
)
if not is_invoice_due:
line.amount_to_invoice = 0.0
continue
We will compare when the code run on the 30th of march or on the 31th of
march.
\## 30th of March
next invoice date is 2025-04-30
start date is 2025-03-30
last_invoice_date is 2025-03-30
next_invoice_date <= today is False
last_invoice_date <= today is True
is_invoice_due = (
not order.last_invoice_date
or (order.next_invoice_date <= today and order.last_invoice_date <= today)
)
Therefore is_invoice_due is False and we enter the condition and set the amount_to_invoice equal to 0.0
\## 31th of March
next invoice date is 2025-04-30
start date is 2025-03-31
last_invoice_date is False
next_invoice_date <= today is False (same)
last_invoice_date <= today is False because last_invoice_date is not set
Therefore, is_invoice_due is True and we set amount_to_invoice to the recurring total of the SO.
The issue is occuring because next invoice date is 2025-04-30 in both situations !
2025-03-30 + relativedelta(months=1) is equal to 2025-03-31 + relativedelta(months=1)
In the definition of last_invoice_date, we compare the next invoice date - billing_period to today:
last_date = order.next_invoice_date and order.plan_id.billing_period and order.next_invoice_date - order.plan_id.billing_period
\# When we start the 30th of March:
\# last_date = 30th of april - 1 month = 30th of march
\# When we start the 31th of March:
\# last_date keep the same value because the next_invoice_date is the
same.
start_date = order.start_date or fields.Date.today()
if order.state == 'sale' and last_date and last_date >= start_date:
order.last_invoice_date = last_date <-- 30th of March >= 30th of March (today when we start on the 30th
else:
order.last_invoice_date = False <-- 30th of March is not larger than 31th of March (today when we start on the 31th)
runbot error: 162144
Forward-Port-Of: odoo/enterprise#84542Fixed the following issues in the SLSP reports: - When filters "Including Partners Without TIN" and "Including Importations" are updated, the lines are not refreshed - When the filters above are updated, the name of the current active filters are not refreshed - When "Including Partners Without TIN" is enabled, the grand total does not consider lines from those partners - When exported, amounts from the previous row are carried forward to the current row, if the current row has no
Original PR description
Fixed the following issues in the SLSP reports: - When filters "Including Partners Without TIN" and "Including Importations" are updated, the lines are not refreshed - When the filters above are updated, the name of the current active filters are not refreshed - When "Including Partners Without TIN" is enabled, the grand total does not consider lines from those partners - When exported, amounts from the previous row are carried forward to the current row, if the current row has no value for that amount 4748216 Forward-Port-Of: odoo/enterprise#85336 Forward-Port-Of: odoo/enterprise#85249
**issue:** When a task with an allocated time > 0.0 but no timesheets is created in a shared project (with edit rights), the portal user incorrectly sees 0.0 as the allocated time. **Steps to reproduce:** - Ensure the sale_timesheet module is installed. - Create a new project. - Create a task with allocated time and no timesheets. - Share the project with a portal user (edit permission). In the portal user's kanban view, the allocated time of the task is displayed as 0.0 instead o
Original PR description
**issue:** When a task with an allocated time > 0.0 but no timesheets is created in a shared project (with edit rights), the portal user incorrectly sees 0.0 as the allocated time. **Steps to reproduce:** - Ensure the sale_timesheet module is installed. - Create a new project. - Create a task with allocated time and no timesheets. - Share the project with a portal user (edit permission). In the portal user's kanban view, the allocated time of the task is displayed as 0.0 instead of the correct allocated time. opw-4582705 Forward-Port-Of: odoo/enterprise#84706 Forward-Port-Of: odoo/enterprise#82171
Fix timezone handling by replacing DateTime.fromSQL with deserializeDateTime Ensures date-times are shown in the correct timezone instead of assuming local time. Forward-Port-Of: odoo/enterprise#84966
Original PR description
Fix timezone handling by replacing DateTime.fromSQL with deserializeDateTime Ensures date-times are shown in the correct timezone instead of assuming local time. Forward-Port-Of: odoo/enterprise#84966
Steps to reproduce the bug: - Create a quality point with the following settings: - Measure on: Operation - Picking Type: Manufacturing - Product Category: "All" - Create a storable product “P1”: - Product Category: "All" - BoM: - components: - 1 unit of P1 - Create a manufacturing order to produce one unit of P1 - Confirm it Problem: The manufacturing order is confirmed, but the corresponding quality check is not created. This issue occurs when a quality
Original PR description
Steps to reproduce the bug: - Create a quality point with the following settings: - Measure on: Operation - Picking Type: Manufacturing - Product Category: "All" - Create a storable product “P1”: -…
Steps to reproduce the bug:
- Create a quality point with the following settings:
- Measure on: Operation
- Picking Type: Manufacturing
- Product Category: "All"
- Create a storable product “P1”:
- Product Category: "All"
- BoM: - components: - 1 unit of P1
- Create a manufacturing order to produce one unit of P1
- Confirm it
Problem:
The manufacturing order is confirmed, but the corresponding quality check is not created.
This issue occurs when a quality point is configured with "Measure on:
Operation". In that case, the quality check should be created for
manufacturing orders here:
https://github.com/odoo/enterprise/blob/18.0/quality_mrp/models/stock_move.py#L49-L51
However, an empty record is passed for the product parameter.
As a result, the domain defined here:
https://github.com/odoo/enterprise/blob/18.0/quality_mrp/models/stock_move.py#L19-L21
is evaluated with both product and category set to False, which
prevents the created quality point from being matched and thus no
quality check is created.
https://github.com/odoo/enterprise/blob/6ee3472937118e758399a9577251efad8c4c1195/quality_control/models/quality.py#L175-L177
opw-4762914
Forward-Port-Of: odoo/enterprise#85186
Forward-Port-Of: odoo/enterprise#84683Similar to: https://github.com/odoo/odoo/pull/184830 We've recently introduced a new operator: “is within” in the domain selector, which can be used to find out whether a date is within a dynamic range (e.g. within a month, within 4 days, within 3 weeks, etc.). To works, this domain needs dynamic elements, such as `context_today`, which is defined in `py_builtin.js` and dynamically retrieves the current date. https://github.com/odoo/odoo/blob/17.0/addons/web/static/src/core/py_js/py
Original PR description
Similar to: https://github.com/odoo/odoo/pull/184830 We've recently introduced a new operator: “is within” in the domain selector, which can be used to find out whether a date is within a dynamic…
Similar to: https://github.com/odoo/odoo/pull/184830
We've recently introduced a new operator: “is within” in the domain
selector, which can be used to find out whether a date is within a
dynamic range (e.g. within a month, within 4 days, within 3 weeks, etc.).
To works, this domain needs dynamic elements, such as `context_today`,
which is defined in `py_builtin.js` and dynamically retrieves the
current date.
https://github.com/odoo/odoo/blob/17.0/addons/web/static/src/core/py_js/py_builtin.js#L77-L79
However, the problem isn't limited to this operator in the selector
domain, as it's only been available since 18.0, and this pr target is
17.0.s
In fact, it is possible in certain cases to use these fields via debug
mode, and there are several cases where `uid`, `user`, etc. are used.
There is therefore an inconsistency where users see the use of these
variables in these cases and when they try to use them elsewhere with,
for example, a field of this style:
`("date", "=", context_today())`, they get a traceback.
This happens mainly because, in Python, the domain is evaluated via
`literal_eval`, and since it contains variables that are designed for
the web, it causes a traceback because this function expects to receive
only a correctly formatted string, with no context and no variables.
The community commit (https://github.com/odoo/odoo/pull/204172) handles:
- website/model_page.py:
https://github.com/odoo/odoo/blob/17.0/addons/website/controllers/model_page.py#L13-L18
https://github.com/odoo/odoo/blob/17.0/addons/website/controllers/model_page.py#L47-L50
This commit
handles two other cases:
- web_studio/approval:
Here in this case there are several calls to literal_eval on domains
received from the web, notably to create and check its approval spec.
a function has been used to avoid rewriting the same thing several times
in the file.2
- marketing_automation/activity:
Here too, several calls are made to this file, as in the case of
approval, a function has been created to replace all calls to
`literal_eval`
In all three cases, the problem is the same: the problem is not only
present in `is_within` but in the fact that python has no way of
understanding the domain received from the web, so the same fix has been
applied everywhere:
- First, `to_utc()` is removed from the domain, since it's purely
client-side and this notion doesn't exist in the python server
- We replace the `literal_eval` call with `safe_eval`, which will do
more than just transform a string containing only a literal value of
type X into type X (e.g. tuple, string, number, array, etc.)
- `safe_eval` can therefore either evaluate expressions or execute
statements. In our case, what we really want is to evaluate just a
string like literal_eval with just one more context, and to be able to
define local or global values, such as defining `context_today()`
- For the moment, the values we use are the same as those used by
`is_within`, i.e.:
- context_today()
- relative_delta()
- datetime
- time
opw-4551335
opw-4672902
opw-4678894
opw-4669315
opw-4577091
community: https://github.com/odoo/odoo/pull/204172
Forward-Port-Of: odoo/enterprise#84203
Forward-Port-Of: odoo/enterprise#8256429 changes
Enhancements to existing features
The underlying evaluation logic used by payroll calculations has been simplified to remove outdated options and make behavior more predictable. This reduces confusion for developers maintaining payroll rules while keeping business functionality unchanged.
Original PR description
This PR simplifies `safe_eval` which, up until now, allowed passing global and local namespaces. There is no usecase for this anymore. We want safe_eval exec mode to begave like a top-level module scope. `nocopy` is not needed anymore either. It's a relic of when the context could be dynamic (e.g. for already deleted `RecordDictWrapper` or `QWebContext`). Passed in context is always a dict. It will always be mutated with the local eval namespace dict after evaluation. This all makes `safe_eval` API less confusing. See: odoo/odoo#206846 See: odoo/upgrade-util#265 task-4378806
Menu syncing for UrbanPiper point-of-sale integrations now uses only active option values, reducing the chance of sync errors caused by outdated or inactive product options. This should make menu updates more reliable while simplifying the underlying process.
Original PR description
Before this commit: === - Iterated over each product and its attribute lines to fetch product template attribute values (PTAVs). - Risk of expected singleton error when multiple PTAVs (active/inactive) existed. After this commit: === - Fetch only active PTAVs directly using a filtered search. -Simplified the loop and removed redundant product-option search.
This update lets Odoo’s read-only route logic use values captured directly from the web address, such as an ID or keyword in the URL. It avoids duplicate processing and makes route behavior more accurate for document-related pages.
Original PR description
The signature of `collable` inside `@route(readonly=callable)` was:
class ...(http.Controller):
def callable(self) -> bool:
...
It was possible to access the path, query-string and body via the globalish `request` object:
request.httprequest.path
request.httprequest.args
request.httprequest.get_data()
But it was not possible up to this point to get the parameters extracted from the path.
Take for example the following endpoint:
@route('/endpoint/<word>', readonly=callable)
def endpoint(self, word):
....
The `callable` function has no way to get `word` unless we match the endpoint again.
With this PR we change the definition of those readonly callable once again, this time to include:
- `rule`: the endpoint that was matched along with its `routing` dictionnary (the `@route` extracted informations)
- `args`: a dict containing the arguments extracted from the path.
task-4572591Resolved issues and error corrections
This fixes two IoT-related actions that were still using an outdated internal message name after a recent change. It helps ensure self-order kiosks open correctly and delivery labels can be printed without interruption.
Original PR description
In commit 313bde6, the `_send_message` method was renamed to `send_message`, but not all of its usages were updated. This commit fixes the remaining usages (opening kiosk and printing delivery labels).
Code cleanup and technical improvements
This update streamlines internal AI agent code by removing inputs that the system can already determine automatically. It reduces maintenance complexity without changing the visible user experience.
Original PR description
Some method args can be removed because they can be inferred from `self` and its field values like the `topic_ids`.
Miscellaneous changes
During uninstall, fields (columns) bound to the module get deleted first, so the columns used for the search don't exist anymore and the search fails, which leads to the tables not being properly dropped, which can then lead to the module reinstallation not being clean e.g. because there are rows left in the table which can lead to constraints not being addable on install. This has been the cause of `resource` failing forever in the uninstall nightly test: it's most likely been failing since
Original PR description
During uninstall, fields (columns) bound to the module get deleted first, so the columns used for the search don't exist anymore and the search fails, which leads to the tables not being properly dropped, which can then lead to the module reinstallation not being clean e.g. because there are rows left in the table which can lead to constraints not being addable on install. This has been the cause of `resource` failing forever in the uninstall nightly test: it's most likely been failing since this hook was introduced. Forward-Port-Of: odoo/enterprise#85439
Description ------------ For non-admin users, loading the default kanban view of the Appointment application triggers the compute method `_compute_appointment_counts`. This is quite slow as it calls an override of `_read_group`, which adds an elaborate domain for privacy in `_get_default_privacy_domain`. This patch optimizes domains to generate more efficient queries by: - Simplifying useless sub-queries of the form `fkey in (select id from comodel where id = X)` to `fkey in (X)` where
Original PR description
Description ------------ For non-admin users, loading the default kanban view of the Appointment application triggers the compute method `_compute_appointment_counts`. This is quite slow as it calls an override of `_read_group`, which adds an elaborate domain for privacy in `_get_default_privacy_domain`. This patch optimizes domains to generate more efficient queries by: - Simplifying useless sub-queries of the form `fkey in (select id from comodel where id = X)` to `fkey in (X)` where it makes sense (in `sudo` context) - Adding supporting indexes Benchmark ---------- On odoo.com, the time for a regular user to open the default kanban view of appointments is: | Before (hot) | After (hot) | Speedup | |--------------|-------------|---------| | 11s | 1.2s | 9.2x | Reference --------- task-4744275 Community PR: https://github.com/odoo/odoo/pull/207015 Forward-Port-Of: odoo/enterprise#85401 Forward-Port-Of: odoo/enterprise#83916
Version: - saas-18.3 Steps to reproduce: - Add one template. - Add two signer. - Try to send/sign now template Issue: - The second signer (the one added last) doesn't appear in the signing wizard. Cause: - The saveBeforeAction() function calls signStatus.save(), which tries to save multiple document iframes at once but doesn't wait for all of them to finish saving. Solution: - Modify the save() method to return a Promise that resolves only after all Document saves are complete
Original PR description
Version: - saas-18.3 Steps to reproduce: - Add one template. - Add two signer. - Try to send/sign now template Issue: - The second signer (the one added last) doesn't appear in the signing wizard. Cause: - The saveBeforeAction() function calls signStatus.save(), which tries to save multiple document iframes at once but doesn't wait for all of them to finish saving. Solution: - Modify the save() method to return a Promise that resolves only after all Document saves are complete. Forward-Port-Of: odoo/enterprise#85367
Steps to reproduce: === - Install the pos_urban_piper module. - Configure UrbanPiper credentials. - Place a test order. - Open the preparation display. - The display remains blank, and a Traceback occurred. Issue: === - Traceback or incorrect behavior while accessing delivery information. - Duration countdown is not working properly. - Some UI issues due to missing field references. Cause: === - Preparation display was revamped (https://github.com/odoo/odoo/pull/201170, https:/
Original PR description
Steps to reproduce: === - Install the pos_urban_piper module. - Configure UrbanPiper credentials. - Place a test order. - Open the preparation display. - The display remains blank, and a Traceback occurred. Issue: === - Traceback or incorrect behavior while accessing delivery information. - Duration countdown is not working properly. - Some UI issues due to missing field references. Cause: === - Preparation display was revamped (https://github.com/odoo/odoo/pull/201170, https://github.com/odoo/enterprise/pull/78493). - preparationDisplay renamed to prepDisplay. - Wrong field access in delivery information. Fix: === - Updated preparationDisplay to prepDisplay. - Fixed condition to properly show scheduled delivery time. task-4755595 Forward-Port-Of: odoo/enterprise#84256
Commit odoo/odoo@abd909498e4fd relaxed the multi-company rule for hr.employee (more records are visible). Instead the action domains were updated to include the restricted company rules (see only from your company) The domains in the Employee dashboard was not updated though. It means the dashboard takes into account employees from other companies (as allowed by the ir.rule) opw-4777122 Forward-Port-Of: odoo/enterprise#85212 Forward-Port-Of: odoo/enterprise#84972
Original PR description
Commit odoo/odoo@abd909498e4fd relaxed the multi-company rule for hr.employee (more records are visible). Instead the action domains were updated to include the restricted company rules (see only from your company) The domains in the Employee dashboard was not updated though. It means the dashboard takes into account employees from other companies (as allowed by the ir.rule) opw-4777122 Forward-Port-Of: odoo/enterprise#85212 Forward-Port-Of: odoo/enterprise#84972
…queryCount Extra query made by the tax engine to retrieve the country from the company. Forward-Port-Of: odoo/enterprise#85315 Forward-Port-Of: odoo/enterprise#85092
Original PR description
…queryCount Extra query made by the tax engine to retrieve the country from the company. Forward-Port-Of: odoo/enterprise#85315 Forward-Port-Of: odoo/enterprise#85092
Beofre this commit: Products with both positive and negative sales order lines in SO can result it total quantity = 0 when calcuating average cost. Causing division by zero error. After this commit: Added a check to prevent division if total quantity of product is zero. Negative order lines are usually used for return of product, it is not included in shipping request. opw-4655713 Forward-Port-Of: odoo/enterprise#84201 Forward-Port-Of: odoo/enterprise#83500
Original PR description
Beofre this commit: Products with both positive and negative sales order lines in SO can result it total quantity = 0 when calcuating average cost. Causing division by zero error. After this commit: Added a check to prevent division if total quantity of product is zero. Negative order lines are usually used for return of product, it is not included in shipping request. opw-4655713 Forward-Port-Of: odoo/enterprise#84201 Forward-Port-Of: odoo/enterprise#83500
Before this commit, the test_automatic_invoice_token test would fail with the following traceback: FAIL: TestSubscriptionController.test_automatic_invoice_token Traceback (most recent call last): File "/data/build/enterprise/sale_subscription/tests/test_subscription_controller.py", line 157, in test_automatic_invoice_token subscription = self._portal_payment_controller_flow() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/data/build/enterprise/s
Original PR description
Before this commit, the test_automatic_invoice_token test would fail with the following traceback: FAIL: TestSubscriptionController.test_automatic_invoice_token Traceback (most recent call last):…
Before this commit, the test_automatic_invoice_token test would fail
with the following traceback:
FAIL: TestSubscriptionController.test_automatic_invoice_token
Traceback (most recent call last):
File "/data/build/enterprise/sale_subscription/tests/test_subscription_controller.py", line 157, in test_automatic_invoice_token
subscription = self._portal_payment_controller_flow()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/tests/test_subscription_controller.py", line 235, in _portal_payment_controller_flow
self.assertEqual(subscription.invoice_ids.sorted('id').mapped('state'), ['posted'])
AssertionError: Lists differ: ['posted', 'posted'] != ['posted']
First list contains 1 additional elements.
First extra element 1:
'posted'
- ['posted', 'posted']
+ ['posted']
The issue was detected when the test was running on the last day of the
month.
When we were not on the last day of the month, in the controller /my/subscriptions/<int:order_id>/transaction
invoice_to_pay was None because there was only once invoice already paid.
As a result, amount_to_invoice was 0.0 in this code:
amount_to_invoice = invoice_to_pay.amount_total if invoice_to_pay else order_sudo.amount_to_invoice
a tx with an amount equal to 0 would be created in the controller and
in payment_transaction.py, during the postprocess, a "partially paid tx" would be found as the amount would not match (2.3 and 0.0).
We prefer to fix the test by making sure an amount is set in the parameters of the controller. It will make the flow more coherent and realistic.
\# Explanation
When /my/subscriptions/<int:order_id>/transaction was called the second
time in the test, no amount kwarg was provided. As a result the
following line would be called in the controller:
amount_to_invoice = invoice_to_pay.amount_total if invoice_to_pay else order_sudo.amount_to_invoice
invoice_to_pay is always None and therefore the amount_to_invoice is
equal to order_sudo.amount_to_invoice
When we look,at _compute_amount_to_invoice, we have:
is_invoice_due = (
not order.last_invoice_date
or (order.next_invoice_date <= today and order.last_invoice_date <= today)
)
if not is_invoice_due:
line.amount_to_invoice = 0.0
continue
We will compare when the code run on the 30th of march or on the 31th of
march.
\## 30th of March
next invoice date is 2025-04-30
start date is 2025-03-30
last_invoice_date is 2025-03-30
next_invoice_date <= today is False
last_invoice_date <= today is True
is_invoice_due = (
not order.last_invoice_date
or (order.next_invoice_date <= today and order.last_invoice_date <= today)
)
Therefore is_invoice_due is False and we enter the condition and set the amount_to_invoice equal to 0.0
\## 31th of March
next invoice date is 2025-04-30
start date is 2025-03-31
last_invoice_date is False
next_invoice_date <= today is False (same)
last_invoice_date <= today is False because last_invoice_date is not set
Therefore, is_invoice_due is True and we set amount_to_invoice to the recurring total of the SO.
The issue is occuring because next invoice date is 2025-04-30 in both situations !
2025-03-30 + relativedelta(months=1) is equal to 2025-03-31 + relativedelta(months=1)
In the definition of last_invoice_date, we compare the next invoice date - billing_period to today:
last_date = order.next_invoice_date and order.plan_id.billing_period and order.next_invoice_date - order.plan_id.billing_period
\# When we start the 30th of March:
\# last_date = 30th of april - 1 month = 30th of march
\# When we start the 31th of March:
\# last_date keep the same value because the next_invoice_date is the
same.
start_date = order.start_date or fields.Date.today()
if order.state == 'sale' and last_date and last_date >= start_date:
order.last_invoice_date = last_date <-- 30th of March >= 30th of March (today when we start on the 30th
else:
order.last_invoice_date = False <-- 30th of March is not larger than 31th of March (today when we start on the 31th)
runbot error: 162144
Forward-Port-Of: odoo/enterprise#84542Fixed the following issues in the SLSP reports: ~~When filters "Including Partners Without TIN" and "Including Importations" are updated, the lines are not refreshed~~ ~~When the filters above are updated, the name of the current active filters are not refreshed~~ - When "Including Partners Without TIN" is enabled, the grand total does not consider lines from those partners - When exported, amounts from the previous row are carried forward to the current row, if the current row has no
Original PR description
Fixed the following issues in the SLSP reports: ~~When filters "Including Partners Without TIN" and "Including Importations" are updated, the lines are not refreshed~~ ~~When the filters above are updated, the name of the current active filters are not refreshed~~ - When "Including Partners Without TIN" is enabled, the grand total does not consider lines from those partners - When exported, amounts from the previous row are carried forward to the current row, if the current row has no value for that amount 4748216 Forward-Port-Of: odoo/enterprise#85336 Forward-Port-Of: odoo/enterprise#85249
**issue:** When a task with an allocated time > 0.0 but no timesheets is created in a shared project (with edit rights), the portal user incorrectly sees 0.0 as the allocated time. **Steps to reproduce:** - Ensure the sale_timesheet module is installed. - Create a new project. - Create a task with allocated time and no timesheets. - Share the project with a portal user (edit permission). In the portal user's kanban view, the allocated time of the task is displayed as 0.0 instead o
Original PR description
**issue:** When a task with an allocated time > 0.0 but no timesheets is created in a shared project (with edit rights), the portal user incorrectly sees 0.0 as the allocated time. **Steps to reproduce:** - Ensure the sale_timesheet module is installed. - Create a new project. - Create a task with allocated time and no timesheets. - Share the project with a portal user (edit permission). In the portal user's kanban view, the allocated time of the task is displayed as 0.0 instead of the correct allocated time. opw-4582705 Forward-Port-Of: odoo/enterprise#84706 Forward-Port-Of: odoo/enterprise#82171
After this commit, the orders that have a preset_time and that are to be prepared for the same day will only be shown if the preset_time is lower than next time slot. related: https://github.com/odoo/odoo/pull/208975 task-4725279 Forward-Port-Of: odoo/enterprise#84957
Original PR description
After this commit, the orders that have a preset_time and that are to be prepared for the same day will only be shown if the preset_time is lower than next time slot. related: https://github.com/odoo/odoo/pull/208975 task-4725279 Forward-Port-Of: odoo/enterprise#84957
Steps to reproduce the bug: - Create a quality point with the following settings: - Measure on: Operation - Picking Type: Manufacturing - Product Category: "All" - Create a storable product “P1”: - Product Category: "All" - BoM: - components: - 1 unit of P1 - Create a manufacturing order to produce one unit of P1 - Confirm it Problem: The manufacturing order is confirmed, but the corresponding quality check is not created. This issue occurs when a quality
Original PR description
Steps to reproduce the bug: - Create a quality point with the following settings: - Measure on: Operation - Picking Type: Manufacturing - Product Category: "All" - Create a storable product “P1”: -…
Steps to reproduce the bug:
- Create a quality point with the following settings:
- Measure on: Operation
- Picking Type: Manufacturing
- Product Category: "All"
- Create a storable product “P1”:
- Product Category: "All"
- BoM: - components: - 1 unit of P1
- Create a manufacturing order to produce one unit of P1
- Confirm it
Problem:
The manufacturing order is confirmed, but the corresponding quality check is not created.
This issue occurs when a quality point is configured with "Measure on:
Operation". In that case, the quality check should be created for
manufacturing orders here:
https://github.com/odoo/enterprise/blob/18.0/quality_mrp/models/stock_move.py#L49-L51
However, an empty record is passed for the product parameter.
As a result, the domain defined here:
https://github.com/odoo/enterprise/blob/18.0/quality_mrp/models/stock_move.py#L19-L21
is evaluated with both product and category set to False, which
prevents the created quality point from being matched and thus no
quality check is created.
https://github.com/odoo/enterprise/blob/6ee3472937118e758399a9577251efad8c4c1195/quality_control/models/quality.py#L175-L177
opw-4762914
Forward-Port-Of: odoo/enterprise#85186
Forward-Port-Of: odoo/enterprise#84683To ease multi-company usage, we introduce the company_id field on insurance views since one insurance per company has to be created Forward-Port-Of: odoo/enterprise#85238 Forward-Port-Of: odoo/enterprise#84968
Original PR description
To ease multi-company usage, we introduce the company_id field on insurance views since one insurance per company has to be created Forward-Port-Of: odoo/enterprise#85238 Forward-Port-Of: odoo/enterprise#84968
If the user deleted some leave types, the payroll app will not be able to function anymore, in this PR we fallback and only browse for the ones that were not deleted Forward-Port-Of: odoo/enterprise#85237 Forward-Port-Of: odoo/enterprise#85119
Original PR description
If the user deleted some leave types, the payroll app will not be able to function anymore, in this PR we fallback and only browse for the ones that were not deleted Forward-Port-Of: odoo/enterprise#85237 Forward-Port-Of: odoo/enterprise#85119
- This fix backport some of the changes made in the `master` PR (https://github.com/odoo/enterprise/pull/80267) to the `saas-18.2 branch`. - Multiples issues were appearing when invoicing a POS order containing settling lines. In this fix we put the quantity of the settling lines to 0 before sending it to the backend (as it's done in `master`), that way when invoicing the settling order it just act as a note and does not create a new debt. - When paying an order with customer account and gener
Original PR description
- This fix backport some of the changes made in the `master` PR (https://github.com/odoo/enterprise/pull/80267) to the `saas-18.2 branch`. - Multiples issues were appearing when invoicing a POS order…
- This fix backport some of the changes made in the `master` PR (https://github.com/odoo/enterprise/pull/80267) to the `saas-18.2 branch`. - Multiples issues were appearing when invoicing a POS order containing settling lines. In this fix we put the quantity of the settling lines to 0 before sending it to the backend (as it's done in `master`), that way when invoicing the settling order it just act as a note and does not create a new debt. - When paying an order with customer account and generating an invoice from PoS, now we can pay (partially or not) the invoice from the backend, and it will be reflected in the PoS (as it's done in `master`). First issue to reproduce (settle order with invoicing): - Open PoS - Select a customer - Pay a product with customer account - Open customer popup and search for this customer (he should have a debt based on the previous amount) - Settle the due account - Click "Payment" - Enable "invoice" - Pay with card - => Open customer popup and look for this customer again, he still have a debt Second issue to reproduce (paying invoice from backend): - Open PoS - Select a customer - Pay a product with customer account - Open customer popup and search for this customer (he should have a debt based on the previous amount) - Close PoS session - Open the backend and go to the customer invoice - Open the invoice and pay it half of the amount - Go back to PoS and open the customer popup - Search for this customer and click settle due accounts - The amount due from the PoS order is not the same (the amount paid from the backend is not reflected in the PoS) task-id: 4751971 community PR: https://github.com/odoo/odoo/pull/207444 Forward-Port-Of: odoo/enterprise#84622 Forward-Port-Of: odoo/enterprise#84117
**Steps To Reproduce:** - Go to accounting -> reconcile. - Select 1 or 2 entries and try to reconcile. **Issue:** - By clicking on the reconcile button, a traceback occurs. **Cause:** - In the new bank reconciliation widget, the field "counterpart_type" is removed from the 'account.reconciliation.model' ([Ref](https://github.com/odoo/odoo/pull/203327/files#diff-c217a13a40a3cc27dc516b899793abecfac8cab9a42fed407d4776bcbc9de9a8L180 )), but it is not removed from one domain, w
Original PR description
**Steps To Reproduce:** - Go to accounting -> reconcile. - Select 1 or 2 entries and try to reconcile. **Issue:** - By clicking on the reconcile button, a traceback occurs. **Cause:** - In the new bank reconciliation widget, the field "counterpart_type" is removed from the 'account.reconciliation.model' ([Ref](https://github.com/odoo/odoo/pull/203327/files#diff-c217a13a40a3cc27dc516b899793abecfac8cab9a42fed407d4776bcbc9de9a8L180 )), but it is not removed from one domain, which causes the traceback. - **Solution:** - The fields which is removed from the 'account.reconciliation.model', is removed from the domain. Task-4784111 Forward-Port-Of: odoo/enterprise#85351
… for On a virgin DB Go to renting => product Enter studio The kanban of product.template triggers an onchange to get default values Before this commit there was a crash due to a bug in the ORM: the compute of the display_price field did not compute the currency_id id correctly. task to solve the ORM bug: 4264573 solving PR: https://github.com/odoo/odoo/pull/165930 runbot-error-161799 Forward-Port-Of: odoo/enterprise#85359
Original PR description
… for On a virgin DB Go to renting => product Enter studio The kanban of product.template triggers an onchange to get default values Before this commit there was a crash due to a bug in the ORM: the compute of the display_price field did not compute the currency_id id correctly. task to solve the ORM bug: 4264573 solving PR: https://github.com/odoo/odoo/pull/165930 runbot-error-161799 Forward-Port-Of: odoo/enterprise#85359
Steps: - install `web_studio` and `documents_spreadsheet` - open documents - open studio on the spreadsheet kanban view (the default one) - change sort by field to "created on" field - error This commit replaces encodeURIComponent with window.encodeURIComponent, because owl won't try to evaluate this variable via the context. And so the fix ```js get renderingContext() { const context = super.renderingContext; context.encodeURIComponent = encodeURIComponent;
Original PR description
Steps:
- install `web_studio` and `documents_spreadsheet`
- open documents
- open studio on the spreadsheet kanban view (the default one)
- change sort by field to "created on" field
- error
This commit replaces encodeURIComponent with window.encodeURIComponent,
because owl won't try to evaluate this variable via the context.
And so the fix
```js
get renderingContext() {
const context = super.renderingContext;
context.encodeURIComponent = encodeURIComponent;
...
}
```
In `DocumentsKanbanRecord` is no longer necessary.
The error occurred because `encodeURIComponent` was not found in the context object.
The reason this fix doesn't work with studio is the view is defined as
```xml
<kanban js_class="documents_kanban"/>
```
and studio does not load view js classes.
And since the fix is in `documents_kanban`, it's not taken into account. opw-4744886
Forward-Port-Of: odoo/enterprise#84411Add in missing modules to tx/config where their pots were auto-added by the pot export sync. Forward-Port-Of: odoo/enterprise#85480
Original PR description
Add in missing modules to tx/config where their pots were auto-added by the pot export sync. Forward-Port-Of: odoo/enterprise#85480
Steps to reproduce: - Activate foreign currency EUR (main company in USD) - Have a Bank journal in EUR - Create one Vendor "Send" payment of 100 EUR - Create a new Vendor batch payment and add the payment. - Open EUR Bank and register an outgoing transaction of 100 EUR - Match the transaction with the Batch payment Issue: Looking at the debit/credit columns it can be seen that the transaction amount is properly converted in company currency, but the batch amount is not converted (rate
Original PR description
Steps to reproduce: - Activate foreign currency EUR (main company in USD) - Have a Bank journal in EUR - Create one Vendor "Send" payment of 100 EUR - Create a new Vendor batch payment and add the payment. - Open EUR Bank and register an outgoing transaction of 100 EUR - Match the transaction with the Batch payment Issue: Looking at the debit/credit columns it can be seen that the transaction amount is properly converted in company currency, but the batch amount is not converted (rate 1.00) This occurs because when the payments in a batch don't have an associated move, the amount residual is converted from payment currency (EUR) to batch currency (still EUR) and not company currency (USD) opw-4656807 Forward-Port-Of: odoo/enterprise#85015 Forward-Port-Of: odoo/enterprise#83632
This PR updates and improves the AI / ChatGPT integration that already existed in odoo for messages and HTML fields. Now instead of a dedicated dialog, that covers the whole screen, the AI chat is integrated with discuss so users can talk with the AI bot as if they were talking with another user. Apart from the visual change, the functionality of the AI was also improved. Now, when the AI is prompted, a JSON with the record's information available to the current user is given to the AI con
Original PR description
This PR updates and improves the AI / ChatGPT integration that already existed in odoo for messages and HTML fields. Now instead of a dedicated dialog, that covers the whole screen, the AI chat is…
This PR updates and improves the AI / ChatGPT integration that already existed in odoo for messages and HTML fields. Now instead of a dedicated dialog, that covers the whole screen, the AI chat is integrated with discuss so users can talk with the AI bot as if they were talking with another user. Apart from the visual change, the functionality of the AI was also improved. Now, when the AI is prompted, a JSON with the record's information available to the current user is given to the AI context in order for the AI to generate more relevant text. If the context requires it (when composing messages/notes) we also input a list of all messages/notes from the chatter in the context, so the AI can take previous conversations about a record into account. When using the AI to improve a piece of text through text selection, no record information is shared. Also a new way to call the AI is added from the top of the chatter. From there, users can ask for a summary of the chatter conversation as well as generate messages and notes directly. A new app is added to change the ai pre-prompts configurations. A new module ai_apps was added to add all the above features. Also some bridge modules were created and some code was moved in order to loosen the dependencies between ai_apps and other modules, making the AI app fully deletable. Previous PR that targetted master: https://github.com/odoo/enterprise/pull/83428 task-4526290 Forward-Port-Of: odoo/enterprise#84868
The Issue: Prior to this commit, retrieving the amount currency from the transaction details caused a traceback. This occurred because the transaction details are stored as a jsonb object, and the code attempted to access a string within a dictionary, resulting in a TypeError mismatch. The Fix: The jsonb object is now converted to a string before processing. Additionally, an IndexError is caught to handle cases where the expected group is not found in the match. opw-4754518 Forward-Port
Original PR description
The Issue: Prior to this commit, retrieving the amount currency from the transaction details caused a traceback. This occurred because the transaction details are stored as a jsonb object, and the code attempted to access a string within a dictionary, resulting in a TypeError mismatch. The Fix: The jsonb object is now converted to a string before processing. Additionally, an IndexError is caught to handle cases where the expected group is not found in the match. opw-4754518 Forward-Port-Of: odoo/enterprise#84769
### Steps to reproduce: - Create an employee with flexible schedule with 8 hours per day - Navigate to Attendance app -> Gantt View - Check the progress bar for the flexible employee - Notice the progress bar will show X/11 ### Cause: This is happening as when calculating the maximum value for the employee's working hours we are adding a day to the date range https://github.com/odoo/enterprise/blob/2da6836520c4e7760e57062e3e97a22b744baacf/hr_attendance_gantt/models/hr_attendance.py#L
Original PR description
### Steps to reproduce: - Create an employee with flexible schedule with 8 hours per day - Navigate to Attendance app -> Gantt View - Check the progress bar for the flexible employee - Notice the progress bar will show X/11 ### Cause: This is happening as when calculating the maximum value for the employee's working hours we are adding a day to the date range https://github.com/odoo/enterprise/blob/2da6836520c4e7760e57062e3e97a22b744baacf/hr_attendance_gantt/models/hr_attendance.py#L47 ### Fix: We don't need to add this extra day as already the difference between the start and stop is relfecting the correct number of days opw-4680513 Forward-Port-Of: odoo/enterprise#84250
Steps to reproduce: 1. Go to documents 2. Try to mark your favourite document 3. It will ghost you. Technical Reason: Used record.load() as value was not updating instantly in the UI. 'this.props.record.data[this.props.name] = result' fetched correct value, but didn’t trigger re-render. After this commit: favorite icon state updates instantly. Task-4766725 Forward-Port-Of: odoo/enterprise#84666
Original PR description
Steps to reproduce: 1. Go to documents 2. Try to mark your favourite document 3. It will ghost you. Technical Reason: Used record.load() as value was not updating instantly in the UI. 'this.props.record.data[this.props.name] = result' fetched correct value, but didn’t trigger re-render. After this commit: favorite icon state updates instantly. Task-4766725 Forward-Port-Of: odoo/enterprise#84666
25 changes
Enhancements to existing features
This update improves and fixes automated tests for Hoot and several Odoo Enterprise test areas, including Gantt views, dashboards, Studio, and the web client. It helps Odoo maintain product quality while keeping changes limited to internal testing, so business impact and rollout risk are low.
Original PR description
## Pull Request HOOT (PRHOOT) 31 This pull requests brings various improvements and fixes to Hoot and the Odoo unit test ecosystem. See the different commit messages for more details. Note: these changes are made in stable to avoid having to support multiple versions of the HOOT API. As such, these changes are intended to be strictly limited to unit tests as to not put the rest of the code base at risk. Community: https://github.com/odoo/odoo/pull/205405 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This update improves Odoo's internal Hoot testing tools and related unit tests so developers can run tests more consistently and with fewer false failures. The changes are intentionally limited to the test ecosystem, reducing risk to day-to-day business features while improving product quality assurance.
Original PR description
## Pull Request HOOT (PRHOOT) 31 This pull requests brings various improvements and fixes to Hoot and the Odoo unit test ecosystem. See the different commit messages for more details. Note: these changes are made in stable to avoid having to support multiple versions of the HOOT API. As such, these changes are intended to be strictly limited to unit tests as to not put the rest of the code base at risk. Enterprise: https://github.com/odoo/enterprise/pull/83169 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The HTML editor now hides its floating toolbar when scrolling would push it outside the editable area. This prevents the toolbar from covering fixed page elements like headers, improving the editing experience in scrollable content.
Original PR description
Problem: In a scrollable editable, the floating toolbar may overflow and appear on top of fixed elements like headers. Solution: Detect overflow relative to the scrollable container and hide the toolbar when it is no longer fully visible. Before:  After:  Steps to reproduce: 1. Open the TODO app. 2. Add enough content to make the editable scrollable. 3. Open the floating toolbar on the first element. 4. Scroll down. → The toolbar overlaps with the page header. opw-4770575 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where Firefox could delete a backtick character while users were typing in the HTML editor. The editor now avoids interrupting Firefox's text input process unless it is actually applying inline code formatting, helping preserve what users type.
Original PR description
Problem: In Firefox, typing the backtick character "`" can cause it to be automatically deleted. Cause: Typing "`" initiates a composition session. If the selection is changed while `isComposing` is true, Firefox cancels the session and deletes the character. Solution: In `InlineCodePlugin.onInput`, the selection is now modified only when the `<code>` tag is applied. This intentional change ends the composition safely. In all other cases, we avoid changing the selection during composition to preserve user input. Steps to reproduce: 1. Open the HTML editor in Firefox. 2. Type "`". → The character disappears unexpectedly. opw-4760478 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Sharing a project no longer removes the project manager from the follower list. This keeps the responsible manager informed after collaborators are added, avoiding missed project updates.
Original PR description
**Issue:** When sharing a project, the project manager was accidentally removed from the project's followers **Steps to reproduce:** - create a new project. - in the project settings, click “Share Project”. - add a collaborator and share. The project manager disappears from the follower list, leaving only the new collaborator. opw-4764035
When viewing a task in debug mode, opening a timesheet line from the embedded list now shows the dedicated timesheet form instead of the generic analytic item form. This reduces confusion and helps users edit timesheet details in the expected screen.
Original PR description
Before this commit, when the user is in debug mode and go to the form view of a task with some timesheets, he can optionally display the view button in the sub list view of timesheets. The problem is the view button will return the first form view found in timesheet model. Since timesheet model is in fact `account.analytic.line`, the first form view opened is the one used for Analytic Items and not for the timesheets. This commit alters the form view by using `form_view_ref` context key on timesheet_ids field to be able to load the expected form view. task-4781729
Fixes an issue where the Timesheets custom grouping dropdown could close immediately in some browsers. Users can now select custom groups without the timer button unexpectedly taking focus.
Original PR description
**Steps to reproduce** Reproduced on Linux/Firefox. Not reproducible on all browsers. - Open Timesheets app. - Try to add a custom grouping via the "Add Custom Group" select. Bug: the dropdown closes immediately **Cause** Commit 72af4ca4d9859e7236a21cb71401d9f690c42eb6 added an event listener https://github.com/odoo/enterprise/blob/72af4ca4d9859e7236a21cb71401d9f690c42eb6/timesheet_grid/static/src/components/timesheet_timer_header/timesheet_timer_header.js#L41-L48 Depending on the browser, the first click on a `select` may not propagate to its anchestors all the way to the document `body`. However, if it does, the timer button is focused and the dropdown closes. **Solution** Exlude clicks on popover elments from focusing the timer Start/Stop button. opw-4768571
Automatically created approval actions in Studio are no longer counted as custom code lines. This prevents automated system-generated items from affecting usage or billing metrics intended for user-created customizations.
Original PR description
…d not CLOC Before this commit, when approvals created action servers, there were part of the CLOC After this commit, they are not. opw-4784181
This fix makes an automated rental checkout test wait until rental time options are fully loaded before continuing. It reduces false build failures caused by timing issues, helping teams get more dependable test results without changing customer-facing behavior.
Original PR description
The rental_cart_update_duration tour was failing due to a timeout while selecting for the .o_time_picker_select:eq(0) element. This change add a wait step was to ensure the rental options are fully loaded before proceeding. Avoiding flaky behavior caused by timing issues in the UI. build_error-161173
This fixes an uninstall issue where worksheet templates could prevent related database tables from being cleaned up properly. It helps ensure modules can be removed and reinstalled cleanly, reducing failures in automated maintenance tests and avoiding leftover data problems.
Original PR description
During uninstall, fields (columns) bound to the module get deleted first, so the columns used for the search don't exist anymore and the search fails, which leads to the tables not being properly dropped, which can then lead to the module reinstallation not being clean e.g. because there are rows left in the table which can lead to constraints not being addable on install. This has been the cause of `resource` failing forever in the uninstall nightly test: it's most likely been failing since this hook was introduced.
This fix prevents the automated subscription expiration process from replacing an already defined end date with the current date. Businesses keep accurate contract and billing period records when subscriptions are closed after their planned end date.
Original PR description
- 18.0 **Steps to Reproduce:** - Create a subscription with a custom end date (e.g., 2025-04-09). - Manually generate an invoice covering a specific period (e.g., March 10 to April 9). - Wait until after the end date has passed (e.g., run expiration cron on 10 April or later). - The expiration cron triggers and overwrites the manually set end_date with the current date **Issue:** - The expiration cron overrides the existing end_date of the subscription. **Cause:** - The _get_closing_end_date method sets the end_date unconditionally during closure, even when an end_date is already defined. **Solution:** - Update the _get_closing_end_date logic to return the existing end_date if it is already set and valid, preventing it from being overridden when called by the expiration cron. task-4703577
Miscellaneous changes
When the invoice can't be sent via Peppol, we are adding a footer in the Invoice email. We sent this regardless of the partner Peppol status. This PR narrows the cases when we sent the footer. Another issue is that "we recommend" Odoo, we are speaking in the name of our user. A better phrasing will make things fairer, such as this footer keeps its informative value, without being too pushy. task-4782004 Forward-Port-Of: odoo/odoo#209707 Forward-Port-Of: odoo/odoo#209432
Original PR description
When the invoice can't be sent via Peppol, we are adding a footer in the Invoice email. We sent this regardless of the partner Peppol status. This PR narrows the cases when we sent the footer. Another issue is that "we recommend" Odoo, we are speaking in the name of our user. A better phrasing will make things fairer, such as this footer keeps its informative value, without being too pushy. task-4782004 Forward-Port-Of: odoo/odoo#209707 Forward-Port-Of: odoo/odoo#209432
Versions -------- - 16.0+ Steps ----- 1. Enable abandoned cart reminder emails; 2. have an event with a limited number of seats; 3. open a cart for a ticket to the event; 4. abandon the cart; 5. have available seats fill up. Issue ----- You still get an email reminding you to buy the ticket, even though it's no longer available. As a consequence, you can still pay the sales order, but it won't get confirmed. Cause ----- There is no custom logic in place for `website_event_sa
Original PR description
Versions -------- - 16.0+ Steps ----- 1. Enable abandoned cart reminder emails; 2. have an event with a limited number of seats; 3. open a cart for a ticket to the event; 4. abandon the cart; 5. have…
Versions -------- - 16.0+ Steps ----- 1. Enable abandoned cart reminder emails; 2. have an event with a limited number of seats; 3. open a cart for a ticket to the event; 4. abandon the cart; 5. have available seats fill up. Issue ----- You still get an email reminding you to buy the ticket, even though it's no longer available. As a consequence, you can still pay the sales order, but it won't get confirmed. Cause ----- There is no custom logic in place for `website_event_sale` to filter out abandoned carts with tickets that are no longer eligible. Additionally, the `is_sold_out` field of tickets can be `False` while the event's `event_registrations_sold_out` field is `True`. Solution -------- - Add the event's `event_registrations_sold_out` field as a dependency to `event.event.ticket`'s `_comute_is_sold_out` method. - Add an override for `_filter_can_send_abandoned_cart_mail` which filters out carts with tickets that are sold out, or events with no free places remaining. opw-4453539 Forward-Port-Of: odoo/odoo#209565 Forward-Port-Of: odoo/odoo#199877
On slow networks, users or runbot may click checkboxes before the JavaScript is fully loaded by the lazy loader, causing event handlers to not be attached. Fix: Split the test into two separate tours. One while logged in for donation configuration, and another while logged out to test it, since the issue does not occur when the iframe is not present. **Tested with a custom multi-build and the test do not fail anymore** runbot-77224 Forward-Port-Of: odoo/odoo#179885
Original PR description
On slow networks, users or runbot may click checkboxes before the JavaScript is fully loaded by the lazy loader, causing event handlers to not be attached. Fix: Split the test into two separate tours. One while logged in for donation configuration, and another while logged out to test it, since the issue does not occur when the iframe is not present. **Tested with a custom multi-build and the test do not fail anymore** runbot-77224 Forward-Port-Of: odoo/odoo#179885
With Jordan Company setup: - Set dummy values on the Jordan electronic invoicing settings - Enable USD, set a rate and currency precision to 5 - Set the Product Price decimal accuracy to 5 - Make an invoice in USD adding a line as follows: - Price 0.13793 - Qty 9 - Discount 100% - Tax: 16% - Confirm - Send & Print, activate e-invoice (JoFotara (Jordan EDI)) Issue will raise: ``` odoo.addons.base.models.ir_qweb.QWebException: Error while render the template Template: accou
Original PR description
With Jordan Company setup: - Set dummy values on the Jordan electronic invoicing settings - Enable USD, set a rate and currency precision to 5 - Set the Product Price decimal accuracy to 5 - Make an…
With Jordan Company setup: - Set dummy values on the Jordan electronic invoicing settings - Enable USD, set a rate and currency precision to 5 - Set the Product Price decimal accuracy to 5 - Make an invoice in USD adding a line as follows: - Price 0.13793 - Qty 9 - Discount 100% - Tax: 16% - Confirm - Send & Print, activate e-invoice (JoFotara (Jordan EDI)) Issue will raise: ``` odoo.addons.base.models.ir_qweb.QWebException: Error while render the template Template: account_edi_ubl_cii.ubl_20_MonetaryTotalType Path: /t/t/cbc:TaxInclusiveAmount Node: <ns0:TaxInclusiveAmount xmlns:ns0="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" t-att-currencyID="vals[\'currency\'].name" t-out="format_float(vals.get(\'tax_inclusive_amount\'), vals.get(\'currency_dp\'))"/> ``` This occurs because on high currency precision we may work with numbers that are represented in scientific notation (-2e-09) that when converted to string may keep the literal form unless using a specific format opw-4739342 Forward-Port-Of: odoo/odoo#209624
**Issue:** Some tests are failing when "account" module is not installed because they use "account.group_account_invoice". **Solution:** Skip these tests if "account" module is not installed. runbot-163123 runbot-163124 runbot-163125 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#209719 Forward-Port-Of: odoo/odoo#209661
Original PR description
**Issue:** Some tests are failing when "account" module is not installed because they use "account.group_account_invoice". **Solution:** Skip these tests if "account" module is not installed. runbot-163123 runbot-163124 runbot-163125 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#209719 Forward-Port-Of: odoo/odoo#209661
Before this commit, when a product had multiple taxes, the X report was displaying a wrong total base tax amount. This was due to the fact that the tax amount was being calculated as the sum of all the tax bases. This was wrong as the amount tax excluded of the product sold was included twice in this sum. opw-4727830 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#208642
Original PR description
Before this commit, when a product had multiple taxes, the X report was displaying a wrong total base tax amount. This was due to the fact that the tax amount was being calculated as the sum of all the tax bases. This was wrong as the amount tax excluded of the product sold was included twice in this sum. opw-4727830 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#208642
Versions -------- - 16.0+ Steps ----- 1. Have multiple companies; 2. create an eWallet program available to all companies; 3. set its email template to "Gift Card: Gift Card Information"; 4. create & confirm an order containing the "Top-up eWallet" product; 5. switch to a different company; 6. create an new order for the same client. Issue ----- Access Error Cause ----- Commit eaa6f6c5a415f added the `_get_mail_author` method to ensure gift card emails always have an author
Original PR description
Versions -------- - 16.0+ Steps ----- 1. Have multiple companies; 2. create an eWallet program available to all companies; 3. set its email template to "Gift Card: Gift Card Information"; 4. create &…
Versions -------- - 16.0+ Steps ----- 1. Have multiple companies; 2. create an eWallet program available to all companies; 3. set its email template to "Gift Card: Gift Card Information"; 4. create & confirm an order containing the "Top-up eWallet" product; 5. switch to a different company; 6. create an new order for the same client. Issue ----- Access Error Cause ----- Commit eaa6f6c5a415f added the `_get_mail_author` method to ensure gift card emails always have an author. When using the gift card template for eWallets, this can cause an issue for 2 reasons: 1. When creating an eWallet via the top-up product, its `order_id` is the order that created the eWallet. This order may belong to a different company than the one it is getting used for. 2. The `send_reward_coupon_mail` method fetches its coupons by calling `_get_reward_coupons` on the order. This returns any applied eWallets, therefore calling `_send_creation_communication` whenever the eWallet gets used. The reason it returns applied eWallets as a "reward coupon" is because `_update_programs_and_rewards` creates `sale.order.coupon.points` records with 0 points when applying a `loyalty.card`, which then get assumed to be a reward, despite not granting any points: https://github.com/odoo/odoo/blob/9e22dbb7b6fb581d2f11bf0ec48b230047686050/addons/sale_loyalty/models/sale_order.py#L499-L504 Solution -------- 1. In the `_get_mail_author` yield to `super` if the order's company isn't in `self.env.companies`. 2. In the `_get_points_programs` and `_get_reward_coupons` methods, filter out `coupon_point_ids` that don't grant any points. (Alternatively, we could avoid creating `sale.order.coupon.points` records with 0 points, but this might be risky for stable.) opw-4731588 Forward-Port-Of: odoo/odoo#209515 Forward-Port-Of: odoo/odoo#208637
Steps to reporduce: - Make two orderlines that are cannot be merged with same product (add a comment, combo, etc ...) - Open the split bill screen - Selecet any of the orderlines and try to unselect it - Impossible to unselect the orderlines with same product but different line Fix: Calculate the line quantity selected based on the linked order line quantity and not the total number of same product in the order. Description of the issue/feature this PR addresses: Current behavior
Original PR description
Steps to reporduce: - Make two orderlines that are cannot be merged with same product (add a comment, combo, etc ...) - Open the split bill screen - Selecet any of the orderlines and try to unselect it - Impossible to unselect the orderlines with same product but different line Fix: Calculate the line quantity selected based on the linked order line quantity and not the total number of same product in the order. 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 Forward-Port-Of: odoo/odoo#209332 Forward-Port-Of: odoo/odoo#208640
In the case where the name of the related partner is changed, the bank account holder name will not reflect the changes, we add here a dependency on partner_id.name Forward-Port-Of: odoo/odoo#209436
Original PR description
In the case where the name of the related partner is changed, the bank account holder name will not reflect the changes, we add here a dependency on partner_id.name Forward-Port-Of: odoo/odoo#209436
This commit adds an `await animationFrame()` in a reference field test. This makes the first assertion relevant, as it wasn't before (the view could never be there instantly). It also makes the test more robust as it could sometimes fail for the second assertions (race condition), see https://runbot.odoo.com/runbot/build/80157085 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the
Original PR description
This commit adds an `await animationFrame()` in a reference field test. This makes the first assertion relevant, as it wasn't before (the view could never be there instantly). It also makes the test more robust as it could sometimes fail for the second assertions (race condition), see https://runbot.odoo.com/runbot/build/80157085 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 Forward-Port-Of: odoo/odoo#209474
The live chat uses a shadow DOM to preserve its styles. However, shopify hides empty block. Since the live chat root only contains the shadow DOM, it is considered empty which leads to the chat bubble not being displayed. This commit fixes the issue by explicitly setting the "display" style on the live chat root. opw-4768389 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CL
Original PR description
The live chat uses a shadow DOM to preserve its styles. However, shopify hides empty block. Since the live chat root only contains the shadow DOM, it is considered empty which leads to the chat bubble not being displayed. This commit fixes the issue by explicitly setting the "display" style on the live chat root. opw-4768389 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 Forward-Port-Of: odoo/odoo#209592
Issue: ------------ The width of the "Upload and Set" button did not adjust based on its text, resulting in the text being clipped. Fix: ----------- This commit enables automatic width adjustment for the "Upload and Set" button to ensure both the button and its text are fully visible on the same line. Steps to Reproduce (mobile view): ------------------ - Install the project module - Open the task Kanban view - Click on Set Cover Image task-3761269 Forward-P
Original PR description
Issue: ------------ The width of the "Upload and Set" button did not adjust based on its text, resulting in the text being clipped. Fix: ----------- This commit enables automatic width adjustment for the "Upload and Set" button to ensure both the button and its text are fully visible on the same line. Steps to Reproduce (mobile view): ------------------ - Install the project module - Open the task Kanban view - Click on Set Cover Image task-3761269 Forward-Port-Of: odoo/odoo#160913
Description of the issue this commit addresses: When multiple lines that are in budget on their own are above budget when summed together, neither the lines nor the budget button show that the budget will be exceeded. This leads to making purchase orders that shouldn't be made. --- Desired behavior after this commit is merged: This commit makes it so that when the lines together will exceed the budget, the budget smart button and all the lines become red as a single line would.
Original PR description
Description of the issue this commit addresses: When multiple lines that are in budget on their own are above budget when summed together, neither the lines nor the budget button show that the budget will be exceeded. This leads to making purchase orders that shouldn't be made. --- Desired behavior after this commit is merged: This commit makes it so that when the lines together will exceed the budget, the budget smart button and all the lines become red as a single line would. --- task-4710838 Forward-Port-Of: odoo/enterprise#84653
In case of a multi-company enabled database, it was possible to assign a journal to an online account of a different company, which didn't make much sense. Forward-Port-Of: odoo/enterprise#84909 Forward-Port-Of: odoo/enterprise#82080
Original PR description
In case of a multi-company enabled database, it was possible to assign a journal to an online account of a different company, which didn't make much sense. Forward-Port-Of: odoo/enterprise#84909 Forward-Port-Of: odoo/enterprise#82080