Currently when recording global leaves on the ressource calendar
the worked line has no code or description, which are required.
Specify a default value to allow the saving of the payslip.
closesodoo/odoo#29655
Use case: a x2m (ex: attribute values) displayed in a x2m (ex: attributes on
product) using different fields in different views (ex: tags in product form view
and list in product attribute form view). When opening the x2m record (in a
wizard) then going back on the form view, the tags are empty because the
`display_name` value has been lost when fetching x2m for the second time.
In this case, the list `fieldsInfo` needs to be updated with the existing
(default for tags) one so all the fields will be correctly loaded.
Task 1916891
closesodoo/odoo#29598
Before this commit, the notification "Odoobot has a request" would
stay on screen even though the user blocked them in Firefox.
This case occurred when the user clicks on "Not Now", which tells the
browser that the push notifications should be blocked until the next
page reload.
This commit fixes this issue, so that the notification is removed
when clicking on "Not Now", in addition to cleaning tests related
to push notifications.
Task-ID 1918476
closesodoo/odoo#29584
Imagine the following use case: you have a partner (company) with
children (person). Selling a service to that company will create
a task on SO confirmation. Then the project lives its life, and
sometime a person of that company requests a task. The task
customer is the person, but should be linked to the SO as the
time spent on its should be invoiced to the client (the company,
customer of the SO).
This is not possible, as the selectable Sale lines for a task was
the one of the exact partner of the the task.
This commit changes that by checking the commercial partner instead
of the partner. So, for reporting purpose, we can keep the real
customer of the task, and correctly invoice the related timesheet
on the SO of customer company.
opw-1915703
closesodoo/odoo#29921
Create a Sale Order linked to a timesheet, for k hours.
Add the a line for the k hours, invoice the SO.
Then, next time you add a line or modify the value of an existing line,
the SO invoice_status becomes "upselling".
Then, everytime you do it again, it triggers a recompute which writes the
invoice_status "upselling" on the SO.
Now since commit 17c9b7afee every time you write
an invoice_status as "upselling" this creates a new activity to upsell the SO.
However it was intended to run only once, the first time the status changes.
Before creating an activity, we check what was the invoice_status to ignore
records that were already in that state.
opw 1911642
opw 1919283
opw 1919284
closesodoo/odoo#29891
Sending a letter resulted systematically in an error due to the insertion of the binary of the PDF in the JSON sent to IAP-services.
closesodoo/odoo#29880
The original issue is described in #29528, and the commit was reverted
in eb19016ba3.
The root cause of the issue was that the module `base.automation`
performs a `commit()` in `_update_registry`, which is called during a
`create`. This conflicts with the `savepoint` created in `load_demo`.
We postpone the registry reload after installing the demo data. Note
that we only do this in `base_automation`, to limit the potential side
effects.
opw-1920636
Co-authored-by: Raphael Collet <rco@odoo.com>
closesodoo/odoo#29863
This revision moves the `cache_key` to the first level
dict of the cache, instead of the last one.
Doing so, we reduce the number of times the reference
to the cache key is stored in the dict.
For instance,
for 100.000 records, 20 fields and 2 env (e.g. with and without sudo)
formerly, there were 100.000 * 20 * 2 occurences of cache key references
now, there is only 2 references.
Storing references to an object consumes memory.
Therefore, by reducing the number of object references
in the cache, we reduce the memory consumed by the cache.
Also, we reduce the time to access a value in the cache
as the cache size is smaller.
The time and memory consumption are therefore improved,
while keeping the advantages of revision
d7190a3fd0
which was about sharing the cache of fields
which do not depends on the context, but
only on the cursor and user id.
This revision relies on the fact there are less different references
to the cache key then references to fields/records.
Indeed, this is more likely to have 100.000 different records stored
in the cache rather than 100.000 different environments.
Here is the Python proof of concept that was used
to make the conclusion that setting the cache_key
in the first level dict of the cache is more efficient.
```Python
import os
import psutil
import time
from collections import defaultdict
cr = object()
uid = 1
fields = [object() for i in range(20)]
number_items = 500000
p = psutil.Process(os.getpid())
m = p.memory_info().rss
s = time.time()
cache_key = (cr, uid)
cache = defaultdict(lambda: defaultdict(dict))
for field in fields:
for i in range(number_items):
cache[field][i][cache_key] = 5.0
# cache[cache_key][field][i] = 5.0
print('Memory: %s' % (p.memory_info().rss - m,))
print('Time: %s' % (time.time() - s,))
```
- Using `cache[field][i][cache_key]`:
- Time: 3.17s
- Memory: 3138MB
- Using `cache[cache_key][field][i]`:
- Time: 1.43s
- Memory: 756MB
Even worse, when the cache key tuple is instantiated inside the loop,
for the former cache structure (e.g. `cache[field][i][(cr, uid)]`),
the time goes from 3.17s to 25.63s and the memory from 3138MB to 3773MB
Here is the same proof of concept, but using the Odoo API and Cache:
```Python
import os
import psutil
import time
from odoo.api import Cache
model = env['res.users']
records = [model.new() for i in range(100000)]
p = psutil.Process(os.getpid())
m = p.memory_info().rss
s = time.time()
cache = Cache()
char_fields = [field for field in model._fields.values() if field.type == 'char']
for field in char_fields:
for record in records:
cache.set(record, field, 'test')
print('Memory: %s' % (p.memory_info().rss - m,))
print('Time: %s' % (time.time() - s,))
```
- Before (`cache[field][record_id][cache_key]` and cache_key tuple instantiated in the loop):
- Time: 4.12s
- Memory: 810MB
- After (`cache[cache_key][field][record_id]` and cache_key tuple stored in the env and re-used):
- Time: 1.63s
- Memory: 125MB
This can be played in an Odoo shell, for instance
by storing it in `/tmp/test.py`, and then
piping it to the Odoo shell:
`cat /tmp/test.py | ./odoo-bin shell -d 12.0`
closesodoo/odoo#29676
* = account, sale_management, website
Settings that are using groups internally should not appear on the user form
without using debug mode.
The admin should not get the idea that he should configure those per user,
because they are going to be reset if/when changing the general setting.
closes#29842
PR: #29860
The generated query in _generate_goals_from_challenge lacked spaces
between the date clause, which caused a traceback.
The traceback only appears since v12 and above, because the dates are
now casted as dates (::date) in SQL, which has to be followed by a
space. Before that it was "fine" as SQL does allow you to write
g.start_date = '10-10-2017'and g.end_date = '11-11-2017'
Closes#28773closesodoo/odoo#29836
Some aria attributes were missing on menus, and are required to ensure a
good compatibility with keyboard users and screen readers.
To solve the above, the following attributes are included:
- `aria-expanded`: this should be present in all dropdown menus. This is
set on elements with class `dropdown-toggle` and `o_closed_menu`.
- `role`: used to improve given information about what elements are for.
It is added in the following cases:
1. Non-button elements that have the class `dropdown-menu` are set to
`role="button"`.
2. Menu items that have the class `dropdown-item` are set to
`role="menuitem"`.
3. Menu separators that have the class `dropdown-divider` are set to
`role="separator"`.
This is a continuation of baa1c515c5closesodoo/odoo#29719
Suppose calling get_fiscal_year(date, day=29, month=2) with date(year=2017, month=2, day=28)
The computation steps are:
date_from = date(year=2017, month=2, day=28) - 1 year = date(year=2016, month=2, day=28)
date_from = date_from + 1 day = date(year=2016, month=2, day=29)
It's incorrect because the value of date_from must be date(year=2016, month=3, day=1)
closesodoo/odoo#29416
The week_start has been added as an option since commit 27b30daea5.
This stores as a database parameter the day starting the week, [1.. 7] starting
on Monday, while the calendar options expect to get Sunday as 7 % 7 = 0.
As a result the week number would be shifted.
Commit c72403d2ba solved the issue,
this commit adds tests for it.
opw 1916666
closesodoo/odoo#29838
The field ignored is set in javascript on company object to filter the
ones we want to show. As it is not an odoo field, it triggers a
traceback when the trigger_up 'field_changed' is called.
OPW-1921568
closesodoo/odoo#29864
The fields `validity_start` and `validity_stop` are `Date` fields, they
should therefore be compared to `datetime.date`.
opw-1918843
closesodoo/odoo#29834
When using:
```
t-field="res_company.logo" t-options="{'widget': 'image'}"
```
the widget generates a `/web/content/` URL, which ultimately checks the
access rights in method `binary_content`. This means that if the user
doesn't have the `read` access rights on `res_company`, the logo won't
be displayed.
We use the `/logo.png` route instead since it bypasses the access
rights.
opw-1913665
After making improvement to allow user to choose first day of week per
language, it was not taken into account that calendar view uses
different weekdays indexing than newly added field `week_start`. The
difference is in Sunday, where in calendar view it has index 0, but
week_start index is 7 (other days' indexes match).
opw 1916666
closesodoo/odoo#29471
By prefetching only the fields required for the `name_get`
`product.product` & `product.template`
have a huge number of fields,
and prefetching them just to compute
the name is overkill.
Especially, as the browse was done using
sudo, the prefetch was a bit useless as
it was stored in the sudo user cache,
which was most-likely not used afterwards
by the callee of name_get
For a database with 50.000 products,
this reduce the processing time
by 15 (from 60 seconds to 4 seconds measured)
Task 1883977
==== Purpose ====
Keep track of journal entries generated using the reconciliation model.
There is no easy way to see a summary of what journal items have been reconciled with a bank statement. This makes troubleshooting difficult. There should be a way to see the detailed history of which bank statement items were reconciled with which journal items.
==== Technical Specs ====
Make a many2one in account.move.line to retrieve the account.reconcile.model having generated this line.
(Make a computed many2many on account.move to the account.reconcile.model)
Add a stat button on the account.reconcile.model form view to retrieve journal entries more easily.
closesodoo/odoo#28752
Purpose of this commit is to make a single flow to sign and pay in the
customer portal. When having signed its document popup for payment is
automatically opened.
This is much better for usability and avoid to have orders being signed
and not paid because the customer did not see it was still to be paid.
This commit is related to task ID 1910532 and PR #29849 .
Since commit 34c47eecd3 wording of link when
sending a quotation by email is broken. Indeed has document in draft is
not correctly considered as having to be signed and/or paid the link is
not labelled correctly.
This commit fixes it. Parameter is also renamed to be more understandable.
This commit is linked to task ID 1910532 and PR #29849 .
Model methods should be private by default unless they need to be
exposed via RPC on purpose (e.g. for the web client).
The `send_forum_validation_email()` method is only called by a
controller and has no reason to be exposed via RPC, hence the conversion
to private.
Closes#30669
When filtering the calendar view on search filters, the filter `context`
was not taken into account during the reload.
For example, in the Calendar app, the filter 'My Meetings' has a `context`
{'mymeetings': 1} which was not passed to `search_read`.
Task 1917628
closesodoo/odoo#29531
opw-1916064
Have a sales order line on which you decrease the quantity.
Before, this commit, the warning message that says to update the
delivery order did not show. This was because, the onchange in the
python side compared the new quantity against the saved one, and did
not find any difference. This is caused by the onchange itself, which,
in a o2m setting, received from the JS, the changed order
(already containing the changed line) and only then proceeded to the
onchange of the line. The first operation wrote onto _origin the new
line value, which corresponded subsequently to the new value.
After this commit, we compare the real value explicitly retrieved from
the database to the one just entered by the user as an onchange.
The warning message works as expected.
Long story short, _origin in an onchange doesn't guarantee to yield
persisted values in all cases.
closesodoo/odoo#29582
instead of updating the cache by records.
We use `cr.fetchall()` and `zip` to get the values by field, which is more
convenient to be stored in cache.
Result of `cr.fetchall()`:
```
[
(3, 'Marc Demo', 'demo@example.com', '032'),
(1, 'Mitchell Admin', 'admin@example.com', '001'),
]
```
After being grouped by field:
```
[
[3, 1],
['Marc Demo', 'Mitchell Admin],
['demo@example.com', 'admin@example.com'],
['032', '001'],
]
```
That way we can update the cache of a field for all records at once, by calling
the builtin `update` method of `dict` with the `zip` of record ids and
corresponding values.
This significantly speeds up the storage of field values in the cache.
closesodoo/odoo#30817
Instead of iterating on self and then putting the values in the right place in
the `data` dict, iterate over data directly.
This removes the need of the indexing `data[record]`, which takes a significant
time when dealing with hundred of thousands of records.
Calling `len` on a long list and checking that its value is 1 is slower than
just unpacking the list. The point is to check whether there is just one item
in the list, and counting all items just for that is a bit overkill.
Use `env.registry` instead of `env` to get the comodel as a class instead of an
instance, which saves one call to `_browse` each time we access a relational
field. This saves time because of the cost of `object.__new__` and prefetch
update in `_browse`.
The cache is quite time critical, as it is accessed millions times when reading
multiple fields on hundred of thousands of records.
Avoiding indirections and `if` statement when possible speeds up the cache
access time.
- Portal users do not have the rights to read on project.project.
This causes issues on the page "/my/tasks" as it is trying to read the label_tasks and the name of the tasks' project.
To address this issue we read those two fields using sudo
Fixes#30127
opw-1925720
closesodoo/odoo#30955
- The field `signup_valid` was computed and stored using the `superuser`
env, which causes issue since it means the value was computed for the
wrong environment.
Using a compute_sudo instead of manually calling `sudo()` fixes the
issue.
e.g: reading signup_valid using a regular user (non superuser) will
always return False, while doing it as the superuser will return
the correct value.
closesodoo/odoo#30954
- Install a second language, e.g. French
- Set Parter A language to French
- Create an invoice for A with a date due in the past
- On the partner form view, print the 'Due Payments'
The body of the letter is not translated in French.
Something quite weird appears:
- The corresponding string is exported in the `stock` module
- It is linked to the demo data `stock.res_company_1`, which corresponds
to 'My Company, Chicago'.
Therefore, the translation cannot be found by the corresponding query
generated in `_generate_translated_field` and `_read_from_database`:
```
SELECT "res_company"."id" as "id",COALESCE("res_company__overdue_msg"."value", "res_company"."overdue_msg") as "overdue_msg" FROM "res_company" LEFT JOIN
(SELECT DISTINCT ON (res_id) res_id, value
FROM "ir_translation"
WHERE name='res.company,overdue_msg' AND lang='fr_BE' AND value!=''
ORDER BY res_id, id DESC)
as "res_company__overdue_msg" ON ("res_company"."id" = "res_company__overdue_msg"."res_id")
WHERE "res_company".id = 1 ORDER BY "res_company"."sequence" ,"res_company"."name"
```
Indeed, `res_company.id` is 1, while `res_company__overdue_msg.res_id`
is 3.
The root cause has been solved in v11, to we only export the necessary
term.
opw-1908337
closesodoo/odoo#29525