From b01e392d0f5b0d5bfcfa2eee7b64a84603bcfb06 Mon Sep 17 00:00:00 2001 From: jcoux Date: Tue, 5 Jul 2016 11:10:35 +0200 Subject: [PATCH] Add OCA Aged Partner Balance report PDF --- account_financial_report_qweb/__openerp__.py | 1 + account_financial_report_qweb/menuitems.xml | 4 +- .../report/__init__.py | 1 + .../report/aged_partner_balance.py | 550 ++++++++++++++++++ .../report/templates/aged_partner_balance.xml | 292 ++++++++++ account_financial_report_qweb/reports.xml | 13 + .../wizard/aged_partner_balance_wizard.py | 93 +-- .../aged_partner_balance_wizard_view.xml | 44 +- 8 files changed, 934 insertions(+), 64 deletions(-) create mode 100644 account_financial_report_qweb/report/aged_partner_balance.py create mode 100644 account_financial_report_qweb/report/templates/aged_partner_balance.xml diff --git a/account_financial_report_qweb/__openerp__.py b/account_financial_report_qweb/__openerp__.py index 777ac341..72c6a16b 100644 --- a/account_financial_report_qweb/__openerp__.py +++ b/account_financial_report_qweb/__openerp__.py @@ -29,6 +29,7 @@ 'wizard/balance_sheet_wizard_view.xml', 'menuitems.xml', 'reports.xml', + 'report/templates/aged_partner_balance.xml', 'report/templates/general_ledger.xml', 'report/templates/layouts.xml', 'report/templates/open_invoice_report.xml', diff --git a/account_financial_report_qweb/menuitems.xml b/account_financial_report_qweb/menuitems.xml index 55dfd119..23564bc9 100644 --- a/account_financial_report_qweb/menuitems.xml +++ b/account_financial_report_qweb/menuitems.xml @@ -17,8 +17,8 @@ date_range.date_less_30_days + THEN rlo.amount_residual + END + ) AS current, + SUM( + CASE + WHEN + rlo.date_due > date_range.date_less_60_days + AND rlo.date_due <= date_range.date_less_30_days + THEN rlo.amount_residual + END + ) AS age_30_days, + SUM( + CASE + WHEN + rlo.date_due > date_range.date_less_90_days + AND rlo.date_due <= date_range.date_less_60_days + THEN rlo.amount_residual + END + ) AS age_60_days, + SUM( + CASE + WHEN + rlo.date_due > date_range.date_less_120_days + AND rlo.date_due <= date_range.date_less_90_days + THEN rlo.amount_residual + END + ) AS age_90_days, + SUM( + CASE + WHEN + rlo.date_due > date_range.date_older + AND rlo.date_due <= date_range.date_less_120_days + THEN rlo.amount_residual + END + ) AS age_120_days, + SUM( + CASE + WHEN rlo.date_due <= date_range.date_older + THEN rlo.amount_residual + END + ) AS older +FROM + date_range, + report_open_invoice_qweb_move_line rlo +INNER JOIN + report_open_invoice_qweb_partner rpo ON rlo.report_partner_id = rpo.id +INNER JOIN + report_open_invoice_qweb_account rao ON rpo.report_account_id = rao.id +INNER JOIN + report_aged_partner_balance_qweb_account ra ON rao.code = ra.code +INNER JOIN + report_aged_partner_balance_qweb_partner rp + ON + ra.id = rp.report_account_id + """ + if not only_empty_partner_line: + query_inject_line += """ + AND rpo.partner_id = rp.partner_id + """ + elif only_empty_partner_line: + query_inject_line += """ + AND rpo.partner_id IS NULL + AND rp.partner_id IS NULL + """ + query_inject_line += """ +WHERE + rao.report_id = %s +AND ra.report_id = %s +GROUP BY + rp.id + """ + query_inject_line_params = (self.date_at,) * 6 + query_inject_line_params += ( + self.open_invoice_id.id, + self.id, + ) + self.env.cr.execute(query_inject_line, query_inject_line_params) + + def inject_move_line_values(self, only_empty_partner_line=False): + query_inject_move_line = """ +WITH + date_range AS + ( + SELECT + %s AS date_current, + DATE %s - INTEGER '30' AS date_less_30_days, + DATE %s - INTEGER '60' AS date_less_60_days, + DATE %s - INTEGER '90' AS date_less_90_days, + DATE %s - INTEGER '120' AS date_less_120_days, + DATE %s - INTEGER '150' AS date_older + ) +INSERT INTO + report_aged_partner_balance_qweb_move_line + ( + report_partner_id, + date, + date_due, + entry, + journal, + account, + partner, + label, + amount_residual, + current, + age_30_days, + age_60_days, + age_90_days, + age_120_days, + older + ) +SELECT + rp.id AS report_partner_id, + rlo.date, + rlo.date_due, + rlo.entry, + rlo.journal, + rlo.account, + rlo.partner, + rlo.label, + rlo.amount_residual AS amount_residual, + CASE + WHEN rlo.date_due > date_range.date_less_30_days + THEN rlo.amount_residual + END AS current, + CASE + WHEN + rlo.date_due > date_range.date_less_60_days + AND rlo.date_due <= date_range.date_less_30_days + THEN rlo.amount_residual + END AS age_30_days, + CASE + WHEN + rlo.date_due > date_range.date_less_90_days + AND rlo.date_due <= date_range.date_less_60_days + THEN rlo.amount_residual + END AS age_60_days, + CASE + WHEN + rlo.date_due > date_range.date_less_120_days + AND rlo.date_due <= date_range.date_less_90_days + THEN rlo.amount_residual + END AS age_90_days, + CASE + WHEN + rlo.date_due > date_range.date_older + AND rlo.date_due <= date_range.date_less_120_days + THEN rlo.amount_residual + END AS age_120_days, + CASE + WHEN rlo.date_due <= date_range.date_older + THEN rlo.amount_residual + END AS older +FROM + date_range, + report_open_invoice_qweb_move_line rlo +INNER JOIN + report_open_invoice_qweb_partner rpo ON rlo.report_partner_id = rpo.id +INNER JOIN + report_open_invoice_qweb_account rao ON rpo.report_account_id = rao.id +INNER JOIN + report_aged_partner_balance_qweb_account ra ON rao.code = ra.code +INNER JOIN + report_aged_partner_balance_qweb_partner rp + ON + ra.id = rp.report_account_id + """ + if not only_empty_partner_line: + query_inject_move_line += """ + AND rpo.partner_id = rp.partner_id + """ + elif only_empty_partner_line: + query_inject_move_line += """ + AND rpo.partner_id IS NULL + AND rp.partner_id IS NULL + """ + query_inject_move_line += """ +WHERE + rao.report_id = %s +AND ra.report_id = %s + """ + query_inject_move_line_params = (self.date_at,) * 6 + query_inject_move_line_params += ( + self.open_invoice_id.id, + self.id, + ) + self.env.cr.execute(query_inject_move_line, + query_inject_move_line_params) + + def compute_accounts_cumul(self): + query_compute_accounts_cumul = """ +WITH + cumuls AS + ( + SELECT + ra.id AS report_account_id, + SUM(rl.amount_residual) AS cumul_amount_residual, + SUM(rl.current) AS cumul_current, + SUM(rl.age_30_days) AS cumul_age_30_days, + SUM(rl.age_60_days) AS cumul_age_60_days, + SUM(rl.age_90_days) AS cumul_age_90_days, + SUM(rl.age_120_days) AS cumul_age_120_days, + SUM(rl.older) AS cumul_older + FROM + report_aged_partner_balance_qweb_line rl + INNER JOIN + report_aged_partner_balance_qweb_partner rp + ON rl.report_partner_id = rp.id + INNER JOIN + report_aged_partner_balance_qweb_account ra + ON rp.report_account_id = ra.id + WHERE + ra.report_id = %s + GROUP BY + ra.id + ) +UPDATE + report_aged_partner_balance_qweb_account +SET + cumul_amount_residual = c.cumul_amount_residual, + cumul_current = c.cumul_current, + cumul_age_30_days = c.cumul_age_30_days, + cumul_age_60_days = c.cumul_age_60_days, + cumul_age_90_days = c.cumul_age_90_days, + cumul_age_120_days = c.cumul_age_120_days, + cumul_older = c.cumul_older, + percent_current = + CASE + WHEN c.cumul_amount_residual != 0 + THEN 100 * c.cumul_current / c.cumul_amount_residual + END, + percent_age_30_days = + CASE + WHEN c.cumul_amount_residual != 0 + THEN 100 * c.cumul_age_30_days / c.cumul_amount_residual + END, + percent_age_60_days = + CASE + WHEN c.cumul_amount_residual != 0 + THEN 100 * c.cumul_age_60_days / c.cumul_amount_residual + END, + percent_age_90_days = + CASE + WHEN c.cumul_amount_residual != 0 + THEN 100 * c.cumul_age_90_days / c.cumul_amount_residual + END, + percent_age_120_days = + CASE + WHEN c.cumul_amount_residual != 0 + THEN 100 * c.cumul_age_120_days / c.cumul_amount_residual + END, + percent_older = + CASE + WHEN c.cumul_amount_residual != 0 + THEN 100 * c.cumul_older / c.cumul_amount_residual + END +FROM + cumuls c +WHERE + id = c.report_account_id + """ + params_compute_accounts_cumul = (self.id,) + self.env.cr.execute(query_compute_accounts_cumul, + params_compute_accounts_cumul) diff --git a/account_financial_report_qweb/report/templates/aged_partner_balance.xml b/account_financial_report_qweb/report/templates/aged_partner_balance.xml new file mode 100644 index 00000000..7ce179ef --- /dev/null +++ b/account_financial_report_qweb/report/templates/aged_partner_balance.xml @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + diff --git a/account_financial_report_qweb/reports.xml b/account_financial_report_qweb/reports.xml index a06012a4..94b20997 100644 --- a/account_financial_report_qweb/reports.xml +++ b/account_financial_report_qweb/reports.xml @@ -20,6 +20,15 @@ file="account_financial_report_qweb.report_open_invoice_qweb" /> + + General Ledger XLSX report ledger.report.wizard @@ -53,5 +62,9 @@ + + + + diff --git a/account_financial_report_qweb/wizard/aged_partner_balance_wizard.py b/account_financial_report_qweb/wizard/aged_partner_balance_wizard.py index 57a87fab..ec3f33eb 100644 --- a/account_financial_report_qweb/wizard/aged_partner_balance_wizard.py +++ b/account_financial_report_qweb/wizard/aged_partner_balance_wizard.py @@ -1,66 +1,75 @@ # -*- coding: utf-8 -*- # Author: Damien Crier, Andrea Stirpe, Kevin Graveman, Dennis Sluijk +# Author: Julien Coux # Copyright 2016 Camptocamp SA, Onestein B.V. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from datetime import datetime -from openerp.exceptions import Warning as UserError from openerp import api, fields, models -class AccountAgedTrialBalance(models.TransientModel): +class AgedPartnerBalance(models.TransientModel): + """Aged partner balance report wizard.""" - _name = 'account.aged.trial.balance.wizard' - _description = 'Aged partner balanced' + _name = 'aged.partner.balance.wizard' + _description = 'Aged Partner Balance Wizard' company_id = fields.Many2one( - 'res.company', - string='Company', - required=True, - default=lambda s: s.env.user.company_id + comodel_name='res.company', + default=lambda self: self.env.user.company_id ) + date_at = fields.Date(required=True, + default=fields.Date.to_string(datetime.today())) target_move = fields.Selection([('posted', 'All Posted Entries'), ('all', 'All Entries')], string='Target Moves', required=True, - default='posted') - result_selection = fields.Selection( - [('customer', 'Receivable Accounts'), - ('supplier', 'Payable Accounts'), - ('customer_supplier', 'Receivable and Payable Accounts') - ], - string="Partner's", - default='customer') + default='all') + account_ids = fields.Many2many( + comodel_name='account.account', + string='Filter accounts', + ) + receivable_accounts_only = fields.Boolean() + payable_accounts_only = fields.Boolean() partner_ids = fields.Many2many( - 'res.partner', + comodel_name='res.partner', string='Filter partners', ) - at_date = fields.Date( - required=True, - default=fields.Date.to_string(datetime.today())) - until_date = fields.Date( - "Clearance date", required=True, - help="""The clearance date is essentially a tool used for debtors - provisionning calculation. - By default, this date is equal to the the end date ( - ie: 31/12/2011 if you select fy 2011). - By amending the clearance date, you will be, for instance, - able to answer the question : 'based on my last - year end debtors open invoices, which invoices are still - unpaid today (today is my clearance date)?'""") + show_move_line_details = fields.Boolean() - @api.onchange('at_date') - def onchange_atdate(self): - self.until_date = self.at_date + @api.onchange('date_range_id') + def onchange_date_range_id(self): + """Handle date range change.""" + self.date_at = self.date_range_id.date_end + if self.date_range_id.date_start: + self.fy_start_date = self.env.user.company_id.find_daterange_fy( + fields.Date.from_string(self.date_range_id.date_start) + ).date_start - @api.onchange('until_date') - def onchange_untildate(self): - # ---- until_date must be always >= of at_date - if self.until_date: - if self.until_date < self.at_date: - raise UserError( - 'Until Date must be equal or greater than At Date') + @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 = [] + 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 @api.multi - def check_report(self): - return True + def button_export_pdf(self): + model = self.env['report_aged_partner_balance_qweb'] + report = model.create({ + 'date_at': self.date_at, + 'only_posted_moves': self.target_move == 'posted', + 'company_id': self.company_id.id, + 'filter_account_ids': [(6, 0, self.account_ids.ids)], + 'filter_partner_ids': [(6, 0, self.partner_ids.ids)], + 'show_move_line_details': self.show_move_line_details, + }) + return report.print_report() diff --git a/account_financial_report_qweb/wizard/aged_partner_balance_wizard_view.xml b/account_financial_report_qweb/wizard/aged_partner_balance_wizard_view.xml index 9b945a10..504750d1 100644 --- a/account_financial_report_qweb/wizard/aged_partner_balance_wizard_view.xml +++ b/account_financial_report_qweb/wizard/aged_partner_balance_wizard_view.xml @@ -2,31 +2,35 @@ - - Aged Partner Balance Report - account.aged.trial.balance.wizard + + + Aged Partner Balance + aged.partner.balance.wizard
- - - - - + - - - + + + - - + + + - - +