[FIX+IMP] account_tax_balance:
* Tests * PEP8 * Use invoice._convert_to_write(invoice._cache). This way, the onchange will be inheritable and will add here also the added values * better get_context_values * unify method compute_balance * open move lines linked to balancepull/468/head
parent
d2b6841321
commit
337fda6119
|
@ -12,7 +12,7 @@ It depends on date_range module and exposes 'compute' methods that can be called
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
Accounting --> Reporting --> Open Tax Balances
|
Accounting --> Reporting --> Taxes Balance
|
||||||
|
|
||||||
Select the company, the date range, the target moves and 'open taxes'
|
Select the company, the date range, the target moves and 'open taxes'
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ Contributors
|
||||||
------------
|
------------
|
||||||
|
|
||||||
* Lorenzo Battistini <lorenzo.battistini@agilebg.com>
|
* Lorenzo Battistini <lorenzo.battistini@agilebg.com>
|
||||||
|
* Giovanni Capalbo <giovanni@therp.nl>
|
||||||
|
|
||||||
Maintainer
|
Maintainer
|
||||||
----------
|
----------
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
"version": "9.0.1.0.0",
|
"version": "9.0.1.0.0",
|
||||||
"category": "Accounting & Finance",
|
"category": "Accounting & Finance",
|
||||||
"website": "https://www.agilebg.com/",
|
"website": "https://www.agilebg.com/",
|
||||||
"author": "Agile Business Group, Odoo Community Association (OCA)",
|
"author": "Agile Business Group, Therp BV, "
|
||||||
|
"Odoo Community Association (OCA)",
|
||||||
"license": "AGPL-3",
|
"license": "AGPL-3",
|
||||||
"application": False,
|
"application": False,
|
||||||
"installable": True,
|
"installable": True,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# © 2016 Lorenzo Battistini - Agile Business Group
|
# © 2016 Lorenzo Battistini - Agile Business Group
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from openerp import models, fields
|
from openerp import models, fields, api
|
||||||
|
|
||||||
|
|
||||||
class AccountTax(models.Model):
|
class AccountTax(models.Model):
|
||||||
|
@ -13,31 +13,18 @@ class AccountTax(models.Model):
|
||||||
string="Base Balance", compute="_compute_balance")
|
string="Base Balance", compute="_compute_balance")
|
||||||
|
|
||||||
def get_context_values(self):
|
def get_context_values(self):
|
||||||
if not self.env.context.get('from_date'):
|
context = self.env.context
|
||||||
from_date = fields.Date.context_today(self)
|
return (
|
||||||
else:
|
context.get('from_date', fields.Date.context_today(self)),
|
||||||
from_date = self.env.context['from_date']
|
context.get('to_date', fields.Date.context_today(self)),
|
||||||
if not self.env.context.get('to_date'):
|
context.get('company_id', self.env.user.company_id.id),
|
||||||
to_date = fields.Date.context_today(self)
|
context.get('target_move', 'posted')
|
||||||
else:
|
)
|
||||||
to_date = self.env.context['to_date']
|
|
||||||
if not self.env.context.get('target_move'):
|
|
||||||
target_move = 'posted'
|
|
||||||
else:
|
|
||||||
target_move = self.env.context['target_move']
|
|
||||||
if not self.env.context.get('company_id'):
|
|
||||||
company_id = self.env.user.company_id.id
|
|
||||||
else:
|
|
||||||
company_id = self.env.context['company_id']
|
|
||||||
return from_date, to_date, company_id, target_move
|
|
||||||
|
|
||||||
def _compute_balance(self):
|
def _compute_balance(self):
|
||||||
from_date, to_date, company_id, target_move = self.get_context_values()
|
|
||||||
for tax in self:
|
for tax in self:
|
||||||
tax.balance = tax.compute_balance(
|
tax.balance = tax.compute_balance(tax_or_base='tax')
|
||||||
from_date, to_date, company_id, target_move)
|
tax.base_balance = tax.compute_balance(tax_or_base='base')
|
||||||
tax.base_balance = tax.compute_base_balance(
|
|
||||||
from_date, to_date, company_id, target_move)
|
|
||||||
|
|
||||||
def get_target_state_list(self, target_move="posted"):
|
def get_target_state_list(self, target_move="posted"):
|
||||||
if target_move == 'posted':
|
if target_move == 'posted':
|
||||||
|
@ -48,39 +35,63 @@ class AccountTax(models.Model):
|
||||||
state = []
|
state = []
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def get_move_line_domain(self, from_date, to_date, company_id):
|
def get_move_line_partial_domain(self, from_date, to_date, company_id):
|
||||||
return [
|
return [
|
||||||
('date', '<=', to_date),
|
('date', '<=', to_date),
|
||||||
('date', '>=', from_date),
|
('date', '>=', from_date),
|
||||||
('company_id', '=', company_id),
|
('company_id', '=', company_id),
|
||||||
]
|
]
|
||||||
|
|
||||||
def compute_balance(
|
def compute_balance(self, tax_or_base='tax'):
|
||||||
self, from_date, to_date, company_id, target_move="posted"
|
|
||||||
):
|
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
move_line_model = self.env['account.move.line']
|
move_lines = self.get_move_lines_domain(tax_or_base=tax_or_base)
|
||||||
state_list = self.get_target_state_list(target_move)
|
# balance is debit - credit whereas on tax return you want to see what
|
||||||
domain = self.get_move_line_domain(from_date, to_date, company_id)
|
# vat has to be paid so:
|
||||||
domain.extend([
|
# VAT on sales (credit) - VAT on purchases (debit).
|
||||||
('move_id.state', 'in', state_list),
|
total = -sum([l.balance for l in move_lines])
|
||||||
('tax_line_id', '=', self.id),
|
|
||||||
])
|
|
||||||
move_lines = move_line_model.search(domain)
|
|
||||||
total = sum([l.balance for l in move_lines])
|
|
||||||
return total
|
return total
|
||||||
|
|
||||||
def compute_base_balance(
|
def get_balance_domain(self, state_list):
|
||||||
self, from_date, to_date, company_id, target_move="posted"
|
return [
|
||||||
):
|
('move_id.state', 'in', state_list),
|
||||||
self.ensure_one()
|
('tax_line_id', '=', self.id),
|
||||||
move_line_model = self.env['account.move.line']
|
]
|
||||||
state_list = self.get_target_state_list(target_move)
|
|
||||||
domain = self.get_move_line_domain(from_date, to_date, company_id)
|
def get_base_balance_domain(self, state_list):
|
||||||
domain.extend([
|
return [
|
||||||
('move_id.state', 'in', state_list),
|
('move_id.state', 'in', state_list),
|
||||||
('tax_ids', 'in', self.id),
|
('tax_ids', 'in', self.id),
|
||||||
])
|
]
|
||||||
move_lines = move_line_model.search(domain)
|
|
||||||
total = sum([l.balance for l in move_lines])
|
def get_move_lines_domain(self, tax_or_base='tax'):
|
||||||
return total
|
move_line_model = self.env['account.move.line']
|
||||||
|
from_date, to_date, company_id, target_move = self.get_context_values()
|
||||||
|
state_list = self.get_target_state_list(target_move)
|
||||||
|
domain = self.get_move_line_partial_domain(
|
||||||
|
from_date, to_date, company_id)
|
||||||
|
balance_domain = []
|
||||||
|
if tax_or_base == 'tax':
|
||||||
|
balance_domain = self.get_balance_domain(state_list)
|
||||||
|
elif tax_or_base == 'base':
|
||||||
|
balance_domain = self.get_base_balance_domain(state_list)
|
||||||
|
domain.extend(balance_domain)
|
||||||
|
return move_line_model.search(domain)
|
||||||
|
|
||||||
|
def get_lines_action(self, tax_or_base='tax'):
|
||||||
|
move_lines = self.get_move_lines_domain(tax_or_base=tax_or_base)
|
||||||
|
move_line_ids = [l.id for l in move_lines]
|
||||||
|
action = self.env.ref('account.action_account_moves_all_tree')
|
||||||
|
vals = action.read()[0]
|
||||||
|
vals['context'] = {}
|
||||||
|
vals['domain'] = [('id', 'in', move_line_ids)]
|
||||||
|
return vals
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def view_tax_lines(self):
|
||||||
|
self.ensure_one()
|
||||||
|
return self.get_lines_action(tax_or_base='tax')
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def view_base_lines(self):
|
||||||
|
self.ensure_one()
|
||||||
|
return self.get_lines_action(tax_or_base='base')
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
#Accounting tests extending AccountingTestCase
|
# -*- coding: utf-8 -*-
|
||||||
|
# © 2016 Lorenzo Battistini - Agile Business Group
|
||||||
|
# © 2016 Giovanni Capalbo
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from . import test_account_tax_balance
|
from . import test_account_tax_balance
|
||||||
|
|
|
@ -1,51 +1,54 @@
|
||||||
#from openerp.addons.account.tests.account_test_users import AccountTestUsers
|
# -*- coding: utf-8 -*-
|
||||||
|
# © 2016 Lorenzo Battistini - Agile Business Group
|
||||||
|
# © 2016 Giovanni Capalbo <giovanni@therp.nl>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from openerp.tests.common import TransactionCase
|
from openerp.tests.common import TransactionCase
|
||||||
from openerp.tools import float_compare
|
from datetime import datetime
|
||||||
|
from dateutil.rrule import MONTHLY
|
||||||
|
|
||||||
|
|
||||||
class TestAccountTaxBalance(TransactionCase):
|
class TestAccountTaxBalance(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestAccountTaxBalance, self).setUp()
|
super(TestAccountTaxBalance, self).setUp()
|
||||||
self.fixed_tax = self.tax_model.create({
|
self.range_type = self.env['date.range.type'].create(
|
||||||
'name': "Fixed tax",
|
{'name': 'Fiscal year',
|
||||||
'amount_type': 'fixed',
|
'company_id': False,
|
||||||
'amount': 10.0,
|
'allow_overlap': False})
|
||||||
'sequence': 1,
|
self.range_generator = self.env['date.range.generator']
|
||||||
})
|
self.current_year = datetime.now().year
|
||||||
self.fixed_tax_bis = self.tax_model.create({
|
self.current_month = datetime.now().month
|
||||||
'name': "Fixed tax bis",
|
range_generator = self.range_generator.create({
|
||||||
'amount_type': 'fixed',
|
'date_start': '%s-01-01' % self.current_year,
|
||||||
'amount': 15,
|
'name_prefix': '%s-' % self.current_year,
|
||||||
'sequence': 2,
|
'type_id': self.range_type.id,
|
||||||
})
|
'duration_count': 1,
|
||||||
self.percent_tax = self.tax_model.create({
|
'unit_of_time': MONTHLY,
|
||||||
'name': "Percent tax",
|
'count': 12})
|
||||||
'amount_type': 'percent',
|
range_generator.action_apply()
|
||||||
'amount': 10.0,
|
self.range = self.env['date.range']
|
||||||
'sequence': 3,
|
|
||||||
})
|
|
||||||
self.bank_journal = self.env['account.journal'].search([('type', '=', 'bank'), ('company_id', '=', self.account_manager.company_id.id)])[0]
|
|
||||||
self.bank_account = self.bank_journal.default_debit_account_id
|
|
||||||
self.expense_account = self.env['account.account'].search([('user_type_id.type', '=', 'payable')], limit=1) #Should be done by onchange later
|
|
||||||
|
|
||||||
|
|
||||||
def test_tax_balance(self):
|
def test_tax_balance(self):
|
||||||
company_id = self.env['res.users'].browse(self.env.uid).company_id.id
|
tax_account_id = self.env['account.account'].search(
|
||||||
|
[('name', '=', 'Tax Paid')], limit=1).id
|
||||||
tax = self.env['account.tax'].create({
|
tax = self.env['account.tax'].create({
|
||||||
'name': 'Tax 10.0',
|
'name': 'Tax 10.0',
|
||||||
'amount': 10.0,
|
'amount': 10.0,
|
||||||
'amount_type': 'fixed',
|
'amount_type': 'fixed',
|
||||||
|
'account_id': tax_account_id,
|
||||||
})
|
})
|
||||||
analytic_account = self.env['account.analytic.account'].create({
|
invoice_account_id = self.env['account.account'].search(
|
||||||
'name': 'test account',
|
[('user_type_id', '=', self.env.ref(
|
||||||
})
|
'account.data_account_type_receivable'
|
||||||
invoice_account = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_receivable').id)], limit=1).id
|
).id)], limit=1).id
|
||||||
invoice_line_account = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_expenses').id)], limit=1).id
|
invoice_line_account_id = self.env['account.account'].search(
|
||||||
|
[('user_type_id', '=', self.env.ref(
|
||||||
|
'account.data_account_type_expenses').id)], limit=1).id
|
||||||
invoice = self.env['account.invoice'].create({
|
invoice = self.env['account.invoice'].create({
|
||||||
'partner_id': self.env.ref('base.res_partner_2').id,
|
'partner_id': self.env.ref('base.res_partner_2').id,
|
||||||
'account_id': invoice_account,
|
'account_id': invoice_account_id,
|
||||||
'type': 'in_invoice',
|
'type': 'out_invoice',
|
||||||
})
|
})
|
||||||
|
|
||||||
self.env['account.invoice.line'].create({
|
self.env['account.invoice.line'].create({
|
||||||
|
@ -54,19 +57,56 @@ class TestAccountTaxBalance(TransactionCase):
|
||||||
'price_unit': 100.0,
|
'price_unit': 100.0,
|
||||||
'invoice_id': invoice.id,
|
'invoice_id': invoice.id,
|
||||||
'name': 'product that cost 100',
|
'name': 'product that cost 100',
|
||||||
'account_id': invoice_line_account,
|
'account_id': invoice_line_account_id,
|
||||||
'invoice_line_tax_ids': [(6, 0, [tax.id])],
|
'invoice_line_tax_ids': [(6, 0, [tax.id])],
|
||||||
'account_analytic_id': analytic_account.id,
|
|
||||||
})
|
})
|
||||||
|
invoice._onchange_invoice_line_ids()
|
||||||
|
invoice._convert_to_write(invoice._cache)
|
||||||
|
self.assertEqual(invoice.state, 'draft')
|
||||||
|
|
||||||
# : check that Initially supplier bill state is "Draft"
|
# change the state of invoice to open by clicking Validate button
|
||||||
self.assertTrue((invoice.state == 'draft'), "Initially vendor bill state is Draft")
|
|
||||||
|
|
||||||
#change the state of invoice to open by clicking Validate button
|
|
||||||
invoice.signal_workflow('invoice_open')
|
invoice.signal_workflow('invoice_open')
|
||||||
|
|
||||||
self.assertEquals(tax.base_balance, 100)
|
self.assertEquals(tax.base_balance, 100)
|
||||||
self.assertEquals(tax.balance, 10)
|
self.assertEquals(tax.balance, 10)
|
||||||
|
|
||||||
|
# testing wizard
|
||||||
|
current_range = self.range.search([
|
||||||
|
('date_start', '=', '%s-%s-01' % (
|
||||||
|
self.current_year, self.current_month))
|
||||||
|
])
|
||||||
|
wizard = self.env['wizard.open.tax.balances'].new({})
|
||||||
|
self.assertFalse(wizard.from_date)
|
||||||
|
self.assertFalse(wizard.to_date)
|
||||||
|
wizard = self.env['wizard.open.tax.balances'].new({
|
||||||
|
'date_range_id': current_range[0].id,
|
||||||
|
})
|
||||||
|
wizard.onchange_date_range_id()
|
||||||
|
wizard._convert_to_write(wizard._cache)
|
||||||
|
action = wizard.open_taxes()
|
||||||
|
self.assertEqual(
|
||||||
|
action['context']['from_date'], current_range[0].date_start)
|
||||||
|
self.assertEqual(
|
||||||
|
action['context']['to_date'], current_range[0].date_end)
|
||||||
|
self.assertEqual(
|
||||||
|
action['xml_id'], 'account_tax_balance.action_tax_balances_tree')
|
||||||
|
|
||||||
|
# testing buttons
|
||||||
|
tax_action = tax.view_tax_lines()
|
||||||
|
base_action = tax.view_base_lines()
|
||||||
|
self.assertTrue(
|
||||||
|
tax_action['domain'][0][2][0] in
|
||||||
|
[l.id for l in invoice.move_id.line_ids])
|
||||||
|
self.assertEqual(
|
||||||
|
tax_action['xml_id'], 'account.action_account_moves_all_tree')
|
||||||
|
self.assertTrue(
|
||||||
|
base_action['domain'][0][2][0] in
|
||||||
|
[l.id for l in invoice.move_id.line_ids])
|
||||||
|
self.assertEqual(
|
||||||
|
base_action['xml_id'], 'account.action_account_moves_all_tree')
|
||||||
|
|
||||||
|
# test specific method
|
||||||
|
state_list = tax.get_target_state_list(target_move='all')
|
||||||
|
self.assertEqual(state_list, ['posted', 'draft'])
|
||||||
|
state_list = tax.get_target_state_list(target_move='whatever')
|
||||||
|
self.assertEqual(state_list, [])
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
<field name="account_id"/>
|
<field name="account_id"/>
|
||||||
<field name="balance" sum="Total"></field>
|
<field name="balance" sum="Total"></field>
|
||||||
<field name="base_balance" sum="Base Total"></field>
|
<field name="base_balance" sum="Base Total"></field>
|
||||||
|
<button type="object" name="view_tax_lines" string="View tax lines" icon="gtk-find"></button>
|
||||||
|
<button type="object" name="view_base_lines" string="View base lines" icon="gtk-copy"></button>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
@ -36,7 +38,7 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="action_tax_balances_tree" model="ir.actions.act_window">
|
<record id="action_tax_balances_tree" model="ir.actions.act_window">
|
||||||
<field name="name">Tax Balances</field>
|
<field name="name">Taxes Balance</field>
|
||||||
<field name="res_model">account.tax</field>
|
<field name="res_model">account.tax</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_mode">tree</field>
|
<field name="view_mode">tree</field>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<field name="name">wizard_open_tax_balances</field>
|
<field name="name">wizard_open_tax_balances</field>
|
||||||
<field name="model">wizard.open.tax.balances</field>
|
<field name="model">wizard.open.tax.balances</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Open Tax Balances">
|
<form string="Taxes Balance">
|
||||||
<group>
|
<group>
|
||||||
<field name="company_id"/>
|
<field name="company_id"/>
|
||||||
<field name="date_range_id"/>
|
<field name="date_range_id"/>
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="action_open_tax_balances" model="ir.actions.act_window">
|
<record id="action_open_tax_balances" model="ir.actions.act_window">
|
||||||
<field name="name">Open Tax Balances</field>
|
<field name="name">Taxes Balance</field>
|
||||||
<field name="res_model">wizard.open.tax.balances</field>
|
<field name="res_model">wizard.open.tax.balances</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_mode">form</field>
|
<field name="view_mode">form</field>
|
||||||
|
|
Loading…
Reference in New Issue