[REF] sale_management: test infrastructure
* New common with a unique dumb empty SO template * clean tests to rely on the new sale commo data Part-of: odoo/odoo#96791
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.sale.tests.common import SaleCommon
|
||||
|
||||
class SaleManagementCommon(SaleCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
cls.empty_order_template = cls.env['sale.order.template'].create({
|
||||
'name': "Test Quotation Template",
|
||||
})
|
||||
@@ -1,23 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.sale.tests.common import TestSaleCommon
|
||||
from odoo.fields import Command
|
||||
from odoo.tests import Form, tagged
|
||||
|
||||
from odoo.addons.sale_management.tests.common import SaleManagementCommon
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestSaleOrder(TestSaleCommon):
|
||||
class TestSaleOrder(SaleManagementCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref=None):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref)
|
||||
|
||||
Pricelist = cls.env['product.pricelist']
|
||||
Product = cls.env['product.product']
|
||||
SaleOrder = cls.env['sale.order']
|
||||
SaleOrderTemplate = cls.env['sale.order.template']
|
||||
SaleOrderTemplateLine = cls.env['sale.order.template.line']
|
||||
SaleOrderTemplateOption = cls.env['sale.order.template.option']
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
# some variables to ease asserts in tests
|
||||
cls.pub_product_price = 100.0
|
||||
@@ -33,147 +28,131 @@ class TestSaleOrder(TestSaleCommon):
|
||||
cls.merged_option_discount = 100.0 - (100.0 - cls.pl_option_discount) * (100.0 - cls.tpl_option_discount) / 100.0
|
||||
|
||||
# create some products
|
||||
cls.product_1 = Product.create({
|
||||
'name': 'Product 1',
|
||||
'lst_price': cls.pub_product_price,
|
||||
})
|
||||
|
||||
cls.optional_product = Product.create({
|
||||
'name': 'Optional product',
|
||||
'lst_price': cls.pub_option_price,
|
||||
})
|
||||
cls.product_1, cls.optional_product = cls.env['product.product'].create([
|
||||
{
|
||||
'name': 'Product 1',
|
||||
'lst_price': cls.pub_product_price,
|
||||
}, {
|
||||
'name': 'Optional product',
|
||||
'lst_price': cls.pub_option_price,
|
||||
}
|
||||
])
|
||||
|
||||
# create some quotation templates
|
||||
cls.quotation_template_no_discount = SaleOrderTemplate.create({
|
||||
'name': 'A quotation template without discount'
|
||||
})
|
||||
|
||||
SaleOrderTemplateLine.create({
|
||||
'sale_order_template_id': cls.quotation_template_no_discount.id,
|
||||
'product_id': cls.product_1.id,
|
||||
})
|
||||
|
||||
SaleOrderTemplateOption.create({
|
||||
'sale_order_template_id': cls.quotation_template_no_discount.id,
|
||||
'product_id': cls.optional_product.id,
|
||||
})
|
||||
|
||||
# create some pricelists
|
||||
cls.discount_included_price_list = Pricelist.create({
|
||||
'name': 'Discount included Pricelist',
|
||||
'discount_policy': 'with_discount',
|
||||
'item_ids': [
|
||||
(0, 0, {
|
||||
'name': 'Product 1 premium price',
|
||||
'applied_on': '1_product',
|
||||
'product_tmpl_id': cls.product_1.product_tmpl_id.id,
|
||||
'compute_price': 'fixed',
|
||||
'fixed_price': cls.pl_product_price
|
||||
cls.quotation_template_no_discount = cls.env['sale.order.template'].create({
|
||||
'name': 'A quotation template',
|
||||
'sale_order_template_line_ids': [
|
||||
Command.create({
|
||||
'product_id': cls.product_1.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'name': 'Optional product premium price',
|
||||
'applied_on': '1_product',
|
||||
'product_tmpl_id': cls.optional_product.product_tmpl_id.id,
|
||||
'compute_price': 'fixed',
|
||||
'fixed_price': cls.pl_option_price
|
||||
})]
|
||||
})
|
||||
|
||||
cls.discount_excluded_price_list = Pricelist.create({
|
||||
'name': 'Discount excluded Pricelist',
|
||||
'discount_policy': 'without_discount',
|
||||
'item_ids': [
|
||||
(0, 0, {
|
||||
'name': 'Product 1 premium price',
|
||||
'applied_on': '1_product',
|
||||
'product_tmpl_id': cls.product_1.product_tmpl_id.id,
|
||||
'compute_price': 'fixed',
|
||||
'fixed_price': cls.pl_product_price
|
||||
],
|
||||
'sale_order_template_option_ids': [
|
||||
Command.create({
|
||||
'product_id': cls.optional_product.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'name': 'Optional product premium price',
|
||||
'applied_on': '1_product',
|
||||
'product_tmpl_id': cls.optional_product.product_tmpl_id.id,
|
||||
'compute_price': 'fixed',
|
||||
'fixed_price': cls.pl_option_price
|
||||
})]
|
||||
],
|
||||
})
|
||||
|
||||
# create some sale orders
|
||||
cls.sale_order = SaleOrder.create({
|
||||
'partner_id': cls.partner_a.id,
|
||||
'pricelist_id': cls.company_data['default_pricelist'].id,
|
||||
})
|
||||
# create two pricelist with different discount policies (same total price)
|
||||
pricelist_rule_values = [
|
||||
Command.create({
|
||||
'name': 'Product 1 premium price',
|
||||
'applied_on': '1_product',
|
||||
'product_tmpl_id': cls.product_1.product_tmpl_id.id,
|
||||
'compute_price': 'fixed',
|
||||
'fixed_price': cls.pl_product_price,
|
||||
}),
|
||||
Command.create({
|
||||
'name': 'Optional product premium price',
|
||||
'applied_on': '1_product',
|
||||
'product_tmpl_id': cls.optional_product.product_tmpl_id.id,
|
||||
'compute_price': 'fixed',
|
||||
'fixed_price': cls.pl_option_price,
|
||||
}),
|
||||
]
|
||||
|
||||
cls.sale_order_no_price_list = SaleOrder.create({
|
||||
'partner_id': cls.partner_a.id,
|
||||
'pricelist_id': cls.company_data['default_pricelist'].id,
|
||||
})
|
||||
(
|
||||
cls.discount_included_price_list,
|
||||
cls.discount_excluded_price_list
|
||||
) = cls.env['product.pricelist'].create([
|
||||
{
|
||||
'name': 'Discount included Pricelist',
|
||||
'discount_policy': 'with_discount',
|
||||
'item_ids': pricelist_rule_values,
|
||||
}, {
|
||||
'name': 'Discount excluded Pricelist',
|
||||
'discount_policy': 'without_discount',
|
||||
'item_ids': pricelist_rule_values,
|
||||
}
|
||||
])
|
||||
|
||||
# variable kept to reduce code diff
|
||||
cls.sale_order = cls.empty_order
|
||||
|
||||
def test_01_template_without_pricelist(self):
|
||||
"""
|
||||
This test checks that without any price list, the public price
|
||||
This test checks that without any rule in the pricelist, the public price
|
||||
of the product is used in the sale order after selecting a
|
||||
quotation template.
|
||||
"""
|
||||
# first case, without discount in the quotation template
|
||||
self.sale_order_no_price_list.write({
|
||||
self.sale_order.write({
|
||||
'sale_order_template_id': self.quotation_template_no_discount.id
|
||||
})
|
||||
self.sale_order_no_price_list._onchange_sale_order_template_id()
|
||||
self.sale_order._onchange_sale_order_template_id()
|
||||
|
||||
self.assertEqual(
|
||||
len(self.sale_order_no_price_list.order_line),
|
||||
len(self.sale_order.order_line),
|
||||
1,
|
||||
"The sale order shall contains the same number of products as"
|
||||
"the quotation template.")
|
||||
|
||||
self.assertEqual(
|
||||
self.sale_order_no_price_list.order_line[0].product_id.id,
|
||||
self.sale_order.order_line[0].product_id.id,
|
||||
self.product_1.id,
|
||||
"The sale order shall contains the same products as the"
|
||||
"quotation template.")
|
||||
|
||||
self.assertEqual(
|
||||
self.sale_order_no_price_list.order_line[0].price_unit,
|
||||
self.sale_order.order_line[0].price_unit,
|
||||
self.pub_product_price,
|
||||
"Without any price list and discount, the public price of"
|
||||
"the product shall be used.")
|
||||
|
||||
self.assertEqual(
|
||||
len(self.sale_order_no_price_list.sale_order_option_ids),
|
||||
len(self.sale_order.sale_order_option_ids),
|
||||
1,
|
||||
"The sale order shall contains the same number of optional products as"
|
||||
"the quotation template.")
|
||||
|
||||
self.assertEqual(
|
||||
self.sale_order_no_price_list.sale_order_option_ids[0].product_id.id,
|
||||
self.sale_order.sale_order_option_ids[0].product_id.id,
|
||||
self.optional_product.id,
|
||||
"The sale order shall contains the same optional products as the"
|
||||
"quotation template.")
|
||||
|
||||
self.assertEqual(
|
||||
self.sale_order_no_price_list.sale_order_option_ids[0].price_unit,
|
||||
self.sale_order.sale_order_option_ids[0].price_unit,
|
||||
self.pub_option_price,
|
||||
"Without any price list and discount, the public price of"
|
||||
"the optional product shall be used.")
|
||||
|
||||
# add the option to the order
|
||||
self.sale_order_no_price_list.sale_order_option_ids[0].button_add_to_order()
|
||||
self.sale_order.sale_order_option_ids[0].button_add_to_order()
|
||||
|
||||
self.assertEqual(
|
||||
len(self.sale_order_no_price_list.order_line),
|
||||
len(self.sale_order.order_line),
|
||||
2,
|
||||
"When an option is added, a new order line is created")
|
||||
|
||||
self.assertEqual(
|
||||
self.sale_order_no_price_list.order_line[1].product_id.id,
|
||||
self.sale_order.order_line[1].product_id.id,
|
||||
self.optional_product.id,
|
||||
"The sale order shall contains the same products as the"
|
||||
"quotation template.")
|
||||
|
||||
self.assertEqual(
|
||||
self.sale_order_no_price_list.order_line[1].price_unit,
|
||||
self.sale_order.order_line[1].price_unit,
|
||||
self.pub_option_price,
|
||||
"Without any price list and discount, the public price of"
|
||||
"the optional product shall be used.")
|
||||
@@ -219,8 +198,6 @@ class TestSaleOrder(TestSaleCommon):
|
||||
the price used in the sale order is the product public price and
|
||||
the discount is computed according to the price list.
|
||||
"""
|
||||
self.env.user.groups_id += self.env.ref('product.group_discount_per_so_line')
|
||||
|
||||
self.sale_order.write({
|
||||
'pricelist_id': self.discount_excluded_price_list.id,
|
||||
'sale_order_template_id': self.quotation_template_no_discount.id
|
||||
@@ -286,12 +263,6 @@ class TestSaleOrder(TestSaleCommon):
|
||||
This test checks that option line's values are correctly
|
||||
updated after a pricelist update
|
||||
"""
|
||||
|
||||
# Necessary for _onchange_discount() check
|
||||
self.env.user.write({
|
||||
'groups_id': [(4, self.env.ref('product.group_discount_per_so_line').id)],
|
||||
})
|
||||
|
||||
self.sale_order.write({
|
||||
'sale_order_template_id': self.quotation_template_no_discount.id
|
||||
})
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import odoo.tests
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests import HttpCase, tagged
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestUi(odoo.tests.HttpCase):
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestUi(HttpCase):
|
||||
|
||||
def test_01_sale_tour(self):
|
||||
self.start_tour("/web", 'sale_tour', login="admin", step_delay=100)
|
||||
|
||||
Reference in New Issue
Block a user