Browse Source

[IMP] account_financial_report: Fix VAT Report and other improvements

pull/660/head
Joan Sisquella 5 years ago
parent
commit
9673efb5cb
  1. 2
      account_financial_report/report/aged_partner_balance.py
  2. 6
      account_financial_report/report/general_ledger.py
  3. 2
      account_financial_report/report/general_ledger_xlsx.py
  4. 97
      account_financial_report/report/vat_report.py
  5. 36
      account_financial_report/tests/test_vat_report.py
  6. 35
      account_financial_report/wizard/general_ledger_wizard.py
  7. 6
      account_financial_report/wizard/vat_report_wizard.py
  8. 1
      account_financial_report/wizard/vat_report_wizard_view.xml

2
account_financial_report/report/aged_partner_balance.py

@ -316,6 +316,8 @@ class AgedPartnerBalanceReport(models.AbstractModel):
}) })
self._compute_maturity_date(ml, date_at_oject) self._compute_maturity_date(ml, date_at_oject)
move_lines.append(ml) move_lines.append(ml)
move_lines = sorted(move_lines,
key=lambda k: (k['date']))
partner.update({ partner.update({
'move_lines': move_lines 'move_lines': move_lines
}) })

6
account_financial_report/report/general_ledger.py

@ -2,7 +2,7 @@
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com) # Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, api
from odoo import _, models, api
import calendar import calendar
import datetime import datetime
import operator import operator
@ -484,7 +484,8 @@ class GeneralLedgerReport(models.AbstractModel):
move_line['balance'] += last_cumul_balance move_line['balance'] += last_cumul_balance
last_cumul_balance = move_line['balance'] last_cumul_balance = move_line['balance']
if move_line['rec_id'] in rec_after_date_to_ids: if move_line['rec_id'] in rec_after_date_to_ids:
move_line['rec_name'] = str('*')+move_line['rec_name']
move_line['rec_name'] = '('+_('future')+') '+move_line[
'rec_name']
return move_lines return move_lines
@api.model @api.model
@ -676,6 +677,7 @@ class GeneralLedgerReport(models.AbstractModel):
account["move_lines"] = self._recalculate_cumul_balance( account["move_lines"] = self._recalculate_cumul_balance(
account["move_lines"], account["move_lines"],
gen_ld_data[account["id"]]["init_bal"]["balance"], gen_ld_data[account["id"]]["init_bal"]["balance"],
rec_after_date_to_ids
) )
if account['partners']: if account['partners']:
account['partners'] = False account['partners'] = False

2
account_financial_report/report/general_ledger_xlsx.py

@ -38,7 +38,7 @@ class GeneralLedgerXslx(models.AbstractModel):
8: {'header': _('Tags'), 8: {'header': _('Tags'),
'field': 'tags', 'field': 'tags',
'width': 10}, 'width': 10},
9: {'header': _('Rec.'), 'field': 'rec_name', 'width': 5},
9: {'header': _('Rec.'), 'field': 'rec_name', 'width': 15},
10: {'header': _('Debit'), 10: {'header': _('Debit'),
'field': 'debit', 'field': 'debit',
'field_initial_balance': 'initial_debit', 'field_initial_balance': 'initial_debit',

97
account_financial_report/report/vat_report.py

@ -20,44 +20,71 @@ class VATReport(models.AbstractModel):
'name': tax.name, 'name': tax.name,
'tax_group_id': tax.tax_group_id.id, 'tax_group_id': tax.tax_group_id.id,
'tags_ids': tax.tag_ids.ids, 'tags_ids': tax.tag_ids.ids,
'type_tax_use': tax.type_tax_use
'type_tax_use': tax.type_tax_use,
'amount_type': tax.amount_type,
} }
}) })
return tax_data return tax_data
@api.model @api.model
def _get_vat_report_domain(self, company_id, date_from, date_to):
def _get_tax_report_domain(self, company_id, date_from,
date_to, only_posted_moves):
domain = [('company_id', '=', company_id), domain = [('company_id', '=', company_id),
('date', '>=', date_from), ('date', '>=', date_from),
('date', '<', date_to),
('date', '<=', date_to),
('tax_line_id', '!=', False), ('tax_line_id', '!=', False),
('tax_exigible', '=', True)] ('tax_exigible', '=', True)]
if only_posted_moves:
domain += [('move_id.state', '=', 'posted')]
return domain return domain
def _get_vat_report_data(self, company_id, date_from, date_to):
domain = self._get_vat_report_domain(company_id, date_from, date_to)
@api.model
def _get_net_report_domain(self, company_id, date_from,
date_to, only_posted_moves):
domain = [('company_id', '=', company_id),
('date', '>=', date_from),
('date', '<=', date_to),
('tax_ids', '!=', False),
('tax_exigible', '=', True)]
if only_posted_moves:
domain += [('move_id.state', '=', 'posted')]
return domain
def _get_vat_report_data(self, company_id, date_from,
date_to, only_posted_moves):
tax_domain = self._get_tax_report_domain(
company_id, date_from, date_to, only_posted_moves
)
ml_fields = ['id', 'tax_base_amount', 'balance', 'tax_line_id', ml_fields = ['id', 'tax_base_amount', 'balance', 'tax_line_id',
'analytic_tag_ids']
'tax_ids', 'analytic_tag_ids']
tax_move_lines = self.env['account.move.line'].search_read( tax_move_lines = self.env['account.move.line'].search_read(
domain=domain,
domain=tax_domain,
fields=ml_fields, fields=ml_fields,
) )
vat_data = {}
tax_ids = list(map(operator.itemgetter('tax_line_id'), tax_move_lines))
tax_ids = [i[0] for i in tax_ids]
tax_data = self._get_tax_data(tax_ids)
net_domain = self._get_net_report_domain(
company_id, date_from, date_to, only_posted_moves
)
taxed_move_lines = self.env['account.move.line'].search_read(
domain=net_domain,
fields=ml_fields,
)
vat_data = []
for tax_move_line in tax_move_lines: for tax_move_line in tax_move_lines:
tax_ml_id = tax_move_line['id']
tax_id = tax_move_line['tax_line_id'][0]
vat_data[tax_ml_id] = {}
vat_data[tax_ml_id].update({
'id': tax_ml_id,
'net': tax_move_line['tax_base_amount'],
'tax': (-1) * tax_move_line['balance']
if tax_data[tax_id]['type_tax_use'] == 'sale'
else tax_move_line['balance'],
'tax_line_id': tax_move_line['tax_line_id'],
vat_data.append({
'net': 0.0,
'tax': tax_move_line['balance'],
'tax_line_id': tax_move_line['tax_line_id'][0],
})
for taxed_move_line in taxed_move_lines:
for tax_id in taxed_move_line['tax_ids']:
vat_data.append({
'net': taxed_move_line['balance'],
'tax': 0.0,
'tax_line_id': tax_id,
}) })
tax_ids = list(map(operator.itemgetter('tax_line_id'), vat_data))
tax_ids = list(set(tax_ids))
tax_data = self._get_tax_data(tax_ids)
return vat_data, tax_data return vat_data, tax_data
def _get_tax_group_data(self, tax_group_ids): def _get_tax_group_data(self, tax_group_ids):
@ -75,20 +102,24 @@ class VATReport(models.AbstractModel):
def _get_vat_report_group_data(self, vat_report_data, tax_data, tax_detail): def _get_vat_report_group_data(self, vat_report_data, tax_data, tax_detail):
vat_report = {} vat_report = {}
for tax_move_line in vat_report_data.values():
tax_id = tax_move_line['tax_line_id'][0]
for tax_move_line in vat_report_data:
tax_id = tax_move_line['tax_line_id']
if tax_data[tax_id]['amount_type'] == 'group':
pass
else:
tax_group_id = tax_data[tax_id]['tax_group_id'] tax_group_id = tax_data[tax_id]['tax_group_id']
if tax_group_id not in vat_report.keys(): if tax_group_id not in vat_report.keys():
vat_report[tax_group_id] = {} vat_report[tax_group_id] = {}
vat_report[tax_group_id]['net'] = 0.0 vat_report[tax_group_id]['net'] = 0.0
vat_report[tax_group_id]['tax'] = 0.0 vat_report[tax_group_id]['tax'] = 0.0
vat_report[tax_group_id][tax_id] = tax_data[tax_id]
vat_report[tax_group_id][tax_id] = dict(tax_data[tax_id])
vat_report[tax_group_id][tax_id].update( vat_report[tax_group_id][tax_id].update(
{'net': 0.0, 'tax': 0.0} {'net': 0.0, 'tax': 0.0}
) )
else: else:
if tax_id not in vat_report[tax_group_id].keys(): if tax_id not in vat_report[tax_group_id].keys():
vat_report[tax_group_id][tax_id] = tax_data[tax_id]
vat_report[tax_group_id][tax_id] = dict(tax_data[
tax_id])
vat_report[tax_group_id][tax_id].update( vat_report[tax_group_id][tax_id].update(
{'net': 0.0, 'tax': 0.0} {'net': 0.0, 'tax': 0.0}
) )
@ -125,8 +156,11 @@ class VATReport(models.AbstractModel):
def _get_vat_report_tag_data(self, vat_report_data, tax_data, tax_detail): def _get_vat_report_tag_data(self, vat_report_data, tax_data, tax_detail):
vat_report = {} vat_report = {}
for tax_move_line in vat_report_data.values():
tax_id = tax_move_line['tax_line_id'][0]
for tax_move_line in vat_report_data:
tax_id = tax_move_line['tax_line_id']
if tax_data[tax_id]['amount_type'] == 'group':
pass
else:
tags_ids = tax_data[tax_id]['tags_ids'] tags_ids = tax_data[tax_id]['tags_ids']
if tags_ids: if tags_ids:
for tag_id in tags_ids: for tag_id in tags_ids:
@ -134,13 +168,14 @@ class VATReport(models.AbstractModel):
vat_report[tag_id] = {} vat_report[tag_id] = {}
vat_report[tag_id]['net'] = 0.0 vat_report[tag_id]['net'] = 0.0
vat_report[tag_id]['tax'] = 0.0 vat_report[tag_id]['tax'] = 0.0
vat_report[tag_id][tax_id] = tax_data[tax_id]
vat_report[tag_id][tax_id] = dict(tax_data[tax_id])
vat_report[tag_id][tax_id].update( vat_report[tag_id][tax_id].update(
{'net': 0.0, 'tax': 0.0} {'net': 0.0, 'tax': 0.0}
) )
else: else:
if tax_id not in vat_report[tag_id].keys(): if tax_id not in vat_report[tag_id].keys():
vat_report[tag_id][tax_id] = tax_data[tax_id]
vat_report[tag_id][tax_id] = dict(tax_data[
tax_id])
vat_report[tag_id][tax_id].update( vat_report[tag_id][tax_id].update(
{'net': 0.0, 'tax': 0.0} {'net': 0.0, 'tax': 0.0}
) )
@ -172,8 +207,10 @@ class VATReport(models.AbstractModel):
date_to = data['date_to'] date_to = data['date_to']
based_on = data['based_on'] based_on = data['based_on']
tax_detail = data['tax_detail'] tax_detail = data['tax_detail']
only_posted_moves = data['only_posted_moves']
vat_report_data, tax_data = self._get_vat_report_data( vat_report_data, tax_data = self._get_vat_report_data(
company_id, date_from, date_to)
company_id, date_from, date_to, only_posted_moves
)
if based_on == 'taxgroups': if based_on == 'taxgroups':
vat_report = self._get_vat_report_group_data( vat_report = self._get_vat_report_group_data(
vat_report_data, tax_data, tax_detail) vat_report_data, tax_data, tax_detail)

36
account_financial_report/tests/test_vat_report.py

@ -212,16 +212,16 @@ class TestVATReport(common.TransactionCase):
tax_20_net, tax_20_tax = self._get_tax_line( tax_20_net, tax_20_tax = self._get_tax_line(
self.tax_20.name, vat_report) self.tax_20.name, vat_report)
self.assertEqual(tag_01_net, 100)
self.assertEqual(tag_01_tax, 10)
self.assertEqual(tag_02_net, 350)
self.assertEqual(tag_02_tax, 60)
self.assertEqual(tag_03_net, 250)
self.assertEqual(tag_03_tax, 50)
self.assertEqual(tax_10_net, 100)
self.assertEqual(tax_10_tax, 10)
self.assertEqual(tax_20_net, 250)
self.assertEqual(tax_20_tax, 50)
self.assertEqual(tag_01_net, -100)
self.assertEqual(tag_01_tax, -10)
self.assertEqual(tag_02_net, -350)
self.assertEqual(tag_02_tax, -60)
self.assertEqual(tag_03_net, -250)
self.assertEqual(tag_03_tax, -50)
self.assertEqual(tax_10_net, -100)
self.assertEqual(tax_10_tax, -10)
self.assertEqual(tax_20_net, -250)
self.assertEqual(tax_20_tax, -50)
# Check report based on taxgroups # Check report based on taxgroups
res_data = self._get_report_lines(taxgroups=True) res_data = self._get_report_lines(taxgroups=True)
@ -249,14 +249,14 @@ class TestVATReport(common.TransactionCase):
tax_20_net, tax_20_tax = self._get_tax_line( tax_20_net, tax_20_tax = self._get_tax_line(
self.tax_20.name, vat_report) self.tax_20.name, vat_report)
self.assertEqual(group_10_net, 100)
self.assertEqual(group_10_tax, 10)
self.assertEqual(group_20_net, 250)
self.assertEqual(group_20_tax, 50)
self.assertEqual(tax_10_net, 100)
self.assertEqual(tax_10_tax, 10)
self.assertEqual(tax_20_net, 250)
self.assertEqual(tax_20_tax, 50)
self.assertEqual(group_10_net, -100)
self.assertEqual(group_10_tax, -10)
self.assertEqual(group_20_net, -250)
self.assertEqual(group_20_tax, -50)
self.assertEqual(tax_10_net, -100)
self.assertEqual(tax_10_tax, -10)
self.assertEqual(tax_20_net, -250)
self.assertEqual(tax_20_tax, -50)
def test_wizard_date_range(self): def test_wizard_date_range(self):
vat_wizard = self.env['vat.report.wizard'] vat_wizard = self.env['vat.report.wizard']

35
account_financial_report/wizard/general_ledger_wizard.py

@ -56,10 +56,8 @@ class GeneralLedgerReportWizard(models.TransientModel):
show_analytic_tags = fields.Boolean( show_analytic_tags = fields.Boolean(
string='Show analytic tags', string='Show analytic tags',
) )
account_type_ids = fields.Many2many(
'account.account.type',
string='Account Types',
)
receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean()
partner_ids = fields.Many2many( partner_ids = fields.Many2many(
comodel_name='res.partner', comodel_name='res.partner',
string='Filter partners', string='Filter partners',
@ -159,8 +157,8 @@ class GeneralLedgerReportWizard(models.TransientModel):
lambda p: p.company_id == self.company_id or lambda p: p.company_id == self.company_id or
not p.company_id) not p.company_id)
if self.company_id and self.account_ids: if self.company_id and self.account_ids:
if self.account_type_ids:
self._onchange_account_type_ids()
if self.receivable_accounts_only or self.payable_accounts_only:
self.onchange_type_accounts_only()
else: else:
self.account_ids = self.account_ids.filtered( self.account_ids = self.account_ids.filtered(
lambda a: a.company_id == self.company_id) lambda a: a.company_id == self.company_id)
@ -206,12 +204,18 @@ class GeneralLedgerReportWizard(models.TransientModel):
_('The Company in the General Ledger Report Wizard and in ' _('The Company in the General Ledger Report Wizard and in '
'Date Range must be the same.')) 'Date Range must be the same.'))
@api.onchange('account_type_ids')
def _onchange_account_type_ids(self):
if self.account_type_ids:
self.account_ids = self.env['account.account'].search([
('company_id', '=', self.company_id.id),
('user_type_id', 'in', self.account_type_ids.ids)])
@api.onchange('receivable_accounts_only', 'payable_accounts_only')
def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change."""
if self.receivable_accounts_only or self.payable_accounts_only:
domain = [('company_id', '=', self.company_id.id)]
if self.receivable_accounts_only and self.payable_accounts_only:
domain += [('internal_type', 'in', ('receivable', 'payable'))]
elif self.receivable_accounts_only:
domain += [('internal_type', '=', 'receivable')]
elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')]
self.account_ids = self.env['account.account'].search(domain)
else: else:
self.account_ids = None self.account_ids = None
@ -219,12 +223,9 @@ class GeneralLedgerReportWizard(models.TransientModel):
def onchange_partner_ids(self): def onchange_partner_ids(self):
"""Handle partners change.""" """Handle partners change."""
if self.partner_ids: if self.partner_ids:
self.account_type_ids = self.env['account.account.type'].search([
('type', 'in', ['receivable', 'payable'])])
self.receivable_accounts_only = self.payable_accounts_only = True
else: else:
self.account_type_ids = None
# Somehow this is required to force onchange on _default_partners()
self._onchange_account_type_ids()
self.receivable_accounts_only = self.payable_accounts_only = False
@api.multi @api.multi
@api.depends('company_id') @api.depends('company_id')

6
account_financial_report/wizard/vat_report_wizard.py

@ -27,6 +27,11 @@ class VATReportWizard(models.TransientModel):
required=True, required=True,
default='taxtags') default='taxtags')
tax_detail = fields.Boolean('Detail Taxes') tax_detail = fields.Boolean('Detail Taxes')
target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')],
string='Target Moves',
required=True,
default='posted')
@api.onchange('company_id') @api.onchange('company_id')
def onchange_company_id(self): def onchange_company_id(self):
@ -99,6 +104,7 @@ class VATReportWizard(models.TransientModel):
'date_from': self.date_from, 'date_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
'based_on': self.based_on, 'based_on': self.based_on,
'only_posted_moves': self.target_move == 'posted',
'tax_detail': self.tax_detail, 'tax_detail': self.tax_detail,
} }

1
account_financial_report/wizard/vat_report_wizard_view.xml

@ -16,6 +16,7 @@
<field name="date_to"/> <field name="date_to"/>
</group> </group>
<group name="other_filters"> <group name="other_filters">
<field name="target_move" widget="radio"/>
<field name="based_on" widget="radio"/> <field name="based_on" widget="radio"/>
<field name="tax_detail"/> <field name="tax_detail"/>
</group> </group>

Loading…
Cancel
Save