[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
This commit is contained in:
Laurent Smet
2020-07-31 08:38:30 +00:00
parent dc1fccf699
commit 6d1e1e09ea
32 changed files with 1204 additions and 1600 deletions
+68 -101
View File
@@ -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',
@@ -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')
+1
View File
@@ -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
+199
View File
@@ -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
+48 -77
View File
@@ -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):
class TestAccessRights(TestSaleCommon):
def setUp(self):
super(TestAccessRights, self).setUp()
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
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])]
})
# 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()
+61 -72
View File
@@ -1,32 +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 TestCommonSaleNoChart
from odoo.tests import Form
from odoo.addons.sale.tests.common import TestSaleCommon
from odoo.tests import Form, tagged
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")
-416
View File
@@ -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,
})
+82
View File
@@ -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},
])
+51 -102
View File
@@ -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. """
+40 -52
View File
@@ -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
+27 -30
View File
@@ -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'
})
+49 -52
View File
@@ -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
+19 -35
View File
@@ -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):
@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,
})
class TestReInvoice(TestExpenseCommon, TestSaleCommon):
def test_expenses_reinvoice(self):
(self.company_data['product_order_sales_price'] + self.company_data['product_delivery_sales_price']).write({
'can_be_expensed': True,
})
# 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'},
])
+23 -36
View File
@@ -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,
})
@@ -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):
+5 -18
View File
@@ -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({
@@ -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
})
@@ -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,
})
@@ -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.')
@@ -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'
@@ -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',
+81 -58
View File
@@ -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)
@@ -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.')
@@ -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)
+46 -46
View File
@@ -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,
})
@@ -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 TestCommonSaleTimesheetNoChart
from odoo.exceptions import UserError
from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheet
from odoo.tests import tagged
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
})
@@ -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):
@tagged('-at_install', 'post_install')
class TestProjectBillingMulticompany(TestCommonSaleTimesheet):
@classmethod
def setUpClass(cls):
super(TestProjectBillingMulticompany, cls).setUpClass()
cls.setUpServiceProducts()
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()
@@ -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):
+67 -71
View File
@@ -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()
+17 -24
View File
@@ -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({
@@ -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):
@@ -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',