The main goal of this commit is to reduce the size of the registry by
removing the (almost) useless __last_update field.
Statistics # of fields with all modules installed:
before 30184 fields, 1299x last_update (4.30%)
Before this commit, the computed field __last_update was added on every model.
The idea behind this field was to have a computed field that had either
the write_date or the create_date if the write_date was empty. However,
the write_date is always written, even on creation, making it useless
to have the computed field __last_update
After this update, we completely remove from BaseModel:
* __last_update
* CONCURRENCY_CHECK_FIELD that was always defined as "__last_update"
* _compute_concurrency_field that was the compute function for __last_update
closesodoo/odoo#105739
Task-id: 3062140 (part of 3062137 improve registry load time)
Related: odoo/upgrade#4038
Related: odoo/enterprise#33939
Signed-off-by: Raphael Collet <rco@odoo.com>
Reproduction:
1. Create a dynamic attribute "dyn_att" with a couple of values
2. Create a product template "dyn_prod" with those attribute values
3. Create an order for "dyn_prod", this will trigger creating a variant
4. Make sure to check Variant Grid Entry in Sales Settings
5. Open variant form view of dyn_prod and edit it to allow duplication
6. Duplicating it leads to an error
Reason: copying the variant is not possible and disabled here:
https://github.com/odoo/odoo/pull/38303 For future convenience, maybe
it’s better to give a temporal working solution. The function
_create_first_product_variant is used in the product module but only
defined in its child module website_sale
Fix: copy the product template, create and return its first possible
variant. Added test for dynamic variant copy. change the definition
place of _create_first_product_variant to module product
opw-2790543
closesodoo/odoo#98809
X-original-commit: 34a2948d3d6e0f597c1b5d65f9f118e891c07cc4
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
Signed-off-by: Liu Jinjiu (jili) <jili@odoo.com>
* commons & setup refactoring:
* convert setUp to setUpClass
* move setups where needed (stock/mrp commons or specific test
classes)
* create test data in batch (faster, less sql queries & batched
operations)
* move most tests post-install to allow runbot splits
* by default, run tests without mail logic
* by default, run tests in a consistent environment (fixed currency
imposed in the BaseCommon)
* refactor existing tests to use new commons data (while trying to keep
diff reduced)
* add dedicated test file to test the common data
* use mute_logger to reduce useless test logs (less spam to scroll in
logs, less data on runbot builds, ...)
Part-of: odoo/odoo#96791
In the web client, in a real use case, it's not possible
to write on fields which are invisible,
as it's not possible to write on fields which are readonly.
This is a first step in the goal to change the behavior
of the `groups=` attribute in the back-end views,
to remove them for the view instead of making them invisible.
This is mainly to reduce the diff of the revision that will introduce
the mentioned above behavior change.
As nodes with `groups=` will be removed from the view
when the user doesn't have the group, it's no longer possible
to set a value on a field having a `groups=` the user doesn't have
in the `Form` test class, as the field will no longer be at all in the
view.
However, these unit tests shouldn't have been able to set values
on invisible fields in the first place.
This revision therefore aims to correct the unit tests setting value
on fields which were invisible because the user executing the
test was not part of the required group(s) for these fields
to be visible in the view.
closesodoo/odoo#94337
Related: odoo/enterprise#28936
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Before this commit, Barcode was not displayed on template
when related product variant is archived.
Here we are making sure that even when a product is
archived, its barcode is still visible in template.
closesodoo/odoo#89363
X-original-commit: f0c7cde3938c01df5fc10bb8dcd72fd3bb18afdb
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
Steps to repoduce:
- Go to Sales - products
- Create a product
- Add variants (3 attributes and 2 values each) Total is 8 variants.
- onfigure variants: Select 1 attribute and exclude it for 1 variant (for example: exclude for size 12x12)
-> the number of variants remains at 8. The one that is excluded is still visible in the Product variants tab.
Solution:
When an exclusion is created, archive all the not-possible-combination.
OPW-2729329
closesodoo/odoo#84883
X-original-commit: 91642f4e29beb89d110084a20443fb300ee26530
Related: odoo/enterprise#24512
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Some aggressive cache invalidation in the middle of method write() where
the model has children models (in the _inherits sense) causes very nasty
errors that are hard to fix.
Consider two models A and B, where B inherits from A. Also consider two
fields a1 and a2 on A, which are thus both inherited by B. Now take a
record from model B, and update both fields as:
record.write({'a1': ..., 'a2': ...})
As both fields appear as related fields on model B, the method write()
puts all values in cache, then it proceeds to call the inverse method of
both fields. The inverse method of a1 is called, and this writes on the
parent record. Now imagine that some override on A invalidates the
whole cache. When the inverse method of a2 is called, the field's value
on B has been invalidated, and this therefore writes the value False on
the record's parent.
This patch removes and adapt such cache invalidations:
- Since 4b1cb41cf7, the cache invalidation
in method write() of product.product is no longer necessary.
- The cache invalidation in method write() of product.pricelist.item
has been removed as well, since field that needs to be recomputed no
longer exists.
Fixes#76946, #77042closesodoo/odoo#82958
Opw: 2657461
X-original-commit: 5a73a8a3697c0f2685471efa252e5eb1af738e83
Signed-off-by: Raphael Collet <rco@odoo.com>
Since [1] whenever the image of a `product.template` is updated, the
write date of all its related `product.product` is updated. This was
done to force a change of the unique parameter on image fields, which is
based on the last update field.
After this commit the `product.product`'s last update is instead
computed by also taking the `product.template`'s last update into
account. This avoids the need for updating the write date when the
image is changed, but on the other hand it also forces product images to
be reloaded whenever any other field of the `product.template` is
changed.
[1] https://github.com/odoo/odoo/pull/71139
Related to https://github.com/odoo/odoo/pull/76309
task-2477438
closesodoo/odoo#78356
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
Co-authored-by: Benoit Socias <bso@odoo.com>
Before this commit, products relying on values of template fields (i.e.
image) were not considered updated when their fallback template field
was updated.
After this commit, upon update of a template image, all products that
would fallback on that template are "touched".
This avoids side-effects such as displaying an outdated template image
in the e-commerce for a given product.
task-2477438
closesodoo/odoo#71139
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Behavior prior to this fix:
When archiving the last variant on a template, the product template
stays active (contrary to the comment indicating that `toggle_active`
will archive the related product.template if there is only one active
`product.product`).
Behavior after the fix:
When archiving the last variant on a template, the product template is
archived. When un-archiving that variant, the product template is
unarchived as well, without un-archiving the other variants.
Note: this is a remake of a fix implemented in 77e5472c041e, as that fix
did not correctly count the inactive variants.
opw-2349862
closesodoo/odoo#60641
X-original-commit: 01160ee5e7f726f3035c566a13e26825236dedfd
Signed-off-by: Nicolas Galler <nicocrm@users.noreply.github.com>
Issue
- Install Sales with Product Configurator
- Create a product with 2 dynamic variants:
- Color: blue, red
- Size: S, M
- Create a quotation with that product (any variant)
- Sales > Products > Products Variants
Your product variant is there
- Modify your product template and add "green"
to colors
- Sales > Products > Products Variants
Your product variant is archived
Cause
The logic which determines which variant
should not be archived is only applied
on products that don't have dynamic variants
See https://github.com/odoo/odoo/blob/820fe9a025e34e81368a189ee295b4abcf9fcbda/addons/product/models/product_template.py#L576
Solution
Do a separate logic for dynamic variants that doesn't compute
all possible combinations.
But being sure that it:
- doesn't archive when adding/removing a value
to an existing attribute line
- archive when adding/removing a new attribute line
OPW-2293346
closesodoo/odoo#55016
X-original-commit: 8517fdfa2605e8d15f5e38f2074ece7ba543d56b
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Updating the uom_id on a product_product will eventually change also the
uom_po_id to have them belonging to the same category. Saving the update
call write() on product with a dict of two values (uom_id and uom_po_id)
As product.product is inherited from product.template, the write() on
the corresponding product_template is called but in this case 2 times
for each values. The first time, only uom_id is updated. The _check_uom
constraint is triggered and obviously failed. The uom_po_id on the
template is not yet updated.
This commit makes the sync in the beginning of write() of product.template.
Which means before calling the constraint.
This commit also makes the onchanges on uom_id acts the same between
product.product and product.template.
Task : 2197818
closesodoo/odoo#48714
Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
Steps to reproduce:
* Create a template with 2 variants
* Archive one variant
* Unarchive this same variant
--> the template is archived
This is due to commit 6a13b565cbbad89ff1c4177b171b01f30c83edf9. If the
variant is the only one, toggle_active on the variant should be
reflected on the template. The issue is that toggle active do not count
archived variant. One active variant and one archived variant are
counted as 1.
This commit make toggle_active count all variants
closesodoo/odoo#34769
Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
Product templates standard_price (cost) is company_dependent,
because the product_product standard_price is company dependent.
closesodoo/odoo#47041
Forward-port-of: odoo/odoo#46841
X-original-commit: 30ee9f1ac411aca9c2bf2158fca9be7db743616d
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
Variants are generated depending on the configuration of attributes
and values on the template, so copying them does not make sense.
For convenience the template is copied instead and its first variant is
returned.
closes#38151
X-original-commit: 259f3b7fcdb88d1f458ee7ea3667964412b88ea1
Have a product template, assign a dynamic attribute to
(the corresponding variant will be created when used in a SO)
Try to name_search for it
e.g.: in the product configurator modal, type some letters to catch it in theory
Before this commit, the product template was not found by the name search
this is because the template doesn't have any variant yet
After this commit, it is found by the name search
OPW 2060603closesodoo/odoo#36215
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
* account, hr_expense, mrp, sale, sale_product_configurator, stock_account,
website_sale, website_sale_comparison
Before this commit, the `product.attribute.value` were stored on the variants.
This required filtering of attribute lines to find the appropriate matching
`product.template.attribute.value` that were used in most of the business code,
such as when computing the `price_extra`.
This also prevented to have multiple attribute lines for the same attribute,
which is needed to handle use cases such as grape varieties for wine products.
This will be done in the following commit.
After this commit, the combination of `product.template.attribute.value` will be
directly stored on the product variant.
Other changes
=============
Add `combination_indices` on product, which allows to quickly find a variant
matching a combination (1 simple indexed equality query as opposed to 1 query
with as many joins as there are attribute lines), and to add an easy
SQL constraint to ensure active combination uniqueness.
Add active field on `product.template.attribute.line` and
`product.template.attribute.value`, with the same behavior as variants:
They become archived if they can't be unlinked. This allows to keep the database
consistent, such as archived variants correctly keeping all their values, sales
order lines keeping their custom and no_variant. This is done with the help of
`ondelete=restrict` on the corresponding m2m fields, and the `unlink` methods
falling back to archiving when `unlink` is restricted.
Part of task-1912579
PR: #32946
Follow up of 58a2ffa26f
Variant specific field `image_raw_original` was meant to be renamed to
`image_variant_1920` instead of `image_variant_max` to follow the same naming
convention as the other fields (having the pixel number in the name).
closesodoo/odoo#35493
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
image_original => image_1920 (now resized to 1920)
image_big => image_1024
image_large => image_256
image_medium => image_128
image_small => image_64
image replaced by image_1920 (when writing) or by image_1024 (when displaying
what was previously the big size)
+ add new intermediate format:
image_512
PR: #34925
Create a product template Pt with attibutes A1, A2,
respectively with values Va1_1, Va1_2, and Va2.
This should make 2 variants, V1 and V2.
Sell some of these variants.
Then they can't be deleted since they are linked to orders/invoices/...
Now delete attribute A2. We know that:
Warning: adding or deleting attributes will delete and recreate existing
variants and lead to the loss of their possible customizations.
In fact, old variants are only archived instead of deleted:
for variant in variants_to_unlink: ... variant.write({'active': False})
as a fallback.
Now add again the attribute A2 to Pt.
It creates a new variant with the correct attributes.
Since the product is not active and has valid attributes and attribute values,
it is reactivated.
As a result we get the same variant twice.
Here we can simply add a check: if there is already an existing variant with
the same values, we can skip this activation.
We add a tiny little test to make sure that we have correct number of variants.
It's basically unreadable but somewhat commented.
fix coauthored with @rco-odoo
opw 2029985
closesodoo/odoo#35013
Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
* = account, mrp, purchase_stock, sale, sale_product_configurator,
stock_account, website_sale
It is always better to create the product template attribute lines before
creating the variants. In a following commit, this will become mandatory.
The variants that are created should always match the combination of attributes
set on the template.
Finally explicitly call `create_variant_ids` when possible instead of reassigning
the attribute lines to implicitly call `create_variant_ids`.
closesodoo/odoo#34122
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
The new product configurator introduces the possibility to create
variants dynamically. One of the main goal is to be able to create
product templates with **many** attributes and values, but not generate
all variants automatically. Only the necessary variants are created
on-the-fly.
However, it turns out that **many** dynamic attributes and values still
fails. For example, create a product with 10 attributes, 10 values for
each. This allows 10^10 theoretical combinations; although the variants
are not created, the creation of the product template fails.
The reason is that the `variant_matrix` contains the list of all
combinations, which causes a `MemoryError`.
An easy modification to improve the process is to keep an iterator
instead of generating the list. This avoids the `MemoryError`, but it
remains necessary to go through all combinations three times, which
would take too much time.
Therefore, some refactoring is necessary in order to keep the same
logic, but avoid going through any huge list. Here are the improvements:
1. Skip the creation part if nothing will be created.
If any attribute is dynamic, no variant is created. Therefore, we can
perform the check upfront and skip the variant creation part if
possible.
2. Stop the creation loop as soon as possible.
There is an hardcoded limit of maximum 1000 variants to create. We
can perform this check along with the list creation instead of
checking at the end.
3. Determine if a product has valid attributes in a different way.
The existing logic is safe but expensive: we check that all attribute
values of a product are part of the possible combinations. This can
be simplified by checking if (1) all attribute values of a variant
are part of the accepted attribute values of the template and (2) a
variant uses all attributes of the template. The second check is
mandatory to delete existing variants when an attribute is added to
the template.
Thanks to these modifications, we at worst go through 1000 possible
attribute values combinations. It might still be possible to optimize
step 3 with a fancy SQL query which would retrieve all (in)valid
products at once. Hopefully this won't be necessary and the optimized
logic will be enough.
opw-1902392
closesodoo/odoo#28530
Targets commit d3530eb07e
Purpose
=======
[Follow up AL review]
Code cleanup and some improved models naming for the product configurator feature (see targeted commit).
Mostly changes the "product.attribute" related models.
Updated models:
- "product.product.attribute.value" to "product.template.attribute.value"
- "product.attribute.filter.line" to "product.template.attribute.exclusion"
- "product.attribute.line" to "product.template.attribute.line"
Updated fields:
- [sale_order_line in sale/sale.py] "product_custom_variant_values" to "product_custom_attribute_value_ids"
- [product_template_attribute_value in product/product_attribute.py] excluded_for is now a o2m instead of a m2m
- [product.attribute in sale/product_product.py] "create_variant" field is now a Selection with "no_variant" (old false), "always" (old true), "dynamic" (new value)
- [product in product/product.py] "product_attribute_value_ids" to "product_template_attribute_value_ids"
Purpose
=======
Product attributes can be configured to create variants "on demand".
This means that product.templates having these attributes will only create product.product variant
when that combination is actually selected in a sale order/in the web shop.
Product attribute values are also improved to handle extra prices and exclusions
in all three modes ("never", "on demand", "always")
Specification
=============
Create variants on demand
- add a new mode to generate variants as they are added to the order/cart
(needed for big # of combinations managed in the inventory and/or produced in mrp with specific boms)
- replace the boolean by a selection radio
tooltip for this new field:
Always:
Variants are generated straight away when
the attribute values are combined in the product configuration.
Only when the product is added to a sales order:
Variants are generated once the combination is selected in the sales order.
This is advised when variants are customized on demand and manufactured as such in Odoo.
Never:
Advised when variants are not needed in Odoo.
The selected values just show up in the description of sales order lines.
- ability to define attribute extra prices & exclude combinations in all variant modes
- if at least one attribute of the product in set to "on demand" mode, generate all the variants "on demand"
In 11.0 7e724f96c5 is_product_variant has been introduced back (it was
removed in 10.0 b747b05fa). But related of _inherits are computed on the
related model so is_product_variant would always be false.
Without fix, added test fails with:
AssertionError:
Items in the first set but not the second: True, Items in the second
set but not the first: False, Product variants are variants
fixes#26961
related to opw-1814973
closes#27163
- Create a product named 'toto'
- Perform a call to `name_search`:
`self.env['product.product'].name_search('pouet', [], 'not ilike')`
Product 'toto' doesn't show up in the result list.
The domain should take into account that `default_code` can be `False`.
Note: the bug also occurs if the product is called 'trululu'.
opw-1837957
In 5c2380e9f an issue when modifying variants values was solved when an
attribute on the product variant had "create_variant" unset.
This commit forward-port what was lost of it in 11.0, that part was
probably lost because the code was previously changed when adapting to
python3.
Without the change, the added test failed creating a new variant keeping
the existing one. With this change, 'nocreate' value are ignored when
computing new variants to create.
opw-1815226
closes#23332
A name_search on attribute line would possibly ends up with a domain like:
['|', ('attribute_id', '=', 'm'), ('value_ids', '=', 'm'),
('attribute_id', '=', 'm')]
which would just search the attribute.
This is caused by calling the default name_search. This commit forgo
the default name_search when we are in this attribute line special case.
courtesy-of: @fmdl
opw-813505
closes#22619closes#22760