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>
This provides a better API to search for records by name without the
formatting part (`display_name`).
This also simplifies all the overridings of `_name_search` that no
longer need to call `name_get()`. The call to `name_get()` is done in
method `name_search` in a generic way.
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>
Using a few regex like
\((_\(.*%s.*)(\) % )([\w\[\]][\w .\[\]\(\)'"]*)\)
($1, $3))
Old syntax is still compatible but starts the migration to the new
syntax that catches error.
When the value is the same for all records, the write can be done in
batch, this can lead to a "slight" performance improvement, depending on
write overrides, and how the value was computed for each line.
Issue
- Install purchase_product_matrix, Inventory
- Create a (storable) Product P with default_code e.g. VOB2A
with a vendor V who uses a product_code e.g. VOB2a
- Create a PO/RFQ for vendor V
- Add a product, search "vob2" (copy/paste)
Infinite loop
Cause
purchase_product_matrix replace purchase.order_line.product.product
by product.template so the name_search is different and the
product.template's name_search loop doesn't support the case where
you have default_code == product_code
Solution
Check if the product's name_search returned a product containing
product_template_ids that we did not wanted (as mentionned in the
domain). If yes, it means that we will have an infinite loop so
we should break.
Additional note: the issue could be in versions < 13 but
purchase_product_matrix is only in 13.0 and this is not a
very common case.
OPW-2193005
closesodoo/odoo#47576
X-original-commit: 9d5d80f77bc04be83d5b2ca0569a6ea50e26a07e
Signed-off-by: Jason Van Malder (jvm) <jvm@odoo.com>
Before this commit when a user archives the product, the barcode
field in its template used to get disappeared.
Since barcode field in template is a related field to product,
the field gets invisible in product template when the user archives
the related product.
After this commit, even when a product is archived,
its barcode will still be visible in template.
Here the barcode field is changed from related to computed.
task-1978559
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>
Issue: on main product's kanban, if you group by categories, all
categories (even the empty ones) appear. This is not desired.
We only wanted this group_expand logic when using the products stat
button on the product category form view.
closesodoo/odoo#46966
X-original-commit: e3f1254e5b28aa801f137835d871427786fb3428
Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
The default product category and uom should be fixed on generic
undeletable records (in data files).
And by caching those default values, we can gain up to 20% time when
creating products without providing uom and categories.
Also remove the unnecessary defaults on the compute fields, which do the
same as the compute (and have no use because it is a non stored field).
closesodoo/odoo#45791
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Delete the uom 'kg'(kilos, kilograms), open a product form view
Traceback will popup because the hardcoded xmlid cannot find the value
in the database since has been deleted. Adding a fallback fix the issue
opw-2194659
closesodoo/odoo#45265
X-original-commit: 62baf8ba12cdf4521c6d0d0fea61ff1aa2e3f4d8
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
- Activate variants and pricelists
- Go to Product > Products Variants
- Search for anything on the 'Pricelist' filter
A traceback is raised: 'Can only create cache keys from hashable
values...'.
This comes from the following change:
https://github.com/odoo/odoo/blob/4b06fe19fa68255b7982d15e5847da2f6d6209fd/addons/web/static/src/js/views/control_panel/control_panel_model.js#L962
It returns a list instead of a string. Since a list is not hashable, it
causes the issue.
There are not much solutions since the context key `pricelist` can be a
`list` or an `int` (an ID). We force the cache key conversion to a tuple
to avoid the `TypeError` and handle the `list` use case (which was
broken on top of crashing).
opw-2187757
closesodoo/odoo#45064
X-original-commit: ec0a8767143b4c4818418281803c4f52fefa8d2a
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
Sometimes when we try to buy a product that doesn't have any variants,
it would result in an error saying there isn't any valid combination
for that product.
This was happening because `_get_variant_id_for_combination` was
considering that the field `combination_indices` would always be
equal to `''` (empty string) in such a case.
This isn't true as `combination_indices` isn't a required field
thus allowing `null` \ `None` to be valid values for that field.
This fix will simply include products with no values set for their
`combination_indices` when searching a corresponding variant from
the `product_template`.
closesodoo/odoo#44056
X-original-commit: 03e7efc3b4592c5f063c665130011a91fcc4d683
Signed-off-by: Toufik Benjaa (tbe) <tbe@odoo.com>
Since [1] `computer_hdd_attribute_lines` is archived instead of unlinked in
`TestSaleProductAttributeValueConfig` which leads to indeterminism in tests due
to the missing `flush`.
Indeed `flush` is necessary before `invalidate_cache` since [2] if the data
that are pending being written must be saved to the database before the cache
invalidation.
[1] which highlighted the issue was merged after v13.0, but it still makes sense
to merge the current fix in the earliest version possible.
[1] 5361706e5e
[2] 9920f20e4cclosesodoo/odoo#43483
X-original-commit: f721bfe2860293d1456770d57be7805920929ca0
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Currently, empty strings and False have different meaning when assigning
a Char or Text field with ORM methods.
So avoid setting empty string on `default_code`.
opw-2151849
closes#41662closesodoo/odoo#41674
X-original-commit: d038cc1a0a6e1d939318763aa9dba48aa1eafcf5
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
Steps to reproduce the bug:
- Go to Sales app and open the form view of a product P
- With studio add the field display_name in the view
- Try to create a new product
Bug:
A access error was raised because a read was made on a record in cache
opw:2070074
closesodoo/odoo#37133
X-original-commit: 90143c18f50ff31ded5aba7d7ba3beb66423ff06
Signed-off-by: Simon Goffin (sig) <sig@openerp.com>
There are too many image sizes. Since they are stored resized this takes time to
generate when saving a new image, it's more rows on the attachment table, more
files on the disk, ...
64px is close enough to 128px that it can be removed without a big impact on
download size.
It will even reduce download and number of requests when both images are
displayed because now only one has to be downloaded and then benefit from cache.
The difference between the two is typically around 1.5kB which is negligible
these days, especially when the request overhead is around 0.5kB already, not
even taking into account other factors such as latency.
If a 64px image must absolutely be returned, it is still possible to pass the
size parameters to the image route. But the current guideline is to handle
resizing in the views when necessary.
Views
=====
- remove width and height attributes when existing CSS rules are overriding them
(eg. `.oe_kanban_avatar` in the right context)
- add CSS rules instead of width and height attributes when possible
- use `object-fit: cover;` where width and height are forced to avoid distortion
of non-square images
- for products, use `object-fit: contain;` instead, keep ratio but without crop
- add new CSS rules where the expected size was max 64px*64px before due to the
image size itself
- remove `img-fluid` where using size classes to avoid conflicting rules
task-2060865
closesodoo/odoo#36147
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
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>
* = sale, website_sale, website_sale_comparison
Purpose
=======
This allows to handle use cases such as grape varieties for wine products where
multiple values need to be set for the same attribute, but they are all
informative and should not generate a choice or variants.
The general logic that existed previously is kept:
- multiple attribute lines on a product behave as an AND between them
- multiple values on a line behave as an OR between them
Example
=======
To generate 2 variants, with one possible value for each:
Line A: val 1, val 2
To generate 1 variant, with both informative values on it:
Line A: val 1
Line A: val 2
Technically
===========
- remove the constraints that prevented this use case from working since the
refactoring done in the previous commit removed the ambiguity when two
different lines have the same value
- update the product and comparison views accordingly
Extra
=====
- make the attribute category translatable and improve its list view
Final part of task-1912579
PR: #32946
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Co-authored-by: Juhil Somaiya <jso@odoo.com>
Co-authored-by: Sébastien Theys <seb@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
This branch is the combination of several optimizations in the ORM:
* store field values once in the cache: the cache reflects more
faithfully the database, only fields that explicitly depend on the
context have an extra indirection in the cache;
* delay recomputations by default: use method `recompute` to explicitly
flush out pending recomputations;
* delay updates in method `write`: updates are stored in a data
structure that can be flushed efficiently to the database with method
`flush` (which also flush out recomputations);
* make method `modified` take advantage of inverse fields to inverse
dependencies;
* filter records by evaluating a domain on records in Python;
* a computed field with `readonly=False` behaves like a normal field
with an onchange method;
* computed fields are computed in superuser mode by default.
Work done by Toufik Ben Jaa, Raphael Collet, Denis Ledoux and Fabien
Pinckaers.
closesodoo/odoo#35659
Signed-off-by: Denis Ledoux <beledouxdenis@users.noreply.github.com>
Manage pricelists through a common configuration between sale and point_of_sale
Remove lots of technical fields
Improved Pricelist Flow
-----------------------
if pricelists enabled (product.group_product_pricelist), two modes are proposed:
* basic(default): pricelists enabled, but only with basic rules
* advanced: pricelists enabled, but with advanced rules (product.group_sale_pricelist)
When pricelists are enabled, we can always access them through the menu OR access their product-targeted rules from the products/templates views.
part of product_configurator logic moved to product to be accessible in purchase even if p_configurator isn't installed.
And adapt configurator to be extended by matrix
This attribute is misleading as it is insufficient to correctly upgrade
the database. It only renames the column in the database, but other
operations are needed, like updating the corresponding `ir.model.fields`
record (and its xmlid). The default values and the translations are also
lost during the upgrade.
Moreover, this feature was misused. It was:
- left on fields during multiple versions.
- used on reports (SQL views). This would be ok if the feature was
complete, but, as is, it was useless.
- kept unchanged after a second renaming of the field (which can happen
versions later the first rename).
- used, even when the meaning of the field changed. i.e. the field
`archived` has been renamed to the classic `active`, but the value
in the database should be switched.
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>
- Install stock module
- Activate multi-company and variants
- Create a second company
- Create a product with 2 variants
- Create a picking with the product for both companies
- Add an attribute on the product with 2 values
- Save
An AccessError is raised on `stock.move`.
It arises because the field `product_qty` on `stock.move` must be
recomputed but is on a record in a different company.
The `try` / `except` clause doesn't protect against the recomputation.
Indeed, what happens is:
- try to unlink in batch => AccessError due to recomputation
- try to unlink individually => AccessError due to recomputation
- try to write individually => the field couldn't be recomputed before
(flagged as dirty), so try again to recompute => AccessError
We perform the operation as sudo, and take care of checking the access
rights beforehand.
opw-2009450
closesodoo/odoo#34369
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>