diff --git a/account_tax_balance/__init__.py b/account_tax_balance/__init__.py
new file mode 100644
index 00000000..11805bd0
--- /dev/null
+++ b/account_tax_balance/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+# © 2016 Lorenzo Battistini - Agile Business Group
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from . import models
+from . import wizard
\ No newline at end of file
diff --git a/account_tax_balance/__openerp__.py b/account_tax_balance/__openerp__.py
new file mode 100644
index 00000000..60683bb3
--- /dev/null
+++ b/account_tax_balance/__openerp__.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# © 2016 Lorenzo Battistini - Agile Business Group
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+{
+ "name": "Tax Balance",
+ "summary": "Compute tax balances based on date range",
+ "version": "9.0.1.0.0",
+ "category": "Accounting & Finance",
+ "website": "https://www.agilebg.com/",
+ "author": "Agile Business Group, Odoo Community Association (OCA)",
+ "license": "AGPL-3",
+ "application": False,
+ "installable": True,
+ "depends": [
+ "account",
+ "date_range",
+ ],
+ "data": [
+ "wizard/open_tax_balances_view.xml",
+ "views/account_tax_view.xml",
+ ],
+}
diff --git a/account_tax_balance/models/__init__.py b/account_tax_balance/models/__init__.py
new file mode 100644
index 00000000..4e12d881
--- /dev/null
+++ b/account_tax_balance/models/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# © 2016 Lorenzo Battistini - Agile Business Group
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from . import account_tax
\ No newline at end of file
diff --git a/account_tax_balance/models/account_tax.py b/account_tax_balance/models/account_tax.py
new file mode 100644
index 00000000..fbcfbce2
--- /dev/null
+++ b/account_tax_balance/models/account_tax.py
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+# © 2016 Lorenzo Battistini - Agile Business Group
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from openerp import models, fields
+
+
+class AccountTax(models.Model):
+ _inherit = 'account.tax'
+
+ balance = fields.Float(string="Balance", compute="_compute_balance")
+ base_balance = fields.Float(
+ string="Base Balance", compute="_compute_balance")
+
+ def get_context_values(self):
+ if not self.env.context.get('from_date'):
+ from_date = fields.Date.context_today(self)
+ else:
+ from_date = self.env.context['from_date']
+ if not self.env.context.get('to_date'):
+ to_date = fields.Date.context_today(self)
+ 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):
+ from_date, to_date, company_id, target_move = self.get_context_values()
+ for tax in self:
+ tax.balance = tax.compute_balance(
+ from_date, to_date, company_id, target_move)
+ tax.base_balance = tax.compute_base_balance(
+ from_date, to_date, company_id, target_move)
+
+ def get_target_state_list(self, target_move="posted"):
+ if target_move == 'posted':
+ state = ['posted']
+ elif target_move == 'all':
+ state = ['posted', 'draft']
+ else:
+ state = []
+ return state
+
+ def get_move_line_domain(self, from_date, to_date, company_id):
+ return [
+ ('date', '<=', to_date),
+ ('date', '>=', from_date),
+ ('company_id', '=', company_id),
+ ]
+
+ def compute_balance(
+ self, from_date, to_date, company_id, target_move="posted"
+ ):
+ self.ensure_one()
+ 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)
+ domain.extend([
+ ('move_id.state', 'in', state_list),
+ ('tax_line_id', '=', self.id),
+ ])
+ move_lines = move_line_model.search(domain)
+ total = sum([l.balance for l in move_lines])
+ return total
+
+ def compute_base_balance(
+ self, from_date, to_date, company_id, target_move="posted"
+ ):
+ self.ensure_one()
+ 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)
+ domain.extend([
+ ('move_id.state', 'in', state_list),
+ ('tax_ids', 'in', self.id),
+ ])
+ move_lines = move_line_model.search(domain)
+ total = sum([l.balance for l in move_lines])
+ return total
diff --git a/account_tax_balance/views/account_tax_view.xml b/account_tax_balance/views/account_tax_view.xml
new file mode 100644
index 00000000..a204056d
--- /dev/null
+++ b/account_tax_balance/views/account_tax_view.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+ account.tax.tree.balance
+ account.tax
+
+
+
+
+
+
+
+
+
+
+
+
+ account.tax.search.balance
+ account.tax
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tax Balances
+ account.tax
+ form
+ tree
+
+
+
+
+
\ No newline at end of file
diff --git a/account_tax_balance/wizard/__init__.py b/account_tax_balance/wizard/__init__.py
new file mode 100644
index 00000000..d625c430
--- /dev/null
+++ b/account_tax_balance/wizard/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# © 2016 Lorenzo Battistini - Agile Business Group
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from . import open_tax_balances
\ No newline at end of file
diff --git a/account_tax_balance/wizard/open_tax_balances.py b/account_tax_balance/wizard/open_tax_balances.py
new file mode 100644
index 00000000..e0eda7dd
--- /dev/null
+++ b/account_tax_balance/wizard/open_tax_balances.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+# © 2016 Lorenzo Battistini - Agile Business Group
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from openerp import models, fields, api
+from openerp.tools.translate import _
+
+
+class OpenTaxBalances(models.TransientModel):
+ _name = 'wizard.open.tax.balances'
+ company_id = fields.Many2one(
+ 'res.company', 'Company', required=True,
+ default=lambda self: self.env.user.company_id)
+ from_date = fields.Date('From date', required=True)
+ to_date = fields.Date('To date', required=True)
+ date_range_id = fields.Many2one('date.range', 'Date range')
+ target_move = fields.Selection([
+ ('posted', 'All Posted Entries'),
+ ('all', 'All Entries'),
+ ], 'Target Moves', required=True, default='posted')
+
+ @api.onchange('date_range_id')
+ def onchange_date_range_id(self):
+ if self.date_range_id:
+ self.from_date = self.date_range_id.date_start
+ self.to_date = self.date_range_id.date_end
+ else:
+ self.from_date = self.to_date = None
+
+ @api.multi
+ def open_taxes(self):
+ self.ensure_one()
+ action = self.env.ref('account_tax_balance.action_tax_balances_tree')
+ vals = action.read()[0]
+ vals['context'] = {
+ 'from_date': self.from_date,
+ 'to_date': self.to_date,
+ 'target_move': self.target_move,
+ 'company_id': self.company_id.id,
+ }
+ return vals
\ No newline at end of file
diff --git a/account_tax_balance/wizard/open_tax_balances_view.xml b/account_tax_balance/wizard/open_tax_balances_view.xml
new file mode 100644
index 00000000..fed17d33
--- /dev/null
+++ b/account_tax_balance/wizard/open_tax_balances_view.xml
@@ -0,0 +1,40 @@
+
+
+
+
+ wizard_open_tax_balances
+ wizard.open.tax.balances
+
+
+
+
+
+
+ Open Tax Balances
+ wizard.open.tax.balances
+ form
+ form
+
+ new
+
+
+
+
+
\ No newline at end of file