Files
tradon/modules/account/tests/test_module.py
2025-12-26 13:11:43 +00:00

2054 lines
78 KiB
Python
Executable File

# 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, PeriodDatesError)
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, inactive_records
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_change_fiscalyear_dates_with_periods(self):
"Test change fiscal year dates"
company = create_company()
with set_company(company):
fiscalyear = get_fiscalyear(
company,
start_date=datetime.date(2023, 1, 1),
end_date=datetime.date(2023, 12, 31))
fiscalyear.save()
fiscalyear.create_period([fiscalyear])
# Extend
fiscalyear.end_date = datetime.date(2024, 5, 31)
fiscalyear.save()
# Shorten
with self.assertRaises(PeriodDatesError):
fiscalyear.end_date = datetime.date(2023, 5, 31)
fiscalyear.save()
@with_transaction()
def test_change_period_dates_with_move(self):
"Test change period dates"
pool = Pool()
Period = pool.get('account.period')
Move = pool.get('account.move')
Journal = pool.get('account.journal')
company = create_company()
with set_company(company):
create_chart(company)
fiscalyear = get_fiscalyear(company)
fiscalyear.save()
period = Period(
fiscalyear=fiscalyear,
type='adjustment',
name="Period",
start_date=fiscalyear.start_date,
end_date=fiscalyear.start_date)
period.save()
journal, = Journal.search([], limit=1)
move, = Move.create([{
'period': period.id,
'journal': journal.id,
'date': period.start_date,
}])
# Extend
period.end_date = fiscalyear.end_date
period.save()
# Shorten
with self.assertRaises(PeriodDatesError):
period.start_date = fiscalyear.end_date
period.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 + relativedelta(years=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')
# Move lines with debit = credit = 0 are automatically reconciled
receivable_no_party, = Account.copy([receivable], default={
'party_required': False,
})
move = Move()
move.period = period
move.journal = journal_revenue
move.date = period.start_date
move.lines = [
Line(account=receivable_no_party, credit=Decimal(0)),
Line(account=receivable, debit=Decimal(0), party=party),
]
move.save()
Move.post([move])
lines = Line.browse([l.id for l in move.lines
if l.account.reconcile])
self.assertTrue(all(bool(l.reconciliation) for l in lines))
# 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_taxable_mixin_tax_residual_rounding(self):
"Test TaxableMixin for rounding with residual amount"
pool = Pool()
Account = pool.get('account.account')
Tax = pool.get('account.tax')
Configuration = pool.get('account.configuration')
currency = create_currency('cur')
company = create_company()
with set_company(company):
create_chart(company)
config = Configuration(1)
config.tax_rounding = 'line'
config.save()
tax_account, = Account.search([
('name', '=', 'Main Tax'),
])
tax1 = Tax()
tax1.name = tax1.description = "Tax 1"
tax1.type = 'percentage'
tax1.rate = Decimal('.1')
tax1.invoice_account = tax_account
tax1.credit_note_account = tax_account
tax1.save()
tax2 = Tax()
tax2.name = tax2.description = "Tax 2"
tax2.type = 'percentage'
tax2.rate = Decimal('.1')
tax2.invoice_account = tax_account
tax2.credit_note_account = tax_account
tax2.save()
taxable = self.Taxable(
currency=currency,
taxable_lines=[
([tax1, tax2], Decimal('1.0417'), 1, None),
],
company=company)
taxline_1, taxline_2 = taxable._get_taxes()
self.assertEqual(taxline_1['base'], Decimal('1.04'))
self.assertEqual(taxline_1['amount'], Decimal('.11'))
self.assertEqual(taxline_2['base'], Decimal('1.04'))
self.assertEqual(taxline_2['amount'], Decimal('.10'))
@with_transaction()
def test_taxable_mixin_tax_residual_rounding_with_0(self):
"Test TaxableMixin for rounding with residual amount and tax 0"
pool = Pool()
Account = pool.get('account.account')
Tax = pool.get('account.tax')
Configuration = pool.get('account.configuration')
currency = create_currency('cur')
company = create_company()
with set_company(company):
create_chart(company)
config = Configuration(1)
config.tax_rounding = 'line'
config.save()
tax_account, = Account.search([
('name', '=', 'Main Tax'),
])
tax0 = Tax()
tax0.name = tax0.description = "Tax 0"
tax0.type = 'percentage'
tax0.rate = Decimal('0')
tax0.invoice_account = tax_account
tax0.credit_note_account = tax_account
tax0.save()
tax1 = Tax()
tax1.name = tax1.description = "Tax 1"
tax1.type = 'percentage'
tax1.rate = Decimal('.1')
tax1.invoice_account = tax_account
tax1.credit_note_account = tax_account
tax1.save()
tax2 = Tax()
tax2.name = tax2.description = "Tax 2"
tax2.type = 'percentage'
tax2.rate = Decimal('.1')
tax2.invoice_account = tax_account
tax2.credit_note_account = tax_account
tax2.save()
taxable = self.Taxable(
currency=currency,
taxable_lines=[
([tax0, tax1, tax2], Decimal('1.0417'), 1, None),
],
company=company)
taxline_0, taxline_1, taxline_2 = taxable._get_taxes()
self.assertEqual(taxline_0['base'], Decimal('1.04'))
self.assertEqual(taxline_0['amount'], Decimal('0'))
self.assertEqual(taxline_1['base'], Decimal('1.04'))
self.assertEqual(taxline_1['amount'], Decimal('.11'))
self.assertEqual(taxline_2['base'], Decimal('1.04'))
self.assertEqual(taxline_2['amount'], Decimal('.10'))
@with_transaction()
def test_taxable_mixin_tax_residual_rounding_negative_residual(self):
"Test TaxableMixin for rounding with negative residual amount"
pool = Pool()
Account = pool.get('account.account')
Tax = pool.get('account.tax')
Configuration = pool.get('account.configuration')
currency = create_currency('cur')
company = create_company()
with set_company(company):
create_chart(company)
config = Configuration(1)
config.tax_rounding = 'line'
config.save()
tax_account, = Account.search([
('name', '=', 'Main Tax'),
])
tax1 = Tax()
tax1.name = tax1.description = "Tax 1"
tax1.type = 'percentage'
tax1.rate = Decimal('.1')
tax1.invoice_account = tax_account
tax1.credit_note_account = tax_account
tax1.save()
tax2 = Tax()
tax2.name = tax2.description = "Tax 2"
tax2.type = 'percentage'
tax2.rate = Decimal('.1')
tax2.invoice_account = tax_account
tax2.credit_note_account = tax_account
tax2.save()
# -2.95 is the unit price of -3.54 with 20% tax included
taxable = self.Taxable(
currency=currency,
taxable_lines=[
([tax1], Decimal('30.00'), 1, None),
([tax1, tax2], Decimal('-2.95'), 1, None),
],
company=company)
taxline_1, taxline_2, taxline_3 = taxable._get_taxes()
self.assertEqual(taxline_1['base'], Decimal('30.00'))
self.assertEqual(taxline_1['amount'], Decimal('3.00'))
self.assertEqual(taxline_2['base'], Decimal('-2.95'))
self.assertEqual(taxline_2['amount'], Decimal('-0.29'))
self.assertEqual(taxline_3['base'], Decimal('-2.95'))
self.assertEqual(taxline_3['amount'], Decimal('-0.30'))
@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()
Company = pool.get('company.company')
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)
company_test = Company(company.id)
for record, Model in [
(party_test, Party),
(company_test, Company),
]:
for field, value in [
('receivable', Decimal('300')),
('receivable_today', Decimal('100')),
('payable', Decimal('90')),
('payable_today', Decimal('30')),
]:
with self.subTest(
record=record, field=field, value=value):
self.assertEqual(
getattr(record, field), value)
self.assertEqual(
Model.search([(field, '=', value)]),
[record])
self.assertEqual(
Model.search([(field, 'in', [value])]),
[record])
self.assertEqual(
Model.search([(field, '!=', value)]),
[])
self.assertEqual(
Model.search([(field, 'not in', [value])]),
[])
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)
if account.template.replaced_by:
self.assertEqual(
account.replaced_by.name,
account.template.replaced_by.name)
else:
self.assertEqual(account.replaced_by, 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 inactive_records():
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.replaced_by = new_account
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 inactive_records():
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 inactive_records():
self.assertEqual(
Account.search([('name', '=', 'Main Cash')], count=True),
1)
@with_transaction()
def test_update_chart_new_parent(self):
"Test update chart of accounts with new parent"
pool = Pool()
ModelData = pool.get('ir.model.data')
TypeTemplate = pool.get('account.account.type.template')
Type = pool.get('account.account.type')
AccountTemplate = pool.get('account.account.template')
Account = pool.get('account.account')
UpdateChart = pool.get('account.update_chart', type='wizard')
company = create_company()
with set_company(company):
create_chart(company, True)
with Transaction().set_user(0):
root_type_template = TypeTemplate(ModelData.get_id(
'account', 'account_type_template_minimal_en'))
type_template, = TypeTemplate.search([
('parent', '!=', None),
('parent', 'child_of', [root_type_template.id]),
], limit=1)
new_type_template, = TypeTemplate.copy([type_template])
type_template.parent = new_type_template
type_template.save()
root_template = AccountTemplate(ModelData.get_id(
'account', 'account_template_root_en'))
account_template, = AccountTemplate.search([
('parent', '!=', None),
('parent', 'child_of', [root_template.id]),
], limit=1)
new_account_template, = AccountTemplate.copy([account_template])
account_template.parent = new_account_template
account_template.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()
new_type, = Type.search(
[('template', '=', new_type_template.id)])
type, = Type.search(
[('template', '=', type_template.id)])
self.assertEqual(type.parent, new_type)
new_account, = Account.search(
[('template', '=', new_account_template.id)])
account, = Account.search(
[('template', '=', account_template.id)])
self.assertEqual(account.parent, new_account)
del ModuleTestCase