The BoM structure report is recursive, since product X might use a product X.Y,
itself built using a BoM that uses X.Y.Z, and so on.
To avoid breaking the layout in cases with too deep nestedness,
the report returned a level bounded by 6.
This is a totally arbitrary value: the layout can be broken not only
because of nestedness, but also because of the length of the product name.
So it doesn't really solve the problem.
Moreover, a presentation problem should be solved at the presentation layer,
which is CSS.
opw 1921011
closesodoo/odoo#30606
When a user/partner is deleted, their messages lose their author.
Replying to those may result in a failure to fetch the mails from the
incomming mail server.
without this commit, partner_ids == [(4, False)] and this value "goes
down" all the way to the orm method "write" of the Many2many field.
resulting in a SQL query like :
INSERT INTO mail_message_res_partner_rel (mail_message_id, res_partner_id)
(SELECT a, b FROM unnest(ARRAY[149855]) AS a, unnest(ARRAY[false]) AS b)
EXCEPT (SELECT mail_message_id, res_partner_id FROM mail_message_res_partner_rel WHERE mail_message_id IN (149855))
which fails with the ProgrammingError : EXCEPT types boolean and integer
cannot be matched
opw-1921805
closesodoo/odoo#30528
Before this commit, in the customer invoice form, when the outstanding
credits have a big reference or name, the form displayed the name in a
multiple line which made difficult to read and to understand when a
credit starts, and when a credit stops. It also overlapped the name and
the amounts.
Now, when the name is too big, it's truncated, and the full name is
shown when the mouse hovers the field.
OPW-1915966
closesodoo/odoo#30518
- Create a bank statement for a negative amount, e.g. -100.
- Click 'Reconcile'.
- Create a counterpart line for this bank statement, but specify
receivable account.
The payment created has `partner_type` set as `supplier`.
Although a receivable account is used for customers.
This use case can arise in case of a credit note to a customer: the
reimbursement should create a customer payment, not a supplier payment.
Co-authored-by: Nicolas Martinelli <nim@odoo.com>
opw-1910807
closesodoo/odoo#30232
Before this commit, in a multi-companies when the user can manage
multiple stock locations, there is an error with the default Locations
('default location' and 'default Destination Location' in an Unbuild
Orders; and 'Raw Materials Location' and 'Finished Products Location' in
a Manufacturing Orders). The default gives the stock location of the
first company, if we are working in a different company it will generate
an access error. Also, in an Unbuild Order you could choose location
that there are not internal at the company.
Now, the default location, it's the one of the first Warehouse of the
company. And the form only propose to choose internal locations.
OPW-1919771
closesodoo/odoo#30585
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#29676closesodoo/odoo#30554
Before this commit, in the filter, when using a custom filter with a
date field, the operators "is after" and "is before" were set to execute
"is after or equal" and "if before or equal" respectively. That means it
includes in the results, records with the same date as the filter.
Now, the operators 'is after' and 'is before' won't include the records
with the same date as the filter. And the operators 'is after or equal'
and 'is before or equal' will include the records with the same date as
the filter.
Fixes#29868
OPW-1921756
closesodoo/odoo#30560
Because in France the affectation depends on the result (gain or loss) for the selection of account and thus, we cannot arbitrary choose one.
Was PR #17775closesodoo/odoo#30527
Add quantity key to context instead of overwrite the entire context
If another context key was present, it would be lost
Introduced at 166a9d26e3closesodoo/odoo#30519
The sale.order model has an expense_policy selection field, with values in 'no',
'cost', 'sales_price'.
However that value can also be set to False.
The code that handles that field expected the value to always be set to a value.
We explicitly treat False as if it was 'no' (the default value for that field).
opw 1915508
closesodoo/odoo#30336
Use read_group is faster than the python equivalent,
and then don't push ids in ORM cache, which makes
the ORM faster later in the process.
Also unlink in batch.
For editing many2one fields (and partially many2many) most widget show
an autocompleting list of targeted records.
They thus have `autocomplete="off"` to prevent browser completion.
But chromium has an history of breaking `autocomplete="off"`, see:
- https://caniuse.com/#search=autocomplete
- https://crbug.com/468153
- https://crbug.com/587466
- https://crbug.com/914451
- https://crbug.com/923895
It seems that since chromium 71, the heuristic to ignore
`autocomplete="off"` has become more aggressive and for example if there
is at least 3 fields like an address in a page, chromium will ignore
`autocomplete="off"` for the fields like an address.
So for example the eidting the many2One field with placeholder "Country"
in a contact page now has a browser autocomplete menu that is:
- hidding the many2one autocomplete
- going to save empty country it appeared visually filled if the
autocomplete result was selected.
With this changeset, the placeholder in the many2one instance is
interspersed with U+FEFF charcters (ZERO WIDTH NO-BREAK SPACE) so the
browser does enable the autocomplete feature by force.
This should thus remove the issue (until it is fixed by chromium) in the
case of field named "Country" or matching other regexes in this file:
https://github.com/chromium/chromium/blob/cdb1b2073f12/components/autofill/core/common/autofill_regex_constants.cc
U+FEFF has been chosen instead of more recommended characters because
other have been shown erroneous for printing in some windows
configuration (see cb2a3afa7).
10.0 version of #30439
opw-1930588
closes#30439closes#30449
- Create a SO, do not set a partner
- Add a product with a tax
The untaxes amount as well as the taxes remain 0.0.
This is because there is no pricelist, therefore no currency.
There is actually no need of rounding explicitly since these are
monetary fields which will be rounded automatically.
opw-1931796
closesodoo/odoo#30450
OPW 1918926
Current behavior:
The sql query groups by date,id in a intermediary table instead of the result. This allows to get data in the wrong order if the statements were not produced sequentially. The fill values are computed in the wrong order and may override correct values.
Desired behavior:
There is no override of the values correctly computed.
closesodoo/odoo#29936
Define a field on a model as:
- o2m to res.partner
- the field's column, hence its name, has capital letters in it
(studio does that)
create two objects of that class, each one linked to a different partner with the new o2m
merge the partners
Before this commit, the object linked to the second partner, was deleted
This was because merge partner sql requests did not quote the column name
After this commit, the second object still exists
This commit is tested in v12.0 with PR #30300 only. In v10.0 it is not testable as
the model concerned is in CRM, and that no new fields in business modules can be added in stable
OPW 1925060
closesodoo/odoo#30301
Some views have the primary mode while having an inherit_id view
In such views, if the user wants to change the inherit_id,
the mode must remain primary.
The use case behind this is a user who want to change
the inherit_id view of the view
product.product.form (product.product_normal_form_view)
to another view.
This view is in primary mode while having an inherit_id
(product.product_template_form_view).
In such a case, the primary mode must remain,
otherwise the view will no longer be opened by default
when opening a product.
Indeed, when searching the default form view of a model,
it only searches for primary mode views for this model.
The `all` is there because this is an `api.multi` method.
We could consider adding a `self.ensure_one`,
but it breaks the API if someones calls this method with multiple records.
This is likely to happen, as this method is used
in `write` which is likely to be called with multiple records.
In my opinion, in master, this should be replaced by an
onchange so the user can see the change of mode
when he adds or remove an inherit_id for a view.
opw-1916324
closesodoo/odoo#30241
This is essentially a backport of module l10n_be_intrastat_2019 made for
Enterprise v12 + the refactoring needed on the original v10 module to
allow the changes to apply where needed.
Was requested by opw-1887019
closesodoo/odoo#30400
When posting a URL containing a semicolon, odoo stops the link
before the semicolon instead of continuing the link to the end
although it is a valid characters in URL (see RFC-3986)
e.g. the url "example.com&foo;bar" matches "example.com&foo"
instead of the whole link
opw-1918367
closesodoo/odoo#30198
- Create the following attributes with values:
Size: S, M, L, XL
Color: Black, White
- Create a product template with the following attribute values:
Size: S, M, L, XL
Color: Black
The `name_get` of `product.product` returns `Name (SIZE, Black)` while
it should only return `Name (SIZE)`.
When using `attribute_id.value_ids`, the list of values contains all
possible values of the attribute, not only the values which apply to the
given product. In this case, it contains 'Black' and 'White', therefore
the condition `> 1` is verified and the attribute is kept for display.
We go back to the original filtering, and add `attribute_line_ids` in
the list fields read in order to avoid prefetching.
opw-1922140
opw-1922447
closesodoo/odoo#30273
Cherry pick of 5b769650d6 in version 11.0
A customer can pay an order with a non-cash journal (e.g. a credit
card through a stand-alone terminal).
When this order has to be refunded later it should be possible to do
so on that same journal.
Some code prevented this from happening, notably a check in
order_is_valid which explicitly prevented this for an unknown
reason. There is no explanation in the
commit (4647f896a4) introducing that.
This commit allows the following:
1. input what you want to refund with a negative qty
2. click 'Payment'
3. click the Credit Card (type Bank) journal
4. (amount is auto-populated)
5. click 'Validate'
opw-805302
opw-1913731
closesodoo/odoo#30218
- Create a bank statement with more than 80 lines (therefore more than
80 AML)
- Reconcile the lines
- Go back to the bank statement, and try to add a new line
An error arise:
"You cannot do this modification on a posted journal entry, you can just
change some non legal fields"
The error arise on the `move_line_ids` field on which the web client
tries to write.
Actually, this field is hidden since it is only used in the domain of a
stat button. We can make it read-only.
opw-1921138
closesodoo/odoo#30266
The super call of action_payslip_done executes the method compute_sheet.
Without this compute_sheet call, there is no salary lines and no accounting
move is created.
closesodoo/odoo#29737
Start a message mail (respectively note) in the chatter. Attach a file.
Switch to note (respectively mail). The attachment is lost.
With this commit, we keep the attachments after the switch.
opw 1925588
closesodoo/odoo#30197
- Set FIFO as costing method in product category
- Create a stockable product with the category configured previously
- Create a SO with the stockable product for 1 unit with dropship route
and confirm the SO
- Confirm the PO created from the Sale Order to generate the delivery
- Process the stock picking
- Create a new Landed Cost with the stock picking delivered with a cost
line with split method "Equal".
- Generate the valuation adjustments and confirm the landed cost to
generate the journal entry
The debit account is wrong because the system takes the inventory
valuation account instead the expense account.
Odoo must take the expense account because the product never enter to
the company inventory, so is a cost of sale.
opw-1922633
closesodoo/odoo#29947
Detected with OPW 1920765
Reproduce : set multi-companies, install accounting. The due amount for all companies is the sum of the due amount for every single company
Cause : the context for company_id is not set in account.move.line:_query_get
Solution : set it in res.partner:_credit_debit_get in case _query_get is used elsewhere
closesodoo/odoo#30463
Go to 'delivery methods', edit a delivery method.
Click on 'install more providers'.
You land on the 'Apps' app, already filtered on the 'delivery_' modules.
Click on 'more info' of a module: nothing happens.
It should open the form view of the module.
What happens is that the action doesn't contain 'form',
so the framework fails to open the form view from the kanban view.
opw 1928711
closesodoo/odoo#30437