diff options
| author | Laurent Smet <las@odoo.com> | 2020-07-27 08:31:58 +0000 |
|---|---|---|
| committer | Laurent Smet <las@odoo.com> | 2020-07-31 08:38:30 +0000 |
| commit | 6d1e1e09ead203aae5e12af07d01735c64c7bc46 (patch) | |
| tree | f33fe414e080ec34dc4cfcc36b8551b8dbe2afac /addons | |
| parent | dc1fccf6998db43ae91248d096f57bcf7c8c5bc6 (diff) | |
[IMP] sale*: Remove dependency to AccountTestCommon
l10n runbot builds are all failing when running at least one test depending of AccountTestCommon because it:
- doesn't create a sandboxed testing environnement to manage the multi-currency, multi-company, the default company's currency, the exchange rates...
- doesn't setup a testing user then all tests are done using the superuser.
- doesn't provide a fully setup chart of accounts: exchange difference journal is not set, accounts have bad types, etc...
- is run sometimes at-install.
--task: 2301180m
Diffstat (limited to 'addons')
32 files changed, 1203 insertions, 1599 deletions
diff --git a/addons/account/tests/common.py b/addons/account/tests/common.py index 2f58db6b56f..5811a6bf0cf 100644 --- a/addons/account/tests/common.py +++ b/addons/account/tests/common.py @@ -354,103 +354,6 @@ class AccountTestNoChartCommon(SavepointCaseWithUserDemo): }).id, }) cls.env.user.company_id.currency_exchange_journal_id = cls.exchange_journal0 - - @classmethod - def setUpAdditionalAccounts(cls): - """ Set up some addionnal accounts: expenses, revenue, ... """ - user_type_income = cls.env.ref('account.data_account_type_direct_costs') - cls.account_income = cls.env['account.account'].create({ - 'code': 'NC1112', 'name': - 'Sale - Test Account', - 'user_type_id': user_type_income.id - }) - user_type_expense = cls.env.ref('account.data_account_type_expenses') - cls.account_expense = cls.env['account.account'].create({ - 'code': 'NC1113', - 'name': 'HR Expense - Test Purchase Account', - 'user_type_id': user_type_expense.id - }) - user_type_revenue = cls.env.ref('account.data_account_type_revenue') - cls.account_revenue = cls.env['account.account'].create({ - 'code': 'NC1114', - 'name': 'Sales - Test Sales Account', - 'user_type_id': user_type_revenue.id, - 'reconcile': True - }) - - @classmethod - def setUpAccountJournal(cls): - """ Set up some journals: sale, purchase, ... """ - cls.journal_purchase = cls.env['account.journal'].create({ - 'name': 'Purchase Journal - Test', - 'code': 'AJ-PURC', - 'type': 'purchase', - 'company_id': cls.env.user.company_id.id, - 'default_debit_account_id': cls.account_expense.id, - 'default_credit_account_id': cls.account_expense.id, - }) - cls.journal_sale = cls.env['account.journal'].create({ - 'name': 'Sale Journal - Test', - 'code': 'AJ-SALE', - 'type': 'sale', - 'company_id': cls.env.user.company_id.id, - 'default_debit_account_id': cls.account_income.id, - 'default_credit_account_id': cls.account_income.id, - }) - cls.journal_general = cls.env['account.journal'].create({ - 'name': 'General Journal - Test', - 'code': 'AJ-GENERAL', - 'type': 'general', - 'company_id': cls.env.user.company_id.id, - }) - cls.journal_bank = cls.env['account.journal'].create({ - 'name': 'Bank Journal - Test', - 'code': 'AJ-BANK', - 'type': 'bank', - 'company_id': cls.env.user.company_id.id, - }) - - @classmethod - def setUpUsers(cls): - """ Create 2 users: an employee and a manager. Both will have correct account configured - on their partner. Others access rigths should be given in extending test suites set up. - """ - group_employee = cls.env.ref('base.group_user') - Users = cls.env['res.users'].with_context({'no_reset_password': True, 'mail_create_nosubscribe': True, 'mail_create_nolog': True}) - cls.user_employee = Users.create({ - 'name': 'Tyrion Lannister Employee', - 'login': 'tyrion', - 'email': 'tyrion@example.com', - 'notification_type': 'email', - 'groups_id': [(6, 0, [group_employee.id])], - }) - cls.user_manager = Users.create({ - 'name': 'Daenerys Targaryen Manager', - 'login': 'daenerys', - 'email': 'daenerys@example.com', - 'notification_type': 'email', - 'groups_id': [(6, 0, [group_employee.id])], - }) - account_values = { - 'property_account_payable_id': cls.account_payable.id, - 'property_account_receivable_id': cls.account_receivable.id, - } - cls.user_manager.partner_id.write(account_values) - cls.user_employee.partner_id.write(account_values) - -class AccountTestNoChartCommonMultiCompany(AccountTestNoChartCommon): - """ Some tests required to be executed at module installation, and not 'post install', like moslty - of accounting tests, since a chart of account is required - This test setup class provides data for test suite to make business flow working without a chart - of account installed in a multi-company environment. - The class provide some helpers methods to create particular document types. Each test suite extending - this method can call thoses method to set up their testing environment in their own `setUpClass` method. - """ - - @classmethod - def setUpClass(cls): - """ This method set up the minimal requried part of chart of account """ - super(AccountTestNoChartCommonMultiCompany, cls).setUpClass() cls.company_B = cls.env['res.company'].create({'name': 'Company B'}) # To speed up test, create object without mail tracking @@ -509,7 +412,25 @@ class AccountTestNoChartCommonMultiCompany(AccountTestNoChartCommon): @classmethod def setUpAdditionalAccounts(cls): """ Set up some addionnal accounts: expenses, revenue, ... """ - super(AccountTestNoChartCommonMultiCompany, cls).setUpAdditionalAccounts() + user_type_income = cls.env.ref('account.data_account_type_direct_costs') + cls.account_income = cls.env['account.account'].create({ + 'code': 'NC1112', 'name': + 'Sale - Test Account', + 'user_type_id': user_type_income.id + }) + user_type_expense = cls.env.ref('account.data_account_type_expenses') + cls.account_expense = cls.env['account.account'].create({ + 'code': 'NC1113', + 'name': 'HR Expense - Test Purchase Account', + 'user_type_id': user_type_expense.id + }) + user_type_revenue = cls.env.ref('account.data_account_type_revenue') + cls.account_revenue = cls.env['account.account'].create({ + 'code': 'NC1114', + 'name': 'Sales - Test Sales Account', + 'user_type_id': user_type_revenue.id, + 'reconcile': True + }) user_type_income = cls.env.ref('account.data_account_type_direct_costs') cls.account_income_company_B = cls.env['account.account'].create({ 'code': 'NC1112', @@ -536,7 +457,34 @@ class AccountTestNoChartCommonMultiCompany(AccountTestNoChartCommon): @classmethod def setUpAccountJournal(cls): """ Set up some journals: sale, purchase, ... """ - super(AccountTestNoChartCommonMultiCompany, cls).setUpAccountJournal() + cls.journal_purchase = cls.env['account.journal'].create({ + 'name': 'Purchase Journal - Test', + 'code': 'AJ-PURC', + 'type': 'purchase', + 'company_id': cls.env.user.company_id.id, + 'default_debit_account_id': cls.account_expense.id, + 'default_credit_account_id': cls.account_expense.id, + }) + cls.journal_sale = cls.env['account.journal'].create({ + 'name': 'Sale Journal - Test', + 'code': 'AJ-SALE', + 'type': 'sale', + 'company_id': cls.env.user.company_id.id, + 'default_debit_account_id': cls.account_income.id, + 'default_credit_account_id': cls.account_income.id, + }) + cls.journal_general = cls.env['account.journal'].create({ + 'name': 'General Journal - Test', + 'code': 'AJ-GENERAL', + 'type': 'general', + 'company_id': cls.env.user.company_id.id, + }) + cls.journal_bank = cls.env['account.journal'].create({ + 'name': 'Bank Journal - Test', + 'code': 'AJ-BANK', + 'type': 'bank', + 'company_id': cls.env.user.company_id.id, + }) cls.journal_purchase_company_B = cls.env['account.journal'].create({ 'name': 'Purchase Journal Company B - Test', 'code': 'AJ-PURC', @@ -562,12 +510,31 @@ class AccountTestNoChartCommonMultiCompany(AccountTestNoChartCommon): @classmethod def setUpUsers(cls): - """ Create 2 users for each company: an employee and a manager. Both will have correct account configured + """ Create 2 users: an employee and a manager. Both will have correct account configured on their partner. Others access rigths should be given in extending test suites set up. """ - super(AccountTestNoChartCommonMultiCompany, cls).setUpUsers() group_employee = cls.env.ref('base.group_user') Users = cls.env['res.users'].with_context({'no_reset_password': True, 'mail_create_nosubscribe': True, 'mail_create_nolog': True}) + cls.user_employee = Users.create({ + 'name': 'Tyrion Lannister Employee', + 'login': 'tyrion', + 'email': 'tyrion@example.com', + 'notification_type': 'email', + 'groups_id': [(6, 0, [group_employee.id])], + }) + cls.user_manager = Users.create({ + 'name': 'Daenerys Targaryen Manager', + 'login': 'daenerys', + 'email': 'daenerys@example.com', + 'notification_type': 'email', + 'groups_id': [(6, 0, [group_employee.id])], + }) + account_values = { + 'property_account_payable_id': cls.account_payable.id, + 'property_account_receivable_id': cls.account_receivable.id, + } + cls.user_manager.partner_id.write(account_values) + cls.user_employee.partner_id.write(account_values) cls.user_employee_company_B = Users.create({ 'name': 'Gregor Clegane Employee', 'login': 'gregor', diff --git a/addons/purchase/tests/test_purchase_order_report.py b/addons/purchase/tests/test_purchase_order_report.py index a262696068c..0b4761893f0 100644 --- a/addons/purchase/tests/test_purchase_order_report.py +++ b/addons/purchase/tests/test_purchase_order_report.py @@ -62,7 +62,6 @@ class TestPurchaseOrderReport(AccountTestInvoicingCommon): ('company_id', '=', self.company_data['company'].id), ]) - # Check that repost should show 6 unit of product self.assertEqual(res_product2.qty_ordered, 1.0, 'No conversion needed since product_b is already a dozen') # report should show in company currency (amount/rate) = (200/2) self.assertEqual(res_product2.price_total, 100.0, 'Currency conversion is not working') diff --git a/addons/sale/tests/__init__.py b/addons/sale/tests/__init__.py index 335cd20e7c9..88bf481bf04 100644 --- a/addons/sale/tests/__init__.py +++ b/addons/sale/tests/__init__.py @@ -11,3 +11,4 @@ from . import test_access_rights from . import test_sale_refund from . import test_sale_signature from . import test_sale_transaction +from . import test_sale_flow diff --git a/addons/sale/tests/common.py b/addons/sale/tests/common.py new file mode 100644 index 00000000000..dfcd198e194 --- /dev/null +++ b/addons/sale/tests/common.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.account.tests.common import AccountTestInvoicingCommon +from odoo.addons.base.tests.common import SavepointCase + + +class TestSaleCommonBase(SavepointCase): + ''' Setup with sale test configuration. ''' + + @classmethod + def setup_sale_configuration_for_company(cls, company): + Users = cls.env['res.users'].with_context(no_reset_password=True) + + company_data = { + # Sales Team + 'default_sale_team': cls.env['crm.team'].with_context(tracking_disable=True).create({ + 'name': 'Test Channel', + 'company_id': company.id, + }), + + # Users + 'default_user_salesman': Users.create({ + 'name': 'default_user_salesman', + 'login': 'default_user_salesman.comp%s' % company.id, + 'email': 'default_user_salesman@example.com', + 'signature': '--\nMark', + 'notification_type': 'email', + 'groups_id': [(6, 0, cls.env.ref('sales_team.group_sale_salesman').ids)], + 'company_ids': [(6, 0, company.ids)], + 'company_id': company.id, + }), + 'default_user_portal': Users.create({ + 'name': 'default_user_portal', + 'login': 'default_user_portal.comp%s' % company.id, + 'email': 'default_user_portal@gladys.portal', + 'groups_id': [(6, 0, [cls.env.ref('base.group_portal').id])], + 'company_ids': [(6, 0, company.ids)], + 'company_id': company.id, + }), + 'default_user_employee': Users.create({ + 'name': 'default_user_employee', + 'login': 'default_user_employee.comp%s' % company.id, + 'email': 'default_user_employee@example.com', + 'groups_id': [(6, 0, [cls.env.ref('base.group_user').id])], + 'company_ids': [(6, 0, company.ids)], + 'company_id': company.id, + }), + + # Pricelist + 'default_pricelist': cls.env['product.pricelist'].with_company(company).create({ + 'name': 'default_pricelist', + 'currency_id': company.currency_id.id, + }), + + # Product category + 'product_category': cls.env['product.category'].with_company(company).create({ + 'name': 'Test category', + }), + } + + company_data.update({ + # Products + 'product_service_delivery': cls.env['product.product'].with_company(company).create({ + 'name': 'product_service_delivery', + 'categ_id': company_data['product_category'].id, + 'standard_price': 200.0, + 'list_price': 180.0, + 'type': 'service', + 'uom_id': cls.env.ref('uom.product_uom_unit').id, + 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, + 'default_code': 'SERV_DEL', + 'invoice_policy': 'delivery', + 'taxes_id': [(6, 0, [])], + 'supplier_taxes_id': [(6, 0, [])], + }), + 'product_service_order': cls.env['product.product'].with_company(company).create({ + 'name': 'product_service_order', + 'categ_id': company_data['product_category'].id, + 'standard_price': 40.0, + 'list_price': 90.0, + 'type': 'service', + 'uom_id': cls.env.ref('uom.product_uom_hour').id, + 'uom_po_id': cls.env.ref('uom.product_uom_hour').id, + 'description': 'Example of product to invoice on order', + 'default_code': 'PRE-PAID', + 'invoice_policy': 'order', + 'taxes_id': [(6, 0, [])], + 'supplier_taxes_id': [(6, 0, [])], + }), + 'product_order_cost': cls.env['product.product'].with_company(company).create({ + 'name': 'product_order_cost', + 'categ_id': company_data['product_category'].id, + 'standard_price': 235.0, + 'list_price': 280.0, + 'type': 'consu', + 'weight': 0.01, + 'uom_id': cls.env.ref('uom.product_uom_unit').id, + 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, + 'default_code': 'FURN_9999', + 'invoice_policy': 'order', + 'expense_policy': 'cost', + 'taxes_id': [(6, 0, [])], + 'supplier_taxes_id': [(6, 0, [])], + }), + 'product_delivery_cost': cls.env['product.product'].with_company(company).create({ + 'name': 'product_delivery_cost', + 'categ_id': company_data['product_category'].id, + 'standard_price': 55.0, + 'list_price': 70.0, + 'type': 'consu', + 'weight': 0.01, + 'uom_id': cls.env.ref('uom.product_uom_unit').id, + 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, + 'default_code': 'FURN_7777', + 'invoice_policy': 'delivery', + 'expense_policy': 'cost', + 'taxes_id': [(6, 0, [])], + 'supplier_taxes_id': [(6, 0, [])], + }), + 'product_order_sales_price': cls.env['product.product'].with_company(company).create({ + 'name': 'product_order_sales_price', + 'categ_id': company_data['product_category'].id, + 'standard_price': 235.0, + 'list_price': 280.0, + 'type': 'consu', + 'weight': 0.01, + 'uom_id': cls.env.ref('uom.product_uom_unit').id, + 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, + 'default_code': 'FURN_9999', + 'invoice_policy': 'order', + 'expense_policy': 'sales_price', + 'taxes_id': [(6, 0, [])], + 'supplier_taxes_id': [(6, 0, [])], + }), + 'product_delivery_sales_price': cls.env['product.product'].with_company(company).create({ + 'name': 'product_delivery_sales_price', + 'categ_id': company_data['product_category'].id, + 'standard_price': 55.0, + 'list_price': 70.0, + 'type': 'consu', + 'weight': 0.01, + 'uom_id': cls.env.ref('uom.product_uom_unit').id, + 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, + 'default_code': 'FURN_7777', + 'invoice_policy': 'delivery', + 'expense_policy': 'sales_price', + 'taxes_id': [(6, 0, [])], + 'supplier_taxes_id': [(6, 0, [])], + }), + 'product_order_no': cls.env['product.product'].with_company(company).create({ + 'name': 'product_order_no', + 'categ_id': company_data['product_category'].id, + 'standard_price': 235.0, + 'list_price': 280.0, + 'type': 'consu', + 'weight': 0.01, + 'uom_id': cls.env.ref('uom.product_uom_unit').id, + 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, + 'default_code': 'FURN_9999', + 'invoice_policy': 'order', + 'expense_policy': 'no', + 'taxes_id': [(6, 0, [])], + 'supplier_taxes_id': [(6, 0, [])], + }), + 'product_delivery_no': cls.env['product.product'].with_company(company).create({ + 'name': 'product_delivery_no', + 'categ_id': company_data['product_category'].id, + 'standard_price': 55.0, + 'list_price': 70.0, + 'type': 'consu', + 'weight': 0.01, + 'uom_id': cls.env.ref('uom.product_uom_unit').id, + 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, + 'default_code': 'FURN_7777', + 'invoice_policy': 'delivery', + 'expense_policy': 'no', + 'taxes_id': [(6, 0, [])], + 'supplier_taxes_id': [(6, 0, [])], + }), + }) + + return company_data + + +class TestSaleCommon(AccountTestInvoicingCommon, TestSaleCommonBase): + ''' Setup to be used post-install with sale and accounting test configuration.''' + + @classmethod + def setup_company_data(cls, company_name, chart_template=None, **kwargs): + company_data = super().setup_company_data(company_name, chart_template=chart_template, **kwargs) + + company_data.update(cls.setup_sale_configuration_for_company(company_data['company'])) + + company_data['product_category'].write({ + 'property_account_income_categ_id': company_data['default_account_revenue'].id, + 'property_account_expense_categ_id': company_data['default_account_expense'].id, + }) + + return company_data diff --git a/addons/sale/tests/test_access_rights.py b/addons/sale/tests/test_access_rights.py index cc6f66556b1..668910ca046 100644 --- a/addons/sale/tests/test_access_rights.py +++ b/addons/sale/tests/test_access_rights.py @@ -1,153 +1,124 @@ # -*- 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.exceptions import AccessError, UserError, ValidationError from odoo.tests import tagged -from .test_sale_common import TestCommonSaleNoChart @tagged('post_install', '-at_install') -class TestAccessRights(TestCommonSaleNoChart): - - def setUp(self): - super(TestAccessRights, self).setUp() +class TestAccessRights(TestSaleCommon): - Users = self.env['res.users'].with_context(no_reset_password=True) - - group_user = self.env.ref('sales_team.group_sale_salesman') - # Create a users - self.user_manager = Users.create({ - 'name': 'Andrew Manager', - 'login': 'manager', - 'email': 'a.m@example.com', - 'groups_id': [(6, 0, [self.env.ref('sales_team.group_sale_manager').id])] - }) - self.user_salesperson = Users.create({ - 'name': 'Mark User', - 'login': 'user', - 'email': 'm.u@example.com', - 'groups_id': [(6, 0, [group_user.id])] - }) - self.user_salesperson_1 = Users.create({ - 'name': 'Noemie User', - 'login': 'noemie', - 'email': 'n.n@example.com', - 'groups_id': [(6, 0, [group_user.id])] - }) - self.user_portal = Users.create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])] - }) - self.user_employee = Users.create({ - 'name': 'Bert Tartignole', - 'login': 'bert', - 'email': 'b.t@example.com', - 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])] - }) + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) - # Create a Sales Team - self.sales_channel = self.env['crm.team'].with_context(tracking_disable=True).create({ - 'name': 'Test Channel', + cls.company_data['default_user_salesman_2'] = cls.env['res.users'].with_context(no_reset_password=True).create({ + 'name': 'default_user_salesman_2', + 'login': 'default_user_salesman_2.comp%s' % cls.company_data['company'].id, + 'email': 'default_user_salesman_2@example.com', + 'signature': '--\nMark', + 'notification_type': 'email', + 'groups_id': [(6, 0, cls.env.ref('sales_team.group_sale_salesman').ids)], + 'company_ids': [(6, 0, cls.company_data['company'].ids)], + 'company_id': cls.company_data['company'].id, }) # Create the SO with a specific salesperson - self.order = self.env['sale.order'].with_context(tracking_disable=True).create({ - 'partner_id': self.partner_customer_usd.id, - 'user_id': self.user_salesperson.id + cls.order = cls.env['sale.order'].with_context(tracking_disable=True).create({ + 'partner_id': cls.partner_a.id, + 'user_id': cls.company_data['default_user_salesman'].id }) def test_access_sales_manager(self): """ Test sales manager's access rights """ SaleOrder = self.env['sale.order'].with_context(tracking_disable=True) # Manager can see the SO which is assigned to another salesperson - self.order.with_user(self.user_manager).read() + self.order.read() # Manager can change a salesperson of the SO - self.order.with_user(self.user_manager).write({'user_id': self.user_salesperson_1.id}) + self.order.write({'user_id': self.company_data['default_user_salesman'].id}) # Manager can create the SO for other salesperson - sale_order = SaleOrder.with_user(self.user_manager).create({ - 'partner_id': self.partner_customer_usd.id, - 'user_id': self.user_salesperson_1.id + sale_order = SaleOrder.create({ + 'partner_id': self.partner_a.id, + 'user_id': self.company_data['default_user_salesman'].id }) self.assertIn(sale_order.id, SaleOrder.search([]).ids, 'Sales manager should be able to create the SO of other salesperson') # Manager can confirm the SO - sale_order.with_user(self.user_manager).action_confirm() + sale_order.action_confirm() # Manager can not delete confirmed SO with self.assertRaises(UserError): - sale_order.with_user(self.user_manager).unlink() + sale_order.unlink() # Manager can delete the SO of other salesperson if SO is in 'draft' or 'cancel' state - self.order.with_user(self.user_manager).unlink() + self.order.unlink() self.assertNotIn(self.order.id, SaleOrder.search([]).ids, 'Sales manager should be able to delete the SO') # Manager can create a Sales Team - india_channel = self.env['crm.team'].with_context(tracking_disable=True).with_user(self.user_manager).create({ + india_channel = self.env['crm.team'].with_context(tracking_disable=True).create({ 'name': 'India', }) self.assertIn(india_channel.id, self.env['crm.team'].search([]).ids, 'Sales manager should be able to create a Sales Team') # Manager can edit a Sales Team - india_channel.with_user(self.user_manager).write({'name': 'new_india'}) + india_channel.write({'name': 'new_india'}) self.assertEqual(india_channel.name, 'new_india', 'Sales manager should be able to edit a Sales Team') # Manager can delete a Sales Team - india_channel.with_user(self.user_manager).unlink() + india_channel.unlink() self.assertNotIn(india_channel.id, self.env['crm.team'].search([]).ids, 'Sales manager should be able to delete a Sales Team') def test_access_sales_person(self): """ Test Salesperson's access rights """ # Salesperson can see only their own sales order with self.assertRaises(AccessError): - self.order.with_user(self.user_salesperson_1).read() + self.order.with_user(self.company_data['default_user_salesman_2']).read() # Now assign the SO to themselves - self.order.write({'user_id': self.user_salesperson_1.id}) - self.order.with_user(self.user_salesperson_1).read() + self.order.write({'user_id': self.company_data['default_user_salesman_2'].id}) + self.order.with_user(self.company_data['default_user_salesman_2']).read() # Salesperson can change a Sales Team of SO - self.order.with_user(self.user_salesperson_1).write({'team_id': self.sales_channel.id}) + self.order.with_user(self.company_data['default_user_salesman_2']).write({'team_id': self.company_data['default_sale_team'].id}) # Salesperson can't create the SO of other salesperson with self.assertRaises(AccessError): - self.env['sale.order'].with_user(self.user_salesperson_1).create({ - 'partner_id': self.partner_customer_usd.id, - 'user_id': self.user_salesperson.id + self.env['sale.order'].with_user(self.company_data['default_user_salesman_2']).create({ + 'partner_id': self.partner_a.id, + 'user_id': self.company_data['default_user_salesman'].id }) # Salesperson can't delete the SO with self.assertRaises(AccessError): - self.order.with_user(self.user_salesperson_1).unlink() + self.order.with_user(self.company_data['default_user_salesman_2']).unlink() # Salesperson can confirm the SO - self.order.with_user(self.user_salesperson_1).action_confirm() + self.order.with_user(self.company_data['default_user_salesman_2']).action_confirm() def test_access_portal_user(self): """ Test portal user's access rights """ # Portal user can see the confirmed SO for which they are assigned as a customer with self.assertRaises(AccessError): - self.order.with_user(self.user_portal).read() + self.order.with_user(self.company_data['default_user_portal']).read() - self.order.write({'partner_id': self.user_portal.partner_id.id}) + self.order.partner_id = self.company_data['default_user_portal'].partner_id self.order.action_confirm() # Portal user can't edit the SO with self.assertRaises(AccessError): - self.order.with_user(self.user_portal).write({'team_id': self.sales_channel.id}) + self.order.with_user(self.company_data['default_user_portal']).write({'team_id': self.company_data['default_sale_team'].id}) # Portal user can't create the SO with self.assertRaises(AccessError): - self.env['sale.order'].with_user(self.user_portal).create({ - 'partner_id': self.partner_customer_usd.id, + self.env['sale.order'].with_user(self.company_data['default_user_portal']).create({ + 'partner_id': self.partner_a.id, }) # Portal user can't delete the SO which is in 'draft' or 'cancel' state self.order.action_cancel() with self.assertRaises(AccessError): - self.order.with_user(self.user_portal).unlink() + self.order.with_user(self.company_data['default_user_portal']).unlink() def test_access_employee(self): """ Test classic employee's access rights """ # Employee can't see any SO with self.assertRaises(AccessError): - self.order.with_user(self.user_employee).read() + self.order.with_user(self.company_data['default_user_employee']).read() # Employee can't edit the SO with self.assertRaises(AccessError): - self.order.with_user(self.user_employee).write({'team_id': self.sales_channel.id}) + self.order.with_user(self.company_data['default_user_employee']).write({'team_id': self.company_data['default_sale_team'].id}) # Employee can't create the SO with self.assertRaises(AccessError): - self.env['sale.order'].with_user(self.user_employee).create({ - 'partner_id': self.partner_customer_usd.id, + self.env['sale.order'].with_user(self.company_data['default_user_employee']).create({ + 'partner_id': self.partner_a.id, }) # Employee can't delete the SO with self.assertRaises(AccessError): - self.order.with_user(self.user_employee).unlink() + self.order.with_user(self.company_data['default_user_employee']).unlink() diff --git a/addons/sale/tests/test_reinvoice.py b/addons/sale/tests/test_reinvoice.py index 7c681a1f787..d714411c6ce 100644 --- a/addons/sale/tests/test_reinvoice.py +++ b/addons/sale/tests/test_reinvoice.py @@ -1,32 +1,29 @@ # -*- 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.tests import Form, tagged -from odoo.addons.sale.tests.test_sale_common import TestCommonSaleNoChart -from odoo.tests import Form - -class TestReInvoice(TestCommonSaleNoChart): +@tagged('post_install', '-at_install') +class TestReInvoice(TestSaleCommon): @classmethod - def setUpClass(cls): - super(TestReInvoice, cls).setUpClass() - - cls.setUpExpenseProducts() - cls.setUpAdditionalAccounts() - cls.setUpAccountJournal() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) cls.analytic_account = cls.env['account.analytic.account'].create({ 'name': 'Test AA', 'code': 'TESTSALE_REINVOICE', - 'company_id': cls.partner_customer_usd.company_id.id, - 'partner_id': cls.partner_customer_usd.id + 'company_id': cls.partner_a.company_id.id, + 'partner_id': cls.partner_a.id }) cls.sale_order = cls.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, 'analytic_account_id': cls.analytic_account.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) cls.AccountMove = cls.env['account.move'].with_context(default_move_type='in_invoice', mail_notrack=True, mail_create_nolog=True) @@ -35,22 +32,22 @@ class TestReInvoice(TestCommonSaleNoChart): """ Test vendor bill at cost for product based on ordered and delivered quantities. """ # create SO line and confirm SO (with only one line) sale_order_line1 = self.env['sale.order.line'].create({ - 'name': self.product_ordered_cost.name, - 'product_id': self.product_ordered_cost.id, + 'name': self.company_data['product_order_cost'].name, + 'product_id': self.company_data['product_order_cost'].id, 'product_uom_qty': 2, 'qty_delivered': 1, - 'product_uom': self.product_ordered_cost.uom_id.id, - 'price_unit': self.product_ordered_cost.list_price, + 'product_uom': self.company_data['product_order_cost'].uom_id.id, + 'price_unit': self.company_data['product_order_cost'].list_price, 'order_id': self.sale_order.id, }) sale_order_line1.product_id_change() sale_order_line2 = self.env['sale.order.line'].create({ - 'name': self.product_deliver_cost.name, - 'product_id': self.product_deliver_cost.id, + 'name': self.company_data['product_delivery_cost'].name, + 'product_id': self.company_data['product_delivery_cost'].id, 'product_uom_qty': 4, 'qty_delivered': 1, - 'product_uom': self.product_deliver_cost.uom_id.id, - 'price_unit': self.product_deliver_cost.list_price, + 'product_uom': self.company_data['product_delivery_cost'].uom_id.id, + 'price_unit': self.company_data['product_delivery_cost'].list_price, 'order_id': self.sale_order.id, }) sale_order_line2.product_id_change() @@ -61,51 +58,48 @@ class TestReInvoice(TestCommonSaleNoChart): # create invoice lines and validate it move_form = Form(self.AccountMove) - move_form.partner_id = self.partner_customer_usd + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_ordered_cost + line_form.product_id = self.company_data['product_order_cost'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_deliver_cost + line_form.product_id = self.company_data['product_delivery_cost'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account invoice_a = move_form.save() invoice_a.post() - sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.product_ordered_cost) - sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.product_deliver_cost) + sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.company_data['product_order_cost']) + sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.company_data['product_delivery_cost']) self.assertTrue(sale_order_line3, "A new sale line should have been created with ordered product") self.assertTrue(sale_order_line4, "A new sale line should have been created with delivered product") self.assertEqual(len(self.sale_order.order_line), 4, "There should be 4 lines on the SO (2 vendor bill lines created)") self.assertEqual(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 2, "There should be 4 lines on the SO (2 vendor bill lines created)") - self.assertEqual(sale_order_line1.qty_delivered, 1, "Exising SO line 1 should not be impacted by reinvoicing product at cost") - self.assertEqual(sale_order_line2.qty_delivered, 1, "Exising SO line 2 should not be impacted by reinvoicing product at cost") - - self.assertEqual((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.product_ordered_cost.standard_price, 3, 0, 0), 'Sale line is wrong after confirming vendor invoice') - self.assertEqual((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.product_deliver_cost.standard_price, 3, 0, 0), 'Sale line is wrong after confirming vendor invoice') + self.assertEqual((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.company_data['product_order_cost'].standard_price, 3, 0, 0), 'Sale line is wrong after confirming vendor invoice') + self.assertEqual((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.company_data['product_delivery_cost'].standard_price, 3, 0, 0), 'Sale line is wrong after confirming vendor invoice') self.assertEqual(sale_order_line3.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line should be computed by analytic amount") self.assertEqual(sale_order_line4.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line should be computed by analytic amount") # create second invoice lines and validate it move_form = Form(self.AccountMove) - move_form.partner_id = self.partner_customer_usd + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_ordered_cost + line_form.product_id = self.company_data['product_order_cost'] line_form.quantity = 2.0 line_form.analytic_account_id = self.analytic_account with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_deliver_cost + line_form.product_id = self.company_data['product_delivery_cost'] line_form.quantity = 2.0 line_form.analytic_account_id = self.analytic_account invoice_b = move_form.save() invoice_b.post() - sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.product_ordered_cost) - sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.product_deliver_cost) + sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.company_data['product_order_cost']) + sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.company_data['product_delivery_cost']) self.assertTrue(sale_order_line5, "A new sale line should have been created with ordered product") self.assertTrue(sale_order_line6, "A new sale line should have been created with delivered product") @@ -113,8 +107,8 @@ class TestReInvoice(TestCommonSaleNoChart): self.assertEqual(len(self.sale_order.order_line), 6, "There should be still 4 lines on the SO, no new created") self.assertEqual(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 4, "There should be still 2 expenses lines on the SO") - self.assertEqual((sale_order_line5.price_unit, sale_order_line5.qty_delivered, sale_order_line5.product_uom_qty, sale_order_line5.qty_invoiced), (self.product_ordered_cost.standard_price, 2, 0, 0), 'Sale line 5 is wrong after confirming 2e vendor invoice') - self.assertEqual((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line6.product_uom_qty, sale_order_line6.qty_invoiced), (self.product_deliver_cost.standard_price, 2, 0, 0), 'Sale line 6 is wrong after confirming 2e vendor invoice') + self.assertEqual((sale_order_line5.price_unit, sale_order_line5.qty_delivered, sale_order_line5.product_uom_qty, sale_order_line5.qty_invoiced), (self.company_data['product_order_cost'].standard_price, 2, 0, 0), 'Sale line 5 is wrong after confirming 2e vendor invoice') + self.assertEqual((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line6.product_uom_qty, sale_order_line6.qty_invoiced), (self.company_data['product_delivery_cost'].standard_price, 2, 0, 0), 'Sale line 6 is wrong after confirming 2e vendor invoice') def test_sales_price(self): """ Test invoicing vendor bill at sales price for products based on delivered and ordered quantities. Check no existing SO line is incremented, but when invoicing a @@ -122,22 +116,22 @@ class TestReInvoice(TestCommonSaleNoChart): """ # create SO line and confirm SO (with only one line) sale_order_line1 = self.env['sale.order.line'].create({ - 'name': self.product_deliver_sales_price.name, - 'product_id': self.product_deliver_sales_price.id, + 'name': self.company_data['product_delivery_sales_price'].name, + 'product_id': self.company_data['product_delivery_sales_price'].id, 'product_uom_qty': 2, 'qty_delivered': 1, - 'product_uom': self.product_deliver_sales_price.uom_id.id, - 'price_unit': self.product_deliver_sales_price.list_price, + 'product_uom': self.company_data['product_delivery_sales_price'].uom_id.id, + 'price_unit': self.company_data['product_delivery_sales_price'].list_price, 'order_id': self.sale_order.id, }) sale_order_line1.product_id_change() sale_order_line2 = self.env['sale.order.line'].create({ - 'name': self.product_order_sales_price.name, - 'product_id': self.product_order_sales_price.id, + 'name': self.company_data['product_order_sales_price'].name, + 'product_id': self.company_data['product_order_sales_price'].id, 'product_uom_qty': 3, 'qty_delivered': 1, - 'product_uom': self.product_order_sales_price.uom_id.id, - 'price_unit': self.product_order_sales_price.list_price, + 'product_uom': self.company_data['product_order_sales_price'].uom_id.id, + 'price_unit': self.company_data['product_order_sales_price'].list_price, 'order_id': self.sale_order.id, }) sale_order_line2.product_id_change() @@ -146,51 +140,48 @@ class TestReInvoice(TestCommonSaleNoChart): # create invoice lines and validate it move_form = Form(self.AccountMove) - move_form.partner_id = self.partner_customer_usd + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_deliver_sales_price + line_form.product_id = self.company_data['product_delivery_sales_price'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_order_sales_price + line_form.product_id = self.company_data['product_order_sales_price'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account invoice_a = move_form.save() invoice_a.post() - sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.product_deliver_sales_price) - sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.product_order_sales_price) + sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.company_data['product_delivery_sales_price']) + sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.company_data['product_order_sales_price']) self.assertTrue(sale_order_line3, "A new sale line should have been created with ordered product") self.assertTrue(sale_order_line4, "A new sale line should have been created with delivered product") self.assertEqual(len(self.sale_order.order_line), 4, "There should be 4 lines on the SO (2 vendor bill lines created)") self.assertEqual(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 2, "There should be 4 lines on the SO (2 vendor bill lines created)") - self.assertEqual(sale_order_line1.qty_delivered, 1, "Exising SO line 1 should not be impacted by reinvoicing product at cost") - self.assertEqual(sale_order_line2.qty_delivered, 1, "Exising SO line 2 should not be impacted by reinvoicing product at cost") - - self.assertEqual((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.product_deliver_sales_price.list_price, 3, 0, 0), 'Sale line is wrong after confirming vendor invoice') - self.assertEqual((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.product_order_sales_price.list_price, 3, 0, 0), 'Sale line is wrong after confirming vendor invoice') + self.assertEqual((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.company_data['product_delivery_sales_price'].list_price, 3, 0, 0), 'Sale line is wrong after confirming vendor invoice') + self.assertEqual((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.company_data['product_order_sales_price'].list_price, 3, 0, 0), 'Sale line is wrong after confirming vendor invoice') self.assertEqual(sale_order_line3.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line 3 should be computed by analytic amount") self.assertEqual(sale_order_line4.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line 4 should be computed by analytic amount") # create second invoice lines and validate it move_form = Form(self.AccountMove) - move_form.partner_id = self.partner_customer_usd + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_deliver_sales_price + line_form.product_id = self.company_data['product_delivery_sales_price'] line_form.quantity = 2.0 line_form.analytic_account_id = self.analytic_account with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_order_sales_price + line_form.product_id = self.company_data['product_order_sales_price'] line_form.quantity = 2.0 line_form.analytic_account_id = self.analytic_account invoice_b = move_form.save() invoice_b.post() - sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.product_deliver_sales_price) - sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.product_order_sales_price) + sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.company_data['product_delivery_sales_price']) + sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.company_data['product_order_sales_price']) self.assertFalse(sale_order_line5, "No new sale line should have been created with delivered product !!") self.assertTrue(sale_order_line6, "A new sale line should have been created with ordered product") @@ -198,18 +189,18 @@ class TestReInvoice(TestCommonSaleNoChart): self.assertEqual(len(self.sale_order.order_line), 5, "There should be 5 lines on the SO, 1 new created and 1 incremented") self.assertEqual(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 3, "There should be 3 expenses lines on the SO") - self.assertEqual((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line6.qty_invoiced), (self.product_order_sales_price.list_price, 2, 0, 0), 'Sale line is wrong after confirming 2e vendor invoice') + self.assertEqual((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line6.qty_invoiced), (self.company_data['product_order_sales_price'].list_price, 2, 0, 0), 'Sale line is wrong after confirming 2e vendor invoice') def test_no_expense(self): """ Test invoicing vendor bill with no policy. Check nothing happen. """ # confirm SO sale_order_line = self.env['sale.order.line'].create({ - 'name': self.product_no_expense.name, - 'product_id': self.product_no_expense.id, + 'name': self.company_data['product_delivery_no'].name, + 'product_id': self.company_data['product_delivery_no'].id, 'product_uom_qty': 2, 'qty_delivered': 1, - 'product_uom': self.product_no_expense.uom_id.id, - 'price_unit': self.product_no_expense.list_price, + 'product_uom': self.company_data['product_delivery_no'].uom_id.id, + 'price_unit': self.company_data['product_delivery_no'].list_price, 'order_id': self.sale_order.id, }) self.sale_order._compute_tax_id() @@ -217,15 +208,13 @@ class TestReInvoice(TestCommonSaleNoChart): # create invoice lines and validate it move_form = Form(self.AccountMove) - move_form.partner_id = self.partner_customer_usd - move_form.journal_id = self.journal_purchase + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_no_expense + line_form.product_id = self.company_data['product_delivery_no'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account invoice_a = move_form.save() invoice_a.post() self.assertEqual(len(self.sale_order.order_line), 1, "No SO line should have been created (or removed) when validating vendor bill") - self.assertEqual(sale_order_line.qty_delivered, 1, "The delivered quantity of SO line should not have been incremented") self.assertTrue(invoice_a.mapped('line_ids.analytic_line_ids'), "Analytic lines should be generated") diff --git a/addons/sale/tests/test_sale_common.py b/addons/sale/tests/test_sale_common.py deleted file mode 100644 index ef5199a5c95..00000000000 --- a/addons/sale/tests/test_sale_common.py +++ /dev/null @@ -1,416 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from collections import OrderedDict -from odoo.addons.account.tests.common import AccountTestCommon -from odoo.addons.account.tests.common import AccountTestNoChartCommon, AccountTestNoChartCommonMultiCompany - -class TestSaleCommon(AccountTestCommon): - - @classmethod - def setUpClass(cls): - super(TestSaleCommon, cls).setUpClass() - # some users - group_manager = cls.env.ref('sales_team.group_sale_manager') - group_user = cls.env.ref('sales_team.group_sale_salesman') - cls.manager = cls.env['res.users'].create({ - 'name': 'Andrew Manager', - 'login': 'manager', - 'email': 'a.m@example.com', - 'signature': '--\nAndreww', - 'notification_type': 'email', - 'groups_id': [(6, 0, [group_manager.id, cls.env.ref('base.group_user').id])] - }) - cls.user = cls.env['res.users'].create({ - 'name': 'Mark User', - 'login': 'user', - 'email': 'm.u@example.com', - 'signature': '--\nMark', - 'notification_type': 'email', - 'groups_id': [(6, 0, [group_user.id])] - }) - # create quotation with differend kinds of products (all possible combinations) - service_delivery = cls.env['product.product'].create({ - 'name': 'Cost-plus Contract', - # 'categ_id': cls.env.ref('product.product_category_5').id, - 'categ_id': cls.env.ref('product.product_category_all').id, - 'standard_price': 200.0, - 'list_price': 180.0, - 'type': 'service', - 'uom_id': cls.env.ref('uom.product_uom_unit').id, - 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, - 'default_code': 'SERV_DEL', - 'invoice_policy': 'delivery', - }) - service_order_01 = cls.env['product.product'].create({ - 'name': 'Remodeling Service', - 'categ_id': cls.env.ref('product.product_category_all').id, - 'standard_price': 40.0, - 'list_price': 90.0, - 'type': 'service', - 'uom_id': cls.env.ref('uom.product_uom_hour').id, - 'uom_po_id': cls.env.ref('uom.product_uom_hour').id, - 'description': 'Example of product to invoice on order', - 'default_code': 'PRE-PAID', - 'invoice_policy': 'order', - }) - product_order_01 = cls.env['product.product'].create({ - 'name': 'Office Design Software', - 'categ_id': cls.env.ref('product.product_category_all').id, - 'standard_price': 235.0, - 'list_price': 280.0, - 'type': 'consu', # Will be changed in 'product' in sale_stock - 'weight': 0.01, - 'uom_id': cls.env.ref('uom.product_uom_unit').id, - 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, - 'default_code': 'FURN_9999', - 'invoice_policy': 'order', - }) - product_delivery_01 = cls.env['product.product'].create({ - 'name': 'Office Chair', - 'categ_id': cls.env.ref('product.product_category_all').id, - 'standard_price': 55.0, - 'list_price': 70.0, - 'type': 'consu', # Will be changed in 'product' in sale_stock - 'weight': 0.01, - 'uom_id': cls.env.ref('uom.product_uom_unit').id, - 'uom_po_id': cls.env.ref('uom.product_uom_unit').id, - 'default_code': 'FURN_7777', - 'invoice_policy': 'delivery', - }) - cls.products = OrderedDict([ - ('prod_order', product_order_01), - ('serv_del', service_delivery), - ('serv_order', service_order_01), - ('prod_del', product_delivery_01), - ]) - - cls.partner = cls.env['res.partner'].create({'name': 'A test Partner'}) - - -class TestCommonSaleNoChart(AccountTestNoChartCommon): - """ This class should be extended for test suite of sale flows with a minimal chart of accounting - installed. This test suite should be executed at module installation. - This class provides some method to generate testing data well configured, according to the minimal - chart of account, defined in `AccountTestNoChartCommon` class. - """ - - @classmethod - def setUpClass(cls): - super(TestCommonSaleNoChart, cls).setUpClass() - - # create a pricelist - cls.pricelist_usd = cls.env['product.pricelist'].create({ - 'name': 'USD pricelist', - 'active': True, - 'currency_id': cls.env.ref('base.USD').id, - 'company_id': cls.env.user.company_id.id, - }) - - @classmethod - def setUpClassicProducts(cls): - # Create an expense journal - user_type_income = cls.env.ref('account.data_account_type_direct_costs') - cls.account_income_product = cls.env['account.account'].create({ - 'code': 'INCOME_PROD111', - 'name': 'Icome - Test Account', - 'user_type_id': user_type_income.id, - }) - # Create category - cls.product_category = cls.env['product.category'].create({ - 'name': 'Product Category with Income account', - 'property_account_income_categ_id': cls.account_income_product.id - }) - # Products - uom_unit = cls.env.ref('uom.product_uom_unit') - uom_hour = cls.env.ref('uom.product_uom_hour') - cls.product_order = cls.env['product.product'].create({ - 'name': "Zed+ Antivirus", - 'standard_price': 235.0, - 'list_price': 280.0, - 'type': 'consu', - 'uom_id': uom_unit.id, - 'uom_po_id': uom_unit.id, - 'invoice_policy': 'order', - 'expense_policy': 'no', - 'default_code': 'PROD_ORDER', - 'service_type': 'manual', - 'taxes_id': False, - 'categ_id': cls.product_category.id, - }) - cls.service_deliver = cls.env['product.product'].create({ - 'name': "Cost-plus Contract", - 'standard_price': 200.0, - 'list_price': 180.0, - 'type': 'service', - 'uom_id': uom_unit.id, - 'uom_po_id': uom_unit.id, - 'invoice_policy': 'delivery', - 'expense_policy': 'no', - 'default_code': 'SERV_DEL', - 'service_type': 'manual', - 'taxes_id': False, - 'categ_id': cls.product_category.id, - }) - cls.service_order = cls.env['product.product'].create({ - 'name': "Prepaid Consulting", - 'standard_price': 40.0, - 'list_price': 90.0, - 'type': 'service', - 'uom_id': uom_hour.id, - 'uom_po_id': uom_hour.id, - 'invoice_policy': 'order', - 'expense_policy': 'no', - 'default_code': 'PRE-PAID', - 'service_type': 'manual', - 'taxes_id': False, - 'categ_id': cls.product_category.id, - }) - cls.product_deliver = cls.env['product.product'].create({ - 'name': "Switch, 24 ports", - 'standard_price': 55.0, - 'list_price': 70.0, - 'type': 'consu', - 'uom_id': uom_unit.id, - 'uom_po_id': uom_unit.id, - 'invoice_policy': 'delivery', - 'expense_policy': 'no', - 'default_code': 'PROD_DEL', - 'service_type': 'manual', - 'taxes_id': False, - 'categ_id': cls.product_category.id, - }) - - cls.product_map = OrderedDict([ - ('prod_order', cls.product_order), - ('serv_del', cls.service_deliver), - ('serv_order', cls.service_order), - ('prod_del', cls.product_deliver), - ]) - - @classmethod - def setUpExpenseProducts(cls): - # Create an expense journal - user_type_expense = cls.env.ref('account.data_account_type_expenses') - cls.account_expense_for_products = cls.env['account.account'].create({ - 'code': 'EXP_PROD13', - 'name': 'Expense - Test Purchase Account', - 'user_type_id': user_type_expense.id - }) - # Expense Products - cls.product_ordered_cost = cls.env['product.product'].create({ - 'name': "Ordered at cost", - 'standard_price': 8, - 'list_price': 10, - 'type': 'consu', - 'invoice_policy': 'order', - 'expense_policy': 'cost', - 'default_code': 'CONSU-ORDERED1', - 'service_type': 'manual', - 'taxes_id': False, - 'property_account_expense_id': cls.account_expense_for_products.id, - }) - - cls.product_deliver_cost = cls.env['product.product'].create({ - 'name': "Delivered at cost", - 'standard_price': 8, - 'list_price': 10, - 'type': 'consu', - 'invoice_policy': 'delivery', - 'expense_policy': 'cost', - 'default_code': 'CONSU-DELI1', - 'service_type': 'manual', - 'taxes_id': False, - 'property_account_expense_id': cls.account_expense_for_products.id, - }) - - cls.product_order_sales_price = cls.env['product.product'].create({ - 'name': "Ordered at sales price", - 'standard_price': 8, - 'list_price': 10, - 'type': 'consu', - 'invoice_policy': 'order', - 'expense_policy': 'sales_price', - 'default_code': 'CONSU-ORDERED2', - 'service_type': 'manual', - 'taxes_id': False, - 'property_account_expense_id': cls.account_expense_for_products.id, - }) - - cls.product_deliver_sales_price = cls.env['product.product'].create({ - 'name': "Delivered at sales price", - 'standard_price': 8, - 'list_price': 10, - 'type': 'consu', - 'invoice_policy': 'delivery', - 'expense_policy': 'sales_price', - 'default_code': 'CONSU-DELI2', - 'service_type': 'manual', - 'taxes_id': False, - 'property_account_expense_id': cls.account_expense_for_products.id, - }) - - cls.product_no_expense = cls.env['product.product'].create({ - 'name': "No expense", - 'standard_price': 8, - 'list_price': 10, - 'type': 'consu', - 'invoice_policy': 'delivery', - 'expense_policy': 'no', - 'default_code': 'CONSU-NO', - 'service_type': 'manual', - 'taxes_id': False, - 'property_account_expense_id': cls.account_expense_for_products.id, - }) - - -class TestCommonSaleMultiCompanyNoChart(AccountTestNoChartCommonMultiCompany, TestCommonSaleNoChart): - """ This class should be extended for test suite of sale flows with a minimal chart of accounting - installed. This test suite should be executed at module installation. - This class provides some method to generate testing data well configured, according to the minimal - chart of account, defined in `TestAccountNoChartCommon` class. - """ - - @classmethod - def setUpClass(cls): - super(TestCommonSaleMultiCompanyNoChart, cls).setUpClass() - cls.setUpAdditionalAccounts() - - @classmethod - def setUpClassicProducts(cls): - super(TestCommonSaleMultiCompanyNoChart, cls).setUpClassicProducts() - # Create an expense journal - user_type_income = cls.env.ref('account.data_account_type_direct_costs') - cls.account_income_product_company_B = cls.env['account.account'].create({ - 'code': 'INCOME_PROD111', - 'name': 'Income - Test Account Company B', - 'user_type_id': user_type_income.id, - 'company_id': cls.company_B.id, - }) - # Create category - cls.product_category_company_B = cls.env['product.category'].create({ - 'name': 'Product Category with Income account Company B', - 'property_account_income_categ_id': cls.account_income_product_company_B.id - }) - # Products - uom_unit = cls.env.ref('uom.product_uom_unit') - uom_hour = cls.env.ref('uom.product_uom_hour') - - cls.product_order_company_B = cls.env['product.product'].create({ - 'name': "Pigeon pie", - 'standard_price': 235.0, - 'list_price': 280.0, - 'type': 'consu', - 'uom_id': uom_unit.id, - 'uom_po_id': uom_unit.id, - 'invoice_policy': 'order', - 'expense_policy': 'no', - 'default_code': 'PROD_ORDER', - 'service_type': 'manual', - 'taxes_id': False, - 'categ_id': cls.product_category_company_B.id, - }) - - cls.service_deliver_company_B = cls.env['product.product'].create({ - 'name': "Golden Company Contract", - 'standard_price': 200.0, - 'list_price': 180.0, - 'type': 'service', - 'uom_id': uom_unit.id, - 'uom_po_id': uom_unit.id, - 'invoice_policy': 'delivery', - 'expense_policy': 'no', - 'default_code': 'SERV_DEL', - 'service_type': 'manual', - 'taxes_id': False, - 'categ_id': cls.product_category_company_B.id, - }) - - cls.service_order_company_B = cls.env['product.product'].create({ - 'name': "Maester Consulting", - 'standard_price': 40.0, - 'list_price': 90.0, - 'type': 'service', - 'uom_id': uom_hour.id, - 'uom_po_id': uom_hour.id, - 'invoice_policy': 'order', - 'expense_policy': 'no', - 'default_code': 'PRE-PAID', - 'service_type': 'manual', - 'taxes_id': False, - 'categ_id': cls.product_category_company_B.id, - }) - - cls.product_deliver_company_B = cls.env['product.product'].create({ - 'name': "Swords", - 'standard_price': 55.0, - 'list_price': 70.0, - 'type': 'consu', - 'uom_id': uom_unit.id, - 'uom_po_id': uom_unit.id, - 'invoice_policy': 'delivery', - 'expense_policy': 'no', - 'default_code': 'PROD_DEL', - 'service_type': 'manual', - 'taxes_id': False, - 'categ_id': cls.product_category_company_B.id, - }) - - @classmethod - def setUpExpenseProducts(cls): - super(TestCommonSaleMultiCompanyNoChart, cls).setUpExpenseProducts() - cls.product_ordered_cost_company_B = cls.env['product.product'].create({ - 'name': "Ordered at cost", - 'standard_price': 8, - 'list_price': 10, - 'type': 'consu', - 'invoice_policy': 'order', - 'expense_policy': 'cost', - 'default_code': 'CONSU-ORDERED1', - 'service_type': 'manual', - 'taxes_id': False, - 'property_account_expense_id': cls.account_expense_company_B.id, - 'company_id': cls.company_B.id, - }) - - cls.product_deliver_cost_company_B = cls.env['product.product'].create({ - 'name': "Delivered at cost", - 'standard_price': 8, - 'list_price': 10, - 'type': 'consu', - 'invoice_policy': 'delivery', - 'expense_policy': 'cost', - 'default_code': 'CONSU-DELI1', - 'service_type': 'manual', - 'taxes_id': False, - 'property_account_expense_id': cls.account_expense_company_B.id, - 'company_id': cls.company_B.id, - }) - - cls.product_order_sales_price_company_B = cls.env['product.product'].create({ - 'name': "Ordered at sales price", - 'standard_price': 8, - 'list_price': 10, - 'type': 'consu', - 'invoice_policy': 'order', - 'expense_policy': 'sales_price', - 'default_code': 'CONSU-ORDERED2', - 'service_type': 'manual', - 'taxes_id': False, - 'property_account_expense_id': cls.account_expense_company_B.id, - 'company_id': cls.company_B.id, - }) - - cls.product_deliver_sales_price_company_B = cls.env['product.product'].create({ - 'name': "Delivered at sales price", - 'standard_price': 8, - 'list_price': 10, - 'type': 'consu', - 'invoice_policy': 'delivery', - 'expense_policy': 'sales_price', - 'default_code': 'CONSU-DELI2', - 'service_type': 'manual', - 'taxes_id': False, - 'property_account_expense_id': cls.account_expense_company_B.id, - 'company_id': cls.company_B.id, - }) diff --git a/addons/sale/tests/test_sale_flow.py b/addons/sale/tests/test_sale_flow.py new file mode 100644 index 00000000000..c18d645f9b1 --- /dev/null +++ b/addons/sale/tests/test_sale_flow.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +from odoo.addons.sale.tests.common import TestSaleCommonBase + + +class TestSaleFlow(TestSaleCommonBase): + ''' Test running at-install to test flows independently to other modules, e.g. 'sale_stock'. ''' + + @classmethod + def setUpClass(cls): + super().setUpClass() + + user = cls.env['res.users'].create({ + 'name': 'Because I am saleman!', + 'login': 'saleman', + 'groups_id': [(6, 0, cls.env.user.groups_id.ids), (4, cls.env.ref('account.group_account_user').id)], + }) + user.partner_id.email = 'saleman@test.com' + + # Shadow the current environment/cursor with the newly created user. + cls.env = cls.env(user=user) + cls.cr = cls.env.cr + + cls.company = cls.env['res.company'].create({ + 'name': 'Test Company', + 'currency_id': cls.env.ref('base.USD').id, + }) + cls.company_data = cls.setup_sale_configuration_for_company(cls.company) + + cls.partner_a = cls.env['res.partner'].create({ + 'name': 'partner_a', + 'company_id': False, + }) + + cls.analytic_account = cls.env['account.analytic.account'].create({ + 'name': 'Test analytic_account', + 'code': 'analytic_account', + 'company_id': cls.company.id, + 'partner_id': cls.partner_a.id + }) + + user.company_ids |= cls.company + user.company_id = cls.company + + def test_qty_delivered(self): + ''' Test 'qty_delivered' at-install to avoid a change in the behavior when 'sale_stock' is installed. ''' + + sale_order = self.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({ + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'analytic_account_id': self.analytic_account.id, + 'pricelist_id': self.company_data['default_pricelist'].id, + 'order_line': [ + (0, 0, { + 'name': self.company_data['product_order_cost'].name, + 'product_id': self.company_data['product_order_cost'].id, + 'product_uom_qty': 2, + 'qty_delivered': 1, + 'product_uom': self.company_data['product_order_cost'].uom_id.id, + 'price_unit': self.company_data['product_order_cost'].list_price, + }), + (0, 0, { + 'name': self.company_data['product_delivery_cost'].name, + 'product_id': self.company_data['product_delivery_cost'].id, + 'product_uom_qty': 4, + 'qty_delivered': 1, + 'product_uom': self.company_data['product_delivery_cost'].uom_id.id, + 'price_unit': self.company_data['product_delivery_cost'].list_price, + }), + ], + }) + for line in sale_order.order_line: + line.product_id_change() + + sale_order.onchange_partner_id() + sale_order._compute_tax_id() + sale_order.action_confirm() + + self.assertRecordValues(sale_order.order_line, [ + {'qty_delivered': 1.0}, + {'qty_delivered': 1.0}, + ]) diff --git a/addons/sale/tests/test_sale_order.py b/addons/sale/tests/test_sale_order.py index 5311ac632f6..6634e2b33ae 100644 --- a/addons/sale/tests/test_sale_order.py +++ b/addons/sale/tests/test_sale_order.py @@ -1,75 +1,61 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. - -import odoo from odoo.exceptions import UserError, AccessError -from odoo.tests import Form +from odoo.tests import Form, tagged from odoo.tools import float_compare -from .test_sale_common import TestCommonSaleNoChart +from .common import TestSaleCommon -class TestSaleOrder(TestCommonSaleNoChart): +@tagged('post_install', '-at_install') +class TestSaleOrder(TestSaleCommon): @classmethod - def setUpClass(cls): - super(TestSaleOrder, cls).setUpClass() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) SaleOrder = cls.env['sale.order'].with_context(tracking_disable=True) - # set up users - cls.setUpUsers() - group_salemanager = cls.env.ref('sales_team.group_sale_manager') - group_salesman = cls.env.ref('sales_team.group_sale_salesman') - group_employee = cls.env.ref('base.group_user') - cls.user_manager.write({'groups_id': [(6, 0, [group_salemanager.id, group_employee.id])]}) - cls.user_employee.write({'groups_id': [(6, 0, [group_salesman.id, group_employee.id])]}) - - # set up accounts and products and journals - cls.setUpAdditionalAccounts() - cls.setUpClassicProducts() - cls.setUpAccountJournal() - # create a generic Sale Order with all classical products and empty pricelist cls.sale_order = SaleOrder.create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, - 'pricelist_id': cls.pricelist_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) cls.sol_product_order = cls.env['sale.order.line'].create({ - 'name': cls.product_order.name, - 'product_id': cls.product_order.id, + 'name': cls.company_data['product_order_no'].name, + 'product_id': cls.company_data['product_order_no'].id, 'product_uom_qty': 2, - 'product_uom': cls.product_order.uom_id.id, - 'price_unit': cls.product_order.list_price, + 'product_uom': cls.company_data['product_order_no'].uom_id.id, + 'price_unit': cls.company_data['product_order_no'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_serv_deliver = cls.env['sale.order.line'].create({ - 'name': cls.service_deliver.name, - 'product_id': cls.service_deliver.id, + 'name': cls.company_data['product_service_delivery'].name, + 'product_id': cls.company_data['product_service_delivery'].id, 'product_uom_qty': 2, - 'product_uom': cls.service_deliver.uom_id.id, - 'price_unit': cls.service_deliver.list_price, + 'product_uom': cls.company_data['product_service_delivery'].uom_id.id, + 'price_unit': cls.company_data['product_service_delivery'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_serv_order = cls.env['sale.order.line'].create({ - 'name': cls.service_order.name, - 'product_id': cls.service_order.id, + 'name': cls.company_data['product_service_order'].name, + 'product_id': cls.company_data['product_service_order'].id, 'product_uom_qty': 2, - 'product_uom': cls.service_order.uom_id.id, - 'price_unit': cls.service_order.list_price, + 'product_uom': cls.company_data['product_service_order'].uom_id.id, + 'price_unit': cls.company_data['product_service_order'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_product_deliver = cls.env['sale.order.line'].create({ - 'name': cls.product_deliver.name, - 'product_id': cls.product_deliver.id, + 'name': cls.company_data['product_delivery_no'].name, + 'product_id': cls.company_data['product_delivery_no'].id, 'product_uom_qty': 2, - 'product_uom': cls.product_deliver.uom_id.id, - 'price_unit': cls.product_deliver.list_price, + 'product_uom': cls.company_data['product_delivery_no'].uom_id.id, + 'price_unit': cls.company_data['product_delivery_no'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) @@ -81,7 +67,7 @@ class TestSaleOrder(TestCommonSaleNoChart): # DBO TODO: validate invoice and register payments self.sale_order.order_line.read(['name', 'price_unit', 'product_uom_qty', 'price_total']) - self.assertEqual(self.sale_order.amount_total, sum([2 * p.list_price for p in self.product_map.values()]), 'Sale: total amount is wrong') + self.assertEqual(self.sale_order.amount_total, 1240.0, 'Sale: total amount is wrong') self.sale_order.order_line._compute_product_updatable() self.assertTrue(self.sale_order.order_line[0].product_updatable) # send quotation @@ -100,7 +86,7 @@ class TestSaleOrder(TestCommonSaleNoChart): # create invoice: only 'invoice on order' products are invoiced invoice = self.sale_order._create_invoices() self.assertEqual(len(invoice.invoice_line_ids), 2, 'Sale: invoice is missing lines') - self.assertEqual(invoice.amount_total, sum([2 * p.list_price if p.invoice_policy == 'order' else 0 for p in self.product_map.values()]), 'Sale: invoice total amount is wrong') + self.assertEqual(invoice.amount_total, 740.0, 'Sale: invoice total amount is wrong') self.assertTrue(self.sale_order.invoice_status == 'no', 'Sale: SO status after invoicing should be "nothing to invoice"') self.assertTrue(len(self.sale_order.invoice_ids) == 1, 'Sale: invoice is missing') self.sale_order.order_line._compute_product_updatable() @@ -112,7 +98,7 @@ class TestSaleOrder(TestCommonSaleNoChart): self.assertTrue(self.sale_order.invoice_status == 'to invoice', 'Sale: SO status after delivery should be "to invoice"') invoice2 = self.sale_order._create_invoices() self.assertEqual(len(invoice2.invoice_line_ids), 2, 'Sale: second invoice is missing lines') - self.assertEqual(invoice2.amount_total, sum([2 * p.list_price if p.invoice_policy == 'delivery' else 0 for p in self.product_map.values()]), 'Sale: second invoice total amount is wrong') + self.assertEqual(invoice2.amount_total, 500.0, 'Sale: second invoice total amount is wrong') self.assertTrue(self.sale_order.invoice_status == 'invoiced', 'Sale: SO status after invoicing everything should be "invoiced"') self.assertTrue(len(self.sale_order.invoice_ids) == 2, 'Sale: invoice is missing') @@ -137,7 +123,7 @@ class TestSaleOrder(TestCommonSaleNoChart): invoice3 = self.sale_order._create_invoices() self.assertEqual(len(invoice3.invoice_line_ids), 1, 'Sale: third invoice is missing lines') - self.assertEqual(invoice3.amount_total, 8 * self.product_map['serv_order'].list_price, 'Sale: second invoice total amount is wrong') + self.assertEqual(invoice3.amount_total, 720.0, 'Sale: second invoice total amount is wrong') self.assertTrue(self.sale_order.invoice_status == 'invoiced', 'Sale: SO status after invoicing everything (including the upsel) should be "invoiced"') def test_sale_sequence(self): @@ -159,8 +145,8 @@ class TestSaleOrder(TestCommonSaleNoChart): # SO in state 'draft' can be deleted so_copy = self.sale_order.copy() with self.assertRaises(AccessError): - so_copy.with_user(self.user_employee).unlink() - self.assertTrue(so_copy.with_user(self.user_manager).unlink(), 'Sale: deleting a quotation should be possible') + so_copy.with_user(self.company_data['default_user_employee']).unlink() + self.assertTrue(so_copy.unlink(), 'Sale: deleting a quotation should be possible') # SO in state 'cancel' can be deleted so_copy = self.sale_order.copy() @@ -169,25 +155,22 @@ class TestSaleOrder(TestCommonSaleNoChart): so_copy.action_cancel() self.assertTrue(so_copy.state == 'cancel', 'Sale: SO should be in state "cancel"') with self.assertRaises(AccessError): - so_copy.with_user(self.user_employee).unlink() - self.assertTrue(so_copy.with_user(self.user_manager).unlink(), 'Sale: deleting a cancelled SO should be possible') + so_copy.with_user(self.company_data['default_user_employee']).unlink() + self.assertTrue(so_copy.unlink(), 'Sale: deleting a cancelled SO should be possible') # SO in state 'sale' or 'done' cannot be deleted self.sale_order.action_confirm() self.assertTrue(self.sale_order.state == 'sale', 'Sale: SO should be in state "sale"') with self.assertRaises(UserError): - self.sale_order.with_user(self.user_manager).unlink() + self.sale_order.unlink() self.sale_order.action_done() self.assertTrue(self.sale_order.state == 'done', 'Sale: SO should be in state "done"') with self.assertRaises(UserError): - self.sale_order.with_user(self.user_manager).unlink() + self.sale_order.unlink() def test_cost_invoicing(self): """ Test confirming a vendor invoice to reinvoice cost on the so """ - # force the pricelist to have the same currency as the company - self.pricelist_usd.currency_id = self.env.ref('base.main_company').currency_id - serv_cost = self.env['product.product'].create({ 'name': "Ordered at cost", 'standard_price': 160, @@ -198,19 +181,19 @@ class TestSaleOrder(TestCommonSaleNoChart): 'default_code': 'PROD_COST', 'service_type': 'manual', }) - prod_gap = self.service_order + prod_gap = self.company_data['product_service_order'] so = self.env['sale.order'].create({ - 'partner_id': self.partner_customer_usd.id, - 'partner_invoice_id': self.partner_customer_usd.id, - 'partner_shipping_id': self.partner_customer_usd.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, 'order_line': [(0, 0, {'name': prod_gap.name, 'product_id': prod_gap.id, 'product_uom_qty': 2, 'product_uom': prod_gap.uom_id.id, 'price_unit': prod_gap.list_price})], - 'pricelist_id': self.pricelist_usd.id, + 'pricelist_id': self.company_data['default_pricelist'].id, }) so.action_confirm() so._create_analytic_account() inv = self.env['account.move'].with_context(default_move_type='in_invoice').create({ - 'partner_id': self.partner_customer_usd.id, + 'partner_id': self.partner_a.id, 'invoice_line_ids': [ (0, 0, { 'name': serv_cost.name, @@ -268,66 +251,32 @@ class TestSaleOrder(TestCommonSaleNoChart): """Check that only taxes of the right company are applied on the lines.""" # Preparing test Data - company_1 = self.env.ref('base.main_company') - company_2 = self.env['res.company'].create({ - 'name': 'company 2', - 'parent_id': company_1.id, - }) - - user_demo = self.env['res.users'].create({ - 'login': 'zizizmyuser', - 'password': 'zizizmyuser', - 'email': 'test@test.com', - 'partner_id': self.env['res.partner'].create({'name': 'Zizizmypartner'}).id, - 'company_ids': [(6, False, [company_1.id])], - 'company_id': company_1.id, - 'groups_id': [(6, 0, [ - self.env.ref('base.group_user').id, - self.env.ref('base.group_partner_manager').id, - self.env.ref('sales_team.group_sale_manager').id])]}) - - user_demo.company_ids = (company_1 | company_2).ids - so_partner = self.env['res.partner'].create({'name': 'SO Partner'}) - so_partner.write({ - 'property_account_position_id': False, - }) - - tax_company_1 = self.env['account.tax'].create({ - 'name': 'T1', - 'amount': 90, - 'company_id': company_1.id, - }) - - tax_company_2 = self.env['account.tax'].create({ - 'name': 'T2', - 'amount': 90, - 'company_id': company_2.id, - }) - product_shared = self.env['product.template'].create({ 'name': 'shared product', 'invoice_policy': 'order', - 'taxes_id': [(6, False, [tax_company_1.id, tax_company_2.id])], - 'property_account_income_id': self.account_receivable.id, + 'taxes_id': [(6, False, (self.company_data['default_tax_sale'] + self.company_data_2['default_tax_sale']).ids)], + 'property_account_income_id': self.company_data['default_account_revenue'].id, }) - so_1 = self.env['sale.order'].with_user(user_demo.id).create({ + so_1 = self.env['sale.order'].with_user(self.company_data['default_user_salesman']).create({ 'partner_id': self.env['res.partner'].create({'name': 'A partner'}).id, - 'company_id': company_1.id, + 'company_id': self.company_data['company'].id, }) so_1.write({ 'order_line': [(0, False, {'product_id': product_shared.product_variant_id.id, 'order_id': so_1.id})], }) - self.assertEqual(set(so_1.order_line.tax_id.ids), set([tax_company_1.id]), + self.assertEqual(so_1.order_line.tax_id, self.company_data['default_tax_sale'], 'Only taxes from the right company are put by default') so_1.action_confirm() # i'm not interested in groups/acls, but in the multi-company flow only # the sudo is there for that and does not impact the invoice that gets created # the goal here is to invoice in company 1 (because the order is in company 1) while being # 'mainly' in company 2 (through the context), the invoice should be in company 1 - inv=so_1.sudo().with_context(allowed_company_ids=[company_2.id, company_1.id])._create_invoices() - self.assertEqual(inv.company_id, company_1, 'invoices should be created in the company of the SO, not the main company of the context') + inv=so_1.sudo()\ + .with_context(allowed_company_ids=(self.company_data['company'] + self.company_data_2['company']).ids)\ + ._create_invoices() + self.assertEqual(inv.company_id, self.company_data['company'], 'invoices should be created in the company of the SO, not the main company of the context') def test_group_invoice(self): """ Test that invoicing multiple sales order for the same customer works. """ diff --git a/addons/sale/tests/test_sale_pricelist.py b/addons/sale/tests/test_sale_pricelist.py index 6f655db4eb0..7c0fd5c5970 100644 --- a/addons/sale/tests/test_sale_pricelist.py +++ b/addons/sale/tests/test_sale_pricelist.py @@ -1,61 +1,59 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from .test_sale_common import TestCommonSaleNoChart +from .common import TestSaleCommon +from odoo.tests import tagged -class TestSaleOrder(TestCommonSaleNoChart): +@tagged('post_install', '-at_install') +class TestSaleOrder(TestSaleCommon): @classmethod - def setUpClass(cls): - super(TestSaleOrder, cls).setUpClass() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) Pricelist = cls.env['product.pricelist'] PricelistItem = cls.env['product.pricelist.item'] SaleOrder = cls.env['sale.order'].with_context(tracking_disable=True) SaleOrderLine = cls.env['sale.order.line'].with_context(tracking_disable=True) - # set up accounts and products and journals - cls.setUpAdditionalAccounts() - cls.setUpClassicProducts() - cls.setUpAccountJournal() - # Create a product category cls.product_category_1 = cls.env['product.category'].create({ 'name': 'Product Category for pricelist', }) - # Create a pricelist with discount policy: percentage on services, fixed price for product_order cls.pricelist_discount_incl = Pricelist.create({ 'name': 'Pricelist A', 'discount_policy': 'with_discount', + 'company_id': cls.company_data['company'].id, }) PricelistItem.create({ 'pricelist_id': cls.pricelist_discount_incl.id, 'applied_on': '1_product', - 'product_tmpl_id': cls.service_order.product_tmpl_id.id, + 'product_tmpl_id': cls.company_data['product_service_order'].product_tmpl_id.id, 'compute_price': 'percentage', 'percent_price': 10 }) PricelistItem.create({ 'pricelist_id': cls.pricelist_discount_incl.id, 'applied_on': '1_product', - 'product_tmpl_id': cls.service_deliver.product_tmpl_id.id, + 'product_tmpl_id': cls.company_data['product_service_delivery'].product_tmpl_id.id, 'compute_price': 'percentage', - 'percent_price': 20 + 'percent_price': 20, }) cls.pricelist_discount_incl_item3 = PricelistItem.create({ 'pricelist_id': cls.pricelist_discount_incl.id, 'applied_on': '1_product', - 'product_tmpl_id': cls.product_order.product_tmpl_id.id, + 'product_tmpl_id': cls.company_data['product_order_no'].product_tmpl_id.id, 'compute_price': 'fixed', - 'fixed_price': 211 + 'fixed_price': 211, }) # Create a pricelist without discount policy: formula for product_category_1 category, percentage for service_order cls.pricelist_discount_excl = Pricelist.create({ 'name': 'Pricelist B', 'discount_policy': 'without_discount', + 'company_id': cls.company_data['company'].id, }) PricelistItem.create({ 'pricelist_id': cls.pricelist_discount_excl.id, @@ -63,70 +61,60 @@ class TestSaleOrder(TestCommonSaleNoChart): 'categ_id': cls.product_category_1.id, 'compute_price': 'formula', 'base': 'standard_price', - 'price_discount': 10 + 'price_discount': 10, }) PricelistItem.create({ 'pricelist_id': cls.pricelist_discount_excl.id, 'applied_on': '1_product', - 'product_tmpl_id': cls.service_order.product_tmpl_id.id, + 'product_tmpl_id': cls.company_data['product_service_order'].product_tmpl_id.id, 'compute_price': 'percentage', - 'percent_price': 20 + 'percent_price': 20, }) # create a generic Sale Order with all classical products and empty pricelist cls.sale_order = SaleOrder.create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, - 'pricelist_id': cls.pricelist_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) cls.sol_product_order = SaleOrderLine.create({ - 'name': cls.product_order.name, - 'product_id': cls.product_order.id, + 'name': cls.company_data['product_order_no'].name, + 'product_id': cls.company_data['product_order_no'].id, 'product_uom_qty': 2, - 'product_uom': cls.product_order.uom_id.id, - 'price_unit': cls.product_order.list_price, + 'product_uom': cls.company_data['product_order_no'].uom_id.id, + 'price_unit': cls.company_data['product_order_no'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_serv_deliver = SaleOrderLine.create({ - 'name': cls.service_deliver.name, - 'product_id': cls.service_deliver.id, + 'name': cls.company_data['product_service_delivery'].name, + 'product_id': cls.company_data['product_service_delivery'].id, 'product_uom_qty': 2, - 'product_uom': cls.service_deliver.uom_id.id, - 'price_unit': cls.service_deliver.list_price, + 'product_uom': cls.company_data['product_service_delivery'].uom_id.id, + 'price_unit': cls.company_data['product_service_delivery'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_serv_order = SaleOrderLine.create({ - 'name': cls.service_order.name, - 'product_id': cls.service_order.id, + 'name': cls.company_data['product_service_order'].name, + 'product_id': cls.company_data['product_service_order'].id, 'product_uom_qty': 2, - 'product_uom': cls.service_order.uom_id.id, - 'price_unit': cls.service_order.list_price, + 'product_uom': cls.company_data['product_service_order'].uom_id.id, + 'price_unit': cls.company_data['product_service_order'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_prod_deliver = SaleOrderLine.create({ - 'name': cls.product_deliver.name, - 'product_id': cls.product_deliver.id, + 'name': cls.company_data['product_delivery_no'].name, + 'product_id': cls.company_data['product_delivery_no'].id, 'product_uom_qty': 2, - 'product_uom': cls.product_deliver.uom_id.id, - 'price_unit': cls.product_deliver.list_price, + 'product_uom': cls.company_data['product_delivery_no'].uom_id.id, + 'price_unit': cls.company_data['product_delivery_no'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) - def test_sale_with_pricelist_empty(self): - # Trigger onchange to reset discount, unit price, subtotal, ... - self.sale_order.onchange_partner_id() - for line in self.sale_order.order_line: - line.product_id_change() - line._onchange_discount() - # Check that pricelist of the SO has been applied on the sale order lines or not - for line in self.sale_order.order_line: - self.assertEqual(line.price_unit, line.product_id.list_price, 'Pricelist of the SO should not be applied on an order line %s' % (line.name,)) - def test_sale_with_pricelist_discount_included(self): """ Test SO with the pricelist and check unit price appeared on its lines """ # Change the pricelist @@ -137,7 +125,7 @@ class TestSaleOrder(TestCommonSaleNoChart): line._onchange_discount() # Check that pricelist of the SO has been applied on the sale order lines or not for line in self.sale_order.order_line: - if line.product_id == self.product_order: + if line.product_id == self.company_data['product_order_no']: self.assertEqual(line.price_unit, self.pricelist_discount_incl_item3.fixed_price, 'Price of product_order should be %s applied on the order line' % (self.pricelist_discount_incl_item3.fixed_price,)) else: # only services (service_order and service_deliver) for item in self.sale_order.pricelist_id.item_ids.filtered(lambda l: l.product_tmpl_id == line.product_id.product_tmpl_id): @@ -150,8 +138,8 @@ class TestSaleOrder(TestCommonSaleNoChart): self.env.user.write({'groups_id': [(4, self.env.ref('product.group_discount_per_so_line').id)]}) # Set product category on consumable products (for the pricelist item applying on this category) - self.product_order.write({'categ_id': self.product_category_1.id}) - self.product_deliver.write({'categ_id': self.product_category_1.id}) + self.company_data['product_order_no'].write({'categ_id': self.product_category_1.id}) + self.company_data['product_delivery_no'].write({'categ_id': self.product_category_1.id}) # Change the pricelist self.sale_order.write({'pricelist_id': self.pricelist_discount_excl.id}) @@ -167,7 +155,7 @@ class TestSaleOrder(TestCommonSaleNoChart): self.assertEqual(line.discount, item.price_discount, "Discount should be displayed on order line %s since its category get some discount" % (line.name,)) self.assertEqual(line.price_unit, line.product_id.standard_price, "Price unit should be the cost price for product %s" % (line.name,)) else: - if line.product_id == self.service_order: # reduction for this product + if line.product_id == self.company_data['product_service_order']: # reduction for this product self.assertEqual(line.discount, 20.0, "Discount for product %s should be 20 percent with pricelist %s" % (line.name, self.pricelist_discount_excl.name)) self.assertEqual(line.price_unit, line.product_id.list_price, 'Unit price of order line should be a sale price as the pricelist not applied on the other category\'s product') else: # no discount for the rest diff --git a/addons/sale/tests/test_sale_refund.py b/addons/sale/tests/test_sale_refund.py index 7c6ae3c5520..d384bc8066d 100644 --- a/addons/sale/tests/test_sale_refund.py +++ b/addons/sale/tests/test_sale_refund.py @@ -1,61 +1,58 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from .test_sale_common import TestCommonSaleNoChart -from odoo.tests import Form +from .common import TestSaleCommon +from odoo.tests import Form, tagged -class TestSaleToInvoice(TestCommonSaleNoChart): +@tagged('post_install', '-at_install') +class TestSaleToInvoice(TestSaleCommon): @classmethod - def setUpClass(cls): - super(TestSaleToInvoice, cls).setUpClass() - - cls.setUpClassicProducts() - cls.setUpAdditionalAccounts() - cls.setUpAccountJournal() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) # Create the SO with four order lines cls.sale_order = cls.env['sale.order'].with_context(tracking_disable=True).create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, - 'pricelist_id': cls.pricelist_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) SaleOrderLine = cls.env['sale.order.line'].with_context(tracking_disable=True) cls.sol_prod_order = SaleOrderLine.create({ - 'name': cls.product_order.name, - 'product_id': cls.product_order.id, + 'name': cls.company_data['product_order_no'].name, + 'product_id': cls.company_data['product_order_no'].id, 'product_uom_qty': 5, - 'product_uom': cls.product_order.uom_id.id, - 'price_unit': cls.product_order.list_price, + 'product_uom': cls.company_data['product_order_no'].uom_id.id, + 'price_unit': cls.company_data['product_order_no'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_serv_deliver = SaleOrderLine.create({ - 'name': cls.service_deliver.name, - 'product_id': cls.service_deliver.id, + 'name': cls.company_data['product_service_delivery'].name, + 'product_id': cls.company_data['product_service_delivery'].id, 'product_uom_qty': 4, - 'product_uom': cls.service_deliver.uom_id.id, - 'price_unit': cls.service_deliver.list_price, + 'product_uom': cls.company_data['product_service_delivery'].uom_id.id, + 'price_unit': cls.company_data['product_service_delivery'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_serv_order = SaleOrderLine.create({ - 'name': cls.service_order.name, - 'product_id': cls.service_order.id, + 'name': cls.company_data['product_service_order'].name, + 'product_id': cls.company_data['product_service_order'].id, 'product_uom_qty': 3, - 'product_uom': cls.service_order.uom_id.id, - 'price_unit': cls.service_order.list_price, + 'product_uom': cls.company_data['product_service_order'].uom_id.id, + 'price_unit': cls.company_data['product_service_order'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_prod_deliver = SaleOrderLine.create({ - 'name': cls.product_deliver.name, - 'product_id': cls.product_deliver.id, + 'name': cls.company_data['product_delivery_no'].name, + 'product_id': cls.company_data['product_delivery_no'].id, 'product_uom_qty': 2, - 'product_uom': cls.product_deliver.uom_id.id, - 'price_unit': cls.product_deliver.list_price, + 'product_uom': cls.company_data['product_delivery_no'].uom_id.id, + 'price_unit': cls.company_data['product_delivery_no'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) @@ -68,7 +65,7 @@ class TestSaleToInvoice(TestCommonSaleNoChart): 'active_model': 'sale.order', 'active_ids': [cls.sale_order.id], 'active_id': cls.sale_order.id, - 'default_journal_id': cls.journal_sale.id, + 'default_journal_id': cls.company_data['default_journal_sale'].id, }).create({ 'advance_payment_method': 'delivered' }) diff --git a/addons/sale/tests/test_sale_to_invoice.py b/addons/sale/tests/test_sale_to_invoice.py index 9b5bfcc170e..a1fefc3cce0 100644 --- a/addons/sale/tests/test_sale_to_invoice.py +++ b/addons/sale/tests/test_sale_to_invoice.py @@ -1,63 +1,59 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import _ from odoo.tools import float_is_zero -from .test_sale_common import TestCommonSaleNoChart -from odoo.tests import Form +from .common import TestSaleCommon +from odoo.tests import Form, tagged -class TestSaleToInvoice(TestCommonSaleNoChart): +@tagged('-at_install', 'post_install') +class TestSaleToInvoice(TestSaleCommon): @classmethod - def setUpClass(cls): - super(TestSaleToInvoice, cls).setUpClass() - - cls.setUpClassicProducts() - cls.setUpAdditionalAccounts() - cls.setUpAccountJournal() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) # Create the SO with four order lines cls.sale_order = cls.env['sale.order'].with_context(tracking_disable=True).create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, - 'pricelist_id': cls.pricelist_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) SaleOrderLine = cls.env['sale.order.line'].with_context(tracking_disable=True) cls.sol_prod_order = SaleOrderLine.create({ - 'name': cls.product_order.name, - 'product_id': cls.product_order.id, + 'name': cls.company_data['product_order_no'].name, + 'product_id': cls.company_data['product_order_no'].id, 'product_uom_qty': 5, - 'product_uom': cls.product_order.uom_id.id, - 'price_unit': cls.product_order.list_price, + 'product_uom': cls.company_data['product_order_no'].uom_id.id, + 'price_unit': cls.company_data['product_order_no'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_serv_deliver = SaleOrderLine.create({ - 'name': cls.service_deliver.name, - 'product_id': cls.service_deliver.id, + 'name': cls.company_data['product_service_delivery'].name, + 'product_id': cls.company_data['product_service_delivery'].id, 'product_uom_qty': 4, - 'product_uom': cls.service_deliver.uom_id.id, - 'price_unit': cls.service_deliver.list_price, + 'product_uom': cls.company_data['product_service_delivery'].uom_id.id, + 'price_unit': cls.company_data['product_service_delivery'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_serv_order = SaleOrderLine.create({ - 'name': cls.service_order.name, - 'product_id': cls.service_order.id, + 'name': cls.company_data['product_service_order'].name, + 'product_id': cls.company_data['product_service_order'].id, 'product_uom_qty': 3, - 'product_uom': cls.service_order.uom_id.id, - 'price_unit': cls.service_order.list_price, + 'product_uom': cls.company_data['product_service_order'].uom_id.id, + 'price_unit': cls.company_data['product_service_order'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) cls.sol_prod_deliver = SaleOrderLine.create({ - 'name': cls.product_deliver.name, - 'product_id': cls.product_deliver.id, + 'name': cls.company_data['product_delivery_no'].name, + 'product_id': cls.company_data['product_delivery_no'].id, 'product_uom_qty': 2, - 'product_uom': cls.product_deliver.uom_id.id, - 'price_unit': cls.product_deliver.list_price, + 'product_uom': cls.company_data['product_delivery_no'].uom_id.id, + 'price_unit': cls.company_data['product_delivery_no'].list_price, 'order_id': cls.sale_order.id, 'tax_id': False, }) @@ -67,7 +63,7 @@ class TestSaleToInvoice(TestCommonSaleNoChart): 'active_model': 'sale.order', 'active_ids': [cls.sale_order.id], 'active_id': cls.sale_order.id, - 'default_journal_id': cls.journal_sale.id, + 'default_journal_id': cls.company_data['default_journal_sale'].id, } def test_downpayment(self): @@ -80,7 +76,7 @@ class TestSaleToInvoice(TestCommonSaleNoChart): payment = self.env['sale.advance.payment.inv'].with_context(self.context).create({ 'advance_payment_method': 'fixed', 'fixed_amount': 100, - 'deposit_account_id': self.account_income.id + 'deposit_account_id': self.company_data['default_account_revenue'].id }) payment.create_invoices() @@ -94,7 +90,7 @@ class TestSaleToInvoice(TestCommonSaleNoChart): # Let's do an invoice with refunds payment = self.env['sale.advance.payment.inv'].with_context(self.context).create({ - 'deposit_account_id': self.account_income.id + 'deposit_account_id': self.company_data['default_account_revenue'].id }) payment.create_invoices() @@ -128,7 +124,8 @@ class TestSaleToInvoice(TestCommonSaleNoChart): self.assertEqual(self.sol_serv_order.untaxed_amount_to_invoice, 297, "The untaxed amount to invoice is wrong") self.assertEqual(self.sol_serv_deliver.untaxed_amount_to_invoice, self.sol_serv_deliver.qty_delivered * self.sol_serv_deliver.price_reduce, "The untaxed amount to invoice should be qty deli * price reduce, so 4 * (180 - 36)") - self.assertEqual(self.sol_prod_deliver.untaxed_amount_to_invoice, 140, "The untaxed amount to invoice should be qty deli * price reduce, so 4 * (180 - 36)") + # 'untaxed_amount_to_invoice' is invalid when 'sale_stock' is installed. + # self.assertEqual(self.sol_prod_deliver.untaxed_amount_to_invoice, 140, "The untaxed amount to invoice should be qty deli * price reduce, so 4 * (180 - 36)") # Let's do an invoice with invoiceable lines payment = self.env['sale.advance.payment.inv'].with_context(self.context).create({ @@ -221,10 +218,10 @@ class TestSaleToInvoice(TestCommonSaleNoChart): """ Test create and invoice with sections from the SO, and check qty invoice/to invoice, and the related amounts """ sale_order = self.env['sale.order'].with_context(tracking_disable=True).create({ - 'partner_id': self.partner_customer_usd.id, - 'partner_invoice_id': self.partner_customer_usd.id, - 'partner_shipping_id': self.partner_customer_usd.id, - 'pricelist_id': self.pricelist_usd.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, }) SaleOrderLine = self.env['sale.order.line'].with_context(tracking_disable=True) @@ -234,11 +231,11 @@ class TestSaleToInvoice(TestCommonSaleNoChart): 'order_id': sale_order.id, }) sol_prod_deliver = SaleOrderLine.create({ - 'name': self.product_order.name, - 'product_id': self.product_order.id, + 'name': self.company_data['product_order_no'].name, + 'product_id': self.company_data['product_order_no'].id, 'product_uom_qty': 5, - 'product_uom': self.product_order.uom_id.id, - 'price_unit': self.product_order.list_price, + 'product_uom': self.company_data['product_order_no'].uom_id.id, + 'price_unit': self.company_data['product_order_no'].list_price, 'order_id': sale_order.id, 'tax_id': False, }) @@ -253,7 +250,7 @@ class TestSaleToInvoice(TestCommonSaleNoChart): 'active_model': 'sale.order', 'active_ids': [sale_order.id], 'active_id': sale_order.id, - 'default_journal_id': self.journal_sale.id, + 'default_journal_id': self.company_data['default_journal_sale'].id, } # Let's do an invoice with invoiceable lines @@ -269,19 +266,19 @@ class TestSaleToInvoice(TestCommonSaleNoChart): def test_qty_invoiced(self): """Verify uom rounding is correctly considered during qty_invoiced compute""" sale_order = self.env['sale.order'].with_context(tracking_disable=True).create({ - 'partner_id': self.partner_customer_usd.id, - 'partner_invoice_id': self.partner_customer_usd.id, - 'partner_shipping_id': self.partner_customer_usd.id, - 'pricelist_id': self.pricelist_usd.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, }) SaleOrderLine = self.env['sale.order.line'].with_context(tracking_disable=True) sol_prod_deliver = SaleOrderLine.create({ - 'name': self.product_order.name, - 'product_id': self.product_order.id, + 'name': self.company_data['product_order_no'].name, + 'product_id': self.company_data['product_order_no'].id, 'product_uom_qty': 5, - 'product_uom': self.product_order.uom_id.id, - 'price_unit': self.product_order.list_price, + 'product_uom': self.company_data['product_order_no'].uom_id.id, + 'price_unit': self.company_data['product_order_no'].list_price, 'order_id': sale_order.id, 'tax_id': False, }) @@ -295,7 +292,7 @@ class TestSaleToInvoice(TestCommonSaleNoChart): 'active_model': 'sale.order', 'active_ids': [sale_order.id], 'active_id': sale_order.id, - 'default_journal_id': self.journal_sale.id, + 'default_journal_id': self.company_data['default_journal_sale'].id, } # Let's do an invoice with invoiceable lines diff --git a/addons/sale_expense/tests/test_reinvoice.py b/addons/sale_expense/tests/test_reinvoice.py index cb66751ec72..0efe34c6dfb 100644 --- a/addons/sale_expense/tests/test_reinvoice.py +++ b/addons/sale_expense/tests/test_reinvoice.py @@ -2,34 +2,26 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.addons.hr_expense.tests.common import TestExpenseCommon -from odoo.addons.sale.tests.test_sale_common import TestCommonSaleNoChart +from odoo.addons.sale.tests.common import TestSaleCommon from odoo.tests import tagged @tagged('-at_install', 'post_install') -class TestReInvoice(TestExpenseCommon, TestCommonSaleNoChart): +class TestReInvoice(TestExpenseCommon, TestSaleCommon): - @classmethod - def setUpClass(cls, chart_template_ref=None): - super().setUpClass(chart_template_ref=chart_template_ref) - super().setUpExpenseProducts() - - cls.price_list = cls.env['product.pricelist'].create({ - 'name': 'default_price_list_company_1', - 'sequence': 1, - 'company_id': cls.company_data['company'].id, - 'currency_id': cls.company_data['currency'].id, + def test_expenses_reinvoice(self): + (self.company_data['product_order_sales_price'] + self.company_data['product_delivery_sales_price']).write({ + 'can_be_expensed': True, }) - def test_expenses_reinvoice(self): # create SO line and confirm SO (with only one line) sale_order = self.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({ 'partner_id': self.partner_a.id, 'partner_invoice_id': self.partner_a.id, 'partner_shipping_id': self.partner_a.id, 'order_line': [(0, 0, { - 'name': self.product_ordered_cost.name, - 'product_id': self.product_ordered_cost.id, + 'name': self.company_data['product_order_sales_price'].name, + 'product_id': self.company_data['product_order_sales_price'].id, 'product_uom_qty': 2.0, 'price_unit': 1000.0, })], @@ -45,8 +37,8 @@ class TestReInvoice(TestExpenseCommon, TestCommonSaleNoChart): (0, 0, { 'name': 'expense_1', 'date': '2016-01-01', - 'product_id': self.product_ordered_cost.id, - 'unit_amount': self.product_ordered_cost.list_price, + 'product_id': self.company_data['product_order_sales_price'].id, + 'unit_amount': self.company_data['product_order_sales_price'].list_price, 'analytic_account_id': self.analytic_account_1.id, 'employee_id': self.expense_employee.id, 'sale_order_id': sale_order.id, @@ -54,8 +46,8 @@ class TestReInvoice(TestExpenseCommon, TestCommonSaleNoChart): (0, 0, { 'name': 'expense_2', 'date': '2016-01-01', - 'product_id': self.product_deliver_cost.id, - 'unit_amount': self.product_deliver_cost.list_price, + 'product_id': self.company_data['product_delivery_sales_price'].id, + 'unit_amount': self.company_data['product_delivery_sales_price'].list_price, 'analytic_account_id': self.analytic_account_1.id, 'employee_id': self.expense_employee.id, 'sale_order_id': sale_order.id, @@ -63,8 +55,8 @@ class TestReInvoice(TestExpenseCommon, TestCommonSaleNoChart): (0, 0, { 'name': 'expense_3', 'date': '2016-01-01', - 'product_id': self.product_order_sales_price.id, - 'unit_amount': self.product_order_sales_price.list_price, + 'product_id': self.company_data['product_order_sales_price'].id, + 'unit_amount': self.company_data['product_order_sales_price'].list_price, 'analytic_account_id': self.analytic_account_1.id, 'employee_id': self.expense_employee.id, 'sale_order_id': sale_order.id, @@ -72,8 +64,8 @@ class TestReInvoice(TestExpenseCommon, TestCommonSaleNoChart): (0, 0, { 'name': 'expense_4', 'date': '2016-01-01', - 'product_id': self.product_deliver_sales_price.id, - 'unit_amount': self.product_deliver_sales_price.list_price, + 'product_id': self.company_data['product_delivery_sales_price'].id, + 'unit_amount': self.company_data['product_delivery_sales_price'].list_price, 'analytic_account_id': self.analytic_account_1.id, 'employee_id': self.expense_employee.id, 'sale_order_id': sale_order.id, @@ -81,8 +73,8 @@ class TestReInvoice(TestExpenseCommon, TestCommonSaleNoChart): (0, 0, { 'name': 'expense_5', 'date': '2016-01-01', - 'product_id': self.product_no_expense.id, - 'unit_amount': self.product_no_expense.list_price, + 'product_id': self.company_data['product_delivery_sales_price'].id, + 'unit_amount': self.company_data['product_delivery_sales_price'].list_price, 'analytic_account_id': self.analytic_account_1.id, 'employee_id': self.expense_employee.id, 'sale_order_id': sale_order.id, @@ -107,12 +99,7 @@ class TestReInvoice(TestExpenseCommon, TestCommonSaleNoChart): 'is_expense': True, }, { - 'qty_delivered': 1.0, - 'product_uom_qty': 0.0, - 'is_expense': True, - }, - { - 'qty_delivered': 1.0, + 'qty_delivered': 3.0, 'product_uom_qty': 0.0, 'is_expense': True, }, @@ -123,11 +110,8 @@ class TestReInvoice(TestExpenseCommon, TestCommonSaleNoChart): }, ]) - # 'qty_delivered_method' is not checked on the first line because it could be multiple things depending if - # 'sale_stock' is installed or not. self.assertRecordValues(sale_order.order_line[1:], [ {'qty_delivered_method': 'analytic'}, {'qty_delivered_method': 'analytic'}, {'qty_delivered_method': 'analytic'}, - {'qty_delivered_method': 'analytic'}, ]) diff --git a/addons/sale_expense/tests/test_sale_expense.py b/addons/sale_expense/tests/test_sale_expense.py index 445fd0bdbce..47a17cf6225 100644 --- a/addons/sale_expense/tests/test_sale_expense.py +++ b/addons/sale_expense/tests/test_sale_expense.py @@ -1,30 +1,29 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.sale.tests.test_sale_common import TestSaleCommon +from odoo.addons.hr_expense.tests.common import TestExpenseCommon +from odoo.addons.sale.tests.common import TestSaleCommon from odoo.tests import tagged @tagged('post_install', '-at_install') -class TestSaleExpense(TestSaleCommon): +class TestSaleExpense(TestExpenseCommon, TestSaleCommon): + def test_sale_expense(self): """ Test the behaviour of sales orders when managing expenses """ - # force the pricelist to have the same currency as the company - self.env.ref('product.list0').currency_id = self.env.ref('base.main_company').currency_id # create a so with a product invoiced on delivery - prod = self.env['product.product'].create({ - 'name': 'A product', - 'invoice_policy': 'delivery', - 'list_price': 30.75, - 'uom_id': self.env.ref('uom.product_uom_hour').id, - 'uom_po_id': self.env.ref('uom.product_uom_hour').id, - }) so = self.env['sale.order'].create({ - 'partner_id': self.partner.id, - 'partner_invoice_id': self.partner.id, - 'partner_shipping_id': self.partner.id, - 'order_line': [(0, 0, {'name': prod.name, 'product_id': prod.id, 'product_uom_qty': 2, 'product_uom': prod.uom_id.id, 'price_unit': prod.list_price})], + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'order_line': [(0, 0, { + 'name': self.company_data['product_delivery_no'].name, + 'product_id': self.company_data['product_delivery_no'].id, + 'product_uom_qty': 2, + 'product_uom': self.company_data['product_delivery_no'].uom_id.id, + 'price_unit': self.company_data['product_delivery_no'].list_price, + })], 'pricelist_id': self.env.ref('product.list0').id, }) so._compute_tax_id() @@ -33,30 +32,18 @@ class TestSaleExpense(TestSaleCommon): init_price = so.amount_total # create some expense and validate it (expense at cost) - prod_exp_1 = self.env['product.product'].create({ - 'name': 'Air Ticket', - 'list_price': 700, - 'can_be_expensed': True, - 'expense_policy': 'cost', - 'type': 'service', - 'invoice_policy': 'delivery', - }) - company = self.env.ref('base.main_company') - journal = self.env['account.journal'].create({'name': 'Purchase Journal - Test', 'code': 'HRTPJ', 'type': 'purchase', 'company_id': company.id}) - employee = self.env['hr.employee'].create({'name': 'Test employee', 'user_id': self.user.id, 'address_home_id': self.user.partner_id.id}) - self.user.partner_id.property_account_payable_id = self.a_pay.id # Submit to Manager sheet = self.env['hr.expense.sheet'].create({ 'name': 'Expense for John Smith', - 'employee_id': employee.id, - 'journal_id': journal.id, + 'employee_id': self.expense_employee.id, + 'journal_id': self.company_data['default_journal_purchase'].id, }) exp = self.env['hr.expense'].create({ 'name': 'Air Travel', - 'product_id': prod_exp_1.id, + 'product_id': self.company_data['product_delivery_cost'].id, 'analytic_account_id': so.analytic_account_id.id, 'unit_amount': 621.54, - 'employee_id': employee.id, + 'employee_id': self.expense_employee.id, 'sheet_id': sheet.id, 'sale_order_id': so.id, }) @@ -65,8 +52,8 @@ class TestSaleExpense(TestSaleCommon): # Create Expense Entries sheet.action_sheet_move_create() # expense should now be in sales order - self.assertIn(prod_exp_1, so.mapped('order_line.product_id'), 'Sale Expense: expense product should be in so') - sol = so.order_line.filtered(lambda sol: sol.product_id.id == prod_exp_1.id) + self.assertIn(self.company_data['product_delivery_cost'], so.mapped('order_line.product_id'), 'Sale Expense: expense product should be in so') + sol = so.order_line.filtered(lambda sol: sol.product_id.id == self.company_data['product_delivery_cost'].id) self.assertEqual((sol.price_unit, sol.qty_delivered), (621.54, 1.0), 'Sale Expense: error when invoicing an expense at cost') self.assertEqual(so.amount_total, init_price, 'Sale Expense: price of so not updated after adding expense') @@ -85,8 +72,8 @@ class TestSaleExpense(TestSaleCommon): # Submit to Manager sheet = self.env['hr.expense.sheet'].create({ 'name': 'Expense for John Smith', - 'employee_id': employee.id, - 'journal_id': journal.id, + 'employee_id': self.expense_employee.id, + 'journal_id': self.company_data['default_journal_purchase'].id, }) exp = self.env['hr.expense'].create({ 'name': 'Car Travel', @@ -95,7 +82,7 @@ class TestSaleExpense(TestSaleCommon): 'product_uom_id': self.env.ref('uom.product_uom_km').id, 'unit_amount': 0.15, 'quantity': 100, - 'employee_id': employee.id, + 'employee_id': self.expense_employee.id, 'sheet_id': sheet.id, 'sale_order_id': so.id, }) diff --git a/addons/sale_management/tests/test_sale_order.py b/addons/sale_management/tests/test_sale_order.py index 551e916b3c0..3047086953c 100644 --- a/addons/sale_management/tests/test_sale_order.py +++ b/addons/sale_management/tests/test_sale_order.py @@ -1,14 +1,16 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.sale.tests.test_sale_common import TestCommonSaleNoChart +from odoo.addons.sale.tests.common import TestSaleCommon +from odoo.tests import tagged -class TestSaleOrder(TestCommonSaleNoChart): +@tagged('-at_install', 'post_install') +class TestSaleOrder(TestSaleCommon): @classmethod - def setUpClass(cls): - super(TestSaleOrder, cls).setUpClass() + 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'] @@ -103,11 +105,13 @@ class TestSaleOrder(TestCommonSaleNoChart): # create some sale orders cls.sale_order = SaleOrder.create({ - 'partner_id': cls.partner_customer_usd.id, + 'partner_id': cls.partner_a.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) cls.sale_order_no_price_list = SaleOrder.create({ - 'partner_id': cls.partner_customer_usd.id, + 'partner_id': cls.partner_a.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) def test_01_template_without_pricelist(self): diff --git a/addons/sale_purchase/tests/common.py b/addons/sale_purchase/tests/common.py index 5d96690b627..652841cc0f3 100644 --- a/addons/sale_purchase/tests/common.py +++ b/addons/sale_purchase/tests/common.py @@ -1,35 +1,22 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.sale.tests.test_sale_common import TestCommonSaleNoChart +from odoo.addons.sale.tests.common import TestSaleCommon -class TestCommonSalePurchaseNoChart(TestCommonSaleNoChart): +class TestCommonSalePurchaseNoChart(TestSaleCommon): @classmethod - def setUpUsers(cls): - super(TestCommonSalePurchaseNoChart, cls).setUpUsers() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) - group_salemanager = cls.env.ref('sales_team.group_sale_manager') - group_salesman = cls.env.ref('sales_team.group_sale_salesman') - cls.user_manager.write({'groups_id': [(6, 0, [group_salemanager.id])]}) - cls.user_employee.write({'groups_id': [(6, 0, [group_salesman.id])]}) - - @classmethod - def setUpServicePurchaseProducts(cls): uom_unit = cls.env.ref('uom.product_uom_unit') uom_dozen = cls.env.ref('uom.product_uom_dozen') - user_type_income = cls.env.ref('account.data_account_type_direct_costs') - cls.account_income_product_purchase = cls.env['account.account'].create({ - 'code': 'INCOME_PROD_PURCHASE', - 'name': 'Icome - Test Account', - 'user_type_id': user_type_income.id, - }) # Create category cls.product_category_purchase = cls.env['product.category'].create({ 'name': 'Product Category with Income account', - 'property_account_income_categ_id': cls.account_income_product_purchase.id + 'property_account_income_categ_id': cls.company_data['default_account_expense'].id }) cls.partner_vendor_service = cls.env['res.partner'].create({ diff --git a/addons/sale_purchase/tests/test_access_rights.py b/addons/sale_purchase/tests/test_access_rights.py index 3fcb7c95a28..5240bc0ed19 100644 --- a/addons/sale_purchase/tests/test_access_rights.py +++ b/addons/sale_purchase/tests/test_access_rights.py @@ -3,15 +3,15 @@ from odoo.exceptions import AccessError from odoo.addons.sale_purchase.tests.common import TestCommonSalePurchaseNoChart +from odoo.tests import tagged +@tagged('-at_install', 'post_install') class TestAccessRights(TestCommonSalePurchaseNoChart): @classmethod - def setUpClass(cls): - super(TestAccessRights, cls).setUpClass() - - cls.setUpServicePurchaseProducts() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) # Create a users group_sale_user = cls.env.ref('sales_team.group_sale_salesman') @@ -34,7 +34,7 @@ class TestAccessRights(TestCommonSalePurchaseNoChart): SaleOrder = self.env['sale.order'].with_context(tracking_disable=True) sale_order = SaleOrder.with_user(self.user_salesperson).create({ - 'partner_id': self.partner_customer_usd.id, + 'partner_id': self.partner_a.id, 'user_id': self.user_salesperson.id }) diff --git a/addons/sale_purchase/tests/test_sale_purchase.py b/addons/sale_purchase/tests/test_sale_purchase.py index 99a37a3ad95..4f85ea2542b 100644 --- a/addons/sale_purchase/tests/test_sale_purchase.py +++ b/addons/sale_purchase/tests/test_sale_purchase.py @@ -2,52 +2,40 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.exceptions import UserError, AccessError - +from odoo.tests import tagged from odoo.addons.sale_purchase.tests.common import TestCommonSalePurchaseNoChart +@tagged('-at_install', 'post_install') class TestSalePurchase(TestCommonSalePurchaseNoChart): @classmethod - def setUpClass(cls): - super(TestSalePurchase, cls).setUpClass() - - # set up users - cls.setUpUsers() - group_salemanager = cls.env.ref('sales_team.group_sale_manager') - group_salesman = cls.env.ref('sales_team.group_sale_salesman') - cls.user_manager.write({'groups_id': [(6, 0, [group_salemanager.id])]}) - cls.user_employee.write({'groups_id': [(6, 0, [group_salesman.id])]}) - - # set up accounts and products and journals - cls.setUpAdditionalAccounts() - cls.setUpAccountJournal() - cls.setUpClassicProducts() - cls.setUpServicePurchaseProducts() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) # create a generic Sale Order with 2 classical products and a purchase service SaleOrder = cls.env['sale.order'].with_context(tracking_disable=True) cls.sale_order_1 = SaleOrder.create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, - 'pricelist_id': cls.pricelist_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) cls.sol1_service_deliver = cls.env['sale.order.line'].create({ - 'name': cls.service_deliver.name, - 'product_id': cls.service_deliver.id, + 'name': cls.company_data['product_service_delivery'].name, + 'product_id': cls.company_data['product_service_delivery'].id, 'product_uom_qty': 1, - 'product_uom': cls.service_deliver.uom_id.id, - 'price_unit': cls.service_deliver.list_price, + 'product_uom': cls.company_data['product_service_delivery'].uom_id.id, + 'price_unit': cls.company_data['product_service_delivery'].list_price, 'order_id': cls.sale_order_1.id, 'tax_id': False, }) cls.sol1_product_order = cls.env['sale.order.line'].create({ - 'name': cls.product_order.name, - 'product_id': cls.product_order.id, + 'name': cls.company_data['product_order_no'].name, + 'product_id': cls.company_data['product_order_no'].id, 'product_uom_qty': 2, - 'product_uom': cls.product_order.uom_id.id, - 'price_unit': cls.product_order.list_price, + 'product_uom': cls.company_data['product_order_no'].uom_id.id, + 'price_unit': cls.company_data['product_order_no'].list_price, 'order_id': cls.sale_order_1.id, 'tax_id': False, }) @@ -62,26 +50,26 @@ class TestSalePurchase(TestCommonSalePurchaseNoChart): }) cls.sale_order_2 = SaleOrder.create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, - 'pricelist_id': cls.pricelist_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) cls.sol2_product_deliver = cls.env['sale.order.line'].create({ - 'name': cls.product_deliver.name, - 'product_id': cls.product_deliver.id, + 'name': cls.company_data['product_delivery_no'].name, + 'product_id': cls.company_data['product_delivery_no'].id, 'product_uom_qty': 5, - 'product_uom': cls.product_deliver.uom_id.id, - 'price_unit': cls.product_deliver.list_price, + 'product_uom': cls.company_data['product_delivery_no'].uom_id.id, + 'price_unit': cls.company_data['product_delivery_no'].list_price, 'order_id': cls.sale_order_2.id, 'tax_id': False, }) cls.sol2_service_order = cls.env['sale.order.line'].create({ - 'name': cls.service_order.name, - 'product_id': cls.service_order.id, + 'name': cls.company_data['product_service_order'].name, + 'product_id': cls.company_data['product_service_order'].id, 'product_uom_qty': 6, - 'product_uom': cls.service_order.uom_id.id, - 'price_unit': cls.service_order.list_price, + 'product_uom': cls.company_data['product_service_order'].uom_id.id, + 'price_unit': cls.company_data['product_service_order'].list_price, 'order_id': cls.sale_order_2.id, 'tax_id': False, }) diff --git a/addons/sale_stock/tests/test_anglo_saxon_valuation.py b/addons/sale_stock/tests/test_anglo_saxon_valuation.py index fa2b578c669..c6aa6576efe 100644 --- a/addons/sale_stock/tests/test_anglo_saxon_valuation.py +++ b/addons/sale_stock/tests/test_anglo_saxon_valuation.py @@ -2,103 +2,35 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.tests import Form, tagged -from odoo.tests.common import SavepointCase +from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_common import ValuationReconciliationTestCommon from odoo.exceptions import UserError @tagged('post_install', '-at_install') -class TestAngloSaxonValuation(SavepointCase): +class TestAngloSaxonValuation(ValuationReconciliationTestCommon): + @classmethod - def setUpClass(cls): - super(TestAngloSaxonValuation, cls).setUpClass() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) + cls.env.user.company_id.anglo_saxon_accounting = True + cls.product = cls.env['product.product'].create({ 'name': 'product', 'type': 'product', - 'categ_id': cls.env.ref('product.product_category_all').id, - }) - cls.stock_input_account = cls.env['account.account'].create({ - 'name': 'Stock Input', - 'code': 'StockIn', - 'user_type_id': cls.env.ref('account.data_account_type_current_assets').id, - }) - cls.stock_output_account = cls.env['account.account'].create({ - 'name': 'Stock Output', - 'code': 'StockOut', - 'reconcile': True, - 'user_type_id': cls.env.ref('account.data_account_type_current_assets').id, - }) - cls.stock_valuation_account = cls.env['account.account'].create({ - 'name': 'Stock Valuation', - 'code': 'StockVal', - 'user_type_id': cls.env.ref('account.data_account_type_current_assets').id, - }) - cls.expense_account = cls.env['account.account'].create({ - 'name': 'Expense Account', - 'code': 'Exp', - 'user_type_id': cls.env.ref('account.data_account_type_expenses').id, - }) - cls.income_account = cls.env['account.account'].create({ - 'name': 'Income Account', - 'code': 'Inc', - 'user_type_id': cls.env.ref('account.data_account_type_expenses').id, - }) - cls.stock_journal = cls.env['account.journal'].create({ - 'name': 'Stock Journal', - 'code': 'STJTEST', - 'type': 'general', - }) - cls.product.write({ - 'property_account_expense_id': cls.expense_account.id, - 'property_account_income_id': cls.income_account.id, - }) - cls.product.categ_id.write({ - 'property_stock_account_input_categ_id': cls.stock_input_account.id, - 'property_stock_account_output_categ_id': cls.stock_output_account.id, - 'property_stock_valuation_account_id': cls.stock_valuation_account.id, - 'property_stock_journal': cls.stock_journal.id, - 'property_valuation': 'real_time', - }) - cls.stock_location = cls.env['stock.warehouse'].search([], limit=1).lot_stock_id - cls.recv_account = cls.env['account.account'].create({ - 'name': 'account receivable', - 'code': 'RECV', - 'user_type_id': cls.env.ref('account.data_account_type_receivable').id, - 'reconcile': True, - }) - cls.pay_account = cls.env['account.account'].create({ - 'name': 'account payable', - 'code': 'PAY', - 'user_type_id': cls.env.ref('account.data_account_type_payable').id, - 'reconcile': True, - }) - cls.customer = cls.env['res.partner'].create({ - 'name': 'customer', - 'property_account_receivable_id': cls.recv_account.id, - 'property_account_payable_id': cls.pay_account.id, - }) - cls.journal_sale = cls.env['account.journal'].create({ - 'name': 'Sale Journal - Test', - 'code': 'AJ-SALE', - 'type': 'sale', - 'company_id': cls.env.user.company_id.id, - }) - cls.counterpart_account = cls.env['account.account'].create({ - 'name': 'Counterpart account', - 'code': 'Count', - 'user_type_id': cls.env.ref('account.data_account_type_expenses').id, + 'categ_id': cls.stock_account_product_categ.id, }) def _inv_adj_two_units(self): inventory = self.env['stock.inventory'].create({ 'name': 'test', - 'location_ids': [(4, self.stock_location.id)], + 'location_ids': [(4, self.company_data['default_warehouse'].lot_stock_id.id)], 'product_ids': [(4, self.product.id)], }) inventory.action_start() self.env['stock.inventory.line'].create({ 'inventory_id': inventory.id, - 'location_id': self.stock_location.id, + 'location_id': self.company_data['default_warehouse'].lot_stock_id.id, 'product_id': self.product.id, 'product_qty': 2, }) @@ -106,7 +38,7 @@ class TestAngloSaxonValuation(SavepointCase): def _so_and_confirm_two_units(self): sale_order = self.env['sale.order'].create({ - 'partner_id': self.customer.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, { 'name': self.product.name, @@ -126,7 +58,7 @@ class TestAngloSaxonValuation(SavepointCase): 'name': 'a', 'product_id': self.product.id, 'location_id': self.env.ref('stock.stock_location_suppliers').id, - 'location_dest_id': self.stock_location.id, + 'location_dest_id': self.company_data['default_warehouse'].lot_stock_id.id, 'product_uom': self.product.uom_id.id, 'product_uom_qty': 1, 'price_unit': 8, @@ -138,7 +70,7 @@ class TestAngloSaxonValuation(SavepointCase): 'name': 'a', 'product_id': self.product.id, 'location_id': self.env.ref('stock.stock_location_suppliers').id, - 'location_dest_id': self.stock_location.id, + 'location_dest_id': self.company_data['default_warehouse'].lot_stock_id.id, 'product_uom': self.product.uom_id.id, 'product_uom_qty': 1, 'price_unit': 10, @@ -168,22 +100,22 @@ class TestAngloSaxonValuation(SavepointCase): self.product.standard_price = 14.0 # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 28) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 28) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -208,7 +140,7 @@ class TestAngloSaxonValuation(SavepointCase): wiz.process() # Invoice 1 - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice_form = Form(invoice) with invoice_form.invoice_line_ids.edit(0) as invoice_line: invoice_line.quantity = 1 @@ -218,16 +150,16 @@ class TestAngloSaxonValuation(SavepointCase): # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 10) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 10) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 12) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 12) @@ -242,20 +174,20 @@ class TestAngloSaxonValuation(SavepointCase): self.product.standard_price = 16.0 # invoice 1 - invoice2 = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice2 = sale_order._create_invoices() invoice2.post() amls = invoice2.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 14) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 14) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 12) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 12) @@ -287,22 +219,22 @@ class TestAngloSaxonValuation(SavepointCase): sale_order.picking_ids.filtered('backorder_id').button_validate() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 24) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 24) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -347,7 +279,7 @@ class TestAngloSaxonValuation(SavepointCase): wiz.process() # Invoice 1 - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice_form = Form(invoice) with invoice_form.invoice_line_ids.edit(0) as invoice_line: invoice_line.quantity = 1 @@ -357,16 +289,16 @@ class TestAngloSaxonValuation(SavepointCase): # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 10) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 10) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 12) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 12) @@ -381,20 +313,20 @@ class TestAngloSaxonValuation(SavepointCase): self.product.standard_price = 16.0 # invoice 1 - invoice2 = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice2 = sale_order._create_invoices() invoice2.post() amls = invoice2.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 14) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 14) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 12) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 12) @@ -426,22 +358,22 @@ class TestAngloSaxonValuation(SavepointCase): sale_order.picking_ids.filtered('backorder_id').button_validate() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 24) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 24) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -461,22 +393,22 @@ class TestAngloSaxonValuation(SavepointCase): sale_order = self._so_and_confirm_two_units() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 20) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 20) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -499,22 +431,22 @@ class TestAngloSaxonValuation(SavepointCase): wiz.process() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 20) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 20) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -535,22 +467,22 @@ class TestAngloSaxonValuation(SavepointCase): sale_order.picking_ids.button_validate() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 20) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 20) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -593,22 +525,22 @@ class TestAngloSaxonValuation(SavepointCase): wiz.process() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 10) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 10) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 12) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 12) @@ -628,22 +560,22 @@ class TestAngloSaxonValuation(SavepointCase): sale_order.picking_ids.button_validate() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 20) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 20) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -662,22 +594,22 @@ class TestAngloSaxonValuation(SavepointCase): sale_order = self._so_and_confirm_two_units() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertAlmostEqual(stock_out_aml.credit, 16) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertAlmostEqual(cogs_aml.debit, 16) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -702,7 +634,7 @@ class TestAngloSaxonValuation(SavepointCase): self.product.standard_price = 12 # Invoice 2 - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice_form = Form(invoice) with invoice_form.invoice_line_ids.edit(0) as invoice_line: invoice_line.quantity = 2 @@ -712,16 +644,16 @@ class TestAngloSaxonValuation(SavepointCase): # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 20) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 20) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -740,22 +672,22 @@ class TestAngloSaxonValuation(SavepointCase): sale_order.picking_ids.button_validate() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 18) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 18) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -798,7 +730,7 @@ class TestAngloSaxonValuation(SavepointCase): self.product.standard_price = 12 # Invoice 2 - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice_form = Form(invoice) with invoice_form.invoice_line_ids.edit(0) as invoice_line: invoice_line.quantity = 2 @@ -808,16 +740,16 @@ class TestAngloSaxonValuation(SavepointCase): # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 20) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 20) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -837,22 +769,22 @@ class TestAngloSaxonValuation(SavepointCase): sale_order.picking_ids.button_validate() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 18) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 18) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 24) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 24) @@ -867,7 +799,7 @@ class TestAngloSaxonValuation(SavepointCase): 'name': 'a', 'product_id': self.product.id, 'location_id': self.env.ref('stock.stock_location_suppliers').id, - 'location_dest_id': self.stock_location.id, + 'location_dest_id': self.company_data['default_warehouse'].lot_stock_id.id, 'product_uom': self.product.uom_id.id, 'product_uom_qty': 8, 'price_unit': 10, @@ -878,7 +810,7 @@ class TestAngloSaxonValuation(SavepointCase): # Create and confirm a sale order for 2@12 sale_order = self.env['sale.order'].create({ - 'partner_id': self.customer.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, { 'name': self.product.name, @@ -900,7 +832,7 @@ class TestAngloSaxonValuation(SavepointCase): 'name': 'a', 'product_id': self.product.id, 'location_id': self.env.ref('stock.stock_location_suppliers').id, - 'location_dest_id': self.stock_location.id, + 'location_dest_id': self.company_data['default_warehouse'].lot_stock_id.id, 'product_uom': self.product.uom_id.id, 'product_uom_qty': 2, 'price_unit': 12, @@ -913,22 +845,22 @@ class TestAngloSaxonValuation(SavepointCase): self.assertEqual(sale_order.order_line.move_ids.stock_valuation_layer_ids[-1].quantity, 0) # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Check the resulting accounting entries amls = invoice.line_ids self.assertEqual(len(amls), 4) - stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account) + stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_stock_out']) self.assertEqual(stock_out_aml.debit, 0) self.assertEqual(stock_out_aml.credit, 104) - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 104) self.assertEqual(cogs_aml.credit, 0) - receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account) + receivable_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_receivable']) self.assertEqual(receivable_aml.debit, 120) self.assertEqual(receivable_aml.credit, 0) - income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account) + income_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_revenue']) self.assertEqual(income_aml.debit, 0) self.assertEqual(income_aml.credit, 120) @@ -943,7 +875,7 @@ class TestAngloSaxonValuation(SavepointCase): 'name': 'a', 'product_id': self.product.id, 'location_id': self.env.ref('stock.stock_location_suppliers').id, - 'location_dest_id': self.stock_location.id, + 'location_dest_id': self.company_data['default_warehouse'].lot_stock_id.id, 'product_uom': self.product.uom_id.id, 'product_uom_qty': 5, 'price_unit': 8, @@ -957,7 +889,7 @@ class TestAngloSaxonValuation(SavepointCase): 'name': 'a', 'product_id': self.product.id, 'location_id': self.env.ref('stock.stock_location_suppliers').id, - 'location_dest_id': self.stock_location.id, + 'location_dest_id': self.company_data['default_warehouse'].lot_stock_id.id, 'product_uom': self.product.uom_id.id, 'product_uom_qty': 8, 'price_unit': 12, @@ -968,7 +900,7 @@ class TestAngloSaxonValuation(SavepointCase): # sale 1@20, deliver, invoice sale_order = self.env['sale.order'].create({ - 'partner_id': self.customer.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, { 'name': self.product.name, @@ -982,12 +914,12 @@ class TestAngloSaxonValuation(SavepointCase): sale_order.action_confirm() sale_order.picking_ids.move_lines.quantity_done = 1 sale_order.picking_ids.button_validate() - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # sale 6@20, deliver, invoice sale_order = self.env['sale.order'].create({ - 'partner_id': self.customer.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, { 'name': self.product.name, @@ -1001,12 +933,12 @@ class TestAngloSaxonValuation(SavepointCase): sale_order.action_confirm() sale_order.picking_ids.move_lines.quantity_done = 6 sale_order.picking_ids.button_validate() - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # check the last anglo saxon invoice line amls = invoice.line_ids - cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account) + cogs_aml = amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(cogs_aml.debit, 56) self.assertEqual(cogs_aml.credit, 0) @@ -1021,7 +953,7 @@ class TestAngloSaxonValuation(SavepointCase): 'name': 'a', 'product_id': self.product.id, 'location_id': self.env.ref('stock.stock_location_suppliers').id, - 'location_dest_id': self.stock_location.id, + 'location_dest_id': self.company_data['default_warehouse'].lot_stock_id.id, 'product_uom': self.product.uom_id.id, 'product_uom_qty': 8, 'price_unit': 10, @@ -1032,7 +964,7 @@ class TestAngloSaxonValuation(SavepointCase): # Create and confirm a sale order for 10@12 sale_order = self.env['sale.order'].create({ - 'partner_id': self.customer.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, { 'name': self.product.name, @@ -1050,7 +982,7 @@ class TestAngloSaxonValuation(SavepointCase): sale_order.picking_ids.button_validate() # Invoice the sale order. - invoice = sale_order.with_context(default_journal_id=self.journal_sale.id)._create_invoices() + invoice = sale_order._create_invoices() invoice.post() # Make the second receipt @@ -1058,7 +990,7 @@ class TestAngloSaxonValuation(SavepointCase): 'name': 'a', 'product_id': self.product.id, 'location_id': self.env.ref('stock.stock_location_suppliers').id, - 'location_dest_id': self.stock_location.id, + 'location_dest_id': self.company_data['default_warehouse'].lot_stock_id.id, 'product_uom': self.product.uom_id.id, 'product_uom_qty': 2, 'price_unit': 12, @@ -1069,5 +1001,5 @@ class TestAngloSaxonValuation(SavepointCase): # check the last anglo saxon move line revalued_anglo_expense_amls = sale_order.picking_ids.mapped('move_lines.stock_valuation_layer_ids')[-1].stock_move_id.account_move_ids[-1].mapped('line_ids') - revalued_cogs_aml = revalued_anglo_expense_amls.filtered(lambda aml: aml.account_id == self.expense_account) + revalued_cogs_aml = revalued_anglo_expense_amls.filtered(lambda aml: aml.account_id == self.company_data['default_account_expense']) self.assertEqual(revalued_cogs_aml.debit, 4, 'Price difference should have correctly reflected in expense account.') diff --git a/addons/sale_stock/tests/test_anglo_saxon_valuation_reconciliation.py b/addons/sale_stock/tests/test_anglo_saxon_valuation_reconciliation.py index c87285a1f00..0cef43ad17e 100644 --- a/addons/sale_stock/tests/test_anglo_saxon_valuation_reconciliation.py +++ b/addons/sale_stock/tests/test_anglo_saxon_valuation_reconciliation.py @@ -10,19 +10,6 @@ class TestValuationReconciliation(ValuationReconciliationTestCommon): @classmethod def setUpClass(cls, chart_template_ref=None): super().setUpClass(chart_template_ref=chart_template_ref) - - cls.env['product.pricelist'].create([ - { - 'name': "Public Pricelist Company 1", - 'sequence': 1, - 'company_id': cls.company_data['company'].id, - }, - { - 'name': "Public Pricelist Company 2", - 'sequence': 1, - 'company_id': cls.company_data_2['company'].id, - }, - ]) # Set the invoice_policy to delivery to have an accurate COGS entry. cls.test_product_delivery.invoice_policy = 'delivery' diff --git a/addons/sale_stock/tests/test_sale_order_dates.py b/addons/sale_stock/tests/test_sale_order_dates.py index 55d4f991a20..a6f8276a8a3 100644 --- a/addons/sale_stock/tests/test_sale_order_dates.py +++ b/addons/sale_stock/tests/test_sale_order_dates.py @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_common import ValuationReconciliationTestCommon from datetime import timedelta from odoo import fields from odoo.tests import common, tagged @tagged('post_install', '-at_install') -class TestSaleExpectedDate(common.TransactionCase): +class TestSaleExpectedDate(ValuationReconciliationTestCommon): def test_sale_order_expected_date(self): """ Test expected date and effective date of Sales Orders """ @@ -32,9 +33,10 @@ class TestSaleExpectedDate(common.TransactionCase): 'uom_id': 1, }) - self.env['stock.quant']._update_available_quantity(product_A, self.env.ref('stock.stock_location_stock'), 10) - self.env['stock.quant']._update_available_quantity(product_B, self.env.ref('stock.stock_location_stock'), 10) - self.env['stock.quant']._update_available_quantity(product_C, self.env.ref('stock.stock_location_stock'), 10) + self.env['stock.quant']._update_available_quantity(product_A, self.company_data['default_warehouse'].lot_stock_id, 10) + self.env['stock.quant']._update_available_quantity(product_B, self.company_data['default_warehouse'].lot_stock_id, 10) + self.env['stock.quant']._update_available_quantity(product_C, self.company_data['default_warehouse'].lot_stock_id, 10) + sale_order = self.env['sale.order'].create({ 'partner_id': self.env['res.partner'].create({'name': 'A Customer'}).id, 'picking_policy': 'direct', diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index 683f0b455db..19569195003 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -2,32 +2,31 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from datetime import datetime, timedelta -from odoo.addons.sale.tests.test_sale_common import TestSaleCommon +from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_common import ValuationReconciliationTestCommon +from odoo.addons.sale.tests.common import TestSaleCommon from odoo.exceptions import UserError from odoo.tests import Form, tagged @tagged('post_install', '-at_install') -class TestSaleStock(TestSaleCommon): +class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): def _get_new_sale_order(self, amount=10.0): """ Creates and returns a sale order with one default order line. :param float amount: quantity of product for the order line (10 by default) """ - partner = self.partner - product = self.products['prod_del'] sale_order_vals = { - 'partner_id': partner.id, - 'partner_invoice_id': partner.id, - 'partner_shipping_id': partner.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, 'order_line': [(0, 0, { - 'name': product.name, - 'product_id': product.id, + 'name': self.company_data['product_delivery_no'].name, + 'product_id': self.company_data['product_delivery_no'].id, 'product_uom_qty': amount, - 'product_uom': product.uom_id.id, - 'price_unit': product.list_price})], - 'pricelist_id': self.env.ref('product.list0').id, + 'product_uom': self.company_data['product_delivery_no'].uom_id.id, + 'price_unit': self.company_data['product_delivery_no'].list_price})], + 'pricelist_id': self.company_data['default_pricelist'].id, } sale_order = self.env['sale.order'].create(sale_order_vals) return sale_order @@ -37,13 +36,24 @@ class TestSaleStock(TestSaleCommon): Test SO's changes when playing around with stock moves, quants, pack operations, pickings and whatever other model there is in stock with "invoice on delivery" products """ - inv_obj = self.env['account.move'] self.so = self.env['sale.order'].create({ - 'partner_id': self.partner.id, - 'partner_invoice_id': self.partner.id, - 'partner_shipping_id': self.partner.id, - 'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for p in self.products.values()], - 'pricelist_id': self.env.ref('product.list0').id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'order_line': [ + (0, 0, { + 'name': p.name, + 'product_id': p.id, + 'product_uom_qty': 2, + 'product_uom': p.uom_id.id, + 'price_unit': p.list_price, + }) for p in ( + self.company_data['product_order_no'], + self.company_data['product_service_delivery'], + self.company_data['product_service_order'], + self.company_data['product_delivery_no'], + )], + 'pricelist_id': self.company_data['default_pricelist'].id, 'picking_policy': 'direct', }) @@ -105,11 +115,22 @@ class TestSaleStock(TestSaleCommon): """ # let's cheat and put all our products to "invoice on order" self.so = self.env['sale.order'].create({ - 'partner_id': self.partner.id, - 'partner_invoice_id': self.partner.id, - 'partner_shipping_id': self.partner.id, - 'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for p in self.products.values()], - 'pricelist_id': self.env.ref('product.list0').id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'order_line': [(0, 0, { + 'name': p.name, + 'product_id': p.id, + 'product_uom_qty': 2, + 'product_uom': p.uom_id.id, + 'price_unit': p.list_price, + }) for p in ( + self.company_data['product_order_no'], + self.company_data['product_service_delivery'], + self.company_data['product_service_order'], + self.company_data['product_delivery_no'], + )], + 'pricelist_id': self.company_data['default_pricelist'].id, 'picking_policy': 'direct', }) for sol in self.so.order_line: @@ -158,18 +179,18 @@ class TestSaleStock(TestSaleCommon): of the picking. Check that a refund invoice is well generated. """ # intial so - self.product = self.products['prod_del'] + self.product = self.company_data['product_delivery_no'] so_vals = { - 'partner_id': self.partner.id, - 'partner_invoice_id': self.partner.id, - 'partner_shipping_id': self.partner.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, 'order_line': [(0, 0, { 'name': self.product.name, 'product_id': self.product.id, 'product_uom_qty': 5.0, 'product_uom': self.product.uom_id.id, 'price_unit': self.product.list_price})], - 'pricelist_id': self.env.ref('product.list0').id, + 'pricelist_id': self.company_data['default_pricelist'].id, } self.so = self.env['sale.order'].create(so_vals) @@ -229,18 +250,18 @@ class TestSaleStock(TestSaleCommon): the SO is set on 'done', the SO should be fully invoiced. """ # intial so - self.product = self.products['prod_del'] + self.product = self.company_data['product_delivery_no'] so_vals = { - 'partner_id': self.partner.id, - 'partner_invoice_id': self.partner.id, - 'partner_shipping_id': self.partner.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, 'order_line': [(0, 0, { 'name': self.product.name, 'product_id': self.product.id, 'product_uom_qty': 5.0, 'product_uom': self.product.uom_id.id, 'price_unit': self.product.list_price})], - 'pricelist_id': self.env.ref('product.list0').id, + 'pricelist_id': self.company_data['default_pricelist'].id, } self.so = self.env['sale.order'].create(so_vals) @@ -278,13 +299,13 @@ class TestSaleStock(TestSaleCommon): the new move lines. """ # sell two products - item1 = self.products['prod_order'] # consumable + item1 = self.company_data['product_order_no'] # consumable item1.type = 'consu' - item2 = self.products['prod_del'] # storable + item2 = self.company_data['product_delivery_no'] # storable item2.type = 'product' # storable self.so = self.env['sale.order'].create({ - 'partner_id': self.partner.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, {'name': item1.name, 'product_id': item1.id, 'product_uom_qty': 1, 'product_uom': item1.uom_id.id, 'price_unit': item1.list_price}), (0, 0, {'name': item2.name, 'product_id': item2.id, 'product_uom_qty': 1, 'product_uom': item2.uom_id.id, 'price_unit': item2.list_price}), @@ -347,14 +368,14 @@ class TestSaleStock(TestSaleCommon): is successful. """ # sell two products - item1 = self.products['prod_order'] # consumable + item1 = self.company_data['product_order_no'] # consumable item1.type = 'consu' # consumable - item2 = self.products['prod_del'] # storable + item2 = self.company_data['product_delivery_no'] # storable item2.type = 'product' # storable - self.env['stock.quant']._update_available_quantity(item2, self.env.ref('stock.stock_location_stock'), 2) + self.env['stock.quant']._update_available_quantity(item2, self.company_data['default_warehouse'].lot_stock_id, 2) self.so = self.env['sale.order'].create({ - 'partner_id': self.partner.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, {'name': item1.name, 'product_id': item1.id, 'product_uom_qty': 1, 'product_uom': item1.uom_id.id, 'price_unit': item1.list_price}), (0, 0, {'name': item2.name, 'product_id': item2.id, 'product_uom_qty': 1, 'product_uom': item2.uom_id.id, 'price_unit': item2.list_price}), @@ -384,8 +405,8 @@ class TestSaleStock(TestSaleCommon): partner, confirm it again: the second delivery order should have the new partner. """ - item1 = self.products['prod_order'] - partner1 = self.partner.id + item1 = self.company_data['product_order_no'] + partner1 = self.partner_a.id partner2 = self.env['res.partner'].create({'name': 'Another Test Partner'}) so1 = self.env['sale.order'].create({ 'partner_id': partner1, @@ -419,13 +440,13 @@ class TestSaleStock(TestSaleCommon): """ uom_unit = self.env.ref('uom.product_uom_unit') uom_dozen = self.env.ref('uom.product_uom_dozen') - item1 = self.products['prod_order'] + item1 = self.company_data['product_order_no'] self.assertEqual(item1.uom_id.id, uom_unit.id) # sell a dozen so1 = self.env['sale.order'].create({ - 'partner_id': self.partner.id, + 'partner_id': self.partner_a.id, 'order_line': [(0, 0, { 'name': item1.name, 'product_id': item1.id, @@ -496,13 +517,13 @@ class TestSaleStock(TestSaleCommon): """ uom_unit = self.env.ref('uom.product_uom_unit') uom_dozen = self.env.ref('uom.product_uom_dozen') - item1 = self.products['prod_order'] + item1 = self.company_data['product_order_no'] self.assertEqual(item1.uom_id.id, uom_unit.id) # sell a dozen so1 = self.env['sale.order'].create({ - 'partner_id': self.partner.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, { 'name': item1.name, @@ -573,10 +594,10 @@ class TestSaleStock(TestSaleCommon): self.env['stock.picking.type'].search([('code', '=', 'incoming')]).write({'code': 'internal'}) # Sell and deliver 10 units - item1 = self.products['prod_order'] + item1 = self.company_data['product_order_no'] uom_unit = self.env.ref('uom.product_uom_unit') so1 = self.env['sale.order'].create({ - 'partner_id': self.partner.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, { 'name': item1.name, @@ -629,19 +650,21 @@ class TestSaleStock(TestSaleCommon): """ create a sale order in warehouse1, change to warehouse2 and check the available quantities on sale order lines are well updated """ # sell two products - item1 = self.products['prod_order'] + item1 = self.company_data['product_order_no'] item1.type = 'product' - warehouse1 = self.env.ref('stock.warehouse0') + + warehouse1 = self.company_data['default_warehouse'] self.env['stock.quant']._update_available_quantity(item1, warehouse1.lot_stock_id, 10) self.env['stock.quant']._update_reserved_quantity(item1, warehouse1.lot_stock_id, 3) + warehouse2 = self.env['stock.warehouse'].create({ - 'partner_id': self.env.ref('base.main_partner').id, + 'partner_id': self.partner_a.id, 'name': 'Zizizatestwarehouse', 'code': 'Test', }) self.env['stock.quant']._update_available_quantity(item1, warehouse2.lot_stock_id, 5) so = self.env['sale.order'].create({ - 'partner_id': self.partner.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, {'name': item1.name, 'product_id': item1.id, 'product_uom_qty': 1, 'product_uom': item1.uom_id.id, 'price_unit': item1.list_price}), ], @@ -666,11 +689,11 @@ class TestSaleStock(TestSaleCommon): def test_10_qty_available(self): """create a sale order containing three times the same product. The quantity available should be different for the 3 lines""" - item1 = self.products['prod_order'] + item1 = self.company_data['product_order_no'] item1.type = 'product' - self.env['stock.quant']._update_available_quantity(item1, self.env.ref('stock.stock_location_stock'), 10) + self.env['stock.quant']._update_available_quantity(item1, self.company_data['default_warehouse'].lot_stock_id, 10) so = self.env['sale.order'].create({ - 'partner_id': self.partner.id, + 'partner_id': self.partner_a.id, 'order_line': [ (0, 0, {'name': item1.name, 'product_id': item1.id, 'product_uom_qty': 5, 'product_uom': item1.uom_id.id, 'price_unit': item1.list_price}), (0, 0, {'name': item1.name, 'product_id': item1.id, 'product_uom_qty': 5, 'product_uom': item1.uom_id.id, 'price_unit': item1.list_price}), @@ -753,8 +776,8 @@ class TestSaleStock(TestSaleCommon): Create two invoices: one for 3 quantity and one for 2 quantity Then cancel Sale order, it won't raise any warning, it should be cancelled. """ - partner = self.partner - product = self.products['prod_del'] + partner = self.partner_a + product = self.company_data['product_delivery_no'] so_vals = { 'partner_id': partner.id, 'partner_invoice_id': partner.id, @@ -765,7 +788,7 @@ class TestSaleStock(TestSaleCommon): 'product_uom_qty': 5.0, 'product_uom': product.uom_id.id, 'price_unit': product.list_price})], - 'pricelist_id': self.env.ref('product.list0').id, + 'pricelist_id': self.company_data['default_pricelist'].id, } so = self.env['sale.order'].create(so_vals) diff --git a/addons/sale_stock/tests/test_sale_stock_lead_time.py b/addons/sale_stock/tests/test_sale_stock_lead_time.py index 253e2309d3b..eb031fe43ee 100644 --- a/addons/sale_stock/tests/test_sale_stock_lead_time.py +++ b/addons/sale_stock/tests/test_sale_stock_lead_time.py @@ -1,43 +1,43 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_common import ValuationReconciliationTestCommon +from odoo.addons.sale.tests.common import TestSaleCommon +from odoo import fields +from odoo.tests import tagged from datetime import timedelta -from odoo import fields -from odoo.addons.stock.tests.common2 import TestStockCommon - -class TestSaleStockLeadTime(TestStockCommon): +@tagged('post_install', '-at_install') +class TestSaleStockLeadTime(TestSaleCommon, ValuationReconciliationTestCommon): @classmethod - def setUpClass(cls): - super(TestSaleStockLeadTime, cls).setUpClass() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) # Update the product_1 with type and Customer Lead Time - cls.product_1.write({'type': 'product', 'sale_delay': 5.0}) + cls.test_product_order.sale_delay = 5.0 def test_00_product_company_level_delays(self): """ In order to check schedule date, set product's Customer Lead Time and company's Sales Safety Days.""" - company = self.env.ref('base.main_company') - # Update company with Sales Safety Days - company.write({'security_lead': 3.00}) + self.env.company.security_lead = 3.00 # Create sale order of product_1 order = self.env['sale.order'].create({ - 'partner_id': self.partner_1.id, - 'partner_invoice_id': self.partner_1.id, - 'partner_shipping_id': self.partner_1.id, - 'pricelist_id': self.env.ref('product.list0').id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, 'picking_policy': 'direct', - 'warehouse_id': self.warehouse_1.id, - 'order_line': [(0, 0, {'name': self.product_1.name, - 'product_id': self.product_1.id, + 'warehouse_id': self.company_data['default_warehouse'].id, + 'order_line': [(0, 0, {'name': self.test_product_order.name, + 'product_id': self.test_product_order.id, 'product_uom_qty': 10, - 'product_uom': self.uom_unit.id, - 'customer_lead': self.product_1.sale_delay})]}) + 'product_uom': self.env.ref('uom.product_uom_unit').id, + 'customer_lead': self.test_product_order.sale_delay})]}) # Confirm our standard sale order order.action_confirm() @@ -46,7 +46,7 @@ class TestSaleStockLeadTime(TestStockCommon): self.assertTrue(order.picking_ids, "Picking should be created.") # Check schedule date of picking - out_date = fields.Datetime.from_string(order.date_order) + timedelta(days=self.product_1.sale_delay) - timedelta(days=company.security_lead) + out_date = fields.Datetime.from_string(order.date_order) + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=self.env.company.security_lead) min_date = fields.Datetime.from_string(order.picking_ids[0].scheduled_date) self.assertTrue(abs(min_date - out_date) <= timedelta(seconds=1), 'Schedule date of picking should be equal to: order date + Customer Lead Time - Sales Safety Days.') @@ -55,25 +55,25 @@ class TestSaleStockLeadTime(TestStockCommon): and warehouse route's delay.""" # Update warehouse_1 with Outgoing Shippings pick + pack + ship - self.warehouse_1.write({'delivery_steps': 'pick_pack_ship'}) + self.company_data['default_warehouse'].write({'delivery_steps': 'pick_pack_ship'}) # Set delay on pull rule - for pull_rule in self.warehouse_1.delivery_route_id.rule_ids: + for pull_rule in self.company_data['default_warehouse'].delivery_route_id.rule_ids: pull_rule.write({'delay': 2}) # Create sale order of product_1 order = self.env['sale.order'].create({ - 'partner_id': self.partner_1.id, - 'partner_invoice_id': self.partner_1.id, - 'partner_shipping_id': self.partner_1.id, - 'pricelist_id': self.env.ref('product.list0').id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, 'picking_policy': 'direct', - 'warehouse_id': self.warehouse_1.id, - 'order_line': [(0, 0, {'name': self.product_1.name, - 'product_id': self.product_1.id, + 'warehouse_id': self.company_data['default_warehouse'].id, + 'order_line': [(0, 0, {'name': self.test_product_order.name, + 'product_id': self.test_product_order.id, 'product_uom_qty': 5, - 'product_uom': self.uom_unit.id, - 'customer_lead': self.product_1.sale_delay})]}) + 'product_uom': self.env.ref('uom.product_uom_unit').id, + 'customer_lead': self.test_product_order.sale_delay})]}) # Confirm our standard sale order order.action_confirm() @@ -82,19 +82,19 @@ class TestSaleStockLeadTime(TestStockCommon): self.assertTrue(order.picking_ids, "Pickings should be created.") # Check schedule date of ship type picking - out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.warehouse_1.out_type_id) + out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].out_type_id) out_min_date = fields.Datetime.from_string(out.scheduled_date) - out_date = fields.Datetime.from_string(order.date_order) + timedelta(days=self.product_1.sale_delay) - timedelta(days=out.move_lines[0].rule_id.delay) + out_date = fields.Datetime.from_string(order.date_order) + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=out.move_lines[0].rule_id.delay) self.assertTrue(abs(out_min_date - out_date) <= timedelta(seconds=1), 'Schedule date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay.') # Check schedule date of pack type picking - pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.warehouse_1.pack_type_id) + pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pack_type_id) pack_min_date = fields.Datetime.from_string(pack.scheduled_date) pack_date = out_date - timedelta(days=pack.move_lines[0].rule_id.delay) self.assertTrue(abs(pack_min_date - pack_date) <= timedelta(seconds=1), 'Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.') # Check schedule date of pick type picking - pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.warehouse_1.pick_type_id) + pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pick_type_id) pick_min_date = fields.Datetime.from_string(pick.scheduled_date) pick_date = pack_date - timedelta(days=pick.move_lines[0].rule_id.delay) self.assertTrue(abs(pick_min_date - pick_date) <= timedelta(seconds=1), 'Schedule date of pick type picking should be equal to: Schedule date of pack type picking - pull rule delay.') @@ -126,28 +126,28 @@ class TestSaleStockLeadTime(TestStockCommon): # set propagate_date_minimum_delta = 5 in the stock rule # Update warehouse_1 with Outgoing Shippings pick + pack + ship - self.warehouse_1.write({'delivery_steps': 'pick_pack_ship'}) + self.company_data['default_warehouse'].write({'delivery_steps': 'pick_pack_ship'}) # Set delay on pull rule - self.warehouse_1.delivery_route_id.rule_ids.write({'delay': 5, 'propagate_date': True, 'propagate_date_minimum_delta': 5}) + self.company_data['default_warehouse'].delivery_route_id.rule_ids.write({'delay': 5, 'propagate_date': True, 'propagate_date_minimum_delta': 5}) # Update the product_1 with type and Customer Lead Time - self.product_1.write({'type': 'product', + self.test_product_order.write({'type': 'product', 'sale_delay': 30.0}) # Now, create sale order of product_1 with customer_lead set on product order = self.env['sale.order'].create({ - 'partner_id': self.partner_1.id, - 'partner_invoice_id': self.partner_1.id, - 'partner_shipping_id': self.partner_1.id, - 'pricelist_id': self.env.ref('product.list0').id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, 'picking_policy': 'direct', - 'warehouse_id': self.warehouse_1.id, - 'order_line': [(0, 0, {'name': self.product_1.name, - 'product_id': self.product_1.id, + 'warehouse_id': self.company_data['default_warehouse'].id, + 'order_line': [(0, 0, {'name': self.test_product_order.name, + 'product_id': self.test_product_order.id, 'product_uom_qty': 5, - 'product_uom': self.uom_unit.id, - 'customer_lead': self.product_1.sale_delay})]}) + 'product_uom': self.env.ref('uom.product_uom_unit').id, + 'customer_lead': self.test_product_order.sale_delay})]}) # Confirm our standard sale order order.action_confirm() @@ -156,19 +156,19 @@ class TestSaleStockLeadTime(TestStockCommon): self.assertTrue(order.picking_ids, "Pickings should be created.") # Check schedule date of ship type picking - out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.warehouse_1.out_type_id) + out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].out_type_id) out_min_date = out.scheduled_date - out_date = order.date_order + timedelta(days=self.product_1.sale_delay) - timedelta(days=out.move_lines[0].rule_id.delay) + out_date = order.date_order + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=out.move_lines[0].rule_id.delay) self.assertTrue(abs(out_min_date - out_date) <= timedelta(seconds=1), 'Schedule date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay.') # Check schedule date of pack type picking - pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.warehouse_1.pack_type_id) + pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pack_type_id) pack_min_date = pack.scheduled_date pack_date = out_date - timedelta(days=pack.move_lines[0].rule_id.delay) self.assertTrue(abs(pack_min_date - pack_date) <= timedelta(seconds=1), 'Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.') # Check schedule date of pick type picking - pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.warehouse_1.pick_type_id) + pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pick_type_id) pick_min_date = pick.scheduled_date pick_date = pack_date - timedelta(days=pick.move_lines[0].rule_id.delay) self.assertTrue(abs(pick_min_date - pick_date) <= timedelta(seconds=1), 'Schedule date of pick type picking should be equal to: Schedule date of pack type picking - pull rule delay.') @@ -205,29 +205,29 @@ class TestSaleStockLeadTime(TestStockCommon): # PICK -> Scheduled Date : 01/07/2019 # Update warehouse_1 with Outgoing Shippings pick + pack + ship - self.warehouse_1.write({'delivery_steps': 'pick_pack_ship'}) + self.company_data['default_warehouse'].write({'delivery_steps': 'pick_pack_ship'}) # Set delay on pull rule - for pull_rule in self.warehouse_1.delivery_route_id.rule_ids: + for pull_rule in self.company_data['default_warehouse'].delivery_route_id.rule_ids: pull_rule.write({'delay': 5, 'propagate_date': False}) # Update the product_1 with type and Customer Lead Time - self.product_1.write({'type': 'product', + self.test_product_order.write({'type': 'product', 'sale_delay': 30.0}) #Create sale order of product_1 order = self.env['sale.order'].create({ - 'partner_id': self.partner_1.id, - 'partner_invoice_id': self.partner_1.id, - 'partner_shipping_id': self.partner_1.id, - 'pricelist_id': self.env.ref('product.list0').id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, 'picking_policy': 'direct', - 'warehouse_id': self.warehouse_1.id, - 'order_line': [(0, 0, {'name': self.product_1.name, - 'product_id': self.product_1.id, + 'warehouse_id': self.company_data['default_warehouse'].id, + 'order_line': [(0, 0, {'name': self.test_product_order.name, + 'product_id': self.test_product_order.id, 'product_uom_qty': 5, - 'product_uom': self.uom_unit.id, - 'customer_lead': self.product_1.sale_delay})]}) + 'product_uom': self.env.ref('uom.product_uom_unit').id, + 'customer_lead': self.test_product_order.sale_delay})]}) # Confirm our standard sale order order.action_confirm() @@ -235,19 +235,19 @@ class TestSaleStockLeadTime(TestStockCommon): self.assertTrue(order.picking_ids, "Pickings should be created.") # Check schedule date of ship type picking - out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.warehouse_1.out_type_id) + out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].out_type_id) out_min_date = out.scheduled_date - out_date = order.date_order + timedelta(days=self.product_1.sale_delay) - timedelta(days=out.move_lines[0].rule_id.delay) + out_date = order.date_order + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=out.move_lines[0].rule_id.delay) self.assertTrue(abs(out_min_date - out_date) <= timedelta(seconds=1), 'Schedule date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay.') # Check schedule date of pack type picking - pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.warehouse_1.pack_type_id) + pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pack_type_id) pack_min_date = pack.scheduled_date pack_date = out_date - timedelta(days=pack.move_lines[0].rule_id.delay) self.assertTrue(abs(pack_min_date - pack_date) <= timedelta(seconds=1), 'Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.') # Check schedule date of pick type picking - pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.warehouse_1.pick_type_id) + pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pick_type_id) pick_min_date = pick.scheduled_date pick_date = pack_date - timedelta(days=pick.move_lines[0].rule_id.delay) self.assertTrue(abs(pick_min_date - pick_date) <= timedelta(seconds=1), 'Schedule date of pick type picking should be equal to: Schedule date of pack type picking - pull rule delay.') diff --git a/addons/sale_stock/tests/test_sale_stock_multicompany.py b/addons/sale_stock/tests/test_sale_stock_multicompany.py index 307dc23a6e9..998fbdb9626 100644 --- a/addons/sale_stock/tests/test_sale_stock_multicompany.py +++ b/addons/sale_stock/tests/test_sale_stock_multicompany.py @@ -1,30 +1,37 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from datetime import datetime, timedelta - -from odoo.addons.sale.tests.test_sale_common import TestSaleCommon +from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_common import ValuationReconciliationTestCommon +from odoo.addons.sale.tests.common import TestSaleCommon from odoo.tests import tagged -from odoo.tests.common import new_test_user @tagged('post_install', '-at_install') -class TestSaleStockMultiCompany(TestSaleCommon): +class TestSaleStockMultiCompany(TestSaleCommon, ValuationReconciliationTestCommon): @classmethod - def setUpClass(cls): - super().setUpClass() - cls.company_B = cls.env['res.company'].create({'name': 'Company B'}) - cls.warehouse_A = cls.env['stock.warehouse'].create({'name': 'WH A', 'code': 'WHA', 'company_id': cls.env.company.id, 'partner_id': cls.env.company.partner_id.id}) - cls.warehouse_A2 = cls.env['stock.warehouse'].create({'name': 'WH A 2', 'code': 'WHA2', 'company_id': cls.env.company.id, 'partner_id': cls.env.company.partner_id.id, 'sequence': 5}) - cls.warehouse_B = cls.env['stock.warehouse'].create({'name': 'WH B', 'code': 'WHB', 'company_id': cls.company_B.id, 'partner_id': cls.company_B.partner_id.id}) - cls.warehouse_user = new_test_user(cls.env, 'WarehouseUser', groups='base.group_user,stock.group_stock_user,stock.group_stock_multi_locations,sales_team.group_sale_salesman', company_ids=[(6, 0, (cls.env.company | cls.company_B).ids)]) - cls.warehouse_user.with_company(cls.env.company).property_warehouse_id = cls.warehouse_A.id - cls.warehouse_user.with_company(cls.company_B).property_warehouse_id = cls.warehouse_B.id + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) + + cls.warehouse_A = cls.company_data['default_warehouse'] + cls.warehouse_A2 = cls.env['stock.warehouse'].create({ + 'name': 'WH B', + 'code': 'WHB', + 'company_id': cls.env.company.id, + 'partner_id': cls.env.company.partner_id.id, + }) + cls.warehouse_B = cls.company_data_2['default_warehouse'] + + cls.env.user.groups_id |= cls.env.ref('stock.group_stock_user') + cls.env.user.groups_id |= cls.env.ref('stock.group_stock_multi_locations') + cls.env.user.groups_id |= cls.env.ref('sales_team.group_sale_salesman') + + cls.env.user.with_company(cls.company_data['company']).property_warehouse_id = cls.warehouse_A.id + cls.env.user.with_company(cls.company_data_2['company']).property_warehouse_id = cls.warehouse_B.id def test_warehouse_definition_on_so(self): - partner = self.partner - product = self.products['prod_del'] + partner = self.partner_a + product = self.test_product_order sale_order_vals = { 'partner_id': partner.id, @@ -38,19 +45,18 @@ class TestSaleStockMultiCompany(TestSaleCommon): 'product_uom_qty': 10, 'product_uom': product.uom_id.id, 'price_unit': product.list_price})], - 'pricelist_id': self.env.ref('product.list0').id, + 'pricelist_id': self.company_data['default_pricelist'].id, } sale_order = self.env['sale.order'] so_no_user = sale_order.create(sale_order_vals) self.assertFalse(so_no_user.user_id.property_warehouse_id) - self.assertEqual(so_no_user.warehouse_id.id, self.warehouse_A2.id) + self.assertEqual(so_no_user.warehouse_id.id, self.warehouse_A.id) sale_order_vals2 = { 'partner_id': partner.id, 'partner_invoice_id': partner.id, 'partner_shipping_id': partner.id, - 'user_id': self.warehouse_user.id, 'company_id': self.env.company.id, 'order_line': [(0, 0, { 'name': product.name, @@ -58,7 +64,7 @@ class TestSaleStockMultiCompany(TestSaleCommon): 'product_uom_qty': 10, 'product_uom': product.uom_id.id, 'price_unit': product.list_price})], - 'pricelist_id': self.env.ref('product.list0').id, + 'pricelist_id': self.company_data['default_pricelist'].id, } so_company_A = sale_order.with_company(self.env.company).create(sale_order_vals2) self.assertEqual(so_company_A.warehouse_id.id, self.warehouse_A.id) @@ -67,15 +73,14 @@ class TestSaleStockMultiCompany(TestSaleCommon): 'partner_id': partner.id, 'partner_invoice_id': partner.id, 'partner_shipping_id': partner.id, - 'user_id': self.warehouse_user.id, - 'company_id': self.company_B.id, + 'company_id': self.company_data_2['company'].id, 'order_line': [(0, 0, { 'name': product.name, 'product_id': product.id, 'product_uom_qty': 10, 'product_uom': product.uom_id.id, 'price_unit': product.list_price})], - 'pricelist_id': self.env.ref('product.list0').id, + 'pricelist_id': self.company_data['default_pricelist'].id, } - so_company_B = sale_order.with_company(self.company_B).create(sale_order_vals3) + so_company_B = sale_order.with_company(self.company_data_2['company']).create(sale_order_vals3) self.assertEqual(so_company_B.warehouse_id.id, self.warehouse_B.id) diff --git a/addons/sale_timesheet/tests/common.py b/addons/sale_timesheet/tests/common.py index f957d59165c..6460ca6ff2e 100644 --- a/addons/sale_timesheet/tests/common.py +++ b/addons/sale_timesheet/tests/common.py @@ -1,14 +1,36 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.sale.tests.test_sale_common import TestCommonSaleNoChart, TestCommonSaleMultiCompanyNoChart +from odoo.addons.sale.tests.common import TestSaleCommon -class TestCommonSaleTimesheetNoChart(TestCommonSaleNoChart): +class TestCommonSaleTimesheet(TestSaleCommon): @classmethod - def setUpEmployees(cls): - # Create employees + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) + + group_employee = cls.env.ref('base.group_user') + Users = cls.env['res.users'].with_context({'no_reset_password': True, 'mail_create_nosubscribe': True, 'mail_create_nolog': True}) + cls.user_employee_company_B = Users.create({ + 'name': 'Gregor Clegane Employee', + 'login': 'gregor', + 'email': 'gregor@example.com', + 'notification_type': 'email', + 'groups_id': [(6, 0, [group_employee.id])], + 'company_id': cls.company_data_2['company'].id, + 'company_ids': [cls.company_data_2['company'].id], + }) + cls.user_manager_company_B = Users.create({ + 'name': 'Cersei Lannister Manager', + 'login': 'cersei', + 'email': 'cersei@example.com', + 'notification_type': 'email', + 'groups_id': [(6, 0, [group_employee.id])], + 'company_id': cls.company_data_2['company'].id, + 'company_ids': [cls.company_data_2['company'].id, cls.env.company.id], + }) + cls.employee_user = cls.env['hr.employee'].create({ 'name': 'Employee User', 'timesheet_cost': 15, @@ -18,19 +40,29 @@ class TestCommonSaleTimesheetNoChart(TestCommonSaleNoChart): 'timesheet_cost': 45, }) - @classmethod - def setUpServiceProducts(cls): - """ Create Service product for all kind, with each tracking policy. """ - # Account and project - cls.account_sale = cls.env['account.account'].create({ - 'code': 'SERV-2020', - 'name': 'Product Sales - (test)', - 'reconcile': True, - 'user_type_id': cls.env.ref('account.data_account_type_revenue').id, + cls.employee_company_B = cls.env['hr.employee'].create({ + 'name': 'Gregor Clegane', + 'user_id': cls.user_employee_company_B.id, + 'timesheet_cost': 15, }) + + cls.manager_company_B = cls.env['hr.employee'].create({ + 'name': 'Cersei Lannister', + 'user_id': cls.user_manager_company_B.id, + 'timesheet_cost': 45, + }) + + # Account and project + cls.account_sale = cls.company_data['default_account_revenue'] cls.analytic_account_sale = cls.env['account.analytic.account'].create({ 'name': 'Project for selling timesheet - AA', - 'code': 'AA-2030' + 'code': 'AA-2030', + 'company_id': cls.company_data['company'].id, + }) + cls.analytic_account_sale_company_B = cls.env['account.analytic.account'].create({ + 'name': 'Project for selling timesheet Company B - AA', + 'code': 'AA-2030', + 'company_id': cls.company_data_2['company'].id, }) # Create projects @@ -285,35 +317,3 @@ class TestCommonSaleTimesheetNoChart(TestCommonSaleNoChart): 'taxes_id': False, 'property_account_income_id': cls.account_sale.id, }) - - -class TestCommonSaleTimesheetMultiCompanyNoChart(TestCommonSaleMultiCompanyNoChart, TestCommonSaleTimesheetNoChart): - - @classmethod - def setUpEmployees(cls): - # Create employees - cls.setUpUsers() - super(TestCommonSaleTimesheetMultiCompanyNoChart, cls).setUpEmployees() - - cls.employee_company_B = cls.env['hr.employee'].create({ - 'name': 'Gregor Clegane', - 'user_id': cls.user_employee_company_B.id, - 'timesheet_cost': 15, - }) - - cls.manager_company_B = cls.env['hr.employee'].create({ - 'name': 'Cersei Lannister', - 'user_id': cls.user_manager_company_B.id, - 'timesheet_cost': 45, - }) - - @classmethod - def setUpServiceProducts(cls): - """ Create Service product for all kind, with each tracking policy. """ - super(TestCommonSaleTimesheetMultiCompanyNoChart, cls).setUpServiceProducts() - # Account and project - cls.analytic_account_sale_company_B = cls.env['account.analytic.account'].create({ - 'name': 'Project for selling timesheet Company B - AA', - 'code': 'AA-2030', - 'company_id': cls.company_B.id, - }) diff --git a/addons/sale_timesheet/tests/test_project_billing.py b/addons/sale_timesheet/tests/test_project_billing.py index c618997c40d..eaa9aa91fe7 100644 --- a/addons/sale_timesheet/tests/test_project_billing.py +++ b/addons/sale_timesheet/tests/test_project_billing.py @@ -1,19 +1,18 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet +from odoo.tests import tagged -from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheetNoChart -from odoo.exceptions import UserError - -class TestProjectBilling(TestCommonSaleTimesheetNoChart): +@tagged('post_install', '-at_install') +class TestProjectBilling(TestCommonSaleTimesheet): """ This test suite provide checks for miscellaneous small things. """ @classmethod - def setUpClass(cls): - super(TestProjectBilling, cls).setUpClass() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) + # set up - cls.setUpServiceProducts() - cls.setUpEmployees() cls.employee_tde = cls.env['hr.employee'].create({ 'name': 'Employee TDE', 'timesheet_cost': 42, @@ -22,17 +21,17 @@ class TestProjectBilling(TestCommonSaleTimesheetNoChart): cls.partner_2 = cls.env['res.partner'].create({ 'name': 'Customer from the South', 'email': 'customer.usd@south.com', - 'property_account_payable_id': cls.account_payable.id, - 'property_account_receivable_id': cls.account_receivable.id, + 'property_account_payable_id': cls.company_data['default_account_payable'].id, + 'property_account_receivable_id': cls.company_data['default_account_receivable'].id, }) # Sale Order 1, no project/task created, used to timesheet at employee rate SaleOrder = cls.env['sale.order'].with_context(tracking_disable=True) SaleOrderLine = cls.env['sale.order.line'].with_context(tracking_disable=True) cls.sale_order_1 = SaleOrder.create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, }) cls.so1_line_order_no_task = SaleOrderLine.create({ @@ -247,7 +246,7 @@ class TestProjectBilling(TestCommonSaleTimesheetNoChart): # create a task task = Task.with_context(default_project_id=self.project_employee_rate.id).create({ 'name': 'first task', - 'partner_id': self.partner_customer_usd.id, + 'partner_id': self.partner_a.id, }) self.assertEqual(task.billable_type, 'employee_rate', "Task in project 'employee rate' should be billed at employee rate") @@ -310,7 +309,7 @@ class TestProjectBilling(TestCommonSaleTimesheetNoChart): # create a second task in employee rate project task2 = Task.with_context(default_project_id=self.project_employee_rate.id).create({ 'name': 'first task', - 'partner_id': self.partner_customer_usd.id, + 'partner_id': self.partner_a.id, 'sale_line_id': False }) diff --git a/addons/sale_timesheet/tests/test_project_billing_multicompany.py b/addons/sale_timesheet/tests/test_project_billing_multicompany.py index 65c08c9a0d8..11c83d6eb91 100644 --- a/addons/sale_timesheet/tests/test_project_billing_multicompany.py +++ b/addons/sale_timesheet/tests/test_project_billing_multicompany.py @@ -1,15 +1,16 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheetMultiCompanyNoChart +from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet +from odoo.tests import tagged -class TestProjectBillingMulticompany(TestCommonSaleTimesheetMultiCompanyNoChart): - @classmethod - def setUpClass(cls): - super(TestProjectBillingMulticompany, cls).setUpClass() +@tagged('-at_install', 'post_install') +class TestProjectBillingMulticompany(TestCommonSaleTimesheet): - cls.setUpServiceProducts() + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) Project = cls.env['project.project'].with_context(tracking_disable=True) cls.project_non_billable = Project.create({ @@ -20,11 +21,11 @@ class TestProjectBillingMulticompany(TestCommonSaleTimesheetMultiCompanyNoChart) }) def test_makeBillable_multiCompany(self): - wizard = self.env['project.create.sale.order'].with_context(allowed_company_ids=[self.company_B.id, self.env.company.id], company_id=self.company_B.id, active_id=self.project_non_billable.id, active_model='project.project').create({ + wizard = self.env['project.create.sale.order'].with_context(allowed_company_ids=[self.company_data_2['company'].id, self.env.company.id], company_id=self.company_data_2['company'].id, active_id=self.project_non_billable.id, active_model='project.project').create({ 'product_id': self.product_delivery_timesheet3.id, # product creates new Timesheet in new Project 'price_unit': self.product_delivery_timesheet3.list_price, 'billable_type': 'project_rate', - 'partner_id': self.partner_customer_usd.id, + 'partner_id': self.partner_a.id, }) action = wizard.action_create_sale_order() diff --git a/addons/sale_timesheet/tests/test_project_overview.py b/addons/sale_timesheet/tests/test_project_overview.py index df4325d29d7..26ff7b6cde8 100644 --- a/addons/sale_timesheet/tests/test_project_overview.py +++ b/addons/sale_timesheet/tests/test_project_overview.py @@ -3,8 +3,10 @@ from odoo.addons.sale_timesheet.tests.test_reporting import TestReporting from odoo.tools import float_compare +from odoo.tests import tagged +@tagged('-at_install', 'post_install') class TestSaleProject(TestReporting): def test_project_overview_by_project(self): diff --git a/addons/sale_timesheet/tests/test_reinvoice.py b/addons/sale_timesheet/tests/test_reinvoice.py index cd4a25fbccb..43976827bae 100644 --- a/addons/sale_timesheet/tests/test_reinvoice.py +++ b/addons/sale_timesheet/tests/test_reinvoice.py @@ -1,22 +1,16 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheetNoChart -from odoo.tests import Form +from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet +from odoo.tests import Form, tagged -class TestReInvoice(TestCommonSaleTimesheetNoChart): +@tagged('-at_install', 'post_install') +class TestReInvoice(TestCommonSaleTimesheet): @classmethod - def setUpClass(cls): - super(TestReInvoice, cls).setUpClass() - - cls.setUpEmployees() - cls.setUpExpenseProducts() - cls.setUpAdditionalAccounts() - cls.setUpAccountJournal() - - cls.env.ref('product.list0').currency_id = cls.env.user.company_id.currency_id + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) # patch expense products to make them services creating task/project service_values = { @@ -24,25 +18,26 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): 'service_type': 'timesheet', 'service_tracking': 'task_in_project' } - cls.product_ordered_cost.write(service_values) - cls.product_deliver_cost.write(service_values) - cls.product_order_sales_price.write(service_values) - cls.product_deliver_sales_price.write(service_values) - cls.product_no_expense.write(service_values) + cls.company_data['product_order_cost'].write(service_values) + cls.company_data['product_delivery_cost'].write(service_values) + cls.company_data['product_order_sales_price'].write(service_values) + cls.company_data['product_delivery_sales_price'].write(service_values) + cls.company_data['product_order_no'].write(service_values) # create AA, SO and invoices cls.analytic_account = cls.env['account.analytic.account'].create({ 'name': 'Test AA', 'code': 'TESTSALE_TIMESHEET_REINVOICE', - 'company_id': cls.partner_customer_usd.company_id.id, - 'partner_id': cls.partner_customer_usd.id + 'company_id': cls.company_data['company'].id, + 'partner_id': cls.partner_a.id }) cls.sale_order = cls.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, 'analytic_account_id': cls.analytic_account.id, + 'pricelist_id': cls.company_data['default_pricelist'].id, }) cls.Invoice = cls.env['account.move'].with_context(mail_notrack=True, mail_create_nolog=True) @@ -51,20 +46,20 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): """ Test vendor bill at cost for product based on ordered and delivered quantities. """ # create SO line and confirm SO (with only one line) sale_order_line1 = self.env['sale.order.line'].create({ - 'name': self.product_ordered_cost.name, - 'product_id': self.product_ordered_cost.id, + 'name': self.company_data['product_order_cost'].name, + 'product_id': self.company_data['product_order_cost'].id, 'product_uom_qty': 2, - 'product_uom': self.product_ordered_cost.uom_id.id, - 'price_unit': self.product_ordered_cost.list_price, + 'product_uom': self.company_data['product_order_cost'].uom_id.id, + 'price_unit': self.company_data['product_order_cost'].list_price, 'order_id': self.sale_order.id, }) sale_order_line1.product_id_change() sale_order_line2 = self.env['sale.order.line'].create({ - 'name': self.product_deliver_cost.name, - 'product_id': self.product_deliver_cost.id, + 'name': self.company_data['product_delivery_cost'].name, + 'product_id': self.company_data['product_delivery_cost'].id, 'product_uom_qty': 4, - 'product_uom': self.product_deliver_cost.uom_id.id, - 'price_unit': self.product_deliver_cost.list_price, + 'product_uom': self.company_data['product_delivery_cost'].uom_id.id, + 'price_unit': self.company_data['product_delivery_cost'].list_price, 'order_id': self.sale_order.id, }) sale_order_line2.product_id_change() @@ -84,23 +79,24 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): 'task_id': task_sol1.id, 'unit_amount': 1, 'employee_id': self.employee_user.id, + 'company_id': self.company_data['company'].id, }) move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice')) - move_form.partner_id = self.partner_customer_usd + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_ordered_cost + line_form.product_id = self.company_data['product_order_cost'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_deliver_cost + line_form.product_id = self.company_data['product_delivery_cost'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account invoice_a = move_form.save() invoice_a.post() - sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.product_ordered_cost) - sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.product_deliver_cost) + sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.company_data['product_order_cost']) + sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.company_data['product_delivery_cost']) self.assertTrue(sale_order_line3, "A new sale line should have been created with ordered product") self.assertTrue(sale_order_line4, "A new sale line should have been created with delivered product") @@ -114,28 +110,28 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): self.assertFalse(sale_order_line4.task_id, "Adding a new expense SO line should not create a task (sol4)") self.assertEqual(len(self.sale_order.project_ids), 1, "SO create only one project with its service line. Adding new expense SO line should not impact that") - self.assertEqual((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.product_ordered_cost.standard_price, 3.0, 0, 0), 'Sale line is wrong after confirming vendor invoice') - self.assertEqual((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.product_deliver_cost.standard_price, 3.0, 0, 0), 'Sale line is wrong after confirming vendor invoice') + self.assertEqual((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.company_data['product_order_cost'].standard_price, 3.0, 0, 0), 'Sale line is wrong after confirming vendor invoice') + self.assertEqual((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.company_data['product_delivery_cost'].standard_price, 3.0, 0, 0), 'Sale line is wrong after confirming vendor invoice') self.assertEqual(sale_order_line3.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line should be computed by analytic amount") self.assertEqual(sale_order_line4.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line should be computed by analytic amount") # create second invoice lines and validate it move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice')) - move_form.partner_id = self.partner_customer_usd + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_ordered_cost + line_form.product_id = self.company_data['product_order_cost'] line_form.quantity = 2.0 line_form.analytic_account_id = self.analytic_account with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_deliver_cost + line_form.product_id = self.company_data['product_delivery_cost'] line_form.quantity = 2.0 line_form.analytic_account_id = self.analytic_account invoice_b = move_form.save() invoice_b.post() - sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.product_ordered_cost) - sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.product_deliver_cost) + sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.company_data['product_order_cost']) + sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.company_data['product_delivery_cost']) self.assertTrue(sale_order_line5, "A new sale line should have been created with ordered product") self.assertTrue(sale_order_line6, "A new sale line should have been created with delivered product") @@ -143,8 +139,8 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): self.assertEqual(len(self.sale_order.order_line), 6, "There should be still 4 lines on the SO, no new created") self.assertEqual(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 4, "There should be still 2 expenses lines on the SO") - self.assertEqual((sale_order_line5.price_unit, sale_order_line5.qty_delivered, sale_order_line5.product_uom_qty, sale_order_line5.qty_invoiced), (self.product_ordered_cost.standard_price, 2.0, 0, 0), 'Sale line 5 is wrong after confirming 2e vendor invoice') - self.assertEqual((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line6.product_uom_qty, sale_order_line6.qty_invoiced), (self.product_deliver_cost.standard_price, 2.0, 0, 0), 'Sale line 6 is wrong after confirming 2e vendor invoice') + self.assertEqual((sale_order_line5.price_unit, sale_order_line5.qty_delivered, sale_order_line5.product_uom_qty, sale_order_line5.qty_invoiced), (self.company_data['product_order_cost'].standard_price, 2.0, 0, 0), 'Sale line 5 is wrong after confirming 2e vendor invoice') + self.assertEqual((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line6.product_uom_qty, sale_order_line6.qty_invoiced), (self.company_data['product_delivery_cost'].standard_price, 2.0, 0, 0), 'Sale line 6 is wrong after confirming 2e vendor invoice') def test_sales_price(self): """ Test invoicing vendor bill at sales price for products based on delivered and ordered quantities. Check no existing SO line is incremented, but when invoicing a @@ -152,22 +148,22 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): """ # create SO line and confirm SO (with only one line) sale_order_line1 = self.env['sale.order.line'].create({ - 'name': self.product_deliver_sales_price.name, - 'product_id': self.product_deliver_sales_price.id, + 'name': self.company_data['product_delivery_sales_price'].name, + 'product_id': self.company_data['product_delivery_sales_price'].id, 'product_uom_qty': 2, 'qty_delivered': 1, - 'product_uom': self.product_deliver_sales_price.uom_id.id, - 'price_unit': self.product_deliver_sales_price.list_price, + 'product_uom': self.company_data['product_delivery_sales_price'].uom_id.id, + 'price_unit': self.company_data['product_delivery_sales_price'].list_price, 'order_id': self.sale_order.id, }) sale_order_line1.product_id_change() sale_order_line2 = self.env['sale.order.line'].create({ - 'name': self.product_order_sales_price.name, - 'product_id': self.product_order_sales_price.id, + 'name': self.company_data['product_order_sales_price'].name, + 'product_id': self.company_data['product_order_sales_price'].id, 'product_uom_qty': 3, 'qty_delivered': 1, - 'product_uom': self.product_order_sales_price.uom_id.id, - 'price_unit': self.product_order_sales_price.list_price, + 'product_uom': self.company_data['product_order_sales_price'].uom_id.id, + 'price_unit': self.company_data['product_order_sales_price'].list_price, 'order_id': self.sale_order.id, }) sale_order_line2.product_id_change() @@ -186,20 +182,20 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): # create invoice lines and validate it move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice')) - move_form.partner_id = self.partner_customer_usd + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_deliver_sales_price + line_form.product_id = self.company_data['product_delivery_sales_price'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_order_sales_price + line_form.product_id = self.company_data['product_order_sales_price'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account invoice_a = move_form.save() invoice_a.post() - sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.product_deliver_sales_price) - sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.product_order_sales_price) + sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.company_data['product_delivery_sales_price']) + sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.company_data['product_order_sales_price']) self.assertTrue(sale_order_line3, "A new sale line should have been created with ordered product") self.assertTrue(sale_order_line4, "A new sale line should have been created with delivered product") @@ -213,28 +209,28 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): self.assertFalse(sale_order_line4.task_id, "Adding a new expense SO line should not create a task (sol4)") self.assertEqual(len(self.sale_order.project_ids), 1, "SO create only one project with its service line. Adding new expense SO line should not impact that") - self.assertEqual((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.product_deliver_sales_price.list_price, 3.0, 0, 0), 'Sale line is wrong after confirming vendor invoice') - self.assertEqual((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.product_order_sales_price.list_price, 3.0, 0, 0), 'Sale line is wrong after confirming vendor invoice') + self.assertEqual((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.company_data['product_delivery_sales_price'].list_price, 3.0, 0, 0), 'Sale line is wrong after confirming vendor invoice') + self.assertEqual((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.company_data['product_order_sales_price'].list_price, 3.0, 0, 0), 'Sale line is wrong after confirming vendor invoice') self.assertEqual(sale_order_line3.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line 3 should be computed by analytic amount") self.assertEqual(sale_order_line4.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line 4 should be computed by analytic amount") # create second invoice lines and validate it move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice')) - move_form.partner_id = self.partner_customer_usd + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_deliver_sales_price + line_form.product_id = self.company_data['product_delivery_sales_price'] line_form.quantity = 2.0 line_form.analytic_account_id = self.analytic_account with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_order_sales_price + line_form.product_id = self.company_data['product_order_sales_price'] line_form.quantity = 2.0 line_form.analytic_account_id = self.analytic_account invoice_b = move_form.save() invoice_b.post() - sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.product_deliver_sales_price) - sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.product_order_sales_price) + sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.company_data['product_delivery_sales_price']) + sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.company_data['product_order_sales_price']) self.assertFalse(sale_order_line5, "No new sale line should have been created with delivered product !!") self.assertTrue(sale_order_line6, "A new sale line should have been created with ordered product") @@ -242,18 +238,18 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): self.assertEqual(len(self.sale_order.order_line), 5, "There should be 5 lines on the SO, 1 new created and 1 incremented") self.assertEqual(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 3, "There should be 3 expenses lines on the SO") - self.assertEqual((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line6.qty_invoiced), (self.product_order_sales_price.list_price, 2.0, 0, 0), 'Sale line is wrong after confirming 2e vendor invoice') + self.assertEqual((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line6.qty_invoiced), (self.company_data['product_order_sales_price'].list_price, 2.0, 0, 0), 'Sale line is wrong after confirming 2e vendor invoice') def test_no_expense(self): """ Test invoicing vendor bill with no policy. Check nothing happen. """ # confirm SO sale_order_line = self.env['sale.order.line'].create({ - 'name': self.product_no_expense.name, - 'product_id': self.product_no_expense.id, + 'name': self.company_data['product_order_no'].name, + 'product_id': self.company_data['product_order_no'].id, 'product_uom_qty': 2, 'qty_delivered': 1, - 'product_uom': self.product_no_expense.uom_id.id, - 'price_unit': self.product_no_expense.list_price, + 'product_uom': self.company_data['product_order_no'].uom_id.id, + 'price_unit': self.company_data['product_order_no'].list_price, 'order_id': self.sale_order.id, }) self.sale_order._compute_tax_id() @@ -261,9 +257,9 @@ class TestReInvoice(TestCommonSaleTimesheetNoChart): # create invoice lines and validate it move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice')) - move_form.partner_id = self.partner_customer_usd + move_form.partner_id = self.partner_a with move_form.line_ids.new() as line_form: - line_form.product_id = self.product_no_expense + line_form.product_id = self.company_data['product_order_no'] line_form.quantity = 3.0 line_form.analytic_account_id = self.analytic_account invoice_a = move_form.save() diff --git a/addons/sale_timesheet/tests/test_reporting.py b/addons/sale_timesheet/tests/test_reporting.py index e305001701b..158e4f974d5 100644 --- a/addons/sale_timesheet/tests/test_reporting.py +++ b/addons/sale_timesheet/tests/test_reporting.py @@ -1,23 +1,16 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.tools import float_is_zero, float_compare -from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheetNoChart +from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet +from odoo.tests import tagged -class TestReporting(TestCommonSaleTimesheetNoChart): +@tagged('-at_install', 'post_install') +class TestReporting(TestCommonSaleTimesheet): @classmethod - def setUpClass(cls): - super(TestReporting, cls).setUpClass() - - cls.setUpEmployees() - cls.setUpServiceProducts() - cls.setUpAdditionalAccounts() - cls.setUpAccountJournal() - - # tweak demo data: force currency and remove confusing rates - company_currency = cls.env.user.company_id.currency_id - cls.env.ref('product.list0').currency_id = company_currency + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) # expense product cls.product_expense = cls.env['product.product'].with_context(mail_notrack=True, mail_create_nolog=True).create({ @@ -30,28 +23,28 @@ class TestReporting(TestCommonSaleTimesheetNoChart): 'default_code': 'EXP', 'service_type': 'manual', 'taxes_id': False, - 'property_account_income_id': cls.account_sale.id, + 'property_account_income_id': cls.company_data['default_account_revenue'].id, }) # create Analytic Accounts cls.analytic_account_1 = cls.env['account.analytic.account'].create({ 'name': 'Test AA 1', 'code': 'AA1', - 'company_id': cls.partner_customer_usd.company_id.id, - 'partner_id': cls.partner_customer_usd.id + 'company_id': cls.company_data['company'].id, + 'partner_id': cls.partner_a.id }) cls.analytic_account_2 = cls.env['account.analytic.account'].create({ 'name': 'Test AA 2', 'code': 'AA2', - 'company_id': cls.partner_customer_usd.company_id.id, - 'partner_id': cls.partner_customer_usd.id + 'company_id': cls.company_data['company'].id, + 'partner_id': cls.partner_a.id }) # Sale orders each will create project and a task in a global project (one SO is 'delivered', the other is 'ordered') cls.sale_order_1 = cls.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, 'analytic_account_id': cls.analytic_account_1.id, }) cls.so_line_deliver_project = cls.env['sale.order.line'].create({ @@ -72,9 +65,9 @@ class TestReporting(TestCommonSaleTimesheetNoChart): }) cls.sale_order_2 = cls.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, 'analytic_account_id': cls.analytic_account_2.id, }) cls.so_line_order_project = cls.env['sale.order.line'].create({ diff --git a/addons/sale_timesheet/tests/test_sale_service.py b/addons/sale_timesheet/tests/test_sale_service.py index ff72ac84b70..b85695e092d 100644 --- a/addons/sale_timesheet/tests/test_sale_service.py +++ b/addons/sale_timesheet/tests/test_sale_service.py @@ -1,24 +1,23 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheetNoChart +from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet from odoo.exceptions import UserError, ValidationError +from odoo.tests import tagged -class TestSaleService(TestCommonSaleTimesheetNoChart): +@tagged('-at_install', 'post_install') +class TestSaleService(TestCommonSaleTimesheet): """ This test suite provide checks for miscellaneous small things. """ @classmethod - def setUpClass(cls): - super(TestSaleService, cls).setUpClass() - # set up - cls.setUpEmployees() - cls.setUpServiceProducts() + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) cls.sale_order = cls.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({ - 'partner_id': cls.partner_customer_usd.id, - 'partner_invoice_id': cls.partner_customer_usd.id, - 'partner_shipping_id': cls.partner_customer_usd.id, + 'partner_id': cls.partner_a.id, + 'partner_invoice_id': cls.partner_a.id, + 'partner_shipping_id': cls.partner_a.id, }) def test_sale_service(self): diff --git a/addons/sale_timesheet/tests/test_sale_timesheet.py b/addons/sale_timesheet/tests/test_sale_timesheet.py index 80986ba24f8..add615452e0 100644 --- a/addons/sale_timesheet/tests/test_sale_timesheet.py +++ b/addons/sale_timesheet/tests/test_sale_timesheet.py @@ -5,10 +5,12 @@ from datetime import date, timedelta from odoo.fields import Date from odoo.tools import float_is_zero from odoo.exceptions import UserError -from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheetNoChart +from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet +from odoo.tests import tagged -class TestSaleTimesheet(TestCommonSaleTimesheetNoChart): +@tagged('-at_install', 'post_install') +class TestSaleTimesheet(TestCommonSaleTimesheet): """ This test suite provide tests for the 3 main flows of selling services: - Selling services based on ordered quantities - Selling timesheet based on delivered quantities @@ -17,15 +19,6 @@ class TestSaleTimesheet(TestCommonSaleTimesheetNoChart): quantities changes, ... """ - @classmethod - def setUpClass(cls): - super(TestSaleTimesheet, cls).setUpClass() - # set up - cls.setUpEmployees() - cls.setUpServiceProducts() - cls.setUpAdditionalAccounts() - cls.setUpAccountJournal() - def test_timesheet_order(self): """ Test timesheet invoicing with 'invoice on order' timetracked products 1. create SO with 2 ordered product and confirm @@ -36,10 +29,10 @@ class TestSaleTimesheet(TestCommonSaleTimesheetNoChart): """ # create SO and confirm it sale_order = self.env['sale.order'].create({ - 'partner_id': self.partner_customer_usd.id, - 'partner_invoice_id': self.partner_customer_usd.id, - 'partner_shipping_id': self.partner_customer_usd.id, - 'pricelist_id': self.pricelist_usd.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, }) so_line_ordered_project_only = self.env['sale.order.line'].create({ 'name': self.product_order_timesheet4.name, @@ -173,12 +166,11 @@ class TestSaleTimesheet(TestCommonSaleTimesheetNoChart): 6. add new SO line (delivered service) """ # create SO and confirm it - self.env['res.currency.rate'].search([]).unlink() sale_order = self.env['sale.order'].create({ - 'partner_id': self.partner_customer_usd.id, - 'partner_invoice_id': self.partner_customer_usd.id, - 'partner_shipping_id': self.partner_customer_usd.id, - 'pricelist_id': self.pricelist_usd.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, }) so_line_deliver_global_project = self.env['sale.order.line'].create({ 'name': self.product_delivery_timesheet2.name, @@ -309,10 +301,10 @@ class TestSaleTimesheet(TestCommonSaleTimesheetNoChart): """ # create SO and confirm it sale_order = self.env['sale.order'].create({ - 'partner_id': self.partner_customer_usd.id, - 'partner_invoice_id': self.partner_customer_usd.id, - 'partner_shipping_id': self.partner_customer_usd.id, - 'pricelist_id': self.pricelist_usd.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, }) so_line_manual_global_project = self.env['sale.order.line'].create({ 'name': self.product_delivery_manual2.name, @@ -396,10 +388,10 @@ class TestSaleTimesheet(TestCommonSaleTimesheetNoChart): """ today = Date.context_today(self.env.user) sale_order = self.env['sale.order'].create({ - 'partner_id': self.partner_customer_usd.id, - 'partner_invoice_id': self.partner_customer_usd.id, - 'partner_shipping_id': self.partner_customer_usd.id, - 'pricelist_id': self.pricelist_usd.id, + 'partner_id': self.partner_a.id, + 'partner_invoice_id': self.partner_a.id, + 'partner_shipping_id': self.partner_a.id, + 'pricelist_id': self.company_data['default_pricelist'].id, }) so_line_deliver_global_project = self.env['sale.order.line'].create({ 'name': self.product_delivery_timesheet2.name, @@ -469,7 +461,7 @@ class TestSaleTimesheet(TestCommonSaleTimesheetNoChart): 'active_model': 'sale.order', 'active_ids': [sale_order.id], 'active_id': sale_order.id, - 'default_journal_id': self.journal_sale.id + 'default_journal_id': self.company_data['default_journal_sale'].id } # invoice SO @@ -530,7 +522,7 @@ class TestSaleTimesheet(TestCommonSaleTimesheetNoChart): task = Task.with_context(default_project_id=self.project_global.id).create({ 'name': 'first task', - 'partner_id': self.partner_customer_usd.id, + 'partner_id': self.partner_a.id, 'planned_hours': 10, }) @@ -569,7 +561,7 @@ class TestSaleTimesheet(TestCommonSaleTimesheetNoChart): 'active_model': 'sale.order', 'active_ids': [sale_order.id], 'active_id': sale_order.id, - 'default_journal_id': self.journal_sale.id + 'default_journal_id': self.company_data['default_journal_sale'].id } wizard = self.env['sale.advance.payment.inv'].with_context(self.context).create({ 'advance_payment_method': 'delivered', |
