From bd469eb507850ac14eecdfea57b1a50fd0fd7608 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Alomar Date: Fri, 22 Jun 2018 01:49:24 +0200 Subject: [PATCH] [IMP] Extend customer_activity_statement to display also payables --- customer_activity_statement/README.rst | 20 +++++---- customer_activity_statement/__manifest__.py | 4 +- .../report/customer_activity_statement.py | 42 +++++++++++-------- .../static/description/index.html | 10 ++--- .../views/statement.xml | 7 +++- .../customer_activity_statement_wizard.py | 4 ++ .../customer_activity_statement_wizard.xml | 11 +++-- 7 files changed, 61 insertions(+), 37 deletions(-) diff --git a/customer_activity_statement/README.rst b/customer_activity_statement/README.rst index e0b84469..a23c75e1 100644 --- a/customer_activity_statement/README.rst +++ b/customer_activity_statement/README.rst @@ -3,17 +3,17 @@ :alt: License: AGPL-3 ================================= -Print Customer Activity Statement +Print Partner Activity Statement ================================= -The activity statement provides details of all activity on the customer receivables +The activity statement provides details of all activity on the partner receivables or payables between two selected dates. This includes all invoices, refunds and payments. Any outstanding balance dated prior to the chosen statement period will appear as a forward balance at the top of the statement. The list is displayed in chronological order and is split by currencies. Aging details can be shown in the report, expressed in aging buckets (30 days -due, ...), so the customer can review how much is open, due or overdue. +due, ...), so the customer or vendor can review how much is open, due or overdue. Configuration ============= @@ -22,22 +22,28 @@ Users willing to access to this report should have proper Accounting & Finance r #. Go to *Settings / Users* and edit your user to add the corresponding access rights as follows. #. In *Application / Accounting & Finance*, select *Billing* or *Billing Manager* -#. In *Technical Setting* mark *Show Full Accounting Features* options. +#. In *Technical Settings* mark *Show Full Accounting Features* options. Usage ===== To use this module, you need to: -#. Go to Invoicing > Sales > Master Data > Customers and select one or more -#. Press 'Action > Customer Activity Statement' -#. Indicate if you want to display aging buckets +#. Go to Invoicing > Sales > Master Data > Customers or Invoicing > Purchases > Master Data > Vendors and select one or more +#. Press 'Action > Partner Activity Statement' +#. Indicate if you want to display receivables or payables, and if you want to display aging buckets .. 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 +Roadmap +======= + +* In v12, the module should be renamed to `Partner Activity Statement`. + Maybe merge this module with the `Partner Outstanding Statement` module. + Bug Tracker =========== diff --git a/customer_activity_statement/__manifest__.py b/customer_activity_statement/__manifest__.py index cc9d3cc1..31cd9f7c 100644 --- a/customer_activity_statement/__manifest__.py +++ b/customer_activity_statement/__manifest__.py @@ -3,8 +3,8 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). { - 'name': 'Customer Activity Statement', - 'version': '11.0.1.0.0', + 'name': 'Partner Activity Statement', + 'version': '11.0.2.0.0', 'category': 'Accounting & Finance', 'summary': 'OCA Financial Reports', 'author': "Eficent, Odoo Community Association (OCA)", diff --git a/customer_activity_statement/report/customer_activity_statement.py b/customer_activity_statement/report/customer_activity_statement.py index 7d2253a9..104484b7 100644 --- a/customer_activity_statement/report/customer_activity_statement.py +++ b/customer_activity_statement/report/customer_activity_statement.py @@ -18,7 +18,7 @@ class CustomerActivityStatement(models.AbstractModel): date = datetime.strptime(str_date, DEFAULT_SERVER_DATE_FORMAT).date() return date.strftime(lang.date_format) - def _initial_balance_sql_q1(self, partners, date_start): + def _initial_balance_sql_q1(self, partners, date_start, account_type): return """ SELECT l.partner_id, l.currency_id, l.company_id, CASE WHEN l.currency_id is not null AND l.amount_currency > 0.0 @@ -32,11 +32,11 @@ class CustomerActivityStatement(models.AbstractModel): FROM account_move_line l JOIN account_account_type at ON (at.id = l.user_type_id) JOIN account_move m ON (l.move_id = m.id) - WHERE l.partner_id IN (%s) AND at.type = 'receivable' + WHERE l.partner_id IN (%s) AND at.type = '%s' AND l.date < '%s' AND not l.blocked GROUP BY l.partner_id, l.currency_id, l.amount_currency, l.company_id - """ % (partners, date_start) + """ % (partners, account_type, date_start) def _initial_balance_sql_q2(self, company_id): return """ @@ -48,7 +48,7 @@ class CustomerActivityStatement(models.AbstractModel): """ % company_id def _get_account_initial_balance(self, company_id, partner_ids, - date_start): + date_start, account_type): res = dict(map(lambda x: (x, []), partner_ids)) partners = ', '.join([str(i) for i in partner_ids]) date_start = datetime.strptime( @@ -56,13 +56,15 @@ class CustomerActivityStatement(models.AbstractModel): # pylint: disable=E8103 self.env.cr.execute("""WITH Q1 AS (%s), Q2 AS (%s) SELECT partner_id, currency_id, balance - FROM Q2""" % (self._initial_balance_sql_q1(partners, date_start), + FROM Q2""" % (self._initial_balance_sql_q1(partners, date_start, + account_type), self._initial_balance_sql_q2(company_id))) for row in self.env.cr.dictfetchall(): res[row.pop('partner_id')].append(row) return res - def _display_lines_sql_q1(self, partners, date_start, date_end): + def _display_lines_sql_q1(self, partners, date_start, date_end, + account_type): return """ SELECT m.name AS move_id, l.partner_id, l.date, l.name, l.ref, l.blocked, l.currency_id, l.company_id, @@ -81,12 +83,12 @@ class CustomerActivityStatement(models.AbstractModel): FROM account_move_line l JOIN account_account_type at ON (at.id = l.user_type_id) JOIN account_move m ON (l.move_id = m.id) - WHERE l.partner_id IN (%s) AND at.type = 'receivable' + WHERE l.partner_id IN (%s) AND at.type = '%s' AND '%s' <= l.date AND l.date <= '%s' GROUP BY l.partner_id, m.name, l.date, l.date_maturity, l.name, l.ref, l.blocked, l.currency_id, l.amount_currency, l.company_id - """ % (partners, date_start, date_end) + """ % (partners, account_type, date_start, date_end) def _display_lines_sql_q2(self, company_id): return """ @@ -99,7 +101,7 @@ class CustomerActivityStatement(models.AbstractModel): """ % company_id def _get_account_display_lines(self, company_id, partner_ids, date_start, - date_end): + date_end, account_type): res = dict(map(lambda x: (x, []), partner_ids)) partners = ', '.join([str(i) for i in partner_ids]) date_start = datetime.strptime( @@ -112,7 +114,8 @@ class CustomerActivityStatement(models.AbstractModel): credit, amount, blocked, currency_id FROM Q2 ORDER BY date, date_maturity, move_id""" % ( - self._display_lines_sql_q1(partners, date_start, date_end), + self._display_lines_sql_q1(partners, date_start, date_end, + account_type), self._display_lines_sql_q2(company_id))) for row in self.env.cr.dictfetchall(): res[row.pop('partner_id')].append(row) @@ -143,7 +146,7 @@ class CustomerActivityStatement(models.AbstractModel): GROUP BY l1.id """ % (date_end, date_end) - def _show_buckets_sql_q1(self, partners, date_end): + def _show_buckets_sql_q1(self, partners, date_end, account_type): return """ SELECT l.partner_id, l.currency_id, l.company_id, l.move_id, CASE WHEN l.balance > 0.0 @@ -174,14 +177,14 @@ class CustomerActivityStatement(models.AbstractModel): ON pr.debit_move_id = l2.id WHERE l2.date <= '%s' ) as pc ON pc.credit_move_id = l.id - WHERE l.partner_id IN (%s) AND at.type = 'receivable' + WHERE l.partner_id IN (%s) AND at.type = '%s' AND (Q0.reconciled_date is null or Q0.reconciled_date > '%s') AND l.date <= '%s' AND not l.blocked GROUP BY l.partner_id, l.currency_id, l.date, l.date_maturity, l.amount_currency, l.balance, l.move_id, l.company_id - """ % (date_end, date_end, partners, date_end, date_end) + """ % (date_end, date_end, partners, account_type, date_end, date_end) def _show_buckets_sql_q2(self, date_end, minus_30, minus_60, minus_90, minus_120): @@ -273,7 +276,8 @@ class CustomerActivityStatement(models.AbstractModel): 'minus_120': date_end - timedelta(days=120), } - def _get_account_show_buckets(self, company_id, partner_ids, date_end): + def _get_account_show_buckets(self, company_id, partner_ids, date_end, + account_type): res = dict(map(lambda x: (x, []), partner_ids)) partners = ', '.join([str(i) for i in partner_ids]) date_end = datetime.strptime( @@ -290,7 +294,7 @@ class CustomerActivityStatement(models.AbstractModel): GROUP BY partner_id, currency_id, current, b_1_30, b_30_60, b_60_90, b_90_120, b_over_120""" % ( self._show_buckets_sql_q0(date_end), - self._show_buckets_sql_q1(partners, date_end), + self._show_buckets_sql_q1(partners, date_end, account_type), self._show_buckets_sql_q2( full_dates['date_end'], full_dates['minus_30'], @@ -309,6 +313,7 @@ class CustomerActivityStatement(models.AbstractModel): partner_ids = data['partner_ids'] date_start = data['date_start'] date_end = data['date_end'] + account_type = data['account_type'] today = fields.Date.today() balance_start_to_display, buckets_to_display = {}, {} @@ -317,7 +322,7 @@ class CustomerActivityStatement(models.AbstractModel): today_display, date_start_display, date_end_display = {}, {}, {} balance_start = self._get_account_initial_balance( - company_id, partner_ids, date_start) + company_id, partner_ids, date_start, account_type) for partner_id in partner_ids: balance_start_to_display[partner_id] = {} @@ -329,7 +334,7 @@ class CustomerActivityStatement(models.AbstractModel): line['balance'] lines = self._get_account_display_lines( - company_id, partner_ids, date_start, date_end) + company_id, partner_ids, date_start, date_end, account_type) for partner_id in partner_ids: lines_to_display[partner_id], amount_due[partner_id] = {}, {} @@ -361,7 +366,7 @@ class CustomerActivityStatement(models.AbstractModel): if data['show_aging_buckets']: buckets = self._get_account_show_buckets( - company_id, partner_ids, date_end) + company_id, partner_ids, date_end, account_type) for partner_id in partner_ids: buckets_to_display[partner_id] = {} for line in buckets[partner_id]: @@ -385,4 +390,5 @@ class CustomerActivityStatement(models.AbstractModel): 'Date_start': date_start_display, 'Date_end': date_end_display, 'Date': today_display, + 'account_type': account_type, } diff --git a/customer_activity_statement/static/description/index.html b/customer_activity_statement/static/description/index.html index 163c9323..a811835d 100644 --- a/customer_activity_statement/static/description/index.html +++ b/customer_activity_statement/static/description/index.html @@ -1,7 +1,7 @@
-

Customer Activity Statement

+

Partner Activity Statement

@@ -10,12 +10,12 @@

The activity statement provides -details of all activity on the customer receivables between two selected dates. This +details of all activity on the receivables or payables of a partner between two selected dates. This includes all invoices, refunds and payments. Any outstanding balance dated prior to the chosen statement period will appear as a forward balance at the top of the statement. The list is displayed in chronological order and is split by currencies.

Aging details can be shown in the report, expressed in aging buckets (30 days due, ...), -so the customer can review how much is open, due or overdue.

+so the customer or vendor can review how much is open, due or overdue.

@@ -45,8 +45,8 @@ so the customer can review how much is open, due or overdue.

To use this module, you need to:

diff --git a/customer_activity_statement/views/statement.xml b/customer_activity_statement/views/statement.xml index 2adc580f..c4878bc9 100644 --- a/customer_activity_statement/views/statement.xml +++ b/customer_activity_statement/views/statement.xml @@ -23,8 +23,11 @@

-

- Activity Statement between and in : +

+ Customer Activity Statement between and in : +

+

+ Supplier Activity Statement between and in :

diff --git a/customer_activity_statement/wizard/customer_activity_statement_wizard.py b/customer_activity_statement/wizard/customer_activity_statement_wizard.py index 1898f213..494e98e3 100644 --- a/customer_activity_statement/wizard/customer_activity_statement_wizard.py +++ b/customer_activity_statement/wizard/customer_activity_statement_wizard.py @@ -30,6 +30,9 @@ class CustomerActivityStatementWizard(models.TransientModel): ) filter_partners_non_due = fields.Boolean( string='Don\'t show partners with no due entries', default=True) + account_type = fields.Selection( + [('receivable', 'Receivable'), + ('payable', 'Payable')], string='Account type', default='receivable') @api.multi def button_export_pdf(self): @@ -45,6 +48,7 @@ class CustomerActivityStatementWizard(models.TransientModel): 'partner_ids': self._context['active_ids'], 'show_aging_buckets': self.show_aging_buckets, 'filter_non_due_partners': self.filter_partners_non_due, + 'account_type': self.account_type, } def _export(self): diff --git a/customer_activity_statement/wizard/customer_activity_statement_wizard.xml b/customer_activity_statement/wizard/customer_activity_statement_wizard.xml index aa3911b3..175c7241 100644 --- a/customer_activity_statement/wizard/customer_activity_statement_wizard.xml +++ b/customer_activity_statement/wizard/customer_activity_statement_wizard.xml @@ -4,7 +4,7 @@

+ + +