diff --git a/account_financial_report/README.rst b/account_financial_report/README.rst index db65e376..92978013 100644 --- a/account_financial_report/README.rst +++ b/account_financial_report/README.rst @@ -15,6 +15,14 @@ Accounting / Reporting / OCA Reports. - Aged Partner Balance - VAT Report +Currently General ledger, Trial Balance and Open Items are fully compatible with a foreign +currency set up in account in order to display balances. Moreover, any foreign +currency used in account move lines is properly shown. + +In case that in an account has not been configured a second currency foreign +currency balances are not available. + + .. 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/11.0 diff --git a/account_financial_report/__manifest__.py b/account_financial_report/__manifest__.py index a2dfb015..ecf80bf0 100644 --- a/account_financial_report/__manifest__.py +++ b/account_financial_report/__manifest__.py @@ -21,6 +21,7 @@ 'data': [ 'wizard/aged_partner_balance_wizard_view.xml', 'wizard/general_ledger_wizard_view.xml', + 'wizard/journal_ledger_wizard_view.xml', 'wizard/open_items_wizard_view.xml', 'wizard/trial_balance_wizard_view.xml', 'wizard/vat_report_wizard_view.xml', @@ -29,12 +30,14 @@ 'report/templates/layouts.xml', 'report/templates/aged_partner_balance.xml', 'report/templates/general_ledger.xml', + 'report/templates/journal_ledger.xml', 'report/templates/open_items.xml', 'report/templates/trial_balance.xml', 'report/templates/vat_report.xml', 'view/account_view.xml', 'view/report_template.xml', 'view/report_general_ledger.xml', + 'view/report_journal_ledger.xml', 'view/report_trial_balance.xml', 'view/report_open_items.xml', 'view/report_aged_partner_balance.xml', diff --git a/account_financial_report/menuitems.xml b/account_financial_report/menuitems.xml index cbbd4458..080f3029 100644 --- a/account_financial_report/menuitems.xml +++ b/account_financial_report/menuitems.xml @@ -15,6 +15,13 @@ sequence="10" /> + + = %s + AND + am.date <= %s + """ + if self.move_target != 'all': + where_clause += """ + AND + am.state = %s + """ + return where_clause + + @api.multi + def _get_inject_move_order_by(self): + self.ensure_one() + order_by = """ + ORDER BY + """ + if self.sort_option == 'move_name': + order_by += " am.name" + elif self.sort_option == 'date': + order_by += " am.date, am.name" + return order_by + + @api.multi + def _get_inject_move_params(self): + params = [ + self.env.uid, + self.id, + self.date_from, + self.date_to + ] + + if self.move_target != 'all': + params.append(self.move_target) + + return tuple(params) + + @api.multi + def _inject_move_line_values(self): + self.ensure_one() + sql = """ + DELETE + FROM report_journal_ledger_move_line + WHERE report_id = %s + """ + params = ( + self.id, + ) + self.env.cr.execute(sql, params) + sql = """ + INSERT INTO report_journal_ledger_move_line ( + create_uid, + create_date, + report_id, + report_journal_ledger_id, + report_move_id, + move_line_id, + account_id, + account, + account_code, + account_type, + partner_id, + partner, + date, + entry, + label, + debit, + credit, + company_currency_id, + amount_currency, + currency_id, + currency_name, + tax_id, + taxes_description, + company_id + ) + SELECT + %s as create_uid, + NOW() as create_date, + rjqm.report_id as report_id, + rjqm.report_journal_ledger_id as report_journal_ledger_id, + rjqm.id as report_move_id, + aml.id as move_line_id, + aml.account_id as account_id, + aa.name as account, + aa.code as account_code, + aa.internal_type as account_type, + aml.partner_id as partner_id, + p.name as partner, + aml.date as date, + rjqm.name as entry, + aml.name as label, + aml.debit as debit, + aml.credit as credit, + aml.company_currency_id as currency_id, + aml.amount_currency as amount_currency, + aml.currency_id as currency_id, + currency.name as currency_name, + aml.tax_line_id as tax_id, + CASE + WHEN + aml.tax_line_id is not null + THEN + COALESCE(at.description, at.name) + WHEN + aml.tax_line_id is null + THEN + (SELECT + array_to_string( + array_agg(COALESCE(at.description, at.name) + ), ', ') + FROM + account_move_line_account_tax_rel aml_at_rel + LEFT JOIN + account_tax at on (at.id = aml_at_rel.account_tax_id) + WHERE + aml_at_rel.account_move_line_id = aml.id) + ELSE + '' + END as taxes_description, + aml.company_id as company_id + FROM + account_move_line aml + INNER JOIN + report_journal_ledger_move rjqm + on (rjqm.move_id = aml.move_id) + LEFT JOIN + account_account aa + on (aa.id = aml.account_id) + LEFT JOIN + res_partner p + on (p.id = aml.partner_id) + LEFT JOIN + account_tax at + on (at.id = aml.tax_line_id) + LEFT JOIN + res_currency currency + on (currency.id = aml.currency_id) + WHERE + rjqm.report_id = %s + """ + params = ( + self.env.uid, + self.id, + ) + self.env.cr.execute(sql, params) + + @api.multi + def _inject_report_tax_values(self): + self.ensure_one() + sql_distinct_tax_id = """ + SELECT + distinct(jrqjtl.tax_id) + FROM + report_journal_ledger_journal_tax_line jrqjtl + WHERE + jrqjtl.report_id = %s + """ + self.env.cr.execute(sql_distinct_tax_id, (self.id,)) + rows = self.env.cr.fetchall() + tax_ids = set([row[0] for row in rows]) + + sql = """ + INSERT INTO report_journal_ledger_report_tax_line ( + create_uid, + create_date, + report_id, + tax_id, + tax_name, + tax_code, + base_debit, + base_credit, + tax_debit, + tax_credit + ) + SELECT + %s as create_uid, + NOW() as create_date, + %s as report_id, + %s as tax_id, + at.name as tax_name, + at.description as tax_code, + ( + SELECT sum(base_debit) + FROM report_journal_ledger_journal_tax_line jrqjtl2 + WHERE jrqjtl2.report_id = %s + AND jrqjtl2.tax_id = %s + ) as base_debit, + ( + SELECT sum(base_credit) + FROM report_journal_ledger_journal_tax_line jrqjtl2 + WHERE jrqjtl2.report_id = %s + AND jrqjtl2.tax_id = %s + ) as base_credit, + ( + SELECT sum(tax_debit) + FROM report_journal_ledger_journal_tax_line jrqjtl2 + WHERE jrqjtl2.report_id = %s + AND jrqjtl2.tax_id = %s + ) as tax_debit, + ( + SELECT sum(tax_credit) + FROM report_journal_ledger_journal_tax_line jrqjtl2 + WHERE jrqjtl2.report_id = %s + AND jrqjtl2.tax_id = %s + ) as tax_credit + FROM + report_journal_ledger_journal_tax_line jrqjtl + LEFT JOIN + account_tax at + on (at.id = jrqjtl.tax_id) + WHERE + jrqjtl.report_id = %s + AND + jrqjtl.tax_id = %s + """ + + for tax_id in tax_ids: + params = ( + self.env.uid, + self.id, + tax_id, + self.id, + tax_id, + self.id, + tax_id, + self.id, + tax_id, + self.id, + tax_id, + self.id, + tax_id, + ) + self.env.cr.execute(sql, params) + + @api.multi + def _inject_journal_tax_values(self): + self.ensure_one() + sql = """ + DELETE + FROM report_journal_ledger_journal_tax_line + WHERE report_id = %s + """ + params = ( + self.id, + ) + self.env.cr.execute(sql, params) + sql_distinct_tax_id = """ + SELECT + distinct(jrqml.tax_id) + FROM + report_journal_ledger_move_line jrqml + WHERE + jrqml.report_journal_ledger_id = %s + """ + + tax_ids_by_journal_id = {} + for report_journal in self.report_journal_ledger_ids: + if report_journal.id not in tax_ids_by_journal_id: + tax_ids_by_journal_id[report_journal.id] = [] + self.env.cr.execute(sql_distinct_tax_id, (report_journal.id,)) + rows = self.env.cr.fetchall() + tax_ids_by_journal_id[report_journal.id].extend([ + row[0] for row in rows if row[0] + ]) + + sql = """ + INSERT INTO report_journal_ledger_journal_tax_line ( + create_uid, + create_date, + report_id, + report_journal_ledger_id, + tax_id, + tax_name, + tax_code, + base_debit, + base_credit, + tax_debit, + tax_credit + ) + SELECT + %s as create_uid, + NOW() as create_date, + %s as report_id, + %s as report_journal_ledger_id, + %s as tax_id, + at.name as tax_name, + at.description as tax_code, + ( + SELECT sum(debit) + FROM report_journal_ledger_move_line jrqml2 + WHERE jrqml2.report_journal_ledger_id = %s + AND ( + SELECT + count(*) + FROM + account_move_line_account_tax_rel aml_at_rel + WHERE + aml_at_rel.account_move_line_id = + jrqml2.move_line_id + AND + aml_at_rel.account_tax_id = %s + ) > 0 + ) as base_debit, + ( + SELECT sum(credit) + FROM report_journal_ledger_move_line jrqml2 + WHERE jrqml2.report_journal_ledger_id = %s + AND ( + SELECT + count(*) + FROM + account_move_line_account_tax_rel aml_at_rel + WHERE + aml_at_rel.account_move_line_id = + jrqml2.move_line_id + AND + aml_at_rel.account_tax_id = %s + ) > 0 + ) as base_credit, + ( + SELECT sum(debit) + FROM report_journal_ledger_move_line jrqml2 + WHERE jrqml2.report_journal_ledger_id = %s + AND jrqml2.tax_id = %s + ) as tax_debit, + ( + SELECT sum(credit) + FROM report_journal_ledger_move_line jrqml2 + WHERE jrqml2.report_journal_ledger_id = %s + AND jrqml2.tax_id = %s + ) as tax_credit + FROM + report_journal_ledger_journal rjqj + LEFT JOIN + account_tax at + on (at.id = %s) + WHERE + rjqj.id = %s + """ + + for report_journal_ledger_id in tax_ids_by_journal_id: + tax_ids = tax_ids_by_journal_id[report_journal_ledger_id] + for tax_id in tax_ids: + params = ( + self.env.uid, + self.id, + report_journal_ledger_id, + tax_id, + report_journal_ledger_id, + tax_id, + report_journal_ledger_id, + tax_id, + report_journal_ledger_id, + tax_id, + report_journal_ledger_id, + tax_id, + tax_id, + report_journal_ledger_id, + ) + self.env.cr.execute(sql, params) + + @api.multi + def _update_journal_report_total_values(self): + self.ensure_one() + sql = """ + UPDATE + report_journal_ledger_journal rjqj + SET + debit = ( + SELECT sum(rjqml.debit) + FROM report_journal_ledger_move_line rjqml + WHERE rjqml.report_journal_ledger_id = rjqj.id + ), + credit = ( + SELECT sum(rjqml.credit) + FROM report_journal_ledger_move_line rjqml + WHERE rjqml.report_journal_ledger_id = rjqj.id + ) + WHERE + rjqj.report_id = %s + """ + self.env.cr.execute(sql, (self.id,)) + + @api.multi + def print_report(self, report_type): + self.ensure_one() + if report_type == 'xlsx': + report_name = 'a_f_r.report_journal_ledger_xlsx' + else: + report_name = 'account_financial_report.' \ + 'report_journal_ledger_qweb' + return self.env['ir.actions.report'].search( + [('report_name', '=', report_name), + ('report_type', '=', report_type)], limit=1).report_action(self) + + def _get_html(self): + result = {} + rcontext = {} + context = dict(self.env.context) + report = self.browse(context.get('active_id')) + if report: + rcontext['o'] = report + result['html'] = self.env.ref( + 'account_financial_report.report_journal_ledger').render( + rcontext) + return result + + @api.model + def get_html(self, given_context=None): + return self._get_html() + + +class ReportJournalLedgerJournal(models.TransientModel): + + _name = 'report_journal_ledger_journal' + + name = fields.Char( + required=True, + ) + code = fields.Char() + report_id = fields.Many2one( + comodel_name='report_journal_ledger', + required=True, + ondelete='cascade' + ) + journal_id = fields.Many2one( + comodel_name='account.journal', + required=True, + ondelete='cascade', + ) + report_move_ids = fields.One2many( + comodel_name='report_journal_ledger_move', + inverse_name='report_journal_ledger_id', + ) + report_tax_line_ids = fields.One2many( + comodel_name='report_journal_ledger_journal_tax_line', + inverse_name='report_journal_ledger_id', + ) + debit = fields.Float( + digits=DIGITS, + ) + credit = fields.Float( + digits=DIGITS, + ) + company_id = fields.Many2one( + comodel_name='res.company', + required=True, + ondelete='cascade' + ) + currency_id = fields.Many2one( + comodel_name='res.currency', + ) + + +class ReportJournalLedgerMove(models.TransientModel): + + _name = 'report_journal_ledger_move' + + report_id = fields.Many2one( + comodel_name='report_journal_ledger', + required=True, + ondelete='cascade' + ) + report_journal_ledger_id = fields.Many2one( + comodel_name='report_journal_ledger_journal', + required=True, + ondelete='cascade', + ) + move_id = fields.Many2one( + comodel_name='account.move', + required=True, + ondelete='cascade', + ) + report_move_line_ids = fields.One2many( + comodel_name='report_journal_ledger_move_line', + inverse_name='report_move_id', + ) + name = fields.Char() + company_id = fields.Many2one( + comodel_name='res.company', + required=True, + ondelete='cascade' + ) + + +class ReportJournalLedgerMoveLine(models.TransientModel): + + _name = 'report_journal_ledger_move_line' + _order = 'partner_id desc, account_id desc' + + report_id = fields.Many2one( + comodel_name='report_journal_ledger', + required=True, + ondelete='cascade' + ) + report_journal_ledger_id = fields.Many2one( + comodel_name='report_journal_ledger_journal', + required=True, + ondelete='cascade', + ) + report_move_id = fields.Many2one( + comodel_name='report_journal_ledger_move', + required=True, + ondelete='cascade', + ) + move_line_id = fields.Many2one( + comodel_name='account.move.line', + required=True, + ondelete='cascade', + ) + account_id = fields.Many2one( + comodel_name='account.account' + ) + account = fields.Char() + account_code = fields.Char() + account_type = fields.Char() + partner = fields.Char() + partner_id = fields.Many2one( + comodel_name='res.partner', + ) + date = fields.Date() + entry = fields.Char() + label = fields.Char() + debit = fields.Float( + digits=DIGITS, + ) + credit = fields.Float( + digits=DIGITS, + ) + company_currency_id = fields.Many2one( + comodel_name='res.currency', + ) + amount_currency = fields.Monetary( + currency_field='currency_id', + ) + currency_id = fields.Many2one( + comodel_name='res.currency', + ) + currency_name = fields.Char() + taxes_description = fields.Char() + tax_id = fields.Many2one( + comodel_name='account.tax' + ) + company_id = fields.Many2one( + comodel_name='res.company', + required=True, + ondelete='cascade' + ) + + +class ReportJournalLedgerReportTaxLine(models.TransientModel): + + _name = 'report_journal_ledger_report_tax_line' + _order = 'tax_code' + + report_id = fields.Many2one( + comodel_name='report_journal_ledger', + required=True, + ondelete='cascade' + ) + tax_id = fields.Many2one( + comodel_name='account.tax' + ) + tax_name = fields.Char() + tax_code = fields.Char() + base_debit = fields.Float( + digits=DIGITS, + ) + base_credit = fields.Float( + digits=DIGITS, + ) + base_balance = fields.Float( + digits=DIGITS, + compute='_compute_base_balance', + ) + tax_debit = fields.Float( + digits=DIGITS, + ) + tax_credit = fields.Float( + digits=DIGITS, + ) + tax_balance = fields.Float( + digits=DIGITS, + compute='_compute_tax_balance' + ) + + @api.multi + def _compute_base_balance(self): + for rec in self: + rec.base_balance = rec.base_debit - rec.base_credit + + @api.multi + def _compute_tax_balance(self): + for rec in self: + rec.tax_balance = rec.tax_debit - rec.tax_credit + + +class ReportJournalLedgerJournalTaxLine(models.TransientModel): + + _name = 'report_journal_ledger_journal_tax_line' + _inherit = 'report_journal_ledger_report_tax_line' + _order = 'tax_code' + + report_journal_ledger_id = fields.Many2one( + comodel_name='report_journal_ledger_journal', + required=True, + ondelete='cascade', + ) diff --git a/account_financial_report/report/journal_ledger_xlsx.py b/account_financial_report/report/journal_ledger_xlsx.py new file mode 100644 index 00000000..26d1e1f6 --- /dev/null +++ b/account_financial_report/report/journal_ledger_xlsx.py @@ -0,0 +1,249 @@ +# Author: Damien Crier +# Author: Julien Coux +# Copyright 2016 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import _, models + + +class JournalLedgerXslx(models.AbstractModel): + _name = 'report.a_f_r.report_journal_ledger_xlsx' + _inherit = 'report.account_financial_report.abstract_report_xlsx' + + def _get_report_name(self): + return _('Journal Ledger') + + def _get_report_columns(self, report): + columns = [ + { + 'header': _('Entry'), + 'field': 'entry', + 'width': 18 + }, + { + 'header': _('Date'), + 'field': 'date', + 'width': 11 + }, + { + 'header': _('Account'), + 'field': 'account_code', + 'width': 9 + }, + ] + + if report.with_account_name: + columns.append({ + 'header': _('Account Name'), + 'field': 'account', + 'width': 15 + }) + + columns += [ + { + 'header': _('Partner'), + 'field': 'partner', + 'width': 25 + }, + { + 'header': _('Ref - Label'), + 'field': 'label', + 'width': 40 + }, + { + 'header': _('Taxes'), + 'field': 'taxes_description', + 'width': 11 + }, + { + 'header': _('Debit'), + 'field': 'debit', + 'type': 'amount', + 'width': 14, + }, + { + 'header': _('Credit'), + 'field': 'credit', + 'type': 'amount', + 'width': 14 + } + ] + + if report.foreign_currency: + columns += [ + { + 'header': _('Currency'), + 'field': 'currency_id', + 'type': 'many2one', + 'width': 14 + }, + { + 'header': _('Amount Currency'), + 'field': 'amount_currency', + 'type': 'amount', + 'width': 18 + }, + ] + + columns_as_dict = {} + for i, column in enumerate(columns): + columns_as_dict[i] = column + return columns_as_dict + + def _get_journal_tax_columns(self, report): + return { + 0: { + 'header': _('Name'), + 'field': 'tax_name', + 'width': 35 + }, + 1: { + 'header': _('Description'), + 'field': 'tax_code', + 'width': 18 + }, + 2: { + 'header': _('Base Debit'), + 'field': 'base_debit', + 'type': 'amount', + 'width': 14 + }, + 3: { + 'header': _('Base Credit'), + 'field': 'base_credit', + 'type': 'amount', + 'width': 14 + }, + 4: { + 'header': _('Base Balance'), + 'field': 'base_balance', + 'type': 'amount', + 'width': 14 + }, + 5: { + 'header': _('Tax Debit'), + 'field': 'tax_debit', + 'type': 'amount', + 'width': 14 + }, + 6: { + 'header': _('Tax Credit'), + 'field': 'tax_credit', + 'type': 'amount', + 'width': 14 + }, + 7: { + 'header': _('Tax Balance'), + 'field': 'tax_balance', + 'type': 'amount', + 'width': 14 + }, + } + + def _get_col_count_filter_name(self): + return 2 + + def _get_col_count_filter_value(self): + return 3 + + def _get_report_filters(self, report): + target_label_by_value = { + value: label + for value, label in + self.env['journal.ledger.report.wizard']._get_move_targets() + } + + sort_option_label_by_value = { + value: label + for value, label in + self.env['journal.ledger.report.wizard']._get_sort_options() + } + + return [ + [ + _('Company'), + report.company_id.name + ], + [ + _('Date range filter'), + _('From: %s To: %s') % (report.date_from, report.date_to) + ], + [ + _('Target moves filter'), + _("%s") % target_label_by_value[report.move_target], + ], + [ + _('Entries sorted by'), + _("%s") % sort_option_label_by_value[report.sort_option], + ], + [ + _('Journals'), + ', '.join([ + "%s - %s" % (report_journal.code, report_journal.name) + for report_journal in report.report_journal_ledger_ids + ]) + + ] + ] + + def _generate_report_content(self, workbook, report): + group_option = report.group_option + if group_option == 'journal': + for report_journal in report.report_journal_ledger_ids: + self._generate_journal_content(workbook, report_journal) + elif group_option == 'none': + self._generate_no_group_content(workbook, report) + + def _generate_no_group_content(self, workbook, report): + self._generate_moves_content( + workbook, report, "Report", report.report_move_ids) + self._generate_no_group_taxes_summary(workbook, report) + + def _generate_journal_content(self, workbook, report_journal): + sheet_name = "%s (%s) - %s" % ( + report_journal.code, + report_journal.currency_id.name, + report_journal.name, + ) + self._generate_moves_content( + workbook, report_journal.report_id, sheet_name, + report_journal.report_move_ids) + self._generate_journal_taxes_summary(workbook, report_journal) + + def _generate_no_group_taxes_summary(self, workbook, report): + self._generate_taxes_summary( + workbook, report, "Tax Report", report.report_tax_line_ids) + + def _generate_journal_taxes_summary(self, workbook, report_journal): + sheet_name = "Tax - %s (%s) - %s" % ( + report_journal.code, + report_journal.currency_id.name, + report_journal.name, + ) + report = report_journal.report_id + self._generate_taxes_summary( + workbook, report, sheet_name, report_journal.report_tax_line_ids) + + def _generate_moves_content(self, workbook, report, sheet_name, moves): + self.workbook = workbook + self.sheet = workbook.add_worksheet(sheet_name) + self._set_column_width() + + self.row_pos = 1 + + self.write_array_title(sheet_name) + self.row_pos += 2 + + self.write_array_header() + for move in moves: + for line in move.report_move_line_ids: + self.write_line(line) + self.row_pos += 1 + + def _generate_taxes_summary(self, workbook, report, sheet_name, tax_lines): + self.workbook = workbook + self.sheet = workbook.add_worksheet(sheet_name) + + self.row_pos = 1 + self.write_array_title(sheet_name) + self.row_pos += 2 diff --git a/account_financial_report/report/open_items.py b/account_financial_report/report/open_items.py index 95264efc..40af61c7 100644 --- a/account_financial_report/report/open_items.py +++ b/account_financial_report/report/open_items.py @@ -22,13 +22,11 @@ class OpenItemsReport(models.TransientModel): date_at = fields.Date() only_posted_moves = fields.Boolean() hide_account_balance_at_0 = fields.Boolean() + foreign_currency = fields.Boolean() company_id = fields.Many2one(comodel_name='res.company') filter_account_ids = fields.Many2many(comodel_name='account.account') filter_partner_ids = fields.Many2many(comodel_name='res.partner') - # Flag fields, used for report display - has_second_currency = fields.Boolean() - # Data fields, used to browse report data account_ids = fields.One2many( comodel_name='report_open_items_account', @@ -56,7 +54,11 @@ class OpenItemsReportAccount(models.TransientModel): # Data fields, used for report display code = fields.Char() name = fields.Char() + currency_id = fields.Many2one('res.currency') final_amount_residual = fields.Float(digits=(16, 2)) + final_amount_total_due = fields.Float(digits=(16, 2)) + final_amount_residual_currency = fields.Float(digits=(16, 2)) + final_amount_total_due_currency = fields.Float(digits=(16, 2)) # Data fields, used to browse report data partner_ids = fields.One2many( @@ -83,7 +85,11 @@ class OpenItemsReportPartner(models.TransientModel): # Data fields, used for report display name = fields.Char() + currency_id = fields.Many2one('res.currency') final_amount_residual = fields.Float(digits=(16, 2)) + final_amount_total_due = fields.Float(digits=(16, 2)) + final_amount_residual_currency = fields.Float(digits=(16, 2)) + final_amount_total_due_currency = fields.Float(digits=(16, 2)) # Data fields, used to browse report data move_line_ids = fields.One2many( @@ -182,10 +188,8 @@ class OpenItemsReportCompute(models.TransientModel): self._clean_partners_and_accounts( only_delete_account_balance_at_0=True ) - # Compute display flag - self._compute_has_second_currency() # Refresh cache because all data are computed with SQL requests - self.refresh() + self.invalidate_cache() def _inject_account_values(self): """Inject report values for report_open_items_account.""" @@ -197,11 +201,14 @@ WITH a.id, a.code, a.name, - a.user_type_id + a.user_type_id, + c.id as currency_id FROM account_account a INNER JOIN account_move_line ml ON a.id = ml.account_id AND ml.date <= %s + LEFT JOIN + res_currency c ON a.currency_id = c.id """ if self.filter_partner_ids: query_inject_account += """ @@ -230,7 +237,7 @@ WITH """ query_inject_account += """ GROUP BY - a.id + a.id, c.id ) INSERT INTO report_open_items_account @@ -239,6 +246,7 @@ INSERT INTO create_uid, create_date, account_id, + currency_id, code, name ) @@ -247,6 +255,7 @@ SELECT %s AS create_uid, NOW() AS create_date, a.id AS account_id, + a.currency_id, a.code, a.name FROM @@ -621,7 +630,25 @@ ORDER BY """ Compute cumulative amount for report_open_items_partner and report_open_items_account. """ - query_compute_partners_cumul = """ + self._compute_partner_cumul() + self._compute_account_cumul() + + def _compute_partner_cumul(self): + where_condition_partner_by_account = """ +WHERE + id IN + ( + SELECT + rp.id + FROM + report_open_items_account ra + INNER JOIN + report_open_items_partner rp + ON ra.id = rp.report_account_id + WHERE + ra.report_id = %s + )""" + query_computer_partner_residual_cumul = """ UPDATE report_open_items_partner SET @@ -634,6 +661,31 @@ SET WHERE rml.report_partner_id = report_open_items_partner.id ) +""" + where_condition_partner_by_account + params_compute_partners_residual_cumul = (self.id,) + self.env.cr.execute(query_computer_partner_residual_cumul, + params_compute_partners_residual_cumul) + + query_compute_partners_due_cumul = """ +UPDATE + report_open_items_partner +SET + final_amount_total_due = + ( + SELECT + SUM(rml.amount_total_due) AS final_amount_total_due + FROM + report_open_items_move_line rml + WHERE + rml.report_partner_id = report_open_items_partner.id + ) +""" + where_condition_partner_by_account + params_compute_partner_due_cumul = (self.id,) + self.env.cr.execute(query_compute_partners_due_cumul, + params_compute_partner_due_cumul) + + # Manage currency in partner + where_condition_partner_by_account_cur = """ WHERE id IN ( @@ -645,13 +697,67 @@ WHERE report_open_items_partner rp ON ra.id = rp.report_account_id WHERE - ra.report_id = %s + ra.report_id = %s AND ra.currency_id IS NOT NULL ) """ - params_compute_partners_cumul = (self.id,) - self.env.cr.execute(query_compute_partners_cumul, - params_compute_partners_cumul) - query_compute_accounts_cumul = """ + query_compute_partners_cur_id_cumul = """ +UPDATE + report_open_items_partner +SET + currency_id = + ( + SELECT + MAX(currency_id) as currency_id + FROM + report_open_items_move_line rml + WHERE + rml.report_partner_id = report_open_items_partner.id + ) +""" + where_condition_partner_by_account_cur + params_compute_partners_cur_id_cumul = (self.id,) + self.env.cr.execute(query_compute_partners_cur_id_cumul, + params_compute_partners_cur_id_cumul) + + query_compute_partners_cur_residual_cumul = """ +UPDATE + report_open_items_partner +SET + final_amount_residual_currency = + ( + SELECT + SUM(rml.amount_residual_currency) + AS final_amount_residual_currency + FROM + report_open_items_move_line rml + WHERE + rml.report_partner_id = report_open_items_partner.id + ) +""" + where_condition_partner_by_account_cur + params_compute_partners_cur_residual_cumul = (self.id,) + self.env.cr.execute(query_compute_partners_cur_residual_cumul, + params_compute_partners_cur_residual_cumul) + + query_compute_partners_cur_due_cumul = """ +UPDATE + report_open_items_partner +SET + final_amount_total_due_currency = + ( + SELECT + SUM(rml.amount_total_due_currency) + AS final_amount_total_due_currency + FROM + report_open_items_move_line rml + WHERE + rml.report_partner_id = report_open_items_partner.id + ) +""" + where_condition_partner_by_account_cur + params_compute_partners_cur_due_cumul = (self.id,) + self.env.cr.execute(query_compute_partners_cur_due_cumul, + params_compute_partners_cur_due_cumul) + + def _compute_account_cumul(self): + query_compute_accounts_residual_cumul = """ UPDATE report_open_items_account SET @@ -667,9 +773,71 @@ SET WHERE report_id = %s """ - params_compute_accounts_cumul = (self.id,) - self.env.cr.execute(query_compute_accounts_cumul, - params_compute_accounts_cumul) + params_compute_accounts_residual_cumul = (self.id,) + self.env.cr.execute(query_compute_accounts_residual_cumul, + params_compute_accounts_residual_cumul) + + query_compute_accounts_cur_residual_cumul = """ +UPDATE + report_open_items_account +SET + final_amount_residual_currency = + ( + SELECT + SUM(rp.final_amount_residual_currency) + AS final_amount_residual_currency + FROM + report_open_items_partner rp + WHERE + rp.report_account_id = report_open_items_account.id + ) +WHERE + report_id = %s + """ + params_compute_accounts_cur_residual_cumul = (self.id,) + self.env.cr.execute(query_compute_accounts_cur_residual_cumul, + params_compute_accounts_cur_residual_cumul) + + query_compute_accounts_due_cumul = """ +UPDATE + report_open_items_account +SET + final_amount_total_due = + ( + SELECT + SUM(rp.final_amount_total_due) AS final_amount_total_due + FROM + report_open_items_partner rp + WHERE + rp.report_account_id = report_open_items_account.id + ) +WHERE + report_id = %s + """ + params_compute_accounts_due_cumul = (self.id,) + self.env.cr.execute(query_compute_accounts_due_cumul, + params_compute_accounts_due_cumul) + + query_compute_accounts_cur_due_cumul = """ +UPDATE + report_open_items_account +SET + final_amount_total_due_currency = + ( + SELECT + SUM(rp.final_amount_total_due_currency) + AS final_amount_total_due_currency + FROM + report_open_items_partner rp + WHERE + rp.report_account_id = report_open_items_account.id + ) +WHERE + report_id = %s + """ + params_compute_accounts_cur_due_cumul = (self.id,) + self.env.cr.execute(query_compute_accounts_cur_due_cumul, + params_compute_accounts_cur_due_cumul) def _clean_partners_and_accounts(self, only_delete_account_balance_at_0=False): @@ -746,31 +914,3 @@ WHERE """ params_clean_accounts = (self.id,) self.env.cr.execute(query_clean_accounts, params_clean_accounts) - - def _compute_has_second_currency(self): - """ Compute "has_second_currency" flag which will used for display.""" - query_update_has_second_currency = """ -UPDATE - report_open_items -SET - has_second_currency = - ( - SELECT - TRUE - FROM - report_open_items_move_line l - INNER JOIN - report_open_items_partner p - ON l.report_partner_id = p.id - INNER JOIN - report_open_items_account a - ON p.report_account_id = a.id - WHERE - a.report_id = %s - AND l.currency_id IS NOT NULL - LIMIT 1 - ) -WHERE id = %s - """ - params = (self.id,) * 2 - self.env.cr.execute(query_update_has_second_currency, params) diff --git a/account_financial_report/report/open_items_xlsx.py b/account_financial_report/report/open_items_xlsx.py index b08b0285..b73c6fae 100644 --- a/account_financial_report/report/open_items_xlsx.py +++ b/account_financial_report/report/open_items_xlsx.py @@ -13,7 +13,7 @@ class OpenItemsXslx(models.AbstractModel): return _('Open Items') def _get_report_columns(self, report): - return { + res = { 0: {'header': _('Date'), 'field': 'date', 'width': 11}, 1: {'header': _('Entry'), 'field': 'entry', 'width': 18}, 2: {'header': _('Journal'), 'field': 'journal', 'width': 8}, @@ -30,17 +30,27 @@ class OpenItemsXslx(models.AbstractModel): 'field_final_balance': 'final_amount_residual', 'type': 'amount', 'width': 14}, - 9: {'header': _('Cur.'), 'field': 'currency_id', - 'type': 'many2one', 'width': 7}, - 10: {'header': _('Cur. Original'), - 'field': 'amount_total_due_currency', - 'type': 'amount', - 'width': 14}, - 11: {'header': _('Cur. Residual'), - 'field': 'amount_residual_currency', - 'type': 'amount', - 'width': 14}, } + if report.foreign_currency: + foreign_currency = { + 9: {'header': _('Cur.'), 'field': 'currency_id', + 'field_currency_balance': 'currency_id', + 'type': 'many2one', 'width': 7}, + 10: {'header': _('Cur. Original'), + 'field': 'amount_total_due_currency', + 'field_final_balance': + 'final_amount_total_due_currency', + 'type': 'amount_currency', + 'width': 14}, + 11: {'header': _('Cur. Residual'), + 'field': 'amount_residual_currency', + 'field_final_balance': + 'final_amount_residual_currency', + 'type': 'amount_currency', + 'width': 14}, + } + res = {**res, **foreign_currency} + return res def _get_report_filters(self, report): return [ @@ -50,6 +60,8 @@ class OpenItemsXslx(models.AbstractModel): 'All entries')], [_('Account balance at 0 filter'), _('Hide') if report.hide_account_balance_at_0 else _('Show')], + [_('Show foreign currency'), + _('Yes') if report.foreign_currency else _('No')], ] def _get_col_count_filter_name(self): @@ -99,6 +111,7 @@ class OpenItemsXslx(models.AbstractModel): if type_object == 'partner': name = my_object.name label = _('Partner ending balance') + my_object.currency_id = my_object.report_account_id.currency_id elif type_object == 'account': name = my_object.code + ' - ' + my_object.name label = _('Ending balance') diff --git a/account_financial_report/report/templates/general_ledger.xml b/account_financial_report/report/templates/general_ledger.xml index 6fa7864f..bb7eed76 100644 --- a/account_financial_report/report/templates/general_ledger.xml +++ b/account_financial_report/report/templates/general_ledger.xml @@ -14,7 +14,7 @@ diff --git a/account_financial_report/report/templates/journal_ledger.xml b/account_financial_report/report/templates/journal_ledger.xml new file mode 100644 index 00000000..8c895074 --- /dev/null +++ b/account_financial_report/report/templates/journal_ledger.xml @@ -0,0 +1,463 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/account_financial_report/report/templates/open_items.xml b/account_financial_report/report/templates/open_items.xml index 01a5ac9c..50e3258b 100644 --- a/account_financial_report/report/templates/open_items.xml +++ b/account_financial_report/report/templates/open_items.xml @@ -13,7 +13,7 @@ diff --git a/account_financial_report/report/templates/trial_balance.xml b/account_financial_report/report/templates/trial_balance.xml index 31075f5f..69d7ee3c 100644 --- a/account_financial_report/report/templates/trial_balance.xml +++ b/account_financial_report/report/templates/trial_balance.xml @@ -13,7 +13,8 @@ @@ -179,6 +187,7 @@
+ @@ -199,8 +208,9 @@ - + +
- + @@ -233,7 +243,7 @@ @@ -247,7 +257,7 @@ @@ -265,7 +275,7 @@ @@ -279,7 +289,7 @@ @@ -295,7 +305,7 @@ @@ -313,7 +323,7 @@ @@ -327,7 +337,7 @@ @@ -343,7 +353,7 @@ @@ -358,7 +368,7 @@ @@ -369,7 +379,7 @@ @@ -382,12 +392,104 @@
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+
+ +
@@ -414,7 +516,7 @@ @@ -429,7 +531,7 @@ @@ -444,7 +546,7 @@ @@ -456,11 +558,50 @@
+ + + +
+ + +
+ +
+ + + + +
+
+ + + + +
+
+ +
+
+
+ +
diff --git a/account_financial_report/report/templates/vat_report.xml b/account_financial_report/report/templates/vat_report.xml index 630d9260..f1c1c150 100644 --- a/account_financial_report/report/templates/vat_report.xml +++ b/account_financial_report/report/templates/vat_report.xml @@ -4,7 +4,7 @@