diff --git a/account_financial_report/report/aged_partner_balance.py b/account_financial_report/report/aged_partner_balance.py index 6984fbc1..bb137bd9 100644 --- a/account_financial_report/report/aged_partner_balance.py +++ b/account_financial_report/report/aged_partner_balance.py @@ -316,6 +316,8 @@ class AgedPartnerBalanceReport(models.AbstractModel): }) self._compute_maturity_date(ml, date_at_oject) move_lines.append(ml) + move_lines = sorted(move_lines, + key=lambda k: (k['date'])) partner.update({ 'move_lines': move_lines }) diff --git a/account_financial_report/report/general_ledger.py b/account_financial_report/report/general_ledger.py index b84144ee..f285af37 100644 --- a/account_financial_report/report/general_ledger.py +++ b/account_financial_report/report/general_ledger.py @@ -2,7 +2,7 @@ # Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com) # 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 datetime import operator @@ -484,7 +484,8 @@ class GeneralLedgerReport(models.AbstractModel): move_line['balance'] += last_cumul_balance last_cumul_balance = move_line['balance'] 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 @api.model @@ -676,6 +677,7 @@ class GeneralLedgerReport(models.AbstractModel): account["move_lines"] = self._recalculate_cumul_balance( account["move_lines"], gen_ld_data[account["id"]]["init_bal"]["balance"], + rec_after_date_to_ids ) if account['partners']: account['partners'] = False diff --git a/account_financial_report/report/general_ledger_xlsx.py b/account_financial_report/report/general_ledger_xlsx.py index e6a04947..c23a1dba 100644 --- a/account_financial_report/report/general_ledger_xlsx.py +++ b/account_financial_report/report/general_ledger_xlsx.py @@ -38,7 +38,7 @@ class GeneralLedgerXslx(models.AbstractModel): 8: {'header': _('Tags'), 'field': 'tags', 'width': 10}, - 9: {'header': _('Rec.'), 'field': 'rec_name', 'width': 5}, + 9: {'header': _('Rec.'), 'field': 'rec_name', 'width': 15}, 10: {'header': _('Debit'), 'field': 'debit', 'field_initial_balance': 'initial_debit', diff --git a/account_financial_report/report/vat_report.py b/account_financial_report/report/vat_report.py index 40c71e8b..d8a14a4b 100644 --- a/account_financial_report/report/vat_report.py +++ b/account_financial_report/report/vat_report.py @@ -20,44 +20,71 @@ class VATReport(models.AbstractModel): 'name': tax.name, 'tax_group_id': tax.tax_group_id.id, '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 @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), ('date', '>=', date_from), - ('date', '<', date_to), + ('date', '<=', date_to), ('tax_line_id', '!=', 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): - 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', - 'analytic_tag_ids'] + 'tax_ids', 'analytic_tag_ids'] tax_move_lines = self.env['account.move.line'].search_read( - domain=domain, + domain=tax_domain, 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: - 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 def _get_tax_group_data(self, tax_group_ids): @@ -75,27 +102,31 @@ class VATReport(models.AbstractModel): def _get_vat_report_group_data(self, vat_report_data, tax_data, tax_detail): vat_report = {} - for tax_move_line in vat_report_data.values(): - tax_id = tax_move_line['tax_line_id'][0] - tax_group_id = tax_data[tax_id]['tax_group_id'] - if tax_group_id not in vat_report.keys(): - vat_report[tax_group_id] = {} - vat_report[tax_group_id]['net'] = 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].update( - {'net': 0.0, 'tax': 0.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: - if tax_id not in vat_report[tax_group_id].keys(): - vat_report[tax_group_id][tax_id] = tax_data[tax_id] + tax_group_id = tax_data[tax_id]['tax_group_id'] + if tax_group_id not in vat_report.keys(): + vat_report[tax_group_id] = {} + vat_report[tax_group_id]['net'] = 0.0 + vat_report[tax_group_id]['tax'] = 0.0 + vat_report[tax_group_id][tax_id] = dict(tax_data[tax_id]) vat_report[tax_group_id][tax_id].update( {'net': 0.0, 'tax': 0.0} ) - vat_report[tax_group_id]['net'] += tax_move_line['net'] - vat_report[tax_group_id]['tax'] += tax_move_line['tax'] - vat_report[tax_group_id][tax_id]['net'] += tax_move_line['net'] - vat_report[tax_group_id][tax_id]['tax'] += tax_move_line['tax'] + else: + if tax_id not in vat_report[tax_group_id].keys(): + vat_report[tax_group_id][tax_id] = dict(tax_data[ + tax_id]) + vat_report[tax_group_id][tax_id].update( + {'net': 0.0, 'tax': 0.0} + ) + vat_report[tax_group_id]['net'] += tax_move_line['net'] + vat_report[tax_group_id]['tax'] += tax_move_line['tax'] + vat_report[tax_group_id][tax_id]['net'] += tax_move_line['net'] + vat_report[tax_group_id][tax_id]['tax'] += tax_move_line['tax'] tax_group_data = self._get_tax_group_data(vat_report.keys()) vat_report_list = [] for tax_group_id in vat_report.keys(): @@ -125,29 +156,33 @@ class VATReport(models.AbstractModel): def _get_vat_report_tag_data(self, vat_report_data, tax_data, tax_detail): vat_report = {} - for tax_move_line in vat_report_data.values(): - tax_id = tax_move_line['tax_line_id'][0] - tags_ids = tax_data[tax_id]['tags_ids'] - if tags_ids: - for tag_id in tags_ids: - if tag_id not in vat_report.keys(): - vat_report[tag_id] = {} - vat_report[tag_id]['net'] = 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].update( - {'net': 0.0, 'tax': 0.0} - ) - else: - if tax_id not in vat_report[tag_id].keys(): - vat_report[tag_id][tax_id] = tax_data[tax_id] + 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'] + if tags_ids: + for tag_id in tags_ids: + if tag_id not in vat_report.keys(): + vat_report[tag_id] = {} + vat_report[tag_id]['net'] = 0.0 + vat_report[tag_id]['tax'] = 0.0 + vat_report[tag_id][tax_id] = dict(tax_data[tax_id]) vat_report[tag_id][tax_id].update( {'net': 0.0, 'tax': 0.0} ) - vat_report[tag_id][tax_id]['net'] += tax_move_line['net'] - vat_report[tag_id][tax_id]['tax'] += tax_move_line['tax'] - vat_report[tag_id]['net'] += tax_move_line['net'] - vat_report[tag_id]['tax'] += tax_move_line['tax'] + else: + if tax_id not in vat_report[tag_id].keys(): + vat_report[tag_id][tax_id] = dict(tax_data[ + tax_id]) + vat_report[tag_id][tax_id].update( + {'net': 0.0, 'tax': 0.0} + ) + vat_report[tag_id][tax_id]['net'] += tax_move_line['net'] + vat_report[tag_id][tax_id]['tax'] += tax_move_line['tax'] + vat_report[tag_id]['net'] += tax_move_line['net'] + vat_report[tag_id]['tax'] += tax_move_line['tax'] tags_data = self._get_tags_data(vat_report.keys()) vat_report_list = [] for tag_id in vat_report.keys(): @@ -172,8 +207,10 @@ class VATReport(models.AbstractModel): date_to = data['date_to'] based_on = data['based_on'] tax_detail = data['tax_detail'] + only_posted_moves = data['only_posted_moves'] 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': vat_report = self._get_vat_report_group_data( vat_report_data, tax_data, tax_detail) diff --git a/account_financial_report/tests/test_vat_report.py b/account_financial_report/tests/test_vat_report.py index 43bd466e..939c7de1 100644 --- a/account_financial_report/tests/test_vat_report.py +++ b/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( 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 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( 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): vat_wizard = self.env['vat.report.wizard'] diff --git a/account_financial_report/wizard/general_ledger_wizard.py b/account_financial_report/wizard/general_ledger_wizard.py index 3581d336..a3d77229 100644 --- a/account_financial_report/wizard/general_ledger_wizard.py +++ b/account_financial_report/wizard/general_ledger_wizard.py @@ -56,10 +56,8 @@ class GeneralLedgerReportWizard(models.TransientModel): show_analytic_tags = fields.Boolean( 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( comodel_name='res.partner', string='Filter partners', @@ -159,8 +157,8 @@ class GeneralLedgerReportWizard(models.TransientModel): lambda p: p.company_id == self.company_id or not p.company_id) 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: self.account_ids = self.account_ids.filtered( 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 ' '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: self.account_ids = None @@ -219,12 +223,9 @@ class GeneralLedgerReportWizard(models.TransientModel): def onchange_partner_ids(self): """Handle partners change.""" 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: - 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.depends('company_id') diff --git a/account_financial_report/wizard/vat_report_wizard.py b/account_financial_report/wizard/vat_report_wizard.py index 01a2a4a6..58aa6e58 100644 --- a/account_financial_report/wizard/vat_report_wizard.py +++ b/account_financial_report/wizard/vat_report_wizard.py @@ -27,6 +27,11 @@ class VATReportWizard(models.TransientModel): required=True, default='taxtags') 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') def onchange_company_id(self): @@ -99,6 +104,7 @@ class VATReportWizard(models.TransientModel): 'date_from': self.date_from, 'date_to': self.date_to, 'based_on': self.based_on, + 'only_posted_moves': self.target_move == 'posted', 'tax_detail': self.tax_detail, } diff --git a/account_financial_report/wizard/vat_report_wizard_view.xml b/account_financial_report/wizard/vat_report_wizard_view.xml index 0b360fa3..fe660e90 100755 --- a/account_financial_report/wizard/vat_report_wizard_view.xml +++ b/account_financial_report/wizard/vat_report_wizard_view.xml @@ -16,6 +16,7 @@ +