mirror of
https://github.com/bringout/oca-ocb-sale.git
synced 2026-04-26 05:11:59 +02:00
19.0 vanilla
This commit is contained in:
parent
79f83631d5
commit
73afc09215
6267 changed files with 1534193 additions and 1130106 deletions
|
|
@ -1,53 +1,81 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import base64
|
||||
from collections import OrderedDict
|
||||
from datetime import timedelta
|
||||
import io
|
||||
import unittest.mock
|
||||
|
||||
from collections import OrderedDict
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from odoo.fields import Command
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests import tagged, TransactionCase, Form
|
||||
from odoo.fields import Command
|
||||
from odoo.tests import Form, TransactionCase, tagged
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
from odoo.addons.product.tests.common import ProductVariantsCommon, ProductAttributesCommon
|
||||
from odoo.addons.product.tests.common import ProductVariantsCommon
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestVariantsSearch(ProductVariantsCommon):
|
||||
|
||||
def test_attribute_line_search(self):
|
||||
product_template_shirt = self.env['product.template'].create({
|
||||
'name': 'Shirt',
|
||||
'categ_id': self.product_category.id,
|
||||
'attribute_line_ids': [
|
||||
Command.create({
|
||||
'attribute_id': self.size_attribute.id,
|
||||
'value_ids': [Command.set([self.size_attribute_l.id])],
|
||||
}),
|
||||
],
|
||||
})
|
||||
search_not_to_be_found = self.env['product.template'].search(
|
||||
[('attribute_line_ids', '=', 'M')]
|
||||
)
|
||||
self.assertNotIn(self.product_template_shirt, search_not_to_be_found,
|
||||
self.assertNotIn(product_template_shirt, search_not_to_be_found,
|
||||
'Shirt should not be found searching M')
|
||||
|
||||
search_attribute = self.env['product.template'].search(
|
||||
[('attribute_line_ids', '=', 'Size')]
|
||||
)
|
||||
self.assertIn(self.product_template_shirt, search_attribute,
|
||||
self.assertIn(product_template_shirt, search_attribute,
|
||||
'Shirt should be found searching Size')
|
||||
|
||||
search_value = self.env['product.template'].search(
|
||||
[('attribute_line_ids', '=', 'L')]
|
||||
)
|
||||
self.assertIn(self.product_template_shirt, search_value,
|
||||
self.assertIn(product_template_shirt, search_value,
|
||||
'Shirt should be found searching L')
|
||||
|
||||
def test_name_search(self):
|
||||
self.product_slip_template = self.env['product.template'].create({
|
||||
'name': 'Slip',
|
||||
'default_code': 'ABC',
|
||||
})
|
||||
res = self.env['product.product'].name_search('Shirt', [], 'not ilike', None)
|
||||
res_ids = [r[0] for r in res]
|
||||
self.assertIn(self.product_slip_template.product_variant_ids.id, res_ids,
|
||||
'Slip should be found searching \'not ilike\'')
|
||||
|
||||
templates = self.product_slip_template.name_search(
|
||||
"ABC",
|
||||
[['id', '!=', -1]],
|
||||
)
|
||||
self.assertFalse(templates, "Should not return template when searching on code")
|
||||
templates = self.product_slip_template.with_context(search_product_product=True).name_search(
|
||||
"ABC",
|
||||
[['id', '!=', -1]],
|
||||
)
|
||||
self.assertTrue(templates, "Should return template when searching on code")
|
||||
|
||||
templates = self.product_slip_template.with_context(search_product_product=True).name_search(
|
||||
"ABC",
|
||||
[['id', '!=', self.product_slip_template.id]],
|
||||
)
|
||||
self.assertFalse(templates, "Should not return template.")
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestVariants(ProductVariantsCommon):
|
||||
|
|
@ -78,7 +106,6 @@ class TestVariants(ProductVariantsCommon):
|
|||
test_template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [Command.create({
|
||||
'attribute_id': self.size_attribute.id,
|
||||
'value_ids': [Command.link(self.size_attribute_s.id)],
|
||||
|
|
@ -93,7 +120,6 @@ class TestVariants(ProductVariantsCommon):
|
|||
test_template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [Command.create({
|
||||
'attribute_id': self.color_attribute.id,
|
||||
'value_ids': [Command.link(self.color_attribute_blue.id)],
|
||||
|
|
@ -111,7 +137,6 @@ class TestVariants(ProductVariantsCommon):
|
|||
test_template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [
|
||||
Command.create({
|
||||
'attribute_id': self.color_attribute.id,
|
||||
|
|
@ -146,7 +171,6 @@ class TestVariants(ProductVariantsCommon):
|
|||
test_template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [
|
||||
Command.create({
|
||||
'attribute_id': self.color_attribute.id,
|
||||
|
|
@ -185,7 +209,6 @@ class TestVariants(ProductVariantsCommon):
|
|||
test_template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [Command.create({
|
||||
'attribute_id': self.color_attribute.id,
|
||||
'value_ids': [Command.link(self.color_attribute_red.id), Command.link(self.color_attribute_blue.id)],
|
||||
|
|
@ -243,6 +266,10 @@ class TestVariants(ProductVariantsCommon):
|
|||
self.assertEqual(template_dyn.name, 'Test Dynamical')
|
||||
|
||||
variant_dyn = template_dyn._create_product_variant(template_dyn._get_first_possible_combination())
|
||||
if 'create_product_product' in variant_dyn.env.context:
|
||||
new_context = dict(variant_dyn.env.context)
|
||||
new_context.pop('create_product_product')
|
||||
variant_dyn = variant_dyn.with_context(new_context)
|
||||
self.assertEqual(len(template_dyn.product_variant_ids), 1)
|
||||
|
||||
variant_dyn_copy = variant_dyn.copy()
|
||||
|
|
@ -291,12 +318,12 @@ class TestVariants(ProductVariantsCommon):
|
|||
})
|
||||
self.assertEqual(len(template.product_variant_ids), 2)
|
||||
variant_1 = template.product_variant_ids[0]
|
||||
variant_1.toggle_active()
|
||||
variant_1.action_archive()
|
||||
self.assertFalse(variant_1.active)
|
||||
self.assertEqual(len(template.product_variant_ids), 1)
|
||||
self.assertEqual(len(template.with_context(
|
||||
active_test=False).product_variant_ids), 2)
|
||||
variant_1.toggle_active()
|
||||
variant_1.action_unarchive()
|
||||
self.assertTrue(variant_1.active)
|
||||
self.assertTrue(template.active)
|
||||
|
||||
|
|
@ -360,16 +387,57 @@ class TestVariants(ProductVariantsCommon):
|
|||
self.assertEqual(len(template.product_variant_ids), 2)
|
||||
variant_1 = template.product_variant_ids[0]
|
||||
variant_2 = template.product_variant_ids[1]
|
||||
template.product_variant_ids.toggle_active()
|
||||
template.product_variant_ids.action_archive()
|
||||
self.assertFalse(variant_1.active, 'Should archive all variants')
|
||||
self.assertFalse(template.active, 'Should archive related template')
|
||||
variant_1.toggle_active()
|
||||
variant_1.action_unarchive()
|
||||
self.assertTrue(variant_1.active, 'Should activate variant')
|
||||
self.assertFalse(variant_2.active, 'Should not re-activate other variant')
|
||||
self.assertTrue(template.active, 'Should re-activate template')
|
||||
|
||||
def test_open_product_form_with_default_uom_id_is_false(self):
|
||||
""" Test default UoM is False when creating a product. """
|
||||
uom_unit = self.env.ref('uom.product_uom_unit')
|
||||
product_form = Form(self.env['product.product'].with_context(
|
||||
default_uom_id=False,
|
||||
))
|
||||
product_form.name = 'Test Product'
|
||||
product = product_form.save()
|
||||
self.assertEqual(uom_unit, product.uom_id)
|
||||
|
||||
def test_single_variant_template_computed_values_after_creation(self):
|
||||
"""Check that variant-related fields on templates are correctly set."""
|
||||
product_template = self.env['product.template'].create({
|
||||
'name': "one variant template",
|
||||
'attribute_line_ids': [Command.create({
|
||||
'attribute_id': self.size_attribute.id,
|
||||
'value_ids': [Command.set(self.size_attribute_s.ids)],
|
||||
})],
|
||||
'barcode': 'THIS IS A TEST',
|
||||
})
|
||||
self.assertEqual(
|
||||
product_template.barcode,
|
||||
product_template.product_variant_id.barcode,
|
||||
)
|
||||
self.assertEqual(
|
||||
product_template.barcode,
|
||||
'THIS IS A TEST',
|
||||
)
|
||||
product_template = self.env['product.template'].create({
|
||||
'name': "one variant template without attribute lines",
|
||||
'barcode': 'THIS IS A BARCODE',
|
||||
})
|
||||
self.assertEqual(
|
||||
product_template.barcode,
|
||||
product_template.product_variant_id.barcode,
|
||||
)
|
||||
self.assertEqual(
|
||||
product_template.barcode,
|
||||
'THIS IS A BARCODE',
|
||||
)
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestVariantsNoCreate(ProductAttributesCommon):
|
||||
class TestVariantsNoCreate(ProductVariantsCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
|
@ -382,7 +450,6 @@ class TestVariantsNoCreate(ProductAttributesCommon):
|
|||
template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [Command.create({
|
||||
'attribute_id': self.size_attribute.id,
|
||||
'value_ids': [Command.link(self.size_attribute_s.id)],
|
||||
|
|
@ -396,7 +463,6 @@ class TestVariantsNoCreate(ProductAttributesCommon):
|
|||
template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
})
|
||||
self.assertEqual(len(template.product_variant_ids), 1)
|
||||
|
||||
|
|
@ -414,7 +480,6 @@ class TestVariantsNoCreate(ProductAttributesCommon):
|
|||
template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [Command.create({
|
||||
'attribute_id': self.size_attribute.id,
|
||||
'value_ids': [Command.set(self.size_attribute.value_ids.ids)],
|
||||
|
|
@ -428,7 +493,6 @@ class TestVariantsNoCreate(ProductAttributesCommon):
|
|||
template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
})
|
||||
self.assertEqual(len(template.product_variant_ids), 1)
|
||||
|
||||
|
|
@ -446,7 +510,6 @@ class TestVariantsNoCreate(ProductAttributesCommon):
|
|||
template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [
|
||||
Command.create({ # no variants for this one
|
||||
'attribute_id': self.size_attribute.id,
|
||||
|
|
@ -470,7 +533,6 @@ class TestVariantsNoCreate(ProductAttributesCommon):
|
|||
template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
})
|
||||
self.assertEqual(len(template.product_variant_ids), 1)
|
||||
|
||||
|
|
@ -497,7 +559,6 @@ class TestVariantsNoCreate(ProductAttributesCommon):
|
|||
template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [
|
||||
Command.create({ # no variants for this one
|
||||
'attribute_id': self.size_attribute.id,
|
||||
|
|
@ -521,7 +582,6 @@ class TestVariantsNoCreate(ProductAttributesCommon):
|
|||
template = self.env['product.template'].create({
|
||||
'name': 'Sofa',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
})
|
||||
self.assertEqual(len(template.product_variant_ids), 1)
|
||||
|
||||
|
|
@ -548,7 +608,6 @@ class TestVariantsNoCreate(ProductAttributesCommon):
|
|||
template = self.env['product.template'].create({
|
||||
'name': 'Sofax',
|
||||
'uom_id': self.uom_unit.id,
|
||||
'uom_po_id': self.uom_unit.id,
|
||||
'attribute_line_ids': [
|
||||
Command.create({ # one variant for this one
|
||||
'attribute_id': self.color_attribute.id,
|
||||
|
|
@ -780,11 +839,11 @@ class TestVariantsImages(ProductVariantsCommon):
|
|||
images = self.variants.mapped('image_1920')
|
||||
self.assertEqual(len(set(images)), 4)
|
||||
variant_no_image = self.variants[0]
|
||||
old_last_update = variant_no_image['__last_update']
|
||||
old_last_update = variant_no_image.write_date
|
||||
|
||||
self.assertFalse(variant_no_image.image_1920)
|
||||
self.template.image_1920 = image_black
|
||||
new_last_update = variant_no_image['__last_update']
|
||||
new_last_update = variant_no_image.write_date
|
||||
|
||||
# the first has no image variant, all the others do
|
||||
self.assertFalse(variant_no_image.image_variant_1920)
|
||||
|
|
@ -881,7 +940,7 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
|
||||
def unlink(self):
|
||||
raise Exception('just')
|
||||
Product._patch_method('unlink', unlink)
|
||||
self.patch(type(Product), 'unlink', unlink)
|
||||
|
||||
variants_2x1 = self.template.product_variant_ids
|
||||
self._assert_2color_x_1size()
|
||||
|
|
@ -903,8 +962,6 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
archived_variants = self._get_archived_variants()
|
||||
self.assertFalse(archived_variants)
|
||||
|
||||
Product._revert_method('unlink')
|
||||
|
||||
def test_02_update_variant_archive_2_value(self):
|
||||
"""We do the same operations on the template as in the previous tests,
|
||||
except we simulate that the variants can't be unlinked.
|
||||
|
|
@ -916,7 +973,7 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
|
||||
def unlink(slef):
|
||||
raise Exception('just')
|
||||
Product._patch_method('unlink', unlink)
|
||||
self.patch(type(Product), 'unlink', unlink)
|
||||
|
||||
variants_2x2 = self.template.product_variant_ids
|
||||
self._assert_2color_x_2size()
|
||||
|
|
@ -972,8 +1029,6 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
self.assertEqual(archived_variants, variants_2x2)
|
||||
self._assert_2color_x_2size(archived_variants)
|
||||
|
||||
Product._revert_method('unlink')
|
||||
|
||||
@mute_logger('odoo.models.unlink')
|
||||
def test_03_update_variant_archive_3_value(self):
|
||||
self._remove_ptal_size()
|
||||
|
|
@ -983,7 +1038,7 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
|
||||
def unlink(slef):
|
||||
raise Exception('just')
|
||||
Product._patch_method('unlink', unlink)
|
||||
self.patch(type(Product), 'unlink', unlink)
|
||||
|
||||
self._assert_2color_x_1size()
|
||||
archived_variants = self._get_archived_variants()
|
||||
|
|
@ -1031,14 +1086,12 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
archived_variants = self._get_archived_variants()
|
||||
self.assertEqual(archived_variants, variants_2x1 + variant_0x0)
|
||||
|
||||
Product._revert_method('unlink')
|
||||
|
||||
def test_04_from_to_single_values(self):
|
||||
Product = self.env['product.product']
|
||||
|
||||
def unlink(slef):
|
||||
raise Exception('just')
|
||||
Product._patch_method('unlink', unlink)
|
||||
self.patch(type(Product), 'unlink', unlink)
|
||||
|
||||
# CASE: remove one value, line becoming single value
|
||||
variants_2x2 = self.template.product_variant_ids
|
||||
|
|
@ -1075,11 +1128,9 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
self._assert_2color_x_0size(archived_variants)
|
||||
self.assertEqual(archived_variants, variants_2x0)
|
||||
|
||||
Product._revert_method('unlink')
|
||||
|
||||
def test_name_search_dynamic_attributes(self):
|
||||
# To be able to test dynamic variant "variants" feature must be set up
|
||||
self.env.user.write({'groups_id': [(4, self.env.ref('product.group_product_variant').id)]})
|
||||
self._enable_variants()
|
||||
dynamic_attr = self.env['product.attribute'].create({
|
||||
'name': 'Dynamic',
|
||||
'create_variant': 'dynamic',
|
||||
|
|
@ -1105,20 +1156,16 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
self._enable_uom()
|
||||
|
||||
units = self.uom_unit
|
||||
cm = self.env.ref('uom.product_uom_cm')
|
||||
mm = self.env.ref('uom.product_uom_millimeter')
|
||||
template = self.product.product_tmpl_id
|
||||
|
||||
template_form = Form(template)
|
||||
template_form.uom_id = cm
|
||||
self.assertEqual(template_form.uom_po_id, cm)
|
||||
template_form.uom_id = mm
|
||||
template = template_form.save()
|
||||
|
||||
variant_form = Form(template.product_variant_ids)
|
||||
variant_form.uom_id = units
|
||||
self.assertEqual(variant_form.uom_po_id, units)
|
||||
variant = variant_form.save()
|
||||
self.assertEqual(variant.uom_po_id, units)
|
||||
self.assertEqual(template.uom_po_id, units)
|
||||
variant_form.save()
|
||||
|
||||
@mute_logger('odoo.models.unlink')
|
||||
def test_dynamic_attributes_archiving(self):
|
||||
|
|
@ -1129,7 +1176,7 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
# Patch unlink method to force archiving instead deleting
|
||||
def unlink(self):
|
||||
self.active = False
|
||||
Product._patch_method('unlink', unlink)
|
||||
self.patch(type(Product), 'unlink', unlink)
|
||||
|
||||
# Creating attributes
|
||||
pa_color = ProductAttribute.create({'sequence': 1, 'name': 'color', 'create_variant': 'dynamic'})
|
||||
|
|
@ -1234,15 +1281,13 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
})
|
||||
self.assertTrue(product_white.active)
|
||||
|
||||
Product._revert_method('unlink')
|
||||
|
||||
def test_set_barcode(self):
|
||||
tmpl = self.product.product_tmpl_id
|
||||
tmpl.barcode = '123'
|
||||
self.assertEqual(tmpl.barcode, '123')
|
||||
self.assertEqual(self.product.barcode, '123')
|
||||
|
||||
tmpl.toggle_active()
|
||||
tmpl.action_archive()
|
||||
|
||||
tmpl.barcode = '456'
|
||||
tmpl.invalidate_recordset(fnames=['barcode'])
|
||||
|
|
@ -1367,6 +1412,40 @@ class TestVariantsArchive(ProductVariantsCommon):
|
|||
self.assertEqual(len(variants), 1)
|
||||
self.assertFalse(variants[0].product_template_attribute_value_ids)
|
||||
|
||||
@mute_logger('odoo.models.unlink')
|
||||
def test_unlink_and_archive_multiple_variants(self):
|
||||
"""
|
||||
Test unlinking multiple variants in various scenarios
|
||||
- Unlink one archived variant
|
||||
- Unlink one archived and one active variant
|
||||
- Unlink multiple archived variants and multiple active variants at once
|
||||
"""
|
||||
products = self.env['product.product'].create([
|
||||
{'name': 'variant 1', 'description': 'var 1'},
|
||||
{'name': 'variant 2', 'description': 'var 2'},
|
||||
{'name': 'variant 3', 'description': 'var 3'},
|
||||
{'name': 'variant 4', 'description': 'var 4'},
|
||||
{'name': 'variant 5', 'description': 'var 5'},
|
||||
{'name': 'variant 6', 'description': 'var 6'},
|
||||
{'name': 'variant 7', 'description': 'var 7'},
|
||||
])
|
||||
# Unlink one archived variant
|
||||
products[0].action_archive()
|
||||
products[0].unlink()
|
||||
self.assertFalse(products[0].exists())
|
||||
|
||||
# Unlink one archived and one active variant
|
||||
products[1].action_archive()
|
||||
active_and_archived = products[1] + products[2]
|
||||
active_and_archived.unlink()
|
||||
self.assertFalse(active_and_archived.exists())
|
||||
|
||||
# Unlink multiple archived variants and multiple active variants at once
|
||||
multiple_archived = products[3] + products[4]
|
||||
multiple_active = products[5] + products[6]
|
||||
multiple_archived.action_archive()
|
||||
(multiple_archived + multiple_active).unlink()
|
||||
self.assertFalse(products.exists())
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestVariantWrite(TransactionCase):
|
||||
|
|
@ -1419,7 +1498,7 @@ class TestVariantWrite(TransactionCase):
|
|||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestVariantsExclusion(ProductAttributesCommon):
|
||||
class TestVariantsExclusion(ProductVariantsCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
|
@ -1551,3 +1630,90 @@ class TestVariantsExclusion(ProductAttributesCommon):
|
|||
|
||||
exclude.unlink()
|
||||
self.assertEqual(len(self.smartphone.product_variant_ids), 4)
|
||||
|
||||
@mute_logger('odoo.models.unlink')
|
||||
def test_dynamic_variants_unarchive(self):
|
||||
""" Make sure that exclusions creation, update & delete are correctly handled.
|
||||
|
||||
Exclusions updates are not necessarily done from a specific template.
|
||||
"""
|
||||
product_template = self.env['product.template'].create({
|
||||
'name': 'Test dynamic',
|
||||
'attribute_line_ids': [
|
||||
Command.create({
|
||||
'attribute_id': self.dynamic_attribute.id,
|
||||
'value_ids': [Command.set(self.dynamic_attribute.value_ids.ids)],
|
||||
}),
|
||||
Command.create({
|
||||
'attribute_id': self.dynamic_attribute.id,
|
||||
'value_ids': [Command.set(self.dynamic_attribute.value_ids.ids)],
|
||||
})
|
||||
]
|
||||
})
|
||||
self.assertFalse(product_template.product_variant_ids)
|
||||
first_line_ptavs = product_template.attribute_line_ids[0].product_template_value_ids
|
||||
second_line_ptavs = product_template.attribute_line_ids[1].product_template_value_ids
|
||||
for ptav1, ptav2 in zip(first_line_ptavs, second_line_ptavs, strict=True):
|
||||
product_template._create_product_variant(ptav1 + ptav2)
|
||||
|
||||
self.assertEqual(len(product_template.product_variant_ids), 2)
|
||||
|
||||
pav_to_remove = self.dynamic_attribute.value_ids[:1]
|
||||
variant_to_archive = product_template.product_variant_ids.filtered(
|
||||
lambda pp:
|
||||
pav_to_remove in pp.product_template_attribute_value_ids.product_attribute_value_id
|
||||
)
|
||||
|
||||
# Removing one option will archive one variant
|
||||
with patch(
|
||||
'odoo.addons.product.models.product_product.ProductProduct._filter_to_unlink',
|
||||
lambda products: products.filtered(
|
||||
lambda pp: pp.product_tmpl_id.id != product_template.id
|
||||
),
|
||||
):
|
||||
product_template.attribute_line_ids[1].value_ids = [
|
||||
Command.unlink(self.dynamic_attribute.value_ids[:1].id)
|
||||
]
|
||||
self.assertEqual(len(product_template.product_variant_ids), 1)
|
||||
self.assertFalse(variant_to_archive.active)
|
||||
|
||||
# Putting it back should unarchive the archived variant
|
||||
product_template.attribute_line_ids[1].value_ids = [
|
||||
Command.link(self.dynamic_attribute.value_ids[:1].id)
|
||||
]
|
||||
self.assertEqual(len(product_template.product_variant_ids), 2)
|
||||
self.assertTrue(variant_to_archive.active)
|
||||
|
||||
def test_supplierinfo_with_dynamic_attribute(self):
|
||||
"""
|
||||
Ensure that supplierinfo.product_id is never automatically set when
|
||||
variants are created dynamically.
|
||||
|
||||
The supplierinfo should remain template-level (product_id = False)
|
||||
unless the user explicitly assigns a specific variant manually,
|
||||
even if only one variant exists initially.
|
||||
"""
|
||||
product_template = self.env['product.template'].create({
|
||||
'name': 'Test dynamic',
|
||||
'attribute_line_ids': [
|
||||
Command.create({
|
||||
'attribute_id': self.dynamic_attribute.id,
|
||||
'value_ids': [Command.set(self.dynamic_attribute.value_ids.ids)],
|
||||
}),
|
||||
]
|
||||
})
|
||||
self.assertFalse(product_template.product_variant_ids)
|
||||
|
||||
supplierinfo = self.env['product.supplierinfo'].create({
|
||||
'partner_id': self.partner.id,
|
||||
'product_tmpl_id': product_template.id,
|
||||
})
|
||||
self.assertFalse(product_template.product_variant_ids)
|
||||
|
||||
product_template._create_product_variant(product_template.attribute_line_ids.product_template_value_ids[0])
|
||||
self.assertEqual(len(product_template.product_variant_ids), 1)
|
||||
self.assertFalse(supplierinfo.product_id)
|
||||
|
||||
product_template._create_product_variant(product_template.attribute_line_ids.product_template_value_ids[1])
|
||||
self.assertEqual(len(product_template.product_variant_ids), 2)
|
||||
self.assertFalse(supplierinfo.product_id)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue