[FIX] sale: free optional product
- Create a dynamic product P1 with an optional product P2 - The list price of P2 is 20 - Create a pricelist where P2 is free (fixed price of 0) - In a SO, choose 'Configure a product' and choose P1, add In the modal which suggests P2, its price is 20 instead of 0. This is because we fall back on the list price when fetching the combination prices. This should not be necessary since: - a pricelist is required to fetch a price - a pricelist should always contain a rule applying to all products Therefore, the list price doesn't need to be used as a fallback. It is then necessary to modify the test tours by adding a partner on the SO before selecting the product. Anyway, this is usually the way to go since the selection of the partner determines the pricelist. opw-1902456 closes odoo/odoo#28687
This commit is contained in:
@@ -183,7 +183,7 @@ class ProductConfiguratorController(http.Controller):
|
||||
|
||||
product_id = None
|
||||
list_price = product_template.price_compute('list_price')[product_template.id]
|
||||
price = product_template.price or list_price
|
||||
price = product_template.price
|
||||
if(product):
|
||||
product = product.with_context(
|
||||
no_variant_attributes_price_extra=[product_attribute_value.price_extra or 0.0
|
||||
@@ -194,7 +194,7 @@ class ProductConfiguratorController(http.Controller):
|
||||
)
|
||||
product_id = product.id
|
||||
list_price = product.price_compute('list_price')[product.id]
|
||||
price = product.price or list_price
|
||||
price = product.price
|
||||
|
||||
display_name = [product_template.name]
|
||||
if filtered_product_template_attribute_values:
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<t t-call="sale.variants" />
|
||||
<h2 class="oe_price product_id mt-3" style="white-space: nowrap;"
|
||||
t-att-data-product-id="product.id"
|
||||
t-esc="product.price if product.price else product.lst_price"
|
||||
t-esc="product.price"
|
||||
t-options='{
|
||||
"widget": "monetary",
|
||||
"display_currency": to_currency
|
||||
|
||||
@@ -16,7 +16,14 @@ tour.register('sale_product_configurator_advanced_tour', {
|
||||
trigger: ".o_list_button_add",
|
||||
extra_trigger: ".o_sale_order"
|
||||
}, {
|
||||
trigger: "a:contains('Configure a product')"
|
||||
trigger: ".o_required_modifier[name=partner_id] input",
|
||||
run: "text Tajine Saucisse",
|
||||
}, {
|
||||
trigger: ".ui-menu-item > a:contains('Tajine Saucisse')",
|
||||
auto: true,
|
||||
}, {
|
||||
trigger: "a:contains('Configure a product')",
|
||||
extra_trigger: ".o_field_widget[name=pricelist_id] > .o_external_button", // Wait for pricelist (onchange_partner_id)
|
||||
}, {
|
||||
trigger: '.o_product_configurator .o_input_dropdown input',
|
||||
run: 'click'
|
||||
@@ -129,4 +136,4 @@ tour.register('sale_product_configurator_advanced_tour', {
|
||||
run: function (){} //check
|
||||
}]);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,7 +16,14 @@ tour.register('sale_product_configurator_tour', {
|
||||
trigger: ".o_list_button_add",
|
||||
extra_trigger: ".o_sale_order"
|
||||
}, {
|
||||
trigger: "a:contains('Configure a product')"
|
||||
trigger: ".o_required_modifier[name=partner_id] input",
|
||||
run: "text Couscous Magique",
|
||||
}, {
|
||||
trigger: ".ui-menu-item > a:contains('Couscous Magique')",
|
||||
auto: true,
|
||||
}, {
|
||||
trigger: "a:contains('Configure a product')",
|
||||
extra_trigger: ".o_field_widget[name=pricelist_id] > .o_external_button", // Wait for pricelist (onchange_partner_id)
|
||||
}, {
|
||||
trigger: '.o_product_configurator .o_input_dropdown input',
|
||||
run: 'click'
|
||||
@@ -85,6 +92,16 @@ tour.register('sale_product_configurator_tour', {
|
||||
extra_trigger: 'div[name="order_line"]',
|
||||
in_modal: false,
|
||||
run: function (){}
|
||||
}, {
|
||||
trigger: '.o_readonly_modifier[name=amount_total]:contains("835")',
|
||||
in_modal: false,
|
||||
edition: 'community',
|
||||
run: function (){}
|
||||
}, {
|
||||
trigger: '.o_readonly_modifier[name=amount_total]:contains("837")',
|
||||
in_modal: false,
|
||||
edition: 'enterprise',
|
||||
run: function (){}
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
@@ -8,14 +8,28 @@ class TestUi(odoo.tests.HttpCase):
|
||||
self.phantom_js("/web", "odoo.__DEBUG__.services['web_tour.tour'].run('sale_tour')", "odoo.__DEBUG__.services['web_tour.tour'].tours.sale_tour.ready", login="admin")
|
||||
|
||||
def test_02_product_configurator(self):
|
||||
# To be able to test the product configurator, admin user must have access to "variants and options" feature, so we give him the right group for that
|
||||
self.env.ref('base.user_admin').write({'groups_id': [(4, self.env.ref('product.group_product_variant').id)]})
|
||||
# group_product_variant: use the product configurator
|
||||
# group_sale_pricelist: display the pricelist to determine when it is changed after choosing
|
||||
# the partner
|
||||
self.env.ref('base.user_admin').write({
|
||||
'groups_id': [
|
||||
(4, self.env.ref('product.group_product_variant').id),
|
||||
(4, self.env.ref('product.group_sale_pricelist').id),
|
||||
],
|
||||
})
|
||||
|
||||
self.phantom_js("/web", "odoo.__DEBUG__.services['web_tour.tour'].run('sale_product_configurator_tour')", "odoo.__DEBUG__.services['web_tour.tour'].tours.sale_product_configurator_tour.ready", login="admin")
|
||||
|
||||
def test_03_product_configurator_advanced(self):
|
||||
# To be able to test the product configurator, admin user must have access to "variants and options" feature, so we give him the right group for that
|
||||
self.env.ref('base.user_admin').write({'groups_id': [(4, self.env.ref('product.group_product_variant').id)]})
|
||||
# group_product_variant: use the product configurator
|
||||
# group_sale_pricelist: display the pricelist to determine when it is changed after choosing
|
||||
# the partner
|
||||
self.env.ref('base.user_admin').write({
|
||||
'groups_id': [
|
||||
(4, self.env.ref('product.group_product_variant').id),
|
||||
(4, self.env.ref('product.group_sale_pricelist').id),
|
||||
],
|
||||
})
|
||||
|
||||
# Prepare relevant test data
|
||||
# This is not included in demo data to avoid useless noise
|
||||
|
||||
Reference in New Issue
Block a user