summaryrefslogtreecommitdiff
path: root/addons/hr_expense/tests/test_expenses.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/hr_expense/tests/test_expenses.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/hr_expense/tests/test_expenses.py')
-rw-r--r--addons/hr_expense/tests/test_expenses.py294
1 files changed, 294 insertions, 0 deletions
diff --git a/addons/hr_expense/tests/test_expenses.py b/addons/hr_expense/tests/test_expenses.py
new file mode 100644
index 00000000..566e187b
--- /dev/null
+++ b/addons/hr_expense/tests/test_expenses.py
@@ -0,0 +1,294 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo.addons.hr_expense.tests.common import TestExpenseCommon
+from odoo.tests import tagged, Form
+from odoo import fields
+from odoo.exceptions import UserError
+
+
+@tagged('-at_install', 'post_install')
+class TestExpenses(TestExpenseCommon):
+
+ def test_expense_values(self):
+ """ Checking accounting move entries and analytic entries when submitting expense """
+
+ # The expense employee is able to a create an expense sheet.
+ # The total should be 1725.0 because:
+ # - first line: 1000.0 (unit amount) + 150.0 (tax) = 1150.0
+ # - second line: (1500.0 (unit amount) + 225.0 (tax)) * 1/3 (rate) = 575.0.
+
+ expense_sheet = self.env['hr.expense.sheet'].create({
+ 'name': 'First Expense for employee',
+ 'employee_id': self.expense_employee.id,
+ 'journal_id': self.company_data['default_journal_purchase'].id,
+ 'accounting_date': '2017-01-01',
+ 'expense_line_ids': [
+ (0, 0, {
+ # Expense without foreign currency.
+ 'name': 'expense_1',
+ 'date': '2016-01-01',
+ 'product_id': self.product_a.id,
+ 'unit_amount': 1000.0,
+ 'tax_ids': [(6, 0, self.company_data['default_tax_purchase'].ids)],
+ 'analytic_account_id': self.analytic_account_1.id,
+ 'employee_id': self.expense_employee.id,
+ }),
+ (0, 0, {
+ # Expense with foreign currency (rate 1:3).
+ 'name': 'expense_1',
+ 'date': '2016-01-01',
+ 'product_id': self.product_b.id,
+ 'unit_amount': 1500.0,
+ 'tax_ids': [(6, 0, self.company_data['default_tax_purchase'].ids)],
+ 'analytic_account_id': self.analytic_account_2.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'employee_id': self.expense_employee.id,
+ }),
+ ],
+ })
+
+ # Check expense sheet values.
+ self.assertRecordValues(expense_sheet, [{'state': 'draft', 'total_amount': 1725.0}])
+
+ expense_sheet.action_submit_sheet()
+ expense_sheet.approve_expense_sheets()
+ expense_sheet.action_sheet_move_create()
+
+ # Check expense sheet journal entry values.
+ self.assertRecordValues(expense_sheet.account_move_id.line_ids.sorted('balance'), [
+ # Receivable line (company currency):
+ {
+ 'debit': 0.0,
+ 'credit': 1150.0,
+ 'amount_currency': -1150.0,
+ 'account_id': self.company_data['default_account_payable'].id,
+ 'product_id': False,
+ 'currency_id': self.company_data['currency'].id,
+ 'tax_line_id': False,
+ 'analytic_account_id': False,
+ },
+ # Receivable line (foreign currency):
+ {
+ 'debit': 0.0,
+ 'credit': 862.5,
+ 'amount_currency': -1725.0,
+ 'account_id': self.company_data['default_account_payable'].id,
+ 'product_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'tax_line_id': False,
+ 'analytic_account_id': False,
+ },
+ # Tax line (foreign currency):
+ {
+ 'debit': 112.5,
+ 'credit': 0.0,
+ 'amount_currency': 225.0,
+ 'account_id': self.company_data['default_account_tax_purchase'].id,
+ 'product_id': False,
+ 'currency_id': self.currency_data['currency'].id,
+ 'tax_line_id': self.company_data['default_tax_purchase'].id,
+ 'analytic_account_id': False,
+ },
+ # Tax line (company currency):
+ {
+ 'debit': 150.0,
+ 'credit': 0.0,
+ 'amount_currency': 150.0,
+ 'account_id': self.company_data['default_account_tax_purchase'].id,
+ 'product_id': False,
+ 'currency_id': self.company_data['currency'].id,
+ 'tax_line_id': self.company_data['default_tax_purchase'].id,
+ 'analytic_account_id': False,
+ },
+ # Product line (foreign currency):
+ {
+ 'debit': 750.0,
+ 'credit': 0.0,
+ 'amount_currency': 1500.0,
+ 'account_id': self.company_data['default_account_expense'].id,
+ 'product_id': self.product_b.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'tax_line_id': False,
+ 'analytic_account_id': self.analytic_account_2.id,
+ },
+ # Product line (company currency):
+ {
+ 'debit': 1000.0,
+ 'credit': 0.0,
+ 'amount_currency': 1000.0,
+ 'account_id': self.company_data['default_account_expense'].id,
+ 'product_id': self.product_a.id,
+ 'currency_id': self.company_data['currency'].id,
+ 'tax_line_id': False,
+ 'analytic_account_id': self.analytic_account_1.id,
+ },
+ ])
+
+ # Check expense analytic lines.
+ self.assertRecordValues(expense_sheet.account_move_id.line_ids.analytic_line_ids.sorted('amount'), [
+ {
+ 'amount': -1000.0,
+ 'date': fields.Date.from_string('2017-01-01'),
+ 'account_id': self.analytic_account_1.id,
+ 'currency_id': self.company_data['currency'].id,
+ },
+ {
+ 'amount': -750.0,
+ 'date': fields.Date.from_string('2017-01-01'),
+ 'account_id': self.analytic_account_2.id,
+ 'currency_id': self.company_data['currency'].id,
+ },
+ ])
+
+ def test_account_entry_multi_currency(self):
+ """ Checking accounting move entries and analytic entries when submitting expense. With
+ multi-currency. And taxes. """
+
+ # Clean-up the rates
+ self.cr.execute("UPDATE res_company SET currency_id = %s WHERE id = %s", [self.env.ref('base.USD').id, self.env.company.id])
+ self.env['res.currency.rate'].search([]).unlink()
+ self.env['res.currency.rate'].create({
+ 'currency_id': self.env.ref('base.EUR').id,
+ 'company_id': self.env.company.id,
+ 'rate': 2.0,
+ 'name': '2010-01-01',
+ })
+
+ expense = self.env['hr.expense.sheet'].create({
+ 'name': 'Expense for Dick Tracy',
+ 'employee_id': self.expense_employee.id,
+ })
+ tax = self.env['account.tax'].create({
+ 'name': 'Expense 10%',
+ 'amount': 10,
+ 'amount_type': 'percent',
+ 'type_tax_use': 'purchase',
+ 'price_include': True,
+ })
+ expense_line = self.env['hr.expense'].create({
+ 'name': 'Choucroute Saucisse',
+ 'employee_id': self.expense_employee.id,
+ 'product_id': self.product_a.id,
+ 'unit_amount': 700.00,
+ 'tax_ids': [(6, 0, tax.ids)],
+ 'sheet_id': expense.id,
+ 'analytic_account_id': self.analytic_account_1.id,
+ 'currency_id': self.env.ref('base.EUR').id,
+ })
+
+ # State should default to draft
+ self.assertEqual(expense.state, 'draft', 'Expense should be created in Draft state')
+ # Submitted to Manager
+ expense.action_submit_sheet()
+ self.assertEqual(expense.state, 'submit', 'Expense is not in Reported state')
+ # Approve
+ expense.approve_expense_sheets()
+ self.assertEqual(expense.state, 'approve', 'Expense is not in Approved state')
+ # Create Expense Entries
+ expense.action_sheet_move_create()
+ self.assertEqual(expense.state, 'post', 'Expense is not in Waiting Payment state')
+ self.assertTrue(expense.account_move_id.id, 'Expense Journal Entry is not created')
+
+ # Should get this result [(0.0, 350.0, -700.0), (318.18, 0.0, 636.36), (31.82, 0.0, 63.64)]
+ for line in expense.account_move_id.line_ids:
+ if line.credit:
+ self.assertAlmostEqual(line.credit, 350.0)
+ self.assertAlmostEqual(line.amount_currency, -700.0)
+ self.assertEqual(len(line.analytic_line_ids), 0, "The credit move line should not have analytic lines")
+ self.assertFalse(line.product_id, "Product of credit move line should be false")
+ else:
+ if not line.tax_line_id == tax:
+ self.assertAlmostEqual(line.debit, 318.18)
+ self.assertAlmostEqual(line.amount_currency, 636.36)
+ self.assertEqual(len(line.analytic_line_ids), 1, "The debit move line should have 1 analytic lines")
+ self.assertEqual(line.product_id, self.product_a, "Product of debit move line should be the one from the expense")
+ else:
+ self.assertEqual(line.tax_base_amount, 318.18)
+ self.assertAlmostEqual(line.debit, 31.82)
+ self.assertAlmostEqual(line.amount_currency, 63.64)
+ self.assertEqual(len(line.analytic_line_ids), 0, "The tax move line should not have analytic lines")
+ self.assertFalse(line.product_id, "Product of tax move line should be false")
+
+ def test_expenses_with_tax_and_lockdate(self):
+ ''' Test creating a journal entry for multiple expenses using taxes. A lock date is set in order to trigger
+ the recomputation of the taxes base amount.
+ '''
+ self.env.company.tax_lock_date = '2020-02-01'
+
+ expense = self.env['hr.expense.sheet'].create({
+ 'name': 'Expense for John Smith',
+ 'employee_id': self.expense_employee.id,
+ 'accounting_date': '2020-01-01'
+ })
+
+ for i in range(2):
+ expense_line = self.env['hr.expense'].create({
+ 'name': 'Car Travel Expenses',
+ 'employee_id': self.expense_employee.id,
+ 'product_id': self.product_a.id,
+ 'unit_amount': 350.00,
+ 'tax_ids': [(6, 0, [self.tax_purchase_a.id])],
+ 'sheet_id': expense.id,
+ 'analytic_account_id': self.analytic_account_1.id,
+ })
+ expense_line._onchange_product_id_date_account_id()
+
+ expense.action_submit_sheet()
+ expense.approve_expense_sheets()
+
+ # Assert not "Cannot create unbalanced journal entry" error.
+ expense.action_sheet_move_create()
+
+ def test_reconcile_payment(self):
+ tax = self.env['account.tax'].create({
+ 'name': 'tax abc',
+ 'type_tax_use': 'purchase',
+ 'amount_type': 'percent',
+ 'amount': 15,
+ 'price_include': False,
+ 'include_base_amount': False,
+ 'tax_exigibility': 'on_payment'
+ })
+ current_assets_type = self.env.ref('account.data_account_type_current_assets')
+ company = self.env.company.id
+ tax.cash_basis_transition_account_id = self.env['account.account'].create({
+ 'name': "test",
+ 'code': 999991,
+ 'reconcile': True,
+ 'user_type_id': current_assets_type.id,
+ 'company_id': company,
+ }).id
+
+ sheet = self.env['hr.expense.sheet'].create({
+ 'company_id': company,
+ 'employee_id': self.expense_employee.id,
+ 'name': 'test sheet',
+ 'expense_line_ids': [
+ (0, 0, {
+ 'name': 'expense_1',
+ 'date': '2016-01-01',
+ 'product_id': self.product_a.id,
+ 'unit_amount': 10.0,
+ 'employee_id': self.expense_employee.id,
+ 'tax_ids': tax
+ }),
+ (0, 0, {
+ 'name': 'expense_2',
+ 'date': '2016-01-01',
+ 'product_id': self.product_a.id,
+ 'unit_amount': 1.0,
+ 'employee_id': self.expense_employee.id,
+ 'tax_ids': tax
+ }),
+ ],
+ })
+
+
+ #actions
+ sheet.action_submit_sheet()
+ sheet.approve_expense_sheets()
+ sheet.action_sheet_move_create()
+ action_data = sheet.action_register_payment()
+ wizard = Form(self.env['account.payment.register'].with_context(action_data['context'])).save()
+ wizard.action_create_payments()
+ self.assertEqual(sheet.state, 'done', 'all account.move.line linked to expenses must be reconciled after payment')