[IMP] sale_expense: add test cases
This commit is contained in:
@@ -1 +1,5 @@
|
||||
from . import test_expenses
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import common
|
||||
from . import test_expenses
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
class CommonTest(common.SavepointCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(CommonTest, cls).setUpClass()
|
||||
|
||||
# Create payable account for the expense
|
||||
user_type = cls.env.ref('account.data_account_type_payable')
|
||||
cls.account_payable = cls.env['account.account'].create({
|
||||
'code': 'X1111',
|
||||
'name': 'HR Expense - Test Payable Account',
|
||||
'user_type_id': user_type.id,
|
||||
'reconcile': True
|
||||
})
|
||||
|
||||
# Create expenses account for the expense
|
||||
user_type = cls.env.ref('account.data_account_type_expenses')
|
||||
cls.account_expense = cls.env['account.account'].create({
|
||||
'code': 'X2120',
|
||||
'name': 'HR Expense - Test Purchase Account',
|
||||
'user_type_id': user_type.id
|
||||
})
|
||||
|
||||
# User groups
|
||||
user_group_employee = cls.env.ref('base.group_user')
|
||||
user_group_manager = cls.env.ref('hr_expense.group_hr_expense_manager')
|
||||
|
||||
# User and Employee Data
|
||||
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': 'Johnny Employee',
|
||||
'login': 'john',
|
||||
'email': 'john@example.com',
|
||||
'notification_type': 'email',
|
||||
'groups_id': [(6, 0, [user_group_employee.id])],
|
||||
})
|
||||
cls.user_manager = Users.create({
|
||||
'name': 'Robert Manager',
|
||||
'login': 'rob',
|
||||
'email': 'rob@example.com',
|
||||
'notification_type': 'email',
|
||||
'groups_id': [(6, 0, [user_group_manager.id])],
|
||||
})
|
||||
cls.employee = cls.env['hr.employee'].create({
|
||||
'name': 'Johnny Employee',
|
||||
'address_home_id': cls.user_employee.partner_id.id,
|
||||
'address_id': cls.user_employee.partner_id.id,
|
||||
})
|
||||
cls.user_manager.partner_id.write({'property_account_payable_id': cls.account_payable.id})
|
||||
cls.user_employee.partner_id.write({'property_account_payable_id': cls.account_payable.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.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.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.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.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.id,
|
||||
})
|
||||
|
||||
# Expense report
|
||||
cls.journal = cls.env['account.journal'].create({
|
||||
'name': 'Purchase Journal - Test',
|
||||
'code': 'HRTPJ',
|
||||
'type': 'purchase',
|
||||
'company_id': cls.env.user.company_id.id,
|
||||
})
|
||||
cls.expense_sheet = cls.env['hr.expense.sheet'].create({
|
||||
'name': 'Expense for Johnny Employee',
|
||||
'employee_id': cls.employee.id,
|
||||
'journal_id': cls.journal.id,
|
||||
})
|
||||
@@ -1 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_sale_expense
|
||||
from . import test_reinvoice
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.hr_expense.tests.common import CommonTest
|
||||
|
||||
|
||||
class TestReInvoice(CommonTest):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestReInvoice, cls).setUpClass()
|
||||
|
||||
cls.partner_customer = cls.env['res.partner'].create({
|
||||
'name': 'Ze Client',
|
||||
'email': 'client@agrolait.com',
|
||||
'property_account_payable_id': cls.account_payable.id,
|
||||
})
|
||||
|
||||
cls.sale_order = cls.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({
|
||||
'partner_id': cls.partner_customer.id,
|
||||
'partner_invoice_id': cls.partner_customer.id,
|
||||
'partner_shipping_id': cls.partner_customer.id,
|
||||
})
|
||||
|
||||
def test_at_cost(self):
|
||||
""" Test invoicing expenses at cost for product based on delivered and ordered quantities. """
|
||||
# create SO line and confirm SO (with only one line)
|
||||
sale_order_line = self.env['sale.order.line'].create({
|
||||
'name': self.product_ordered_cost.name,
|
||||
'product_id': self.product_ordered_cost.id,
|
||||
'product_uom_qty': 2,
|
||||
'product_uom': self.product_ordered_cost.uom_id.id,
|
||||
'price_unit': self.product_ordered_cost.list_price,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
sale_order_line.product_id_change()
|
||||
self.sale_order.onchange_partner_id()
|
||||
self.sale_order._compute_tax_id()
|
||||
self.sale_order.action_confirm()
|
||||
|
||||
self.assertTrue(self.sale_order.analytic_account_id, "Confirming SO with an expense product should trigger the analytic account creation")
|
||||
|
||||
# create expense lines
|
||||
expense1 = self.env['hr.expense'].create({
|
||||
'name': 'Expense for ordered product',
|
||||
'employee_id': self.employee.id,
|
||||
'product_id': self.product_ordered_cost.id,
|
||||
'unit_amount': 12,
|
||||
'quantity': 2,
|
||||
'sheet_id': self.expense_sheet.id,
|
||||
'sale_order_id': self.sale_order.id,
|
||||
'analytic_account_id': self.sale_order.analytic_account_id.id,
|
||||
})
|
||||
expense1._onchange_product_id()
|
||||
expense2 = self.env['hr.expense'].create({
|
||||
'name': 'Expense for delivered product',
|
||||
'employee_id': self.employee.id,
|
||||
'product_id': self.product_deliver_cost.id,
|
||||
'unit_amount': 15,
|
||||
'quantity': 1,
|
||||
'sheet_id': self.expense_sheet.id,
|
||||
'sale_order_id': self.sale_order.id,
|
||||
'analytic_account_id': self.sale_order.analytic_account_id.id,
|
||||
})
|
||||
expense2._onchange_product_id()
|
||||
|
||||
# approve and generate entries
|
||||
self.expense_sheet.approve_expense_sheets()
|
||||
self.expense_sheet.action_sheet_move_create()
|
||||
|
||||
self.assertEquals(len(self.sale_order.order_line), 3, "There should be 3 lines on the SO")
|
||||
self.assertEquals(sale_order_line.qty_delivered, 0, "Exising SO line should not be impacted by reinvoicing product at cost")
|
||||
|
||||
sol_ordered = self.sale_order.order_line.filtered(lambda sol: sol.product_id == self.product_ordered_cost and sol != sale_order_line)
|
||||
self.assertTrue(sol_ordered, "A new line with ordered expense should have been created on expense report posting")
|
||||
self.assertEquals(sol_ordered.price_unit, expense1.unit_amount, "The unit price of new SO line should be the one from the expense (at cost)")
|
||||
self.assertEquals(sol_ordered.product_uom_qty, 0, "The ordered quantity of new SO line should be zero")
|
||||
self.assertEquals(sol_ordered.qty_delivered, expense1.quantity, "The delivered quantity of new SO line should be the one from the expense")
|
||||
|
||||
sol_deliver = self.sale_order.order_line.filtered(lambda sol: sol.product_id == self.product_deliver_cost and sol != sale_order_line)
|
||||
self.assertTrue(sol_deliver, "A new line with delivered expense should have been created on expense report posting")
|
||||
self.assertEquals(sol_deliver.price_unit, expense2.unit_amount, "The unit price of new SO line should be the one from the expense (at cost)")
|
||||
self.assertEquals(sol_deliver.product_uom_qty, 0, "The ordered quantity of new SO line should be zero")
|
||||
self.assertEquals(sol_deliver.qty_delivered, expense2.quantity, "The delivered quantity of new SO line should be the one from the expense")
|
||||
|
||||
def test_sales_price_ordered(self):
|
||||
""" Test invoicing expenses at sales price for product based on ordered quantities. """
|
||||
# confirm SO (with no line)
|
||||
self.sale_order._compute_tax_id()
|
||||
self.sale_order.action_confirm()
|
||||
self.assertFalse(self.sale_order.analytic_account_id, "Confirming SO with no expense product should not trigger the analytic account creation")
|
||||
|
||||
# create expense lines
|
||||
expense1 = self.env['hr.expense'].create({
|
||||
'name': 'Expense for ordered product at sales price',
|
||||
'employee_id': self.employee.id,
|
||||
'product_id': self.product_order_sales_price.id,
|
||||
'unit_amount': 15,
|
||||
'quantity': 2,
|
||||
'sheet_id': self.expense_sheet.id,
|
||||
'sale_order_id': self.sale_order.id,
|
||||
'analytic_account_id': self.sale_order.analytic_account_id.id,
|
||||
})
|
||||
expense1._onchange_product_id()
|
||||
|
||||
# approve and generate entries
|
||||
self.expense_sheet.approve_expense_sheets()
|
||||
self.expense_sheet.action_sheet_move_create()
|
||||
|
||||
self.assertTrue(self.sale_order.analytic_account_id, "Posting expense with an expense product should trigger the analytic account creation on SO")
|
||||
self.assertEquals(self.sale_order.analytic_account_id, expense1.analytic_account_id, "SO analytic account should be the same for the expense")
|
||||
self.assertEquals(len(self.sale_order.order_line), 1, "A new So line should have been created on expense report posting")
|
||||
|
||||
sol_ordered = self.sale_order.order_line.filtered(lambda sol: sol.product_id == expense1.product_id)
|
||||
self.assertTrue(sol_ordered, "A new line with ordered expense should have been created on expense report posting")
|
||||
self.assertEquals(sol_ordered.price_unit, 10, "The unit price of new SO line should be the one from the expense (at sales price)")
|
||||
self.assertEquals(sol_ordered.product_uom_qty, 0, "The ordered quantity of new SO line should be zero")
|
||||
self.assertEquals(sol_ordered.qty_delivered, expense1.quantity, "The delivered quantity of new SO line should be the one from the expense")
|
||||
|
||||
def test_sales_price_delivered(self):
|
||||
""" Test invoicing expenses at sales price for product based on delivered quantities. Check the existing SO line is incremented. """
|
||||
# create SO line and confirm SO (with only one line)
|
||||
sale_order_line = self.env['sale.order.line'].create({
|
||||
'name': self.product_deliver_sales_price.name,
|
||||
'product_id': self.product_deliver_sales_price.id,
|
||||
'product_uom_qty': 2,
|
||||
'product_uom': self.product_deliver_sales_price.uom_id.id,
|
||||
'price_unit': self.product_deliver_sales_price.list_price,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
sale_order_line.product_id_change()
|
||||
self.sale_order._compute_tax_id()
|
||||
self.sale_order.action_confirm()
|
||||
|
||||
self.assertTrue(self.sale_order.analytic_account_id, "Confirming SO with an expense product should trigger the analytic account creation")
|
||||
|
||||
# create expense lines
|
||||
expense1 = self.env['hr.expense'].create({
|
||||
'name': 'Expense for delivered product at sales price',
|
||||
'employee_id': self.employee.id,
|
||||
'product_id': self.product_deliver_sales_price.id,
|
||||
'unit_amount': 15,
|
||||
'quantity': 3,
|
||||
'sheet_id': self.expense_sheet.id,
|
||||
'sale_order_id': self.sale_order.id,
|
||||
'analytic_account_id': self.sale_order.analytic_account_id.id,
|
||||
})
|
||||
expense1._onchange_product_id()
|
||||
|
||||
# approve and generate entries
|
||||
self.expense_sheet.approve_expense_sheets()
|
||||
self.expense_sheet.action_sheet_move_create()
|
||||
|
||||
self.assertEquals(len(self.sale_order.order_line), 1, "No SO line should have been created (or removed) on expense report posting")
|
||||
|
||||
self.assertEquals(sale_order_line.price_unit, 10, "The unit price of SO line should be the same")
|
||||
self.assertEquals(sale_order_line.product_uom_qty, 2, "The ordered quantity of new SO line should be zero")
|
||||
self.assertEquals(sale_order_line.qty_delivered, expense1.quantity, "The delivered quantity of SO line should have been incremented")
|
||||
|
||||
def test_no_expense(self):
|
||||
""" Test invoicing expenses 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,
|
||||
'product_uom_qty': 2,
|
||||
'product_uom': self.product_no_expense.uom_id.id,
|
||||
'price_unit': self.product_no_expense.list_price,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
self.sale_order._compute_tax_id()
|
||||
self.sale_order.action_confirm()
|
||||
|
||||
self.assertFalse(self.sale_order.analytic_account_id, "Confirming SO with an no-expense product should not trigger the analytic account creation")
|
||||
|
||||
# create expense lines
|
||||
expense1 = self.env['hr.expense'].create({
|
||||
'name': 'Expense for no expense product',
|
||||
'employee_id': self.employee.id,
|
||||
'product_id': self.product_no_expense.id,
|
||||
'unit_amount': 15,
|
||||
'quantity': 3,
|
||||
'sheet_id': self.expense_sheet.id,
|
||||
'sale_order_id': self.sale_order.id,
|
||||
'analytic_account_id': self.sale_order.analytic_account_id.id,
|
||||
})
|
||||
expense1._onchange_product_id()
|
||||
|
||||
# approve and generate entries
|
||||
self.expense_sheet.approve_expense_sheets()
|
||||
self.expense_sheet.action_sheet_move_create()
|
||||
|
||||
self.assertTrue(self.sale_order.analytic_account_id, "Posting expense with an expense product (even with no expense pilocy) should trigger the analytic account creation")
|
||||
self.assertEquals(self.sale_order.analytic_account_id, expense1.analytic_account_id, "SO analytic account should be the same for the expense")
|
||||
self.assertEquals(len(self.sale_order.order_line), 1, "No SO line should have been created (or removed) on expense report posting")
|
||||
|
||||
self.assertEquals(sale_order_line.price_unit, self.product_no_expense.list_price, "The unit price of SO line should be the same")
|
||||
self.assertEquals(sale_order_line.product_uom_qty, 2, "The ordered quantity of SO line should be two")
|
||||
self.assertEquals(sale_order_line.qty_delivered, 0, "The delivered quantity of SO line should have been incremented")
|
||||
Reference in New Issue
Block a user