diff --git a/account_tax_balance/README.rst b/account_tax_balance/README.rst new file mode 100644 index 00000000..ba3acddb --- /dev/null +++ b/account_tax_balance/README.rst @@ -0,0 +1,60 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +============ +Tax Balances +============ + +This module allows to compute tax balances within a certain date range. +It depends on date_range module and exposes 'compute' methods that can be called by other modules (like localization ones) + +Usage +===== + +Accounting --> Reporting --> Taxes Balance + +Select the company, the date range, the target moves and 'open taxes' + +.. figure:: /account_tax_balance/static/description/tax_balance.png + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/91/9.0 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Lorenzo Battistini +* Giovanni Capalbo + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/account_tax_balance/__init__.py b/account_tax_balance/__init__.py new file mode 100644 index 00000000..7ef5132c --- /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 diff --git a/account_tax_balance/__openerp__.py b/account_tax_balance/__openerp__.py new file mode 100644 index 00000000..10e3e685 --- /dev/null +++ b/account_tax_balance/__openerp__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# © 2016 Lorenzo Battistini - Agile Business Group +# © 2016 Antonio Espinosa +# 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, Therp BV, Tecnativa, " + "Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "account", + "date_range", + ], + "data": [ + "wizard/open_tax_balances_view.xml", + "views/account_move_view.xml", + "views/account_tax_view.xml", + ], + "images": [ + 'images/tax_balance.png', + ] +} diff --git a/account_tax_balance/i18n/es.po b/account_tax_balance/i18n/es.po new file mode 100644 index 00000000..41cd1957 --- /dev/null +++ b/account_tax_balance/i18n/es.po @@ -0,0 +1,261 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_tax_balance +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-10-21 15:30+0000\n" +"PO-Revision-Date: 2016-10-21 15:30+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_search_balance +msgid "Account" +msgstr "Cuenta" + +#. module: account_tax_balance +#: model:ir.model,name:account_tax_balance.model_account_move +msgid "Account Entry" +msgstr "Asiento contable" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_search_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "Account Tax" +msgstr "Cuenta de impuesto" + +#. module: account_tax_balance +#: selection:wizard.open.tax.balances,target_move:0 +msgid "All Entries" +msgstr "Todos los asientos" + +#. module: account_tax_balance +#: selection:wizard.open.tax.balances,target_move:0 +msgid "All Posted Entries" +msgstr "Todos los asientos asentados" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_account_tax_balance_regular +msgid "Balance" +msgstr "Cuota" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_account_tax_balance_refund +msgid "Balance Refund" +msgstr "Cuota devoluciones" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_account_tax_base_balance_regular +msgid "Base Balance" +msgstr "Base imponible" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_account_tax_base_balance_refund +msgid "Base Balance Refund" +msgstr "Base devoluciones" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "Base Total" +msgstr "Base total" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.wizard_open_tax_balances +msgid "Cancel" +msgstr "Cancelar" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_company_id +msgid "Company" +msgstr "Compañía" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_create_date +msgid "Created on" +msgstr "Creado en" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_date_range_id +msgid "Date range" +msgstr "Periodo" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_from_date +msgid "From date" +msgstr "Desde" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_search_balance +msgid "Group By" +msgstr "Agrupar por" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_id +msgid "ID" +msgstr "ID" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances___last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_write_uid +msgid "Last Updated by" +msgstr "Última modificación por" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_write_date +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: account_tax_balance +#: selection:account.move,move_type:0 +msgid "Liquidity" +msgstr "Liquidez" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_account_move_move_type +msgid "Move type" +msgstr "Tipo de operación" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.wizard_open_tax_balances +msgid "Open Taxes" +msgstr "Ver impuestos" + +#. module: account_tax_balance +#: selection:account.move,move_type:0 +msgid "Other" +msgstr "Otro" + +#. module: account_tax_balance +#: selection:account.move,move_type:0 +msgid "Payable" +msgstr "A pagar" + +#. module: account_tax_balance +#: selection:account.move,move_type:0 +msgid "Payable refund" +msgstr "Devoluciones a cobrar" + +#. module: account_tax_balance +#: selection:account.move,move_type:0 +msgid "Receivable" +msgstr "A cobrar" + +#. module: account_tax_balance +#: selection:account.move,move_type:0 +msgid "Receivable refund" +msgstr "Devoluciones a pagar" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_search_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "Short Name" +msgstr "Nombre corto" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_target_move +msgid "Target Moves" +msgstr "Movimientos destino" + +#. module: account_tax_balance +#: model:ir.model,name:account_tax_balance.model_account_tax +msgid "Tax" +msgstr "Impuesto" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_search_balance +msgid "Tax Group" +msgstr "Grupo del impuesto" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_search_balance +msgid "Tax Scope" +msgstr "Uso del impuesto" + +#. module: account_tax_balance +#: model:ir.actions.act_window,name:account_tax_balance.action_open_tax_balances +#: model:ir.actions.act_window,name:account_tax_balance.action_tax_balances_tree +#: model:ir.ui.menu,name:account_tax_balance.menu_action_open_tax_balances +#: model:ir.ui.view,arch_db:account_tax_balance.wizard_open_tax_balances +msgid "Taxes Balance" +msgstr "Tabla de impuestos" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances_to_date +msgid "To date" +msgstr "Hasta" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "Total" +msgstr "Total" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_account_tax_balance +msgid "Total Balance" +msgstr "Total cuota" + +#. module: account_tax_balance +#: model:ir.model.fields,field_description:account_tax_balance.field_account_tax_base_balance +msgid "Total Base Balance" +msgstr "Total base imponible" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "View base lines" +msgstr "Ver líneas de base imponible" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "View base refund lines" +msgstr "Ver líneas de base imponible de devoluciones" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "View base regular lines" +msgstr "Ver líneas de base imponible de operaciones corrientes" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "View tax lines" +msgstr "Ver líneas de cuota" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "View tax refund lines" +msgstr "Ver líneas de cuota de devoluciones" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.view_tax_tree_balance +msgid "View tax regular lines" +msgstr "Ver líneas de cuota de operaciones corrientes" + +#. module: account_tax_balance +#: model:ir.ui.view,arch_db:account_tax_balance.wizard_open_tax_balances +msgid "or" +msgstr "o" + +#. module: account_tax_balance +#: model:ir.model,name:account_tax_balance.model_wizard_open_tax_balances +msgid "wizard.open.tax.balances" +msgstr "wizard.open.tax.balances" diff --git a/account_tax_balance/models/__init__.py b/account_tax_balance/models/__init__.py new file mode 100644 index 00000000..b78e51cd --- /dev/null +++ b/account_tax_balance/models/__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 account_move +from . import account_tax diff --git a/account_tax_balance/models/account_move.py b/account_tax_balance/models/account_move.py new file mode 100644 index 00000000..a7092c95 --- /dev/null +++ b/account_tax_balance/models/account_move.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# © 2016 Antonio Espinosa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import models, fields, api + + +class AccountMove(models.Model): + _inherit = 'account.move' + + move_type = fields.Selection( + string="Move type", selection=[ + ('other', 'Other'), + ('liquidity', 'Liquidity'), + ('receivable', 'Receivable'), + ('receivable_refund', 'Receivable refund'), + ('payable', 'Payable'), + ('payable_refund', 'Payable refund'), + ], compute='_compute_move_type', store=True, readonly=True) + + @api.multi + @api.depends('line_ids.account_id.internal_type', 'line_ids.balance') + def _compute_move_type(self): + def _balance_get(line_ids, internal_type): + return sum(line_ids.filtered( + lambda x: x.account_id.internal_type == internal_type).mapped( + 'balance')) + + for move in self: + internal_types = move.line_ids.mapped('account_id.internal_type') + if 'liquidity' in internal_types: + move.move_type = 'liquidity' + elif 'payable' in internal_types: + balance = _balance_get(move.line_ids, 'payable') + move.move_type = ( + 'payable' if balance < 0 else 'payable_refund') + elif 'receivable' in internal_types: + balance = _balance_get(move.line_ids, 'receivable') + move.move_type = ( + 'receivable' if balance > 0 else 'receivable_refund') + else: + move.move_type = 'other' diff --git a/account_tax_balance/models/account_tax.py b/account_tax_balance/models/account_tax.py new file mode 100644 index 00000000..a6596899 --- /dev/null +++ b/account_tax_balance/models/account_tax.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +# © 2016 Lorenzo Battistini - Agile Business Group +# © 2016 Antonio Espinosa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import models, fields, api +from openerp.tools.safe_eval import safe_eval + + +class AccountTax(models.Model): + _inherit = 'account.tax' + + balance = fields.Float( + string="Total Balance", compute="_compute_balance", + search='_search_balance') + base_balance = fields.Float( + string="Total Base Balance", compute="_compute_balance", + search='_search_base_balance') + balance_regular = fields.Float( + string="Balance", compute="_compute_balance", + search='_search_balance_regular') + base_balance_regular = fields.Float( + string="Base Balance", compute="_compute_balance", + search='_search_base_balance_regular') + balance_refund = fields.Float( + string="Balance Refund", compute="_compute_balance", + search='_search_balance_refund') + base_balance_refund = fields.Float( + string="Base Balance Refund", compute="_compute_balance", + search='_search_base_balance_refund') + + def _search_balance_field(self, field, operator, value): + operators = {'>', '<', '>=', '<=', '!=', '=', '<>'} + fields = { + 'balance', 'base_balance', 'balance_regular', + 'base_balance_regular', 'balance_refund', 'base_balance_refund', + } + domain = [] + if operator in operators and field in fields: + value = float(value) if value else 0 + taxes = self.search([]).filtered( + lambda x: safe_eval( + '%.2f %s %.2f' % (x[field], operator, value))) + domain.append(('id', 'in', taxes.ids)) + return domain + + def _search_balance(self, operator, value): + return self._search_balance_field('balance', operator, value) + + def _search_base_balance(self, operator, value): + return self._search_balance_field('base_balance', operator, value) + + def _search_balance_regular(self, operator, value): + return self._search_balance_field('balance_regular', operator, value) + + def _search_base_balance_regular(self, operator, value): + return self._search_balance_field( + 'base_balance_regular', operator, value) + + def _search_balance_refund(self, operator, value): + return self._search_balance_field('balance_refund', operator, value) + + def _search_base_balance_refund(self, operator, value): + return self._search_balance_field( + 'base_balance_refund', operator, value) + + def get_context_values(self): + context = self.env.context + return ( + context.get('from_date', fields.Date.context_today(self)), + context.get('to_date', fields.Date.context_today(self)), + context.get('company_id', self.env.user.company_id.id), + context.get('target_move', 'posted') + ) + + def _compute_balance(self): + for tax in self: + tax.balance_regular = tax.compute_balance( + tax_or_base='tax', move_type='regular') + tax.base_balance_regular = tax.compute_balance( + tax_or_base='base', move_type='regular') + tax.balance_refund = tax.compute_balance( + tax_or_base='tax', move_type='refund') + tax.base_balance_refund = tax.compute_balance( + tax_or_base='base', move_type='refund') + tax.balance = tax.balance_regular + tax.balance_refund + tax.base_balance = ( + tax.base_balance_regular + tax.base_balance_refund) + + def get_target_type_list(self, move_type=None): + if move_type == 'refund': + return ['receivable_refund', 'payable_refund'] + elif move_type == 'regular': + return ['receivable', 'payable'] + return [] + + 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_partial_domain(self, from_date, to_date, company_id): + return [ + ('date', '<=', to_date), + ('date', '>=', from_date), + ('company_id', '=', company_id), + ] + + def compute_balance(self, tax_or_base='tax', move_type=None): + self.ensure_one() + move_lines = self.get_move_lines_domain( + tax_or_base=tax_or_base, move_type=move_type) + # balance is debit - credit whereas on tax return you want to see what + # vat has to be paid so: + # VAT on sales (credit) - VAT on purchases (debit). + total = -sum([l.balance for l in move_lines]) + return total + + def get_balance_domain(self, state_list, type_list): + domain = [ + ('move_id.state', 'in', state_list), + ('tax_line_id', '=', self.id), + ] + if type_list: + domain.append(('move_id.move_type', 'in', type_list)) + return domain + + def get_base_balance_domain(self, state_list, type_list): + domain = [ + ('move_id.state', 'in', state_list), + ('tax_ids', 'in', self.id), + ] + if type_list: + domain.append(('move_id.move_type', 'in', type_list)) + return domain + + def get_move_lines_domain(self, tax_or_base='tax', move_type=None): + 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) + type_list = self.get_target_type_list(move_type) + 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, type_list) + elif tax_or_base == 'base': + balance_domain = self.get_base_balance_domain( + state_list, type_list) + domain.extend(balance_domain) + return move_line_model.search(domain) + + def get_lines_action(self, tax_or_base='tax', move_type=None): + move_lines = self.get_move_lines_domain( + tax_or_base=tax_or_base, move_type=move_type) + 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') + + @api.multi + def view_tax_regular_lines(self): + self.ensure_one() + return self.get_lines_action(tax_or_base='tax', move_type='regular') + + @api.multi + def view_base_regular_lines(self): + self.ensure_one() + return self.get_lines_action(tax_or_base='base', move_type='regular') + + @api.multi + def view_tax_refund_lines(self): + self.ensure_one() + return self.get_lines_action(tax_or_base='tax', move_type='refund') + + @api.multi + def view_base_refund_lines(self): + self.ensure_one() + return self.get_lines_action(tax_or_base='base', move_type='refund') diff --git a/account_tax_balance/static/description/icon.png b/account_tax_balance/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/account_tax_balance/static/description/icon.png differ diff --git a/account_tax_balance/static/description/tax_balance.png b/account_tax_balance/static/description/tax_balance.png new file mode 100644 index 00000000..b5063a44 Binary files /dev/null and b/account_tax_balance/static/description/tax_balance.png differ diff --git a/account_tax_balance/tests/__init__.py b/account_tax_balance/tests/__init__.py new file mode 100644 index 00000000..b1bcc511 --- /dev/null +++ b/account_tax_balance/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- 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 diff --git a/account_tax_balance/tests/test_account_tax_balance.py b/account_tax_balance/tests/test_account_tax_balance.py new file mode 100644 index 00000000..e66eca5c --- /dev/null +++ b/account_tax_balance/tests/test_account_tax_balance.py @@ -0,0 +1,145 @@ +# -*- 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 openerp.tests.common import TransactionCase +from datetime import datetime +from dateutil.rrule import MONTHLY + + +class TestAccountTaxBalance(TransactionCase): + + def setUp(self): + super(TestAccountTaxBalance, self).setUp() + self.range_type = self.env['date.range.type'].create( + {'name': 'Fiscal year', + 'company_id': False, + 'allow_overlap': False}) + self.range_generator = self.env['date.range.generator'] + self.current_year = datetime.now().year + self.current_month = datetime.now().month + range_generator = self.range_generator.create({ + 'date_start': '%s-01-01' % self.current_year, + 'name_prefix': '%s-' % self.current_year, + 'type_id': self.range_type.id, + 'duration_count': 1, + 'unit_of_time': MONTHLY, + 'count': 12}) + range_generator.action_apply() + self.range = self.env['date.range'] + + def test_tax_balance(self): + tax_account_id = self.env['account.account'].search( + [('name', '=', 'Tax Paid')], limit=1).id + tax = self.env['account.tax'].create({ + 'name': 'Tax 10.0%', + 'amount': 10.0, + 'amount_type': 'percent', + 'account_id': tax_account_id, + }) + invoice_account_id = self.env['account.account'].search( + [('user_type_id', '=', self.env.ref( + 'account.data_account_type_receivable' + ).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({ + 'partner_id': self.env.ref('base.res_partner_2').id, + 'account_id': invoice_account_id, + 'type': 'out_invoice', + }) + + self.env['account.invoice.line'].create({ + 'product_id': self.env.ref('product.product_product_4').id, + 'quantity': 1.0, + 'price_unit': 100.0, + 'invoice_id': invoice.id, + 'name': 'product that cost 100', + 'account_id': invoice_line_account_id, + 'invoice_line_tax_ids': [(6, 0, [tax.id])], + }) + invoice._onchange_invoice_line_ids() + invoice._convert_to_write(invoice._cache) + self.assertEqual(invoice.state, 'draft') + + # change the state of invoice to open by clicking Validate button + invoice.signal_workflow('invoice_open') + + self.assertEquals(tax.base_balance, 100.) + self.assertEquals(tax.balance, 10.) + self.assertEquals(tax.base_balance_regular, 100.) + self.assertEquals(tax.balance_regular, 10.) + self.assertEquals(tax.base_balance_refund, 0.) + self.assertEquals(tax.balance_refund, 0.) + + # 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, []) + + refund = self.env['account.invoice'].create({ + 'partner_id': self.env.ref('base.res_partner_2').id, + 'account_id': invoice_account_id, + 'type': 'out_refund', + }) + + self.env['account.invoice.line'].create({ + 'product_id': self.env.ref('product.product_product_2').id, + 'quantity': 1.0, + 'price_unit': 25.0, + 'invoice_id': refund.id, + 'name': 'returned product that cost 25', + 'account_id': invoice_line_account_id, + 'invoice_line_tax_ids': [(6, 0, [tax.id])], + }) + refund._onchange_invoice_line_ids() + refund._convert_to_write(invoice._cache) + self.assertEqual(refund.state, 'draft') + + # change the state of refund to open by clicking Validate button + refund.signal_workflow('invoice_open') + + self.assertEquals(tax.base_balance, 75.) + self.assertEquals(tax.balance, 7.5) + self.assertEquals(tax.base_balance_regular, 100.) + self.assertEquals(tax.balance_regular, 10.) + self.assertEquals(tax.base_balance_refund, -25.) + self.assertEquals(tax.balance_refund, -2.5) diff --git a/account_tax_balance/views/account_move_view.xml b/account_tax_balance/views/account_move_view.xml new file mode 100644 index 00000000..5211c056 --- /dev/null +++ b/account_tax_balance/views/account_move_view.xml @@ -0,0 +1,40 @@ + + + + + + + Add move type column + account.move + + + + + + + + + + Add move type field + account.move + + + + + + + + + + Add move type group by + account.move + + + + + + + + + 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..fa1895c8 --- /dev/null +++ b/account_tax_balance/views/account_tax_view.xml @@ -0,0 +1,71 @@ + + + + + + account.tax.tree.balance + account.tax + + + + + + + +