changeset 675bdc9d556b in modules/account:default
details: https://hg.tryton.org/modules/account?cmd=changeset&node=675bdc9d556b
description:
Replace test setuptools command by unittest discover
issue9215
review389851002
diffstat:
setup.py | 6 +-
tests/__init__.py | 8 +-
tests/test_account.py | 1808 ------------------------------------------------
tests/test_module.py | 1740 ++++++++++++++++++++++++++++++++++++++++++++++
tests/test_scenario.py | 22 +
tox.ini | 3 +-
6 files changed, 1769 insertions(+), 1818 deletions(-)
diffs (3632 lines):
diff -r f17e81152e14 -r 675bdc9d556b setup.py
--- a/setup.py Tue Apr 12 10:26:25 2022 +0200
+++ b/setup.py Sat Apr 16 18:30:15 2022 +0200
@@ -141,13 +141,13 @@
license='GPL-3',
python_requires='>=3.7',
install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
dependency_links=dependency_links,
zip_safe=False,
entry_points="""
[trytond.modules]
account = trytond.modules.account
""",
- test_suite='tests',
- test_loader='trytond.test_loader:Loader',
- tests_require=tests_require,
)
diff -r f17e81152e14 -r 675bdc9d556b tests/__init__.py
--- a/tests/__init__.py Tue Apr 12 10:26:25 2022 +0200
+++ b/tests/__init__.py Sat Apr 16 18:30:15 2022 +0200
@@ -1,10 +1,6 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
-try:
- from trytond.modules.account.tests.test_account import (
- create_chart, get_fiscalyear, suite)
-except ImportError:
- from .test_account import create_chart, get_fiscalyear, suite
+from .test_module import create_chart, get_fiscalyear
-__all__ = ['suite', 'create_chart', 'get_fiscalyear']
+__all__ = ['create_chart', 'get_fiscalyear']
diff -r f17e81152e14 -r 675bdc9d556b tests/test_account.py
--- a/tests/test_account.py Tue Apr 12 10:26:25 2022 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1808 +0,0 @@
-# This file is part of Tryton. The COPYRIGHT file at the top level of
-# this repository contains the full copyright notices and license terms.
-import datetime
-import doctest
-import unittest
-from decimal import Decimal
-
-from dateutil.relativedelta import relativedelta
-
-import trytond.tests.test_tryton
-from trytond.exceptions import UserError
-from trytond.modules.account.tax import TaxableMixin
-from trytond.modules.company.tests import (
- CompanyTestMixin, PartyCompanyCheckEraseMixin, create_company, set_company)
-from trytond.modules.currency.tests import create_currency
-from trytond.pool import Pool
-from trytond.tests.test_tryton import (
- ModuleTestCase, doctest_checker, doctest_teardown, with_transaction)
-from trytond.transaction import Transaction
-
-from ..exceptions import FiscalYearDatesError
-
-
-def create_chart(company, tax=False, chart='account.account_template_root_en'):
- pool = Pool()
- AccountTemplate = pool.get('account.account.template')
- TaxTemplate = pool.get('account.tax.template')
- TaxCodeTemplate = pool.get('account.tax.code.template')
- ModelData = pool.get('ir.model.data')
- CreateChart = pool.get('account.create_chart', type='wizard')
- Account = pool.get('account.account')
-
- module, xml_id = chart.split('.')
- template = AccountTemplate(ModelData.get_id(module, xml_id))
- if tax:
- tax_account = AccountTemplate(ModelData.get_id(
- 'account', 'account_template_tax_en'))
- with Transaction().set_user(0):
- tax = TaxTemplate()
- tax.name = tax.description = '20% VAT'
- tax.type = 'percentage'
- tax.rate = Decimal('0.2')
- tax.account = template
- tax.invoice_account = tax_account
- tax.credit_note_account = tax_account
- tax.save()
-
- TaxCodeTemplate.create([{
- 'name': 'Tax Code',
- 'account': template,
- 'lines': [('create', [{
- 'operator': '+',
- 'type': 'invoice',
- 'amount': 'tax',
- 'tax': tax.id,
- }])],
- }, {
- 'name': 'Base Code',
- 'account': template,
- 'lines': [('create', [{
- 'operator': '+',
- 'type': 'invoice',
- 'amount': 'base',
- 'tax': tax.id,
- }])],
- }])
-
- session_id, _, _ = CreateChart.create()
- create_chart = CreateChart(session_id)
- create_chart.account.account_template = template
- create_chart.account.company = company
- create_chart.transition_create_account()
- properties_state = create_chart.states['properties']
- for name, value in properties_state.get_defaults(
- create_chart, 'properties',
- list(create_chart.properties._fields.keys())).items():
- if name in create_chart.properties._fields:
- setattr(create_chart.properties, name, value)
- if not create_chart.properties.account_receivable:
- receivable, = Account.search([
- ('type.receivable', '=', True),
- ('party_required', '=', True),
- ('company', '=', company.id),
- ], limit=1)
- create_chart.properties.account_receivable = receivable
- if not create_chart.properties.account_payable:
- payable, = Account.search([
- ('type.payable', '=', True),
- ('party_required', '=', True),
- ('company', '=', company.id),
- ], limit=1)
- create_chart.properties.account_payable = payable
- create_chart.transition_create_properties()
-
-
-def get_fiscalyear(company, today=None, start_date=None, end_date=None):
- pool = Pool()
- Sequence = pool.get('ir.sequence')
- SequenceType = pool.get('ir.sequence.type')
- FiscalYear = pool.get('account.fiscalyear')
-
- if not today:
- today = datetime.date.today()
- if not start_date:
- start_date = today.replace(month=1, day=1)
- if not end_date:
- end_date = today.replace(month=12, day=31)
-
- sequence_type, = SequenceType.search([
- ('name', '=', "Account Move"),
- ], limit=1)
- sequence, = Sequence.create([{
- 'name': '%s' % today.year,
- 'sequence_type': sequence_type.id,
- 'company': company.id,
- }])
- fiscalyear = FiscalYear(name='%s' % today.year, company=company)
- fiscalyear.start_date = start_date
- fiscalyear.end_date = end_date
- fiscalyear.post_move_sequence = sequence
- return fiscalyear
-
-
-def close_fiscalyear(fiscalyear):
- pool = Pool()
- Sequence = pool.get('ir.sequence')
- Journal = pool.get('account.journal')
- Period = pool.get('account.period')
- AccountType = pool.get('account.account.type')
- Account = pool.get('account.account')
- Move = pool.get('account.move')
- FiscalYear = pool.get('account.fiscalyear')
- BalanceNonDeferral = pool.get(
- 'account.fiscalyear.balance_non_deferral', type='wizard')
-
- # Balance non-deferral
- journal_sequence, = Sequence.search([
- ('sequence_type.name', '=', "Account Journal"),
- ], limit=1)
- journal_closing, = Journal.create([{
- 'name': 'Closing',
- 'code': 'CLO',
- 'type': 'situation',
- 'sequence': journal_sequence.id,
- }])
- period_closing, = Period.create([{
- 'name': 'Closing',
- 'start_date': fiscalyear.end_date,
- 'end_date': fiscalyear.end_date,
- 'fiscalyear': fiscalyear.id,
- 'type': 'adjustment',
- }])
- type_equity, = AccountType.search([
- ('name', '=', 'Equity'),
- ])
- revenue, = Account.search([
- ('type.revenue', '=', True),
- ])
- account_pl, = Account.create([{
- 'name': 'P&L',
- 'type': type_equity.id,
- 'parent': revenue.parent.id,
- }])
-
- session_id = BalanceNonDeferral.create()[0]
- balance_non_deferral = BalanceNonDeferral(session_id)
-
- balance_non_deferral.start.fiscalyear = fiscalyear
- balance_non_deferral.start.journal = journal_closing
- balance_non_deferral.start.period = period_closing
- balance_non_deferral.start.credit_account = account_pl
- balance_non_deferral.start.debit_account = account_pl
-
- balance_non_deferral._execute('balance')
-
- moves = Move.search([
- ('state', '=', 'draft'),
- ('period.fiscalyear', '=', fiscalyear.id),
- ])
- Move.post(moves)
-
- # Close fiscalyear
- FiscalYear.close([fiscalyear])
-
-
-class AccountTestCase(
- PartyCompanyCheckEraseMixin, CompanyTestMixin, ModuleTestCase):
- 'Test Account module'
- module = 'account'
-
- @with_transaction()
- def test_account_chart(self):
- 'Test creation and update of minimal chart of accounts'
- pool = Pool()
- Account = pool.get('account.account')
- Tax = pool.get('account.tax')
- UpdateChart = pool.get('account.update_chart', type='wizard')
-
- company = create_company()
- with set_company(company):
- create_chart(company, tax=True)
- root, = Account.search([('parent', '=', None)])
-
- # Create an account and tax without template
-
- cash, = Account.search([('name', '=', 'Main Cash')])
- Account.copy([cash.id])
-
- tax, = Tax.search([])
- Tax.copy([tax.id])
-
- session_id, _, _ = UpdateChart.create()
- update_chart = UpdateChart(session_id)
- update_chart.start.account = root
- update_chart.transition_update()
-
- @with_transaction()
- def test_account_chart_many_companies(self):
- "Test creation of chart of accounts for many companies"
- company1 = create_company()
- with set_company(company1):
- create_chart(company1, tax=True)
-
- company2 = create_company()
- with set_company(company2):
- create_chart(company2, tax=True)
-
- @with_transaction()
- def test_fiscalyear(self):
- 'Test fiscalyear'
- pool = Pool()
- FiscalYear = pool.get('account.fiscalyear')
- company = create_company()
- with set_company(company):
- fiscalyear = get_fiscalyear(company)
- fiscalyear.save()
- FiscalYear.create_period([fiscalyear])
- self.assertEqual(len(fiscalyear.periods), 12)
-
- @with_transaction()
- def test_fiscalyear_create_periods(self):
- 'Test fiscalyear create periods'
- FiscalYear = Pool().get('account.fiscalyear')
-
- company = create_company()
- with set_company(company):
- year = datetime.date.today().year
- date = datetime.date
- for start_date, end_date, interval, end_day, num_periods in [
- (date(year, 1, 1), date(year, 12, 31), 1, 31, 12),
- (date(year + 1, 1, 1), date(year + 1, 12, 31), 3, 31, 4),
- (date(year + 2, 1, 1), date(year + 2, 12, 31), 5, 31, 3),
- (date(year + 3, 4, 6), date(year + 4, 4, 5), 1, 5, 12),
- (date(year + 4, 4, 6), date(year + 5, 4, 5), 3, 5, 4),
- (date(year + 5, 4, 6), date(year + 6, 4, 5), 5, 5, 3),
- (date(year + 6, 6, 6), date(year + 6, 12, 31), 1, 29, 8),
- (date(year + 7, 7, 7), date(year + 7, 12, 31), 3, 29, 3),
- (date(year + 8, 1, 1), date(year + 9, 8, 7), 1, 29, 20),
- (date(year + 9, 9, 9), date(year + 10, 11, 12), 3, 29, 5),
- ]:
- fiscalyear = get_fiscalyear(
- company, start_date, start_date, end_date)
- fiscalyear.save()
- FiscalYear.create_period([fiscalyear], interval, end_day)
-
- self.assertEqual(len(fiscalyear.periods), num_periods)
-
- self.assertEqual(fiscalyear.periods[-1].end_date, end_date)
- self.assertTrue(all(
- p.end_date == p.end_date + relativedelta(day=end_day)
- for p in fiscalyear.periods[:-1]))
-
- self.assertEqual(fiscalyear.periods[0].start_date, start_date)
- self.assertTrue(all(
- p1.end_date + relativedelta(days=1) == p2.start_date
- for p1, p2 in zip(
- fiscalyear.periods[:-1], fiscalyear.periods[1:])))
-
- @with_transaction()
- def test_open_fiscalyear_before_open(self):
- "Test create open fiscal year before an open one"
- company = create_company()
- with set_company(company):
- create_chart(company)
- fiscalyear = get_fiscalyear(
- company,
- start_date=datetime.date(2022, 1, 1),
- end_date=datetime.date(2022, 12, 31))
- fiscalyear.save()
-
- earlier_fiscalyear = get_fiscalyear(
- company,
- start_date=datetime.date(2021, 1, 1),
- end_date=datetime.date(2021, 12, 31))
- earlier_fiscalyear.save()
-
- @with_transaction()
- def test_open_fiscalyear_before_close(self):
- "Test create open fiscal year before a close one"
- company = create_company()
- with set_company(company):
- create_chart(company)
- fiscalyear = get_fiscalyear(
- company,
- start_date=datetime.date(2022, 1, 1),
- end_date=datetime.date(2022, 12, 31))
- fiscalyear.save()
- close_fiscalyear(fiscalyear)
-
- earlier_fiscalyear = get_fiscalyear(
- company,
- start_date=datetime.date(2021, 1, 1),
- end_date=datetime.date(2021, 12, 31))
- with self.assertRaises(FiscalYearDatesError):
- earlier_fiscalyear.save()
-
- @with_transaction()
- def test_account_debit_credit(self):
- 'Test account debit/credit'
- pool = Pool()
- Party = pool.get('party.party')
- FiscalYear = pool.get('account.fiscalyear')
- Journal = pool.get('account.journal')
- Account = pool.get('account.account')
- Move = pool.get('account.move')
-
- party = Party(name='Party')
- party.save()
-
- company = create_company()
- with set_company(company):
- fiscalyear = get_fiscalyear(company)
- fiscalyear.save()
- FiscalYear.create_period([fiscalyear])
- period = fiscalyear.periods[0]
- create_chart(company)
-
- sec_cur = create_currency('sec')
-
- journal_revenue, = Journal.search([
- ('code', '=', 'REV'),
- ])
- journal_expense, = Journal.search([
- ('code', '=', 'EXP'),
- ])
- revenue, = Account.search([
- ('type.revenue', '=', True),
- ])
- receivable, = Account.search([
- ('type.receivable', '=', True),
- ])
- expense, = Account.search([
- ('type.expense', '=', True),
- ])
- payable, = Account.search([
- ('type.payable', '=', True),
- ])
- cash, = Account.search([
- ('name', '=', 'Main Cash'),
- ])
- cash_cur, = Account.copy([cash], default={
- 'second_currency': sec_cur.id,
- })
- # Create some moves
- vlist = [
- {
- 'period': period.id,
- 'journal': journal_revenue.id,
- 'date': period.start_date,
- 'lines': [
- ('create', [{
- 'account': revenue.id,
- 'credit': Decimal(100),
- }, {
- 'account': receivable.id,
- 'debit': Decimal(100),
- 'party': party.id,
- }]),
- ],
- },
- {
- 'period': period.id,
- 'journal': journal_revenue.id,
- 'date': period.start_date,
- 'lines': [
- ('create', [{
- 'account': receivable.id,
- 'credit': Decimal(80),
- 'second_currency': sec_cur.id,
- 'amount_second_currency': -Decimal(50),
- 'party': party.id,
- }, {
- 'account': cash_cur.id,
- 'debit': Decimal(80),
- 'second_currency': sec_cur.id,
- 'amount_second_currency': Decimal(50),
- }]),
- ],
- },
- {
- 'period': period.id,
- 'journal': journal_expense.id,
- 'date': period.start_date,
- 'lines': [
- ('create', [{
- 'account': expense.id,
- 'debit': Decimal(30),
- }, {
- 'account': payable.id,
- 'credit': Decimal(30),
- 'party': party.id,
- }]),
- ],
- },
- ]
- Move.create(vlist)
-
- # Test debit/credit
- self.assertEqual((revenue.debit, revenue.credit),
- (Decimal(0), Decimal(100)))
- self.assertEqual(revenue.balance, Decimal(-100))
-
- self.assertEqual((cash_cur.debit, cash_cur.credit),
- (Decimal(80), Decimal(0)))
- self.assertEqual(
- cash_cur.amount_second_currency, Decimal(50))
-
- # Use next fiscalyear
- today = datetime.date.today()
- next_fiscalyear = get_fiscalyear(company,
- today=today.replace(year=today.year + 1))
- next_fiscalyear.save()
- FiscalYear.create_period([next_fiscalyear])
-
- # Test debit/credit for next year
- with Transaction().set_context(fiscalyear=next_fiscalyear.id):
- revenue = Account(revenue.id)
- self.assertEqual((revenue.debit, revenue.credit),
- (Decimal(0), Decimal(0)))
- self.assertEqual(revenue.balance, Decimal(-100))
-
- cash_cur = Account(cash_cur.id)
- self.assertEqual(
- cash_cur.amount_second_currency, Decimal(50))
-
- # Test debit/credit cumulate for next year
- with Transaction().set_context(fiscalyear=next_fiscalyear.id,
- cumulate=True):
- revenue = Account(revenue.id)
- self.assertEqual((revenue.debit, revenue.credit),
- (Decimal(0), Decimal(100)))
- self.assertEqual(revenue.balance, Decimal(-100))
-
- cash_cur = Account(cash_cur.id)
- self.assertEqual(
- cash_cur.amount_second_currency, Decimal(50))
-
- close_fiscalyear(fiscalyear)
-
- # Check deferral
- self.assertEqual(revenue.deferrals, ())
-
- deferral_receivable, = receivable.deferrals
- self.assertEqual(
- (deferral_receivable.debit, deferral_receivable.credit),
- (Decimal(100), Decimal(80)))
- self.assertEqual(deferral_receivable.fiscalyear, fiscalyear)
-
- cash_cur = Account(cash_cur.id)
- deferral_cash_cur, = cash_cur.deferrals
- self.assertEqual(
- deferral_cash_cur.amount_second_currency, Decimal(50))
-
- # Test debit/credit
- with Transaction().set_context(fiscalyear=fiscalyear.id):
- revenue = Account(revenue.id)
- self.assertEqual((revenue.debit, revenue.credit),
- (Decimal(100), Decimal(100)))
- self.assertEqual(revenue.balance, Decimal(0))
-
- receivable = Account(receivable.id)
- self.assertEqual((receivable.debit, receivable.credit),
- (Decimal(100), Decimal(80)))
- self.assertEqual(receivable.balance, Decimal(20))
-
- cash_cur = Account(cash_cur.id)
- self.assertEqual(
- cash_cur.amount_second_currency, Decimal(50))
-
- # Test debit/credit for next year
- with Transaction().set_context(fiscalyear=next_fiscalyear.id):
- revenue = Account(revenue.id)
- self.assertEqual((revenue.debit, revenue.credit),
- (Decimal(0), Decimal(0)))
- self.assertEqual(revenue.balance, Decimal(0))
-
- receivable = Account(receivable.id)
- self.assertEqual((receivable.debit, receivable.credit),
- (Decimal(0), Decimal(0)))
- self.assertEqual(receivable.balance, Decimal(20))
-
- cash_cur = Account(cash_cur.id)
- self.assertEqual(
- cash_cur.amount_second_currency, Decimal(50))
-
- # Test debit/credit cumulate for next year
- with Transaction().set_context(fiscalyear=next_fiscalyear.id,
- cumulate=True):
- revenue = Account(revenue.id)
- self.assertEqual((revenue.debit, revenue.credit),
- (Decimal(0), Decimal(0)))
- self.assertEqual(revenue.balance, Decimal(0))
-
- receivable = Account(receivable.id)
- self.assertEqual((receivable.debit, receivable.credit),
- (Decimal(100), Decimal(80)))
- self.assertEqual(receivable.balance, Decimal(20))
-
- cash_cur = Account(cash_cur.id)
- self.assertEqual(
- cash_cur.amount_second_currency, Decimal(50))
-
- @with_transaction()
- def test_account_type_amount(self):
- "Test account type amount"
- pool = Pool()
- Party = pool.get('party.party')
- FiscalYear = pool.get('account.fiscalyear')
- Journal = pool.get('account.journal')
- Account = pool.get('account.account')
- Move = pool.get('account.move')
- Type = pool.get('account.account.type')
-
- party = Party(name='Party')
- party.save()
-
- company = create_company()
- with set_company(company):
- fiscalyear = get_fiscalyear(company)
- fiscalyear.save()
- FiscalYear.create_period([fiscalyear])
- period = fiscalyear.periods[0]
- create_chart(company)
-
- journal_revenue, = Journal.search([
- ('code', '=', 'REV'),
- ])
- revenue, = Account.search([
- ('type.revenue', '=', True),
- ])
- receivable, = Account.search([
- ('type.receivable', '=', True),
- ])
-
- Move.create([{
- 'period': period.id,
- 'journal': journal_revenue.id,
- 'date': period.start_date,
- 'lines': [
- ('create', [{
- 'account': revenue.id,
- 'credit': Decimal(100),
- }, {
- 'account': receivable.id,
- 'debit': Decimal(100),
- 'party': party.id,
- }]),
- ],
- }])
-
- with Transaction().set_context(fiscalyear=fiscalyear.id):
- revenue_type = Type(revenue.type)
- receivable_type = Type(receivable.type)
-
- # Test type amount
- self.assertEqual(revenue_type.amount, Decimal(100))
- self.assertEqual(receivable_type.amount, Decimal(100))
-
- # Set a debit type on receivable
- with Transaction().set_context(fiscalyear=fiscalyear.id):
- debit_receivable_type, = Type.copy([receivable_type])
- receivable.debit_type = debit_receivable_type
- receivable.credit_type = None
- receivable.save()
- self.assertEqual(receivable_type.amount, Decimal(0))
- self.assertEqual(debit_receivable_type.amount, Decimal(100))
-
- # Set a debit type on revenue
- with Transaction().set_context(fiscalyear=fiscalyear.id):
- debit_revenue_type, = Type.copy([revenue_type])
- revenue.debit_type = debit_revenue_type
- revenue.credit_type = None
- revenue.save()
- self.assertEqual(revenue_type.amount, Decimal(100))
- self.assertEqual(debit_revenue_type.amount, Decimal(0))
-
- # Set a credit type on revenue
- with Transaction().set_context(fiscalyear=fiscalyear.id):
- credit_revenue_type, = Type.copy([revenue_type])
- revenue.credit_type = credit_revenue_type
- revenue.debit_type = None
- revenue.save()
- self.assertEqual(revenue_type.amount, Decimal(0))
- self.assertEqual(credit_revenue_type.amount, Decimal(100))
-
- # Set a credit type on receivable
- with Transaction().set_context(fiscalyear=fiscalyear.id):
- credit_receivable_type, = Type.copy([receivable_type])
- receivable.credit_type = credit_receivable_type
- receivable.debit_type = None
- receivable.save()
- self.assertEqual(receivable_type.amount, Decimal(100))
- self.assertEqual(credit_receivable_type.amount, Decimal(0))
-
- @with_transaction()
- def test_move_post(self):
- "Test posting move"
- pool = Pool()
- Party = pool.get('party.party')
- FiscalYear = pool.get('account.fiscalyear')
- Journal = pool.get('account.journal')
- Account = pool.get('account.account')
- Move = pool.get('account.move')
- Line = pool.get('account.move.line')
- Period = pool.get('account.period')
-
- party = Party(name='Party')
- party.save()
-
- company = create_company()
- with set_company(company):
- fiscalyear = get_fiscalyear(company)
- fiscalyear.save()
- FiscalYear.create_period([fiscalyear])
- period = fiscalyear.periods[0]
- create_chart(company)
-
- journal_revenue, = Journal.search([
- ('code', '=', 'REV'),
- ])
- revenue, = Account.search([
- ('type.revenue', '=', True),
- ])
- receivable, = Account.search([
- ('type.receivable', '=', True),
- ])
-
- move = Move()
- move.period = period
- move.journal = journal_revenue
- move.date = period.start_date
- move.lines = [
- Line(account=revenue, credit=Decimal(100)),
- Line(account=receivable, debit=Decimal(100), party=party),
- ]
- move.save()
- Move.post([move])
- move_id = move.id
-
- self.assertEqual(move.state, 'posted')
-
- # Can not post an empty move
- with self.assertRaises(UserError):
- move = Move()
- move.period = period
- move.journal = journal_revenue
- move.date = period.start_date
- move.save()
- Move.post([move])
- Move.delete([move])
-
- # Can not modify posted move
- with self.assertRaises(UserError):
- move = Move(move_id)
- move.date = period.end_date
- move.save()
-
- # Can not go back to draft
- with self.assertRaises(UserError):
- move = Move(move_id)
- move.state = 'draft'
- move.save()
-
- Period.close([period])
-
- # Can not create move with lines on closed period
- with self.assertRaises(UserError):
- move = Move()
- move.period = period
- move.journal = journal_revenue
- move.date = period.start_date
- move.lines = [
- Line(account=revenue, credit=Decimal(100)),
- Line(account=receivable, debit=Decimal(100), party=party),
- ]
- move.save()
-
- @with_transaction()
- def test_tax_compute(self):
- 'Test tax compute/reverse_compute'
- pool = Pool()
- Account = pool.get('account.account')
- Tax = pool.get('account.tax')
- today = datetime.date.today()
-
- company = create_company()
- with set_company(company):
- create_chart(company)
-
- tax_account, = Account.search([
- ('name', '=', 'Main Tax'),
- ])
- tax = Tax()
- tax.name = tax.description = 'Test'
- tax.type = 'none'
- tax.invoice_account = tax_account
- tax.credit_note_account = tax_account
-
- child1 = Tax()
- child1.name = child1.description = 'Child 1'
- child1.type = 'percentage'
- child1.rate = Decimal('0.2')
- child1.invoice_account = tax_account
- child1.credit_note_account = tax_account
- child1.save()
-
- child2 = Tax()
- child2.name = child2.description = 'Child 1'
- child2.type = 'fixed'
- child2.amount = Decimal('10')
- child2.invoice_account = tax_account
- child2.credit_note_account = tax_account
- child2.save()
-
- tax.childs = [child1, child2]
- tax.save()
-
- self.assertEqual(Tax.compute([tax], Decimal('100'), 2, today),
- [{
- 'base': Decimal('200'),
- 'amount': Decimal('40.0'),
- 'tax': child1,
- }, {
- 'base': Decimal('200'),
- 'amount': Decimal('20'),
- 'tax': child2,
- }])
-
- self.assertEqual(
- Tax.reverse_compute(Decimal('130'), [tax], today),
- Decimal('100'))
-
- child1.end_date = today + relativedelta(days=5)
- child1.save()
- self.assertEqual(Tax.compute([tax], Decimal('100'), 2, today),
- [{
- 'base': Decimal('200'),
- 'amount': Decimal('40.0'),
- 'tax': child1,
- }, {
- 'base': Decimal('200'),
- 'amount': Decimal('20'),
- 'tax': child2,
- }])
-
- self.assertEqual(
- Tax.reverse_compute(Decimal('130'), [tax], today),
- Decimal('100'))
-
- child1.start_date = today + relativedelta(days=1)
- child1.save()
- self.assertEqual(Tax.compute([tax], Decimal('100'), 2, today),
- [{
- 'base': Decimal('200'),
- 'amount': Decimal('20'),
- 'tax': child2,
- }])
- self.assertEqual(
- Tax.reverse_compute(Decimal('110'), [tax], today),
- Decimal('100'))
- self.assertEqual(Tax.compute([tax], Decimal('100'), 2,
- today + relativedelta(days=1)), [{
- 'base': Decimal('200'),
- 'amount': Decimal('40.0'),
- 'tax': child1,
- }, {
- 'base': Decimal('200'),
- 'amount': Decimal('20'),
- 'tax': child2,
- }])
- self.assertEqual(
- Tax.reverse_compute(
- Decimal('130'), [tax], today + relativedelta(days=1)),
- Decimal('100'))
- self.assertEqual(Tax.compute([tax], Decimal('100'), 2,
- today + relativedelta(days=5)), [{
- 'base': Decimal('200'),
- 'amount': Decimal('40.0'),
- 'tax': child1,
- }, {
- 'base': Decimal('200'),
- 'amount': Decimal('20'),
- 'tax': child2,
- }])
- self.assertEqual(
- Tax.reverse_compute(Decimal('130'), [tax],
- today + relativedelta(days=5)),
- Decimal('100'))
- self.assertEqual(Tax.compute([tax], Decimal('100'), 2,
- today + relativedelta(days=6)), [{
- 'base': Decimal('200'),
- 'amount': Decimal('20'),
- 'tax': child2,
- }])
- self.assertEqual(
- Tax.reverse_compute(Decimal('110'), [tax],
- today + relativedelta(days=6)),
- Decimal('100'))
-
- child1.end_date = None
- child1.save()
- self.assertEqual(Tax.compute([tax], Decimal('100'), 2,
- today + relativedelta(days=6)), [{
- 'base': Decimal('200'),
- 'amount': Decimal('40.0'),
- 'tax': child1,
- }, {
- 'base': Decimal('200'),
- 'amount': Decimal('20'),
- 'tax': child2,
- }])
- self.assertEqual(
- Tax.reverse_compute(Decimal('130'), [tax],
- today + relativedelta(days=6)),
- Decimal('100'))
-
- ecotax1 = Tax()
- ecotax1.name = ecotax1.description = 'EcoTax 1'
- ecotax1.type = 'fixed'
- ecotax1.amount = Decimal(5)
- ecotax1.invoice_account = tax_account
- ecotax1.credit_note_account = tax_account
- ecotax1.sequence = 10
- ecotax1.save()
-
- vat0 = Tax()
- vat0.name = vat0.description = 'VAT0'
- vat0.type = 'percentage'
- vat0.rate = Decimal('0.1')
- vat0.invoice_account = tax_account
- vat0.credit_note_account = tax_account
- vat0.sequence = 5
- vat0.save()
-
- vat1 = Tax()
- vat1.name = vat1.description = 'VAT1'
- vat1.type = 'percentage'
- vat1.rate = Decimal('0.2')
- vat1.invoice_account = tax_account
- vat1.credit_note_account = tax_account
- vat1.sequence = 20
- vat1.save()
-
- self.assertEqual(
- Tax.compute([vat0, ecotax1, vat1], Decimal(100), 1, today),
- [{
- 'base': Decimal(100),
- 'amount': Decimal(10),
- 'tax': vat0,
- }, {
- 'base': Decimal(100),
- 'amount': Decimal(5),
- 'tax': ecotax1,
- }, {
- 'base': Decimal(100),
- 'amount': Decimal(20),
- 'tax': vat1,
- }])
- self.assertEqual(
- Tax.reverse_compute(
- Decimal(135), [vat0, ecotax1, vat1], today),
- Decimal(100))
-
- @with_transaction()
- def test_tax_compute_with_update_unit_price(self):
- 'Test tax compute with unit_price modifying tax'
- pool = Pool()
- Account = pool.get('account.account')
- Date = pool.get('ir.date')
- Tax = pool.get('account.tax')
- today = Date.today()
-
- company = create_company()
- with set_company(company):
- create_chart(company)
-
- tax_account, = Account.search([
- ('name', '=', 'Main Tax'),
- ])
- ecotax1 = Tax()
- ecotax1.name = ecotax1.description = 'EcoTax 1'
- ecotax1.type = 'fixed'
- ecotax1.amount = Decimal(5)
- ecotax1.invoice_account = tax_account
- ecotax1.credit_note_account = tax_account
- ecotax1.update_unit_price = True
- ecotax1.sequence = 10
- ecotax1.save()
-
- vat1 = Tax()
- vat1.name = vat1.description = 'VAT1'
- vat1.type = 'percentage'
- vat1.rate = Decimal('0.2')
- vat1.invoice_account = tax_account
- vat1.credit_note_account = tax_account
- vat1.sequence = 20
- vat1.save()
-
- self.assertEqual(
- Tax.compute([ecotax1, vat1], Decimal(100), 5, today),
- [{
- 'base': Decimal(500),
- 'amount': Decimal(25),
- 'tax': ecotax1,
- }, {
- 'base': Decimal(525),
- 'amount': Decimal(105),
- 'tax': vat1,
- }])
- self.assertEqual(
- Tax.reverse_compute(Decimal(126), [ecotax1, vat1], today),
- Decimal(100))
-
- ecotax2 = Tax()
- ecotax2.name = ecotax2.description = 'EcoTax 2'
- ecotax2.type = 'percentage'
- ecotax2.rate = Decimal('0.5')
- ecotax2.invoice_account = tax_account
- ecotax2.credit_note_account = tax_account
- ecotax2.update_unit_price = True
- ecotax2.sequence = 10
- ecotax2.save()
-
- self.assertEqual(
- Tax.compute([ecotax1, ecotax2, vat1], Decimal(100), 1, today),
- [{
- 'base': Decimal(100),
- 'amount': Decimal(5),
- 'tax': ecotax1,
- }, {
- 'base': Decimal(100),
- 'amount': Decimal(50),
- 'tax': ecotax2,
- }, {
- 'base': Decimal(155),
- 'amount': Decimal(31),
- 'tax': vat1,
- }])
- self.assertEqual(
- Tax.reverse_compute(
- Decimal(186), [ecotax1, ecotax2, vat1], today),
- Decimal(100))
-
- vat0 = Tax()
- vat0.name = vat0.description = 'VAT0'
- vat0.type = 'percentage'
- vat0.rate = Decimal('0.1')
- vat0.invoice_account = tax_account
- vat0.credit_note_account = tax_account
- vat0.sequence = 5
- vat0.save()
-
- self.assertEqual(
- Tax.compute([vat0, ecotax1, vat1], Decimal(100), 1, today),
- [{
- 'base': Decimal(100),
- 'amount': Decimal(10),
- 'tax': vat0,
- }, {
- 'base': Decimal(100),
- 'amount': Decimal(5),
- 'tax': ecotax1,
- }, {
- 'base': Decimal(105),
- 'amount': Decimal(21),
- 'tax': vat1,
- }])
- self.assertEqual(
- Tax.reverse_compute(
- Decimal(136), [vat0, ecotax1, vat1], today),
- Decimal(100))
-
- self.assertEqual(
- Tax.compute([vat0, ecotax1, ecotax2, vat1],
- Decimal(100), 1, today),
- [{
- 'base': Decimal(100),
- 'amount': Decimal(10),
- 'tax': vat0,
- }, {
- 'base': Decimal(100),
- 'amount': Decimal(5),
- 'tax': ecotax1,
- }, {
- 'base': Decimal(100),
- 'amount': Decimal(50),
- 'tax': ecotax2,
- }, {
- 'base': Decimal(155),
- 'amount': Decimal(31),
- 'tax': vat1,
- }])
- self.assertEqual(
- Tax.reverse_compute(
- Decimal(196), [vat0, ecotax1, ecotax2, vat1], today),
- Decimal(100))
-
- vat2 = Tax()
- vat2.name = vat2.description = 'VAT2'
- vat2.type = 'percentage'
- vat2.rate = Decimal('0.3')
- vat2.invoice_account = tax_account
- vat2.credit_note_account = tax_account
- vat2.sequence = 30
- vat2.save()
-
- self.assertEqual(
- Tax.compute([vat0, ecotax1, vat1, vat2],
- Decimal(100), 1, today),
- [{
- 'base': Decimal(100),
- 'amount': Decimal(10),
- 'tax': vat0,
- }, {
- 'base': Decimal(100),
- 'amount': Decimal(5),
- 'tax': ecotax1,
- }, {
- 'base': Decimal(105),
- 'amount': Decimal(21),
- 'tax': vat1,
- }, {
- 'base': Decimal(105),
- 'amount': Decimal('31.5'),
- 'tax': vat2,
- }])
- self.assertEqual(
- Tax.reverse_compute(
- Decimal('167.5'), [vat0, ecotax1, vat1, vat2], today),
- Decimal(100))
-
- ecotax3 = Tax()
- ecotax3.name = ecotax3.description = 'ECOTAX3'
- ecotax3.type = 'percentage'
- ecotax3.rate = Decimal('0.4')
- ecotax3.invoice_account = tax_account
- ecotax3.credit_note_account = tax_account
- ecotax3.update_unit_price = True
- ecotax3.sequence = 25
- ecotax3.save()
-
- self.assertEqual(
- Tax.compute([vat0, ecotax1, vat1, ecotax3, vat2],
- Decimal(100), 1, today),
- [{
- 'base': Decimal(100),
- 'amount': Decimal(10),
- 'tax': vat0,
- }, {
- 'base': Decimal(100),
- 'amount': Decimal(5),
- 'tax': ecotax1,
- }, {
- 'base': Decimal(105),
- 'amount': Decimal(21),
- 'tax': vat1,
- }, {
- 'base': Decimal(105),
- 'amount': Decimal('42'),
- 'tax': ecotax3,
- }, {
- 'base': Decimal(147),
- 'amount': Decimal('44.1'),
- 'tax': vat2
- }])
- self.assertEqual(
- Tax.reverse_compute(
- Decimal('222.1'),
- [vat0, ecotax1, vat1, ecotax3, vat2],
- today),
- Decimal(100))
-
- class Taxable(TaxableMixin):
- __slots__ = ('currency', 'taxable_lines', 'company')
-
- def __init__(self, currency=None, taxable_lines=None, company=None):
- super().__init__()
- self.currency = currency
- self.taxable_lines = taxable_lines
- self.company = company
-
- @with_transaction()
- def test_taxable_mixin_line(self):
- "Test TaxableMixin with rounding on line"
- pool = Pool()
- Tax = pool.get('account.tax')
- Configuration = pool.get('account.configuration')
- currency = create_currency('cur')
-
- company = create_company()
- with set_company(company):
- create_chart(company, tax=True)
- tax, = Tax.search([])
- config = Configuration(1)
- config.tax_rounding = 'line'
- config.save()
-
- taxable = self.Taxable(
- currency=currency,
- taxable_lines=[
- ([tax], Decimal('1.001'), 1, None),
- ] * 100,
- company=company)
-
- taxes = taxable._get_taxes()
-
- tax, = taxes
- self.assertEqual(tax['base'], Decimal('100.00'))
- self.assertEqual(tax['amount'], Decimal('20.00'))
-
- @with_transaction()
- def test_taxable_mixin_document(self):
- "Test TaxableMixin with rounding on document"
- pool = Pool()
- Tax = pool.get('account.tax')
- Configuration = pool.get('account.configuration')
- currency = create_currency('cur')
-
- company = create_company()
- with set_company(company):
- create_chart(company, tax=True)
- tax, = Tax.search([])
- config = Configuration(1)
- config.tax_rounding = 'document'
- config.save()
-
- taxable = self.Taxable(
- currency=currency,
- taxable_lines=[
- ([tax], Decimal('1.001'), 1, None),
- ] * 100,
- company=company)
-
- taxes = taxable._get_taxes()
-
- tax, = taxes
- self.assertEqual(tax['base'], Decimal('100.00'))
- self.assertEqual(tax['amount'], Decimal('20.02'))
-
- @with_transaction()
- def test_tax_compute_with_children_update_unit_price(self):
- "Test tax compute with children taxes modifying unit_price"
- pool = Pool()
- Account = pool.get('account.account')
- Date = pool.get('ir.date')
- Tax = pool.get('account.tax')
- today = Date.today()
-
- company = create_company()
- with set_company(company):
- create_chart(company)
-
- tax_account, = Account.search([
- ('name', '=', 'Main Tax'),
- ])
-
- tax1 = Tax()
- tax1.name = tax1.description = "Tax 1"
- tax1.type = 'none'
- tax1.update_unit_price = True
- tax1.sequence = 1
- tax1.save()
- child1 = Tax()
- child1.name = child1.description = "Child 1"
- child1.type = 'percentage'
- child1.rate = Decimal('0.1')
- child1.invoice_account = tax_account
- child1.credit_note_account = tax_account
- child1.parent = tax1
- child1.save()
-
- tax2 = Tax()
- tax2.name = tax2.description = "Tax 2"
- tax2.type = 'fixed'
- tax2.amount = Decimal('10')
- tax2.invoice_account = tax_account
- tax2.credit_note_account = tax_account
- tax2.sequence = 2
- tax2.save()
-
- self.assertEqual(
- Tax.compute([tax1, tax2], Decimal(100), 2, today), [{
- 'base': Decimal(200),
- 'amount': Decimal(20),
- 'tax': child1,
- }, {
- 'base': Decimal('220'),
- 'amount': Decimal('20'),
- 'tax': tax2,
- }])
- self.assertEqual(
- Tax.reverse_compute(Decimal('120'), [tax1, tax2], today),
- Decimal('100'))
-
- @with_transaction()
- def test_receivable_payable(self):
- 'Test party receivable payable'
- pool = Pool()
- Party = pool.get('party.party')
- FiscalYear = pool.get('account.fiscalyear')
- Journal = pool.get('account.journal')
- Account = pool.get('account.account')
- Move = pool.get('account.move')
-
- company = create_company()
- with set_company(company):
- create_chart(company)
- fiscalyear = get_fiscalyear(company)
- fiscalyear.save()
- FiscalYear.create_period([fiscalyear])
- period = fiscalyear.periods[0]
- journal_revenue, = Journal.search([
- ('code', '=', 'REV'),
- ])
- journal_expense, = Journal.search([
- ('code', '=', 'EXP'),
- ])
- revenue, = Account.search([
- ('type.revenue', '=', True),
- ])
- receivable, = Account.search([
- ('type.receivable', '=', True),
- ])
- expense, = Account.search([
- ('type.expense', '=', True),
- ])
- payable, = Account.search([
- ('type.payable', '=', True),
- ])
- party, = Party.create([{
- 'name': 'Receivable/Payable party',
- }])
- tomorrow = datetime.date.today() + datetime.timedelta(days=1)
-
- def get_move(journal, amount, credit_account, debit_account, party,
- maturity_date=None):
- return {
- 'period': period.id,
- 'journal': journal.id,
- 'date': period.start_date,
- 'lines': [
- ('create', [{
- 'account': credit_account.id,
- 'credit': amount,
- }, {
- 'account': debit_account.id,
- 'debit': amount,
- 'party': party.id,
- 'maturity_date': maturity_date,
- }]),
- ],
- }
- vlist = [
- get_move(journal_revenue, Decimal(100), revenue, receivable,
- party),
- get_move(journal_expense, Decimal(30), expense, payable,
- party),
- get_move(journal_revenue, Decimal(200), revenue, receivable,
- party, tomorrow),
- get_move(journal_revenue, Decimal(60), expense, payable,
- party, tomorrow),
- ]
- moves = Move.create(vlist)
- Move.post(moves)
-
- def check_fields():
- party_test = Party(party.id)
-
- for field, value in [('receivable', Decimal('300')),
- ('receivable_today', Decimal('100')),
- ('payable', Decimal('90')),
- ('payable_today', Decimal('30')),
- ]:
- msg = 'field: %s, value: %s' % (field, value)
- self.assertEqual(
- getattr(party_test, field), value, msg=msg)
- self.assertEqual(
- Party.search([(field, '=', value)]),
- [party_test], msg=msg)
- self.assertEqual(
- Party.search([(field, 'in', [value])]),
- [party_test], msg=msg)
- self.assertEqual(
- Party.search([(field, '!=', value)]),
- [], msg=msg)
- self.assertEqual(
- Party.search([(field, 'not in', [value])]),
- [], msg=msg)
-
- check_fields()
- close_fiscalyear(fiscalyear)
- check_fields()
-
- @with_transaction()
- def test_sort_taxes(self):
- "Test sort_taxes"
- pool = Pool()
- Tax = pool.get('account.tax')
-
- tax1 = Tax(sequence=None, id=-3)
- tax2 = Tax(sequence=None, id=-2)
- tax3 = Tax(sequence=1, id=-1)
- self.assertSequenceEqual(
- Tax.sort_taxes([tax3, tax2, tax1]), [tax1, tax2, tax3])
-
- @with_transaction()
- def test_configuration_accounts_on_party(self):
- 'Test configuration accounts are used as fallback on party'
- pool = Pool()
- Party = pool.get('party.party')
- Account = pool.get('account.account')
-
- party = Party(name='Party')
- party.save()
-
- self.assertIsNone(party.account_payable)
- self.assertIsNone(party.account_receivable)
-
- company = create_company()
- with set_company(company):
- create_chart(company)
- receivable, = Account.search([
- ('type.receivable', '=', True),
- ])
- payable, = Account.search([
- ('type.payable', '=', True),
- ])
-
- party = Party(party.id)
-
- self.assertEqual(party.account_payable_used, payable)
- self.assertEqual(party.account_receivable_used, receivable)
-
- @with_transaction()
- def test_tax_rule(self):
- "Test tax rule"
- pool = Pool()
- TaxRule = pool.get('account.tax.rule')
- Tax = pool.get('account.tax')
-
- company = create_company()
- with set_company(company):
- create_chart(company, tax=True)
- tax, = Tax.search([])
- target_tax, = Tax.copy([tax])
-
- tax_rule, = TaxRule.create([{
- 'name': 'Test',
- 'kind': 'both',
- 'lines': [('create', [{
- 'origin_tax': tax.id,
- 'tax': target_tax.id,
- }])],
- }])
- self.assertListEqual(tax_rule.apply(tax, {}), [target_tax.id])
-
- @with_transaction()
- def test_tax_rule_start_date(self):
- "Test tax rule start date"
- pool = Pool()
- TaxRule = pool.get('account.tax.rule')
- Tax = pool.get('account.tax')
- Date = pool.get('ir.date')
-
- today = Date.today()
- yesterday = today - datetime.timedelta(days=1)
- tomorrow = today + datetime.timedelta(days=1)
- company = create_company()
- with set_company(company):
- create_chart(company, tax=True)
- tax, = Tax.search([])
- target_tax, = Tax.copy([tax])
-
- tax_rule, = TaxRule.create([{
- 'name': "Test",
- 'kind': 'both',
- 'lines': [('create', [{
- 'start_date': today,
- 'tax': target_tax.id,
- }])],
- }])
-
- self.assertListEqual(tax_rule.apply(tax, {}), [target_tax.id])
- self.assertListEqual(
- tax_rule.apply(tax, {'date': yesterday}), [tax.id])
- self.assertListEqual(
- tax_rule.apply(tax, {'date': tomorrow}), [target_tax.id])
-
- @with_transaction()
- def test_tax_rule_end_date(self):
- "Test tax rule end date"
- pool = Pool()
- TaxRule = pool.get('account.tax.rule')
- Tax = pool.get('account.tax')
- Date = pool.get('ir.date')
-
- today = Date.today()
- yesterday = today - datetime.timedelta(days=1)
- tomorrow = today + datetime.timedelta(days=1)
- company = create_company()
- with set_company(company):
- create_chart(company, tax=True)
- tax, = Tax.search([])
- target_tax, = Tax.copy([tax])
-
- tax_rule, = TaxRule.create([{
- 'name': "Test",
- 'kind': 'both',
- 'lines': [('create', [{
- 'end_date': today,
- 'tax': target_tax.id,
- }])],
- }])
-
- self.assertListEqual(tax_rule.apply(tax, {}), [target_tax.id])
- self.assertListEqual(
- tax_rule.apply(tax, {'date': yesterday}), [target_tax.id])
- self.assertListEqual(
- tax_rule.apply(tax, {'date': tomorrow}), [tax.id])
-
- @with_transaction()
- def test_tax_rule_keep_origin(self):
- "Test tax rule keeps origin"
- pool = Pool()
- TaxRule = pool.get('account.tax.rule')
- Tax = pool.get('account.tax')
-
- company = create_company()
- with set_company(company):
- create_chart(company, tax=True)
- tax, = Tax.search([])
- target_tax, = Tax.copy([tax])
-
- tax_rule, = TaxRule.create([{
- 'name': 'Test',
- 'kind': 'both',
- 'lines': [('create', [{
- 'origin_tax': tax.id,
- 'tax': target_tax.id,
- 'keep_origin': True,
- }])],
- }])
- self.assertListEqual(
- tax_rule.apply(tax, {}), [target_tax.id, tax.id])
-
- @with_transaction()
- def test_update_chart(self):
- 'Test all template models are updated when updating chart'
- pool = Pool()
- TypeTemplate = pool.get('account.account.type.template')
- AccountTemplate = pool.get('account.account.template')
- TaxTemplate = pool.get('account.tax.template')
- TaxCodeTemplate = pool.get('account.tax.code.template')
- ModelData = pool.get('ir.model.data')
- UpdateChart = pool.get('account.update_chart', type='wizard')
- Type = pool.get('account.account.type')
- Account = pool.get('account.account')
- Tax = pool.get('account.tax')
- TaxCode = pool.get('account.tax.code')
-
- def check():
- for type_ in Type.search([]):
- self.assertEqual(type_.name, type_.template.name)
- self.assertEqual(
- type_.statement, type_.template.statement)
- if type_.template.parent:
- self.assertEqual(
- type_.parent.name, type_.template.parent.name)
- else:
- self.assertEqual(type_.parent, None)
-
- for account in Account.search([]):
- self.assertEqual(account.name, account.template.name)
- self.assertEqual(account.code, account.template.code)
- self.assertEqual(account.type.template, account.template.type)
- self.assertEqual(account.reconcile, account.template.reconcile)
- self.assertEqual(
- account.start_date, account.template.start_date)
- self.assertEqual(account.end_date, account.template.end_date)
- self.assertEqual(
- account.party_required, account.template.party_required)
- self.assertEqual(
- account.general_ledger_balance,
- account.template.general_ledger_balance)
- self.assertEqual(
- set(t.template for t in account.taxes),
- set(t for t in account.template.taxes))
- if account.template.parent:
- self.assertEqual(
- account.parent.name, account.template.parent.name)
- else:
- self.assertEqual(account.parent, None)
-
- for tax_code in TaxCode.search([]):
- self.assertEqual(tax_code.name, tax_code.template.name)
- self.assertEqual(tax_code.code, tax_code.template.code)
- for line in tax_code.lines:
- self.assertEqual(line.code.template, line.template.code)
- self.assertEqual(line.operator, line.template.operator)
- self.assertEqual(line.type, line.template.type)
- self.assertEqual(line.tax.template, line.template.tax)
-
- for tax in Tax.search([]):
- self.assertEqual(tax.name, tax.template.name)
- self.assertEqual(tax.description, tax.template.description)
- self.assertEqual(tax.type, tax.template.type)
- self.assertEqual(tax.rate, tax.template.rate)
- self.assertEqual(tax.amount, tax.template.amount)
- self.assertEqual(
- tax.update_unit_price, tax.template.update_unit_price)
- self.assertEqual(
- tax.start_date, tax.template.start_date)
- self.assertEqual(tax.end_date, tax.template.end_date)
- self.assertEqual(
- tax.invoice_account.template, tax.template.invoice_account)
- self.assertEqual(
- tax.credit_note_account.template,
- tax.template.credit_note_account)
-
- company = create_company()
- with set_company(company):
- create_chart(company, True)
-
- with Transaction().set_context(active_test=False):
- self.assertEqual(Type.search([], count=True), 16)
- self.assertEqual(Account.search([], count=True), 7)
- self.assertEqual(Tax.search([], count=True), 1)
-
- check()
-
- with Transaction().set_user(0):
- root_type = TypeTemplate(ModelData.get_id(
- 'account', 'account_type_template_minimal_en'))
- root_type.name = 'Updated Minimal Chart'
- root_type.save()
- chart = AccountTemplate(ModelData.get_id(
- 'account', 'account_template_root_en'))
- new_type = TypeTemplate()
- new_type.name = 'New Type'
- new_type.parent = root_type
- new_type.statement = 'balance'
- new_type.save()
- updated_tax_type, = TypeTemplate.search([
- ('name', '=', "Tax"),
- ])
- updated_tax_type.parent = updated_tax_type.parent.parent
- updated_tax_type.save()
- new_account = AccountTemplate()
- new_account.name = 'New Account'
- new_account.parent = chart
- new_account.type = new_type
- new_account.save()
- updated_tax, = TaxTemplate.search([])
- updated_tax.name = 'VAT'
- updated_tax.invoice_account = new_account
- updated_tax.save()
- updated_account = AccountTemplate(ModelData.get_id(
- 'account', 'account_template_revenue_en'))
- updated_account.code = 'REV'
- updated_account.name = 'Updated Account'
- updated_account.parent = new_account
- updated_account.type = new_account.type
- updated_account.reconcile = True
- updated_account.end_date = datetime.date.today()
- updated_account.taxes = [updated_tax]
- updated_account.save()
- inactive_account = AccountTemplate(ModelData.get_id(
- 'account', 'account_template_expense_en'))
- inactive_account.end_date = datetime.date.min
- inactive_account.save()
- new_tax = TaxTemplate()
- new_tax.name = new_tax.description = '10% VAT'
- new_tax.type = 'percentage'
- new_tax.rate = Decimal('0.1')
- new_tax.account = chart
- new_tax.invoice_account = new_account
- new_tax.credit_note_account = new_account
- new_tax.save()
- updated_tax_code, = TaxCodeTemplate.search([
- ('name', '=', 'Tax Code'),
- ])
- updated_tax_code.name = 'Updated Tax Code'
- updated_tax_code.save()
- updated_tax_code_line, = updated_tax_code.lines
- updated_tax_code_line.operator = '-'
- updated_tax_code_line.save()
-
- with set_company(company):
- account, = Account.search([('parent', '=', None)])
- session_id, _, _ = UpdateChart.create()
- update_chart = UpdateChart(session_id)
- update_chart.start.account = account
- update_chart.transition_update()
-
- with Transaction().set_context(active_test=False):
- self.assertEqual(Type.search([], count=True), 17)
- self.assertEqual(Account.search([], count=True), 8)
- self.assertEqual(Tax.search([], count=True), 2)
-
- check()
-
- @with_transaction()
- def test_update_override(self):
- "Test all models are not updated when template override is True"
- pool = Pool()
- ModelData = pool.get('ir.model.data')
- TypeTemplate = pool.get('account.account.type.template')
- AccountTemplate = pool.get('account.account.template')
- TaxTemplate = pool.get('account.tax.template')
- TaxCodeTemplate = pool.get('account.tax.code.template')
- TaxCodeTemplateLine = pool.get('account.tax.code.line.template')
- UpdateChart = pool.get('account.update_chart', type='wizard')
- Type = pool.get('account.account.type')
- Account = pool.get('account.account')
- Tax = pool.get('account.tax')
- TaxCode = pool.get('account.tax.code')
- TaxCodeLine = pool.get('account.tax.code.line')
-
- new_name = "Updated"
-
- company = create_company()
- with set_company(company):
- create_chart(company, True)
-
- type_count = Type.search([], count=True)
- account_count = Account.search([], count=True)
- tax_count = Tax.search([], count=True)
- tax_code_count = TaxCode.search([], count=True)
- tax_code_line_count = TaxCodeLine.search([], count=True)
-
- with Transaction().set_user(0):
- root = AccountTemplate(ModelData.get_id(
- 'account', 'account_template_root_en'))
-
- template_type, = TypeTemplate.search([
- ('parent', '!=', None),
- ('parent', 'child_of', [root.type.id]),
- ], limit=1)
- template_type.name = new_name
- template_type.save()
- type_, = Type.search([('template', '=', template_type.id)])
- type_.template_override = True
- type_.save()
-
- template_account, = AccountTemplate.search([
- ('parent', '!=', None),
- ('parent', 'child_of', [root.id]),
- ], limit=1)
- template_account.name = new_name
- template_account.save()
- account, = Account.search([('template', '=', template_account.id)])
- account.template_override = True
- account.save()
-
- template_tax, = TaxTemplate.search([])
- template_tax.name = new_name
- template_tax.save()
- tax, = Tax.search([('template', '=', template_tax.id)])
- tax.template_override = True
- tax.save()
-
- template_tax_code, = TaxCodeTemplate.search([], limit=1)
- template_tax_code.name = new_name
- template_tax_code.save()
- tax_code, = TaxCode.search(
- [('template', '=', template_tax_code.id)])
- tax_code.template_override = True
- tax_code.save()
-
- template_tax_code_line, = TaxCodeTemplateLine.search([], limit=1)
- tax_code_line, = TaxCodeLine.search(
- [('template', '=', template_tax_code_line.id)])
- tax_code_line.template_override = True
- tax_code_line.save()
-
- with set_company(company):
- account, = Account.search([('parent', '=', None)])
- session_id, _, _ = UpdateChart.create()
- update_chart = UpdateChart(session_id)
- update_chart.start.account = account
- update_chart.transition_update()
-
- self.assertEqual(Type.search([], count=True), type_count)
- self.assertEqual(Account.search([], count=True), account_count)
- self.assertEqual(Tax.search([], count=True), tax_count)
- self.assertEqual(
- TaxCode.search([], count=True), tax_code_count)
- self.assertEqual(
- TaxCodeLine.search([], count=True), tax_code_line_count)
-
- for Model in [Type, Account, Tax, TaxCode]:
- for record in Model.search([]):
- self.assertNotEqual(record.name, new_name)
-
- @with_transaction()
- def test_update_inactive(self):
- "Test update chart of accounts with inactive account"
- pool = Pool()
- Account = pool.get('account.account')
- UpdateChart = pool.get('account.update_chart', type='wizard')
-
- company = create_company()
- with set_company(company):
- create_chart(company, tax=True)
- root, = Account.search([('parent', '=', None)])
-
- cash, = Account.search([('name', '=', 'Main Cash')])
- cash.template_override = True
- cash.end_date = datetime.date.min
- cash.save()
- self.assertFalse(cash.active)
-
- session_id, _, _ = UpdateChart.create()
- update_chart = UpdateChart(session_id)
- update_chart.start.account = root
- update_chart.transition_update()
-
- with Transaction().set_context(active_test=False):
- self.assertEqual(
- Account.search([('name', '=', 'Main Cash')], count=True),
- 1)
-
-
-def suite():
- suite = trytond.tests.test_tryton.suite()
- suite.addTests(unittest.TestLoader().loadTestsFromTestCase(
- AccountTestCase))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_account_reconciliation.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_account_reconcile.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_account_reconcile_automatic.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_move_cancel.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_move_line_group.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_move_line_reschedule.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_move_template.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_reports.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_renew_fiscalyear.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_close_fiscalyear.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_account_active.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_tax_code.rst',
- tearDown=doctest_teardown, encoding='utf-8',
- checker=doctest_checker,
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- return suite
diff -r f17e81152e14 -r 675bdc9d556b tests/test_module.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_module.py Sat Apr 16 18:30:15 2022 +0200
@@ -0,0 +1,1740 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import datetime
+from decimal import Decimal
+
+from dateutil.relativedelta import relativedelta
+
+from trytond.exceptions import UserError
+from trytond.modules.account.exceptions import FiscalYearDatesError
+from trytond.modules.account.tax import TaxableMixin
+from trytond.modules.company.tests import (
+ CompanyTestMixin, PartyCompanyCheckEraseMixin, create_company, set_company)
+from trytond.modules.currency.tests import create_currency
+from trytond.pool import Pool
+from trytond.tests.test_tryton import ModuleTestCase, with_transaction
+from trytond.transaction import Transaction
+
+
+def create_chart(company, tax=False, chart='account.account_template_root_en'):
+ pool = Pool()
+ AccountTemplate = pool.get('account.account.template')
+ TaxTemplate = pool.get('account.tax.template')
+ TaxCodeTemplate = pool.get('account.tax.code.template')
+ ModelData = pool.get('ir.model.data')
+ CreateChart = pool.get('account.create_chart', type='wizard')
+ Account = pool.get('account.account')
+
+ module, xml_id = chart.split('.')
+ template = AccountTemplate(ModelData.get_id(module, xml_id))
+ if tax:
+ tax_account = AccountTemplate(ModelData.get_id(
+ 'account', 'account_template_tax_en'))
+ with Transaction().set_user(0):
+ tax = TaxTemplate()
+ tax.name = tax.description = '20% VAT'
+ tax.type = 'percentage'
+ tax.rate = Decimal('0.2')
+ tax.account = template
+ tax.invoice_account = tax_account
+ tax.credit_note_account = tax_account
+ tax.save()
+
+ TaxCodeTemplate.create([{
+ 'name': 'Tax Code',
+ 'account': template,
+ 'lines': [('create', [{
+ 'operator': '+',
+ 'type': 'invoice',
+ 'amount': 'tax',
+ 'tax': tax.id,
+ }])],
+ }, {
+ 'name': 'Base Code',
+ 'account': template,
+ 'lines': [('create', [{
+ 'operator': '+',
+ 'type': 'invoice',
+ 'amount': 'base',
+ 'tax': tax.id,
+ }])],
+ }])
+
+ session_id, _, _ = CreateChart.create()
+ create_chart = CreateChart(session_id)
+ create_chart.account.account_template = template
+ create_chart.account.company = company
+ create_chart.transition_create_account()
+ properties_state = create_chart.states['properties']
+ for name, value in properties_state.get_defaults(
+ create_chart, 'properties',
+ list(create_chart.properties._fields.keys())).items():
+ if name in create_chart.properties._fields:
+ setattr(create_chart.properties, name, value)
+ if not create_chart.properties.account_receivable:
+ receivable, = Account.search([
+ ('type.receivable', '=', True),
+ ('party_required', '=', True),
+ ('company', '=', company.id),
+ ], limit=1)
+ create_chart.properties.account_receivable = receivable
+ if not create_chart.properties.account_payable:
+ payable, = Account.search([
+ ('type.payable', '=', True),
+ ('party_required', '=', True),
+ ('company', '=', company.id),
+ ], limit=1)
+ create_chart.properties.account_payable = payable
+ create_chart.transition_create_properties()
+
+
+def get_fiscalyear(company, today=None, start_date=None, end_date=None):
+ pool = Pool()
+ Sequence = pool.get('ir.sequence')
+ SequenceType = pool.get('ir.sequence.type')
+ FiscalYear = pool.get('account.fiscalyear')
+
+ if not today:
+ today = datetime.date.today()
+ if not start_date:
+ start_date = today.replace(month=1, day=1)
+ if not end_date:
+ end_date = today.replace(month=12, day=31)
+
+ sequence_type, = SequenceType.search([
+ ('name', '=', "Account Move"),
+ ], limit=1)
+ sequence, = Sequence.create([{
+ 'name': '%s' % today.year,
+ 'sequence_type': sequence_type.id,
+ 'company': company.id,
+ }])
+ fiscalyear = FiscalYear(name='%s' % today.year, company=company)
+ fiscalyear.start_date = start_date
+ fiscalyear.end_date = end_date
+ fiscalyear.post_move_sequence = sequence
+ return fiscalyear
+
+
+def close_fiscalyear(fiscalyear):
+ pool = Pool()
+ Sequence = pool.get('ir.sequence')
+ Journal = pool.get('account.journal')
+ Period = pool.get('account.period')
+ AccountType = pool.get('account.account.type')
+ Account = pool.get('account.account')
+ Move = pool.get('account.move')
+ FiscalYear = pool.get('account.fiscalyear')
+ BalanceNonDeferral = pool.get(
+ 'account.fiscalyear.balance_non_deferral', type='wizard')
+
+ # Balance non-deferral
+ journal_sequence, = Sequence.search([
+ ('sequence_type.name', '=', "Account Journal"),
+ ], limit=1)
+ journal_closing, = Journal.create([{
+ 'name': 'Closing',
+ 'code': 'CLO',
+ 'type': 'situation',
+ 'sequence': journal_sequence.id,
+ }])
+ period_closing, = Period.create([{
+ 'name': 'Closing',
+ 'start_date': fiscalyear.end_date,
+ 'end_date': fiscalyear.end_date,
+ 'fiscalyear': fiscalyear.id,
+ 'type': 'adjustment',
+ }])
+ type_equity, = AccountType.search([
+ ('name', '=', 'Equity'),
+ ])
+ revenue, = Account.search([
+ ('type.revenue', '=', True),
+ ])
+ account_pl, = Account.create([{
+ 'name': 'P&L',
+ 'type': type_equity.id,
+ 'parent': revenue.parent.id,
+ }])
+
+ session_id = BalanceNonDeferral.create()[0]
+ balance_non_deferral = BalanceNonDeferral(session_id)
+
+ balance_non_deferral.start.fiscalyear = fiscalyear
+ balance_non_deferral.start.journal = journal_closing
+ balance_non_deferral.start.period = period_closing
+ balance_non_deferral.start.credit_account = account_pl
+ balance_non_deferral.start.debit_account = account_pl
+
+ balance_non_deferral._execute('balance')
+
+ moves = Move.search([
+ ('state', '=', 'draft'),
+ ('period.fiscalyear', '=', fiscalyear.id),
+ ])
+ Move.post(moves)
+
+ # Close fiscalyear
+ FiscalYear.close([fiscalyear])
+
+
+class AccountTestCase(
+ PartyCompanyCheckEraseMixin, CompanyTestMixin, ModuleTestCase):
+ 'Test Account module'
+ module = 'account'
+
+ @with_transaction()
+ def test_account_chart(self):
+ 'Test creation and update of minimal chart of accounts'
+ pool = Pool()
+ Account = pool.get('account.account')
+ Tax = pool.get('account.tax')
+ UpdateChart = pool.get('account.update_chart', type='wizard')
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company, tax=True)
+ root, = Account.search([('parent', '=', None)])
+
+ # Create an account and tax without template
+
+ cash, = Account.search([('name', '=', 'Main Cash')])
+ Account.copy([cash.id])
+
+ tax, = Tax.search([])
+ Tax.copy([tax.id])
+
+ session_id, _, _ = UpdateChart.create()
+ update_chart = UpdateChart(session_id)
+ update_chart.start.account = root
+ update_chart.transition_update()
+
+ @with_transaction()
+ def test_account_chart_many_companies(self):
+ "Test creation of chart of accounts for many companies"
+ company1 = create_company()
+ with set_company(company1):
+ create_chart(company1, tax=True)
+
+ company2 = create_company()
+ with set_company(company2):
+ create_chart(company2, tax=True)
+
+ @with_transaction()
+ def test_fiscalyear(self):
+ 'Test fiscalyear'
+ pool = Pool()
+ FiscalYear = pool.get('account.fiscalyear')
+ company = create_company()
+ with set_company(company):
+ fiscalyear = get_fiscalyear(company)
+ fiscalyear.save()
+ FiscalYear.create_period([fiscalyear])
+ self.assertEqual(len(fiscalyear.periods), 12)
+
+ @with_transaction()
+ def test_fiscalyear_create_periods(self):
+ 'Test fiscalyear create periods'
+ FiscalYear = Pool().get('account.fiscalyear')
+
+ company = create_company()
+ with set_company(company):
+ year = datetime.date.today().year
+ date = datetime.date
+ for start_date, end_date, interval, end_day, num_periods in [
+ (date(year, 1, 1), date(year, 12, 31), 1, 31, 12),
+ (date(year + 1, 1, 1), date(year + 1, 12, 31), 3, 31, 4),
+ (date(year + 2, 1, 1), date(year + 2, 12, 31), 5, 31, 3),
+ (date(year + 3, 4, 6), date(year + 4, 4, 5), 1, 5, 12),
+ (date(year + 4, 4, 6), date(year + 5, 4, 5), 3, 5, 4),
+ (date(year + 5, 4, 6), date(year + 6, 4, 5), 5, 5, 3),
+ (date(year + 6, 6, 6), date(year + 6, 12, 31), 1, 29, 8),
+ (date(year + 7, 7, 7), date(year + 7, 12, 31), 3, 29, 3),
+ (date(year + 8, 1, 1), date(year + 9, 8, 7), 1, 29, 20),
+ (date(year + 9, 9, 9), date(year + 10, 11, 12), 3, 29, 5),
+ ]:
+ fiscalyear = get_fiscalyear(
+ company, start_date, start_date, end_date)
+ fiscalyear.save()
+ FiscalYear.create_period([fiscalyear], interval, end_day)
+
+ self.assertEqual(len(fiscalyear.periods), num_periods)
+
+ self.assertEqual(fiscalyear.periods[-1].end_date, end_date)
+ self.assertTrue(all(
+ p.end_date == p.end_date + relativedelta(day=end_day)
+ for p in fiscalyear.periods[:-1]))
+
+ self.assertEqual(fiscalyear.periods[0].start_date, start_date)
+ self.assertTrue(all(
+ p1.end_date + relativedelta(days=1) == p2.start_date
+ for p1, p2 in zip(
+ fiscalyear.periods[:-1], fiscalyear.periods[1:])))
+
+ @with_transaction()
+ def test_open_fiscalyear_before_open(self):
+ "Test create open fiscal year before an open one"
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+ fiscalyear = get_fiscalyear(
+ company,
+ start_date=datetime.date(2022, 1, 1),
+ end_date=datetime.date(2022, 12, 31))
+ fiscalyear.save()
+
+ earlier_fiscalyear = get_fiscalyear(
+ company,
+ start_date=datetime.date(2021, 1, 1),
+ end_date=datetime.date(2021, 12, 31))
+ earlier_fiscalyear.save()
+
+ @with_transaction()
+ def test_open_fiscalyear_before_close(self):
+ "Test create open fiscal year before a close one"
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+ fiscalyear = get_fiscalyear(
+ company,
+ start_date=datetime.date(2022, 1, 1),
+ end_date=datetime.date(2022, 12, 31))
+ fiscalyear.save()
+ close_fiscalyear(fiscalyear)
+
+ earlier_fiscalyear = get_fiscalyear(
+ company,
+ start_date=datetime.date(2021, 1, 1),
+ end_date=datetime.date(2021, 12, 31))
+ with self.assertRaises(FiscalYearDatesError):
+ earlier_fiscalyear.save()
+
+ @with_transaction()
+ def test_account_debit_credit(self):
+ 'Test account debit/credit'
+ pool = Pool()
+ Party = pool.get('party.party')
+ FiscalYear = pool.get('account.fiscalyear')
+ Journal = pool.get('account.journal')
+ Account = pool.get('account.account')
+ Move = pool.get('account.move')
+
+ party = Party(name='Party')
+ party.save()
+
+ company = create_company()
+ with set_company(company):
+ fiscalyear = get_fiscalyear(company)
+ fiscalyear.save()
+ FiscalYear.create_period([fiscalyear])
+ period = fiscalyear.periods[0]
+ create_chart(company)
+
+ sec_cur = create_currency('sec')
+
+ journal_revenue, = Journal.search([
+ ('code', '=', 'REV'),
+ ])
+ journal_expense, = Journal.search([
+ ('code', '=', 'EXP'),
+ ])
+ revenue, = Account.search([
+ ('type.revenue', '=', True),
+ ])
+ receivable, = Account.search([
+ ('type.receivable', '=', True),
+ ])
+ expense, = Account.search([
+ ('type.expense', '=', True),
+ ])
+ payable, = Account.search([
+ ('type.payable', '=', True),
+ ])
+ cash, = Account.search([
+ ('name', '=', 'Main Cash'),
+ ])
+ cash_cur, = Account.copy([cash], default={
+ 'second_currency': sec_cur.id,
+ })
+ # Create some moves
+ vlist = [
+ {
+ 'period': period.id,
+ 'journal': journal_revenue.id,
+ 'date': period.start_date,
+ 'lines': [
+ ('create', [{
+ 'account': revenue.id,
+ 'credit': Decimal(100),
+ }, {
+ 'account': receivable.id,
+ 'debit': Decimal(100),
+ 'party': party.id,
+ }]),
+ ],
+ },
+ {
+ 'period': period.id,
+ 'journal': journal_revenue.id,
+ 'date': period.start_date,
+ 'lines': [
+ ('create', [{
+ 'account': receivable.id,
+ 'credit': Decimal(80),
+ 'second_currency': sec_cur.id,
+ 'amount_second_currency': -Decimal(50),
+ 'party': party.id,
+ }, {
+ 'account': cash_cur.id,
+ 'debit': Decimal(80),
+ 'second_currency': sec_cur.id,
+ 'amount_second_currency': Decimal(50),
+ }]),
+ ],
+ },
+ {
+ 'period': period.id,
+ 'journal': journal_expense.id,
+ 'date': period.start_date,
+ 'lines': [
+ ('create', [{
+ 'account': expense.id,
+ 'debit': Decimal(30),
+ }, {
+ 'account': payable.id,
+ 'credit': Decimal(30),
+ 'party': party.id,
+ }]),
+ ],
+ },
+ ]
+ Move.create(vlist)
+
+ # Test debit/credit
+ self.assertEqual((revenue.debit, revenue.credit),
+ (Decimal(0), Decimal(100)))
+ self.assertEqual(revenue.balance, Decimal(-100))
+
+ self.assertEqual((cash_cur.debit, cash_cur.credit),
+ (Decimal(80), Decimal(0)))
+ self.assertEqual(
+ cash_cur.amount_second_currency, Decimal(50))
+
+ # Use next fiscalyear
+ today = datetime.date.today()
+ next_fiscalyear = get_fiscalyear(company,
+ today=today.replace(year=today.year + 1))
+ next_fiscalyear.save()
+ FiscalYear.create_period([next_fiscalyear])
+
+ # Test debit/credit for next year
+ with Transaction().set_context(fiscalyear=next_fiscalyear.id):
+ revenue = Account(revenue.id)
+ self.assertEqual((revenue.debit, revenue.credit),
+ (Decimal(0), Decimal(0)))
+ self.assertEqual(revenue.balance, Decimal(-100))
+
+ cash_cur = Account(cash_cur.id)
+ self.assertEqual(
+ cash_cur.amount_second_currency, Decimal(50))
+
+ # Test debit/credit cumulate for next year
+ with Transaction().set_context(fiscalyear=next_fiscalyear.id,
+ cumulate=True):
+ revenue = Account(revenue.id)
+ self.assertEqual((revenue.debit, revenue.credit),
+ (Decimal(0), Decimal(100)))
+ self.assertEqual(revenue.balance, Decimal(-100))
+
+ cash_cur = Account(cash_cur.id)
+ self.assertEqual(
+ cash_cur.amount_second_currency, Decimal(50))
+
+ close_fiscalyear(fiscalyear)
+
+ # Check deferral
+ self.assertEqual(revenue.deferrals, ())
+
+ deferral_receivable, = receivable.deferrals
+ self.assertEqual(
+ (deferral_receivable.debit, deferral_receivable.credit),
+ (Decimal(100), Decimal(80)))
+ self.assertEqual(deferral_receivable.fiscalyear, fiscalyear)
+
+ cash_cur = Account(cash_cur.id)
+ deferral_cash_cur, = cash_cur.deferrals
+ self.assertEqual(
+ deferral_cash_cur.amount_second_currency, Decimal(50))
+
+ # Test debit/credit
+ with Transaction().set_context(fiscalyear=fiscalyear.id):
+ revenue = Account(revenue.id)
+ self.assertEqual((revenue.debit, revenue.credit),
+ (Decimal(100), Decimal(100)))
+ self.assertEqual(revenue.balance, Decimal(0))
+
+ receivable = Account(receivable.id)
+ self.assertEqual((receivable.debit, receivable.credit),
+ (Decimal(100), Decimal(80)))
+ self.assertEqual(receivable.balance, Decimal(20))
+
+ cash_cur = Account(cash_cur.id)
+ self.assertEqual(
+ cash_cur.amount_second_currency, Decimal(50))
+
+ # Test debit/credit for next year
+ with Transaction().set_context(fiscalyear=next_fiscalyear.id):
+ revenue = Account(revenue.id)
+ self.assertEqual((revenue.debit, revenue.credit),
+ (Decimal(0), Decimal(0)))
+ self.assertEqual(revenue.balance, Decimal(0))
+
+ receivable = Account(receivable.id)
+ self.assertEqual((receivable.debit, receivable.credit),
+ (Decimal(0), Decimal(0)))
+ self.assertEqual(receivable.balance, Decimal(20))
+
+ cash_cur = Account(cash_cur.id)
+ self.assertEqual(
+ cash_cur.amount_second_currency, Decimal(50))
+
+ # Test debit/credit cumulate for next year
+ with Transaction().set_context(fiscalyear=next_fiscalyear.id,
+ cumulate=True):
+ revenue = Account(revenue.id)
+ self.assertEqual((revenue.debit, revenue.credit),
+ (Decimal(0), Decimal(0)))
+ self.assertEqual(revenue.balance, Decimal(0))
+
+ receivable = Account(receivable.id)
+ self.assertEqual((receivable.debit, receivable.credit),
+ (Decimal(100), Decimal(80)))
+ self.assertEqual(receivable.balance, Decimal(20))
+
+ cash_cur = Account(cash_cur.id)
+ self.assertEqual(
+ cash_cur.amount_second_currency, Decimal(50))
+
+ @with_transaction()
+ def test_account_type_amount(self):
+ "Test account type amount"
+ pool = Pool()
+ Party = pool.get('party.party')
+ FiscalYear = pool.get('account.fiscalyear')
+ Journal = pool.get('account.journal')
+ Account = pool.get('account.account')
+ Move = pool.get('account.move')
+ Type = pool.get('account.account.type')
+
+ party = Party(name='Party')
+ party.save()
+
+ company = create_company()
+ with set_company(company):
+ fiscalyear = get_fiscalyear(company)
+ fiscalyear.save()
+ FiscalYear.create_period([fiscalyear])
+ period = fiscalyear.periods[0]
+ create_chart(company)
+
+ journal_revenue, = Journal.search([
+ ('code', '=', 'REV'),
+ ])
+ revenue, = Account.search([
+ ('type.revenue', '=', True),
+ ])
+ receivable, = Account.search([
+ ('type.receivable', '=', True),
+ ])
+
+ Move.create([{
+ 'period': period.id,
+ 'journal': journal_revenue.id,
+ 'date': period.start_date,
+ 'lines': [
+ ('create', [{
+ 'account': revenue.id,
+ 'credit': Decimal(100),
+ }, {
+ 'account': receivable.id,
+ 'debit': Decimal(100),
+ 'party': party.id,
+ }]),
+ ],
+ }])
+
+ with Transaction().set_context(fiscalyear=fiscalyear.id):
+ revenue_type = Type(revenue.type)
+ receivable_type = Type(receivable.type)
+
+ # Test type amount
+ self.assertEqual(revenue_type.amount, Decimal(100))
+ self.assertEqual(receivable_type.amount, Decimal(100))
+
+ # Set a debit type on receivable
+ with Transaction().set_context(fiscalyear=fiscalyear.id):
+ debit_receivable_type, = Type.copy([receivable_type])
+ receivable.debit_type = debit_receivable_type
+ receivable.credit_type = None
+ receivable.save()
+ self.assertEqual(receivable_type.amount, Decimal(0))
+ self.assertEqual(debit_receivable_type.amount, Decimal(100))
+
+ # Set a debit type on revenue
+ with Transaction().set_context(fiscalyear=fiscalyear.id):
+ debit_revenue_type, = Type.copy([revenue_type])
+ revenue.debit_type = debit_revenue_type
+ revenue.credit_type = None
+ revenue.save()
+ self.assertEqual(revenue_type.amount, Decimal(100))
+ self.assertEqual(debit_revenue_type.amount, Decimal(0))
+
+ # Set a credit type on revenue
+ with Transaction().set_context(fiscalyear=fiscalyear.id):
+ credit_revenue_type, = Type.copy([revenue_type])
+ revenue.credit_type = credit_revenue_type
+ revenue.debit_type = None
+ revenue.save()
+ self.assertEqual(revenue_type.amount, Decimal(0))
+ self.assertEqual(credit_revenue_type.amount, Decimal(100))
+
+ # Set a credit type on receivable
+ with Transaction().set_context(fiscalyear=fiscalyear.id):
+ credit_receivable_type, = Type.copy([receivable_type])
+ receivable.credit_type = credit_receivable_type
+ receivable.debit_type = None
+ receivable.save()
+ self.assertEqual(receivable_type.amount, Decimal(100))
+ self.assertEqual(credit_receivable_type.amount, Decimal(0))
+
+ @with_transaction()
+ def test_move_post(self):
+ "Test posting move"
+ pool = Pool()
+ Party = pool.get('party.party')
+ FiscalYear = pool.get('account.fiscalyear')
+ Journal = pool.get('account.journal')
+ Account = pool.get('account.account')
+ Move = pool.get('account.move')
+ Line = pool.get('account.move.line')
+ Period = pool.get('account.period')
+
+ party = Party(name='Party')
+ party.save()
+
+ company = create_company()
+ with set_company(company):
+ fiscalyear = get_fiscalyear(company)
+ fiscalyear.save()
+ FiscalYear.create_period([fiscalyear])
+ period = fiscalyear.periods[0]
+ create_chart(company)
+
+ journal_revenue, = Journal.search([
+ ('code', '=', 'REV'),
+ ])
+ revenue, = Account.search([
+ ('type.revenue', '=', True),
+ ])
+ receivable, = Account.search([
+ ('type.receivable', '=', True),
+ ])
+
+ move = Move()
+ move.period = period
+ move.journal = journal_revenue
+ move.date = period.start_date
+ move.lines = [
+ Line(account=revenue, credit=Decimal(100)),
+ Line(account=receivable, debit=Decimal(100), party=party),
+ ]
+ move.save()
+ Move.post([move])
+ move_id = move.id
+
+ self.assertEqual(move.state, 'posted')
+
+ # Can not post an empty move
+ with self.assertRaises(UserError):
+ move = Move()
+ move.period = period
+ move.journal = journal_revenue
+ move.date = period.start_date
+ move.save()
+ Move.post([move])
+ Move.delete([move])
+
+ # Can not modify posted move
+ with self.assertRaises(UserError):
+ move = Move(move_id)
+ move.date = period.end_date
+ move.save()
+
+ # Can not go back to draft
+ with self.assertRaises(UserError):
+ move = Move(move_id)
+ move.state = 'draft'
+ move.save()
+
+ Period.close([period])
+
+ # Can not create move with lines on closed period
+ with self.assertRaises(UserError):
+ move = Move()
+ move.period = period
+ move.journal = journal_revenue
+ move.date = period.start_date
+ move.lines = [
+ Line(account=revenue, credit=Decimal(100)),
+ Line(account=receivable, debit=Decimal(100), party=party),
+ ]
+ move.save()
+
+ @with_transaction()
+ def test_tax_compute(self):
+ 'Test tax compute/reverse_compute'
+ pool = Pool()
+ Account = pool.get('account.account')
+ Tax = pool.get('account.tax')
+ today = datetime.date.today()
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+
+ tax_account, = Account.search([
+ ('name', '=', 'Main Tax'),
+ ])
+ tax = Tax()
+ tax.name = tax.description = 'Test'
+ tax.type = 'none'
+ tax.invoice_account = tax_account
+ tax.credit_note_account = tax_account
+
+ child1 = Tax()
+ child1.name = child1.description = 'Child 1'
+ child1.type = 'percentage'
+ child1.rate = Decimal('0.2')
+ child1.invoice_account = tax_account
+ child1.credit_note_account = tax_account
+ child1.save()
+
+ child2 = Tax()
+ child2.name = child2.description = 'Child 1'
+ child2.type = 'fixed'
+ child2.amount = Decimal('10')
+ child2.invoice_account = tax_account
+ child2.credit_note_account = tax_account
+ child2.save()
+
+ tax.childs = [child1, child2]
+ tax.save()
+
+ self.assertEqual(Tax.compute([tax], Decimal('100'), 2, today),
+ [{
+ 'base': Decimal('200'),
+ 'amount': Decimal('40.0'),
+ 'tax': child1,
+ }, {
+ 'base': Decimal('200'),
+ 'amount': Decimal('20'),
+ 'tax': child2,
+ }])
+
+ self.assertEqual(
+ Tax.reverse_compute(Decimal('130'), [tax], today),
+ Decimal('100'))
+
+ child1.end_date = today + relativedelta(days=5)
+ child1.save()
+ self.assertEqual(Tax.compute([tax], Decimal('100'), 2, today),
+ [{
+ 'base': Decimal('200'),
+ 'amount': Decimal('40.0'),
+ 'tax': child1,
+ }, {
+ 'base': Decimal('200'),
+ 'amount': Decimal('20'),
+ 'tax': child2,
+ }])
+
+ self.assertEqual(
+ Tax.reverse_compute(Decimal('130'), [tax], today),
+ Decimal('100'))
+
+ child1.start_date = today + relativedelta(days=1)
+ child1.save()
+ self.assertEqual(Tax.compute([tax], Decimal('100'), 2, today),
+ [{
+ 'base': Decimal('200'),
+ 'amount': Decimal('20'),
+ 'tax': child2,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(Decimal('110'), [tax], today),
+ Decimal('100'))
+ self.assertEqual(Tax.compute([tax], Decimal('100'), 2,
+ today + relativedelta(days=1)), [{
+ 'base': Decimal('200'),
+ 'amount': Decimal('40.0'),
+ 'tax': child1,
+ }, {
+ 'base': Decimal('200'),
+ 'amount': Decimal('20'),
+ 'tax': child2,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(
+ Decimal('130'), [tax], today + relativedelta(days=1)),
+ Decimal('100'))
+ self.assertEqual(Tax.compute([tax], Decimal('100'), 2,
+ today + relativedelta(days=5)), [{
+ 'base': Decimal('200'),
+ 'amount': Decimal('40.0'),
+ 'tax': child1,
+ }, {
+ 'base': Decimal('200'),
+ 'amount': Decimal('20'),
+ 'tax': child2,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(Decimal('130'), [tax],
+ today + relativedelta(days=5)),
+ Decimal('100'))
+ self.assertEqual(Tax.compute([tax], Decimal('100'), 2,
+ today + relativedelta(days=6)), [{
+ 'base': Decimal('200'),
+ 'amount': Decimal('20'),
+ 'tax': child2,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(Decimal('110'), [tax],
+ today + relativedelta(days=6)),
+ Decimal('100'))
+
+ child1.end_date = None
+ child1.save()
+ self.assertEqual(Tax.compute([tax], Decimal('100'), 2,
+ today + relativedelta(days=6)), [{
+ 'base': Decimal('200'),
+ 'amount': Decimal('40.0'),
+ 'tax': child1,
+ }, {
+ 'base': Decimal('200'),
+ 'amount': Decimal('20'),
+ 'tax': child2,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(Decimal('130'), [tax],
+ today + relativedelta(days=6)),
+ Decimal('100'))
+
+ ecotax1 = Tax()
+ ecotax1.name = ecotax1.description = 'EcoTax 1'
+ ecotax1.type = 'fixed'
+ ecotax1.amount = Decimal(5)
+ ecotax1.invoice_account = tax_account
+ ecotax1.credit_note_account = tax_account
+ ecotax1.sequence = 10
+ ecotax1.save()
+
+ vat0 = Tax()
+ vat0.name = vat0.description = 'VAT0'
+ vat0.type = 'percentage'
+ vat0.rate = Decimal('0.1')
+ vat0.invoice_account = tax_account
+ vat0.credit_note_account = tax_account
+ vat0.sequence = 5
+ vat0.save()
+
+ vat1 = Tax()
+ vat1.name = vat1.description = 'VAT1'
+ vat1.type = 'percentage'
+ vat1.rate = Decimal('0.2')
+ vat1.invoice_account = tax_account
+ vat1.credit_note_account = tax_account
+ vat1.sequence = 20
+ vat1.save()
+
+ self.assertEqual(
+ Tax.compute([vat0, ecotax1, vat1], Decimal(100), 1, today),
+ [{
+ 'base': Decimal(100),
+ 'amount': Decimal(10),
+ 'tax': vat0,
+ }, {
+ 'base': Decimal(100),
+ 'amount': Decimal(5),
+ 'tax': ecotax1,
+ }, {
+ 'base': Decimal(100),
+ 'amount': Decimal(20),
+ 'tax': vat1,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(
+ Decimal(135), [vat0, ecotax1, vat1], today),
+ Decimal(100))
+
+ @with_transaction()
+ def test_tax_compute_with_update_unit_price(self):
+ 'Test tax compute with unit_price modifying tax'
+ pool = Pool()
+ Account = pool.get('account.account')
+ Date = pool.get('ir.date')
+ Tax = pool.get('account.tax')
+ today = Date.today()
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+
+ tax_account, = Account.search([
+ ('name', '=', 'Main Tax'),
+ ])
+ ecotax1 = Tax()
+ ecotax1.name = ecotax1.description = 'EcoTax 1'
+ ecotax1.type = 'fixed'
+ ecotax1.amount = Decimal(5)
+ ecotax1.invoice_account = tax_account
+ ecotax1.credit_note_account = tax_account
+ ecotax1.update_unit_price = True
+ ecotax1.sequence = 10
+ ecotax1.save()
+
+ vat1 = Tax()
+ vat1.name = vat1.description = 'VAT1'
+ vat1.type = 'percentage'
+ vat1.rate = Decimal('0.2')
+ vat1.invoice_account = tax_account
+ vat1.credit_note_account = tax_account
+ vat1.sequence = 20
+ vat1.save()
+
+ self.assertEqual(
+ Tax.compute([ecotax1, vat1], Decimal(100), 5, today),
+ [{
+ 'base': Decimal(500),
+ 'amount': Decimal(25),
+ 'tax': ecotax1,
+ }, {
+ 'base': Decimal(525),
+ 'amount': Decimal(105),
+ 'tax': vat1,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(Decimal(126), [ecotax1, vat1], today),
+ Decimal(100))
+
+ ecotax2 = Tax()
+ ecotax2.name = ecotax2.description = 'EcoTax 2'
+ ecotax2.type = 'percentage'
+ ecotax2.rate = Decimal('0.5')
+ ecotax2.invoice_account = tax_account
+ ecotax2.credit_note_account = tax_account
+ ecotax2.update_unit_price = True
+ ecotax2.sequence = 10
+ ecotax2.save()
+
+ self.assertEqual(
+ Tax.compute([ecotax1, ecotax2, vat1], Decimal(100), 1, today),
+ [{
+ 'base': Decimal(100),
+ 'amount': Decimal(5),
+ 'tax': ecotax1,
+ }, {
+ 'base': Decimal(100),
+ 'amount': Decimal(50),
+ 'tax': ecotax2,
+ }, {
+ 'base': Decimal(155),
+ 'amount': Decimal(31),
+ 'tax': vat1,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(
+ Decimal(186), [ecotax1, ecotax2, vat1], today),
+ Decimal(100))
+
+ vat0 = Tax()
+ vat0.name = vat0.description = 'VAT0'
+ vat0.type = 'percentage'
+ vat0.rate = Decimal('0.1')
+ vat0.invoice_account = tax_account
+ vat0.credit_note_account = tax_account
+ vat0.sequence = 5
+ vat0.save()
+
+ self.assertEqual(
+ Tax.compute([vat0, ecotax1, vat1], Decimal(100), 1, today),
+ [{
+ 'base': Decimal(100),
+ 'amount': Decimal(10),
+ 'tax': vat0,
+ }, {
+ 'base': Decimal(100),
+ 'amount': Decimal(5),
+ 'tax': ecotax1,
+ }, {
+ 'base': Decimal(105),
+ 'amount': Decimal(21),
+ 'tax': vat1,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(
+ Decimal(136), [vat0, ecotax1, vat1], today),
+ Decimal(100))
+
+ self.assertEqual(
+ Tax.compute([vat0, ecotax1, ecotax2, vat1],
+ Decimal(100), 1, today),
+ [{
+ 'base': Decimal(100),
+ 'amount': Decimal(10),
+ 'tax': vat0,
+ }, {
+ 'base': Decimal(100),
+ 'amount': Decimal(5),
+ 'tax': ecotax1,
+ }, {
+ 'base': Decimal(100),
+ 'amount': Decimal(50),
+ 'tax': ecotax2,
+ }, {
+ 'base': Decimal(155),
+ 'amount': Decimal(31),
+ 'tax': vat1,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(
+ Decimal(196), [vat0, ecotax1, ecotax2, vat1], today),
+ Decimal(100))
+
+ vat2 = Tax()
+ vat2.name = vat2.description = 'VAT2'
+ vat2.type = 'percentage'
+ vat2.rate = Decimal('0.3')
+ vat2.invoice_account = tax_account
+ vat2.credit_note_account = tax_account
+ vat2.sequence = 30
+ vat2.save()
+
+ self.assertEqual(
+ Tax.compute([vat0, ecotax1, vat1, vat2],
+ Decimal(100), 1, today),
+ [{
+ 'base': Decimal(100),
+ 'amount': Decimal(10),
+ 'tax': vat0,
+ }, {
+ 'base': Decimal(100),
+ 'amount': Decimal(5),
+ 'tax': ecotax1,
+ }, {
+ 'base': Decimal(105),
+ 'amount': Decimal(21),
+ 'tax': vat1,
+ }, {
+ 'base': Decimal(105),
+ 'amount': Decimal('31.5'),
+ 'tax': vat2,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(
+ Decimal('167.5'), [vat0, ecotax1, vat1, vat2], today),
+ Decimal(100))
+
+ ecotax3 = Tax()
+ ecotax3.name = ecotax3.description = 'ECOTAX3'
+ ecotax3.type = 'percentage'
+ ecotax3.rate = Decimal('0.4')
+ ecotax3.invoice_account = tax_account
+ ecotax3.credit_note_account = tax_account
+ ecotax3.update_unit_price = True
+ ecotax3.sequence = 25
+ ecotax3.save()
+
+ self.assertEqual(
+ Tax.compute([vat0, ecotax1, vat1, ecotax3, vat2],
+ Decimal(100), 1, today),
+ [{
+ 'base': Decimal(100),
+ 'amount': Decimal(10),
+ 'tax': vat0,
+ }, {
+ 'base': Decimal(100),
+ 'amount': Decimal(5),
+ 'tax': ecotax1,
+ }, {
+ 'base': Decimal(105),
+ 'amount': Decimal(21),
+ 'tax': vat1,
+ }, {
+ 'base': Decimal(105),
+ 'amount': Decimal('42'),
+ 'tax': ecotax3,
+ }, {
+ 'base': Decimal(147),
+ 'amount': Decimal('44.1'),
+ 'tax': vat2
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(
+ Decimal('222.1'),
+ [vat0, ecotax1, vat1, ecotax3, vat2],
+ today),
+ Decimal(100))
+
+ class Taxable(TaxableMixin):
+ __slots__ = ('currency', 'taxable_lines', 'company')
+
+ def __init__(self, currency=None, taxable_lines=None, company=None):
+ super().__init__()
+ self.currency = currency
+ self.taxable_lines = taxable_lines
+ self.company = company
+
+ @with_transaction()
+ def test_taxable_mixin_line(self):
+ "Test TaxableMixin with rounding on line"
+ pool = Pool()
+ Tax = pool.get('account.tax')
+ Configuration = pool.get('account.configuration')
+ currency = create_currency('cur')
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company, tax=True)
+ tax, = Tax.search([])
+ config = Configuration(1)
+ config.tax_rounding = 'line'
+ config.save()
+
+ taxable = self.Taxable(
+ currency=currency,
+ taxable_lines=[
+ ([tax], Decimal('1.001'), 1, None),
+ ] * 100,
+ company=company)
+
+ taxes = taxable._get_taxes()
+
+ tax, = taxes
+ self.assertEqual(tax['base'], Decimal('100.00'))
+ self.assertEqual(tax['amount'], Decimal('20.00'))
+
+ @with_transaction()
+ def test_taxable_mixin_document(self):
+ "Test TaxableMixin with rounding on document"
+ pool = Pool()
+ Tax = pool.get('account.tax')
+ Configuration = pool.get('account.configuration')
+ currency = create_currency('cur')
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company, tax=True)
+ tax, = Tax.search([])
+ config = Configuration(1)
+ config.tax_rounding = 'document'
+ config.save()
+
+ taxable = self.Taxable(
+ currency=currency,
+ taxable_lines=[
+ ([tax], Decimal('1.001'), 1, None),
+ ] * 100,
+ company=company)
+
+ taxes = taxable._get_taxes()
+
+ tax, = taxes
+ self.assertEqual(tax['base'], Decimal('100.00'))
+ self.assertEqual(tax['amount'], Decimal('20.02'))
+
+ @with_transaction()
+ def test_tax_compute_with_children_update_unit_price(self):
+ "Test tax compute with children taxes modifying unit_price"
+ pool = Pool()
+ Account = pool.get('account.account')
+ Date = pool.get('ir.date')
+ Tax = pool.get('account.tax')
+ today = Date.today()
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+
+ tax_account, = Account.search([
+ ('name', '=', 'Main Tax'),
+ ])
+
+ tax1 = Tax()
+ tax1.name = tax1.description = "Tax 1"
+ tax1.type = 'none'
+ tax1.update_unit_price = True
+ tax1.sequence = 1
+ tax1.save()
+ child1 = Tax()
+ child1.name = child1.description = "Child 1"
+ child1.type = 'percentage'
+ child1.rate = Decimal('0.1')
+ child1.invoice_account = tax_account
+ child1.credit_note_account = tax_account
+ child1.parent = tax1
+ child1.save()
+
+ tax2 = Tax()
+ tax2.name = tax2.description = "Tax 2"
+ tax2.type = 'fixed'
+ tax2.amount = Decimal('10')
+ tax2.invoice_account = tax_account
+ tax2.credit_note_account = tax_account
+ tax2.sequence = 2
+ tax2.save()
+
+ self.assertEqual(
+ Tax.compute([tax1, tax2], Decimal(100), 2, today), [{
+ 'base': Decimal(200),
+ 'amount': Decimal(20),
+ 'tax': child1,
+ }, {
+ 'base': Decimal('220'),
+ 'amount': Decimal('20'),
+ 'tax': tax2,
+ }])
+ self.assertEqual(
+ Tax.reverse_compute(Decimal('120'), [tax1, tax2], today),
+ Decimal('100'))
+
+ @with_transaction()
+ def test_receivable_payable(self):
+ 'Test party receivable payable'
+ pool = Pool()
+ Party = pool.get('party.party')
+ FiscalYear = pool.get('account.fiscalyear')
+ Journal = pool.get('account.journal')
+ Account = pool.get('account.account')
+ Move = pool.get('account.move')
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+ fiscalyear = get_fiscalyear(company)
+ fiscalyear.save()
+ FiscalYear.create_period([fiscalyear])
+ period = fiscalyear.periods[0]
+ journal_revenue, = Journal.search([
+ ('code', '=', 'REV'),
+ ])
+ journal_expense, = Journal.search([
+ ('code', '=', 'EXP'),
+ ])
+ revenue, = Account.search([
+ ('type.revenue', '=', True),
+ ])
+ receivable, = Account.search([
+ ('type.receivable', '=', True),
+ ])
+ expense, = Account.search([
+ ('type.expense', '=', True),
+ ])
+ payable, = Account.search([
+ ('type.payable', '=', True),
+ ])
+ party, = Party.create([{
+ 'name': 'Receivable/Payable party',
+ }])
+ tomorrow = datetime.date.today() + datetime.timedelta(days=1)
+
+ def get_move(journal, amount, credit_account, debit_account, party,
+ maturity_date=None):
+ return {
+ 'period': period.id,
+ 'journal': journal.id,
+ 'date': period.start_date,
+ 'lines': [
+ ('create', [{
+ 'account': credit_account.id,
+ 'credit': amount,
+ }, {
+ 'account': debit_account.id,
+ 'debit': amount,
+ 'party': party.id,
+ 'maturity_date': maturity_date,
+ }]),
+ ],
+ }
+ vlist = [
+ get_move(journal_revenue, Decimal(100), revenue, receivable,
+ party),
+ get_move(journal_expense, Decimal(30), expense, payable,
+ party),
+ get_move(journal_revenue, Decimal(200), revenue, receivable,
+ party, tomorrow),
+ get_move(journal_revenue, Decimal(60), expense, payable,
+ party, tomorrow),
+ ]
+ moves = Move.create(vlist)
+ Move.post(moves)
+
+ def check_fields():
+ party_test = Party(party.id)
+
+ for field, value in [('receivable', Decimal('300')),
+ ('receivable_today', Decimal('100')),
+ ('payable', Decimal('90')),
+ ('payable_today', Decimal('30')),
+ ]:
+ msg = 'field: %s, value: %s' % (field, value)
+ self.assertEqual(
+ getattr(party_test, field), value, msg=msg)
+ self.assertEqual(
+ Party.search([(field, '=', value)]),
+ [party_test], msg=msg)
+ self.assertEqual(
+ Party.search([(field, 'in', [value])]),
+ [party_test], msg=msg)
+ self.assertEqual(
+ Party.search([(field, '!=', value)]),
+ [], msg=msg)
+ self.assertEqual(
+ Party.search([(field, 'not in', [value])]),
+ [], msg=msg)
+
+ check_fields()
+ close_fiscalyear(fiscalyear)
+ check_fields()
+
+ @with_transaction()
+ def test_sort_taxes(self):
+ "Test sort_taxes"
+ pool = Pool()
+ Tax = pool.get('account.tax')
+
+ tax1 = Tax(sequence=None, id=-3)
+ tax2 = Tax(sequence=None, id=-2)
+ tax3 = Tax(sequence=1, id=-1)
+ self.assertSequenceEqual(
+ Tax.sort_taxes([tax3, tax2, tax1]), [tax1, tax2, tax3])
+
+ @with_transaction()
+ def test_configuration_accounts_on_party(self):
+ 'Test configuration accounts are used as fallback on party'
+ pool = Pool()
+ Party = pool.get('party.party')
+ Account = pool.get('account.account')
+
+ party = Party(name='Party')
+ party.save()
+
+ self.assertIsNone(party.account_payable)
+ self.assertIsNone(party.account_receivable)
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+ receivable, = Account.search([
+ ('type.receivable', '=', True),
+ ])
+ payable, = Account.search([
+ ('type.payable', '=', True),
+ ])
+
+ party = Party(party.id)
+
+ self.assertEqual(party.account_payable_used, payable)
+ self.assertEqual(party.account_receivable_used, receivable)
+
+ @with_transaction()
+ def test_tax_rule(self):
+ "Test tax rule"
+ pool = Pool()
+ TaxRule = pool.get('account.tax.rule')
+ Tax = pool.get('account.tax')
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company, tax=True)
+ tax, = Tax.search([])
+ target_tax, = Tax.copy([tax])
+
+ tax_rule, = TaxRule.create([{
+ 'name': 'Test',
+ 'kind': 'both',
+ 'lines': [('create', [{
+ 'origin_tax': tax.id,
+ 'tax': target_tax.id,
+ }])],
+ }])
+ self.assertListEqual(tax_rule.apply(tax, {}), [target_tax.id])
+
+ @with_transaction()
+ def test_tax_rule_start_date(self):
+ "Test tax rule start date"
+ pool = Pool()
+ TaxRule = pool.get('account.tax.rule')
+ Tax = pool.get('account.tax')
+ Date = pool.get('ir.date')
+
+ today = Date.today()
+ yesterday = today - datetime.timedelta(days=1)
+ tomorrow = today + datetime.timedelta(days=1)
+ company = create_company()
+ with set_company(company):
+ create_chart(company, tax=True)
+ tax, = Tax.search([])
+ target_tax, = Tax.copy([tax])
+
+ tax_rule, = TaxRule.create([{
+ 'name': "Test",
+ 'kind': 'both',
+ 'lines': [('create', [{
+ 'start_date': today,
+ 'tax': target_tax.id,
+ }])],
+ }])
+
+ self.assertListEqual(tax_rule.apply(tax, {}), [target_tax.id])
+ self.assertListEqual(
+ tax_rule.apply(tax, {'date': yesterday}), [tax.id])
+ self.assertListEqual(
+ tax_rule.apply(tax, {'date': tomorrow}), [target_tax.id])
+
+ @with_transaction()
+ def test_tax_rule_end_date(self):
+ "Test tax rule end date"
+ pool = Pool()
+ TaxRule = pool.get('account.tax.rule')
+ Tax = pool.get('account.tax')
+ Date = pool.get('ir.date')
+
+ today = Date.today()
+ yesterday = today - datetime.timedelta(days=1)
+ tomorrow = today + datetime.timedelta(days=1)
+ company = create_company()
+ with set_company(company):
+ create_chart(company, tax=True)
+ tax, = Tax.search([])
+ target_tax, = Tax.copy([tax])
+
+ tax_rule, = TaxRule.create([{
+ 'name': "Test",
+ 'kind': 'both',
+ 'lines': [('create', [{
+ 'end_date': today,
+ 'tax': target_tax.id,
+ }])],
+ }])
+
+ self.assertListEqual(tax_rule.apply(tax, {}), [target_tax.id])
+ self.assertListEqual(
+ tax_rule.apply(tax, {'date': yesterday}), [target_tax.id])
+ self.assertListEqual(
+ tax_rule.apply(tax, {'date': tomorrow}), [tax.id])
+
+ @with_transaction()
+ def test_tax_rule_keep_origin(self):
+ "Test tax rule keeps origin"
+ pool = Pool()
+ TaxRule = pool.get('account.tax.rule')
+ Tax = pool.get('account.tax')
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company, tax=True)
+ tax, = Tax.search([])
+ target_tax, = Tax.copy([tax])
+
+ tax_rule, = TaxRule.create([{
+ 'name': 'Test',
+ 'kind': 'both',
+ 'lines': [('create', [{
+ 'origin_tax': tax.id,
+ 'tax': target_tax.id,
+ 'keep_origin': True,
+ }])],
+ }])
+ self.assertListEqual(
+ tax_rule.apply(tax, {}), [target_tax.id, tax.id])
+
+ @with_transaction()
+ def test_update_chart(self):
+ 'Test all template models are updated when updating chart'
+ pool = Pool()
+ TypeTemplate = pool.get('account.account.type.template')
+ AccountTemplate = pool.get('account.account.template')
+ TaxTemplate = pool.get('account.tax.template')
+ TaxCodeTemplate = pool.get('account.tax.code.template')
+ ModelData = pool.get('ir.model.data')
+ UpdateChart = pool.get('account.update_chart', type='wizard')
+ Type = pool.get('account.account.type')
+ Account = pool.get('account.account')
+ Tax = pool.get('account.tax')
+ TaxCode = pool.get('account.tax.code')
+
+ def check():
+ for type_ in Type.search([]):
+ self.assertEqual(type_.name, type_.template.name)
+ self.assertEqual(
+ type_.statement, type_.template.statement)
+ if type_.template.parent:
+ self.assertEqual(
+ type_.parent.name, type_.template.parent.name)
+ else:
+ self.assertEqual(type_.parent, None)
+
+ for account in Account.search([]):
+ self.assertEqual(account.name, account.template.name)
+ self.assertEqual(account.code, account.template.code)
+ self.assertEqual(account.type.template, account.template.type)
+ self.assertEqual(account.reconcile, account.template.reconcile)
+ self.assertEqual(
+ account.start_date, account.template.start_date)
+ self.assertEqual(account.end_date, account.template.end_date)
+ self.assertEqual(
+ account.party_required, account.template.party_required)
+ self.assertEqual(
+ account.general_ledger_balance,
+ account.template.general_ledger_balance)
+ self.assertEqual(
+ set(t.template for t in account.taxes),
+ set(t for t in account.template.taxes))
+ if account.template.parent:
+ self.assertEqual(
+ account.parent.name, account.template.parent.name)
+ else:
+ self.assertEqual(account.parent, None)
+
+ for tax_code in TaxCode.search([]):
+ self.assertEqual(tax_code.name, tax_code.template.name)
+ self.assertEqual(tax_code.code, tax_code.template.code)
+ for line in tax_code.lines:
+ self.assertEqual(line.code.template, line.template.code)
+ self.assertEqual(line.operator, line.template.operator)
+ self.assertEqual(line.type, line.template.type)
+ self.assertEqual(line.tax.template, line.template.tax)
+
+ for tax in Tax.search([]):
+ self.assertEqual(tax.name, tax.template.name)
+ self.assertEqual(tax.description, tax.template.description)
+ self.assertEqual(tax.type, tax.template.type)
+ self.assertEqual(tax.rate, tax.template.rate)
+ self.assertEqual(tax.amount, tax.template.amount)
+ self.assertEqual(
+ tax.update_unit_price, tax.template.update_unit_price)
+ self.assertEqual(
+ tax.start_date, tax.template.start_date)
+ self.assertEqual(tax.end_date, tax.template.end_date)
+ self.assertEqual(
+ tax.invoice_account.template, tax.template.invoice_account)
+ self.assertEqual(
+ tax.credit_note_account.template,
+ tax.template.credit_note_account)
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company, True)
+
+ with Transaction().set_context(active_test=False):
+ self.assertEqual(Type.search([], count=True), 16)
+ self.assertEqual(Account.search([], count=True), 7)
+ self.assertEqual(Tax.search([], count=True), 1)
+
+ check()
+
+ with Transaction().set_user(0):
+ root_type = TypeTemplate(ModelData.get_id(
+ 'account', 'account_type_template_minimal_en'))
+ root_type.name = 'Updated Minimal Chart'
+ root_type.save()
+ chart = AccountTemplate(ModelData.get_id(
+ 'account', 'account_template_root_en'))
+ new_type = TypeTemplate()
+ new_type.name = 'New Type'
+ new_type.parent = root_type
+ new_type.statement = 'balance'
+ new_type.save()
+ updated_tax_type, = TypeTemplate.search([
+ ('name', '=', "Tax"),
+ ])
+ updated_tax_type.parent = updated_tax_type.parent.parent
+ updated_tax_type.save()
+ new_account = AccountTemplate()
+ new_account.name = 'New Account'
+ new_account.parent = chart
+ new_account.type = new_type
+ new_account.save()
+ updated_tax, = TaxTemplate.search([])
+ updated_tax.name = 'VAT'
+ updated_tax.invoice_account = new_account
+ updated_tax.save()
+ updated_account = AccountTemplate(ModelData.get_id(
+ 'account', 'account_template_revenue_en'))
+ updated_account.code = 'REV'
+ updated_account.name = 'Updated Account'
+ updated_account.parent = new_account
+ updated_account.type = new_account.type
+ updated_account.reconcile = True
+ updated_account.end_date = datetime.date.today()
+ updated_account.taxes = [updated_tax]
+ updated_account.save()
+ inactive_account = AccountTemplate(ModelData.get_id(
+ 'account', 'account_template_expense_en'))
+ inactive_account.end_date = datetime.date.min
+ inactive_account.save()
+ new_tax = TaxTemplate()
+ new_tax.name = new_tax.description = '10% VAT'
+ new_tax.type = 'percentage'
+ new_tax.rate = Decimal('0.1')
+ new_tax.account = chart
+ new_tax.invoice_account = new_account
+ new_tax.credit_note_account = new_account
+ new_tax.save()
+ updated_tax_code, = TaxCodeTemplate.search([
+ ('name', '=', 'Tax Code'),
+ ])
+ updated_tax_code.name = 'Updated Tax Code'
+ updated_tax_code.save()
+ updated_tax_code_line, = updated_tax_code.lines
+ updated_tax_code_line.operator = '-'
+ updated_tax_code_line.save()
+
+ with set_company(company):
+ account, = Account.search([('parent', '=', None)])
+ session_id, _, _ = UpdateChart.create()
+ update_chart = UpdateChart(session_id)
+ update_chart.start.account = account
+ update_chart.transition_update()
+
+ with Transaction().set_context(active_test=False):
+ self.assertEqual(Type.search([], count=True), 17)
+ self.assertEqual(Account.search([], count=True), 8)
+ self.assertEqual(Tax.search([], count=True), 2)
+
+ check()
+
+ @with_transaction()
+ def test_update_override(self):
+ "Test all models are not updated when template override is True"
+ pool = Pool()
+ ModelData = pool.get('ir.model.data')
+ TypeTemplate = pool.get('account.account.type.template')
+ AccountTemplate = pool.get('account.account.template')
+ TaxTemplate = pool.get('account.tax.template')
+ TaxCodeTemplate = pool.get('account.tax.code.template')
+ TaxCodeTemplateLine = pool.get('account.tax.code.line.template')
+ UpdateChart = pool.get('account.update_chart', type='wizard')
+ Type = pool.get('account.account.type')
+ Account = pool.get('account.account')
+ Tax = pool.get('account.tax')
+ TaxCode = pool.get('account.tax.code')
+ TaxCodeLine = pool.get('account.tax.code.line')
+
+ new_name = "Updated"
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company, True)
+
+ type_count = Type.search([], count=True)
+ account_count = Account.search([], count=True)
+ tax_count = Tax.search([], count=True)
+ tax_code_count = TaxCode.search([], count=True)
+ tax_code_line_count = TaxCodeLine.search([], count=True)
+
+ with Transaction().set_user(0):
+ root = AccountTemplate(ModelData.get_id(
+ 'account', 'account_template_root_en'))
+
+ template_type, = TypeTemplate.search([
+ ('parent', '!=', None),
+ ('parent', 'child_of', [root.type.id]),
+ ], limit=1)
+ template_type.name = new_name
+ template_type.save()
+ type_, = Type.search([('template', '=', template_type.id)])
+ type_.template_override = True
+ type_.save()
+
+ template_account, = AccountTemplate.search([
+ ('parent', '!=', None),
+ ('parent', 'child_of', [root.id]),
+ ], limit=1)
+ template_account.name = new_name
+ template_account.save()
+ account, = Account.search([('template', '=', template_account.id)])
+ account.template_override = True
+ account.save()
+
+ template_tax, = TaxTemplate.search([])
+ template_tax.name = new_name
+ template_tax.save()
+ tax, = Tax.search([('template', '=', template_tax.id)])
+ tax.template_override = True
+ tax.save()
+
+ template_tax_code, = TaxCodeTemplate.search([], limit=1)
+ template_tax_code.name = new_name
+ template_tax_code.save()
+ tax_code, = TaxCode.search(
+ [('template', '=', template_tax_code.id)])
+ tax_code.template_override = True
+ tax_code.save()
+
+ template_tax_code_line, = TaxCodeTemplateLine.search([], limit=1)
+ tax_code_line, = TaxCodeLine.search(
+ [('template', '=', template_tax_code_line.id)])
+ tax_code_line.template_override = True
+ tax_code_line.save()
+
+ with set_company(company):
+ account, = Account.search([('parent', '=', None)])
+ session_id, _, _ = UpdateChart.create()
+ update_chart = UpdateChart(session_id)
+ update_chart.start.account = account
+ update_chart.transition_update()
+
+ self.assertEqual(Type.search([], count=True), type_count)
+ self.assertEqual(Account.search([], count=True), account_count)
+ self.assertEqual(Tax.search([], count=True), tax_count)
+ self.assertEqual(
+ TaxCode.search([], count=True), tax_code_count)
+ self.assertEqual(
+ TaxCodeLine.search([], count=True), tax_code_line_count)
+
+ for Model in [Type, Account, Tax, TaxCode]:
+ for record in Model.search([]):
+ self.assertNotEqual(record.name, new_name)
+
+ @with_transaction()
+ def test_update_inactive(self):
+ "Test update chart of accounts with inactive account"
+ pool = Pool()
+ Account = pool.get('account.account')
+ UpdateChart = pool.get('account.update_chart', type='wizard')
+
+ company = create_company()
+ with set_company(company):
+ create_chart(company, tax=True)
+ root, = Account.search([('parent', '=', None)])
+
+ cash, = Account.search([('name', '=', 'Main Cash')])
+ cash.template_override = True
+ cash.end_date = datetime.date.min
+ cash.save()
+ self.assertFalse(cash.active)
+
+ session_id, _, _ = UpdateChart.create()
+ update_chart = UpdateChart(session_id)
+ update_chart.start.account = root
+ update_chart.transition_update()
+
+ with Transaction().set_context(active_test=False):
+ self.assertEqual(
+ Account.search([('name', '=', 'Main Cash')], count=True),
+ 1)
+
+
+del ModuleTestCase
diff -r f17e81152e14 -r 675bdc9d556b tests/test_scenario.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_scenario.py Sat Apr 16 18:30:15 2022 +0200
@@ -0,0 +1,22 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import doctest
+import glob
+import os
+
+from trytond.tests.test_tryton import doctest_checker, doctest_teardown
+
+
+def load_tests(loader, tests, pattern):
+ cwd = os.getcwd()
+ try:
+ os.chdir(os.path.dirname(__file__))
+ for scenario in glob.glob('*.rst'):
+ tests.addTests(doctest.DocFileSuite(
+ scenario, tearDown=doctest_teardown, encoding='utf-8',
+ checker=doctest_checker,
+ optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
+ finally:
+ os.chdir(cwd)
+ return tests
diff -r f17e81152e14 -r 675bdc9d556b tox.ini
--- a/tox.ini Tue Apr 12 10:26:25 2022 +0200
+++ b/tox.ini Sat Apr 16 18:30:15 2022 +0200
@@ -2,8 +2,9 @@
envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
[testenv]
+extras = test
commands =
- coverage run --include=.*/account/* setup.py test
+ coverage run --include=.*/account/* -m unittest discover -s tests
coverage report --include=.*/account/* --omit=*/tests/*
deps =
coverage