From 86423d6104d8f9d7b33aabfc3fc5f779fa6d8543 Mon Sep 17 00:00:00 2001 From: mreficent Date: Mon, 26 Feb 2018 17:14:06 +0100 Subject: [PATCH 1/3] [FIX] Consider reconciled_date and fix aging report --- customer_activity_statement/__openerp__.py | 2 +- .../report/customer_activity_statement.py | 79 +++++++++++++------ .../views/statement.xml | 9 ++- .../customer_activity_statement_wizard.py | 4 +- 4 files changed, 65 insertions(+), 29 deletions(-) diff --git a/customer_activity_statement/__openerp__.py b/customer_activity_statement/__openerp__.py index 6e8479c2..3c25742a 100644 --- a/customer_activity_statement/__openerp__.py +++ b/customer_activity_statement/__openerp__.py @@ -5,7 +5,7 @@ { 'name': 'Customer Activity Statement', - 'version': '9.0.1.0.0', + 'version': '9.0.1.1.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 9b2ec147..52750c24 100644 --- a/customer_activity_statement/report/customer_activity_statement.py +++ b/customer_activity_statement/report/customer_activity_statement.py @@ -35,7 +35,7 @@ class CustomerActivityStatement(models.AbstractModel): 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' - AND l.date <= '%s' AND not l.blocked + 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) @@ -83,7 +83,7 @@ class CustomerActivityStatement(models.AbstractModel): 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' - AND '%s' < l.date AND l.date <= '%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 @@ -107,6 +107,7 @@ class CustomerActivityStatement(models.AbstractModel): date_start, DEFAULT_SERVER_DATE_FORMAT).date() date_end = datetime.strptime( date_end, DEFAULT_SERVER_DATE_FORMAT).date() + # pylint: disable=E8103 self.env.cr.execute("""WITH Q1 AS (%s), Q2 AS (%s) SELECT partner_id, move_id, date, date_maturity, name, ref, debit, credit, amount, blocked, currency_id @@ -118,6 +119,31 @@ class CustomerActivityStatement(models.AbstractModel): res[row.pop('partner_id')].append(row) return res + def _show_buckets_sql_q0(self, date_end): + return """ + SELECT l1.id, + CASE WHEN l1.reconciled = TRUE and l1.balance > 0.0 + THEN max(pd.max_date) + WHEN l1.reconciled = TRUE and l1.balance < 0.0 + THEN max(pc.max_date) + ELSE null + END as reconciled_date + FROM account_move_line l1 + LEFT JOIN (SELECT pr.* + FROM account_partial_reconcile pr + INNER JOIN account_move_line l2 + ON pr.credit_move_id = l2.id + WHERE l2.date <= '%s' + ) as pd ON pd.debit_move_id = l1.id + LEFT JOIN (SELECT pr.* + FROM account_partial_reconcile pr + INNER JOIN account_move_line l2 + ON pr.debit_move_id = l2.id + WHERE l2.date <= '%s' + ) as pc ON pc.credit_move_id = l1.id + GROUP BY l1.id + """ % (date_end, date_end) + def _show_buckets_sql_q1(self, partners, date_end): return """ SELECT l.partner_id, l.currency_id, l.company_id, l.move_id, @@ -136,6 +162,7 @@ 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) + LEFT JOIN Q0 ON Q0.id = l.id LEFT JOIN (SELECT pr.* FROM account_partial_reconcile pr INNER JOIN account_move_line l2 @@ -149,13 +176,15 @@ class CustomerActivityStatement(models.AbstractModel): WHERE l2.date <= '%s' ) as pc ON pc.credit_move_id = l.id WHERE l.partner_id IN (%s) AND at.type = 'receivable' - AND not l.reconciled AND not l.blocked + 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, partners, date_end, date_end) - def _show_buckets_sql_q2(self, today, minus_30, minus_60, minus_90, + def _show_buckets_sql_q2(self, date_end, minus_30, minus_60, minus_90, minus_120): return """ SELECT partner_id, currency_id, date_maturity, open_due, @@ -209,10 +238,10 @@ class CustomerActivityStatement(models.AbstractModel): FROM Q1 GROUP BY partner_id, currency_id, date_maturity, open_due, open_due_currency, move_id, company_id - """ % (today, today, minus_30, today, minus_30, today, minus_60, - minus_30, minus_60, minus_30, minus_90, minus_60, minus_90, - minus_60, minus_120, minus_90, minus_120, minus_90, minus_120, - minus_120) + """ % (date_end, date_end, minus_30, date_end, minus_30, date_end, + minus_60, minus_30, minus_60, minus_30, minus_90, minus_60, + minus_90, minus_60, minus_120, minus_90, minus_120, minus_90, + minus_120, minus_120) def _show_buckets_sql_q3(self, company_id): return """ @@ -236,21 +265,24 @@ class CustomerActivityStatement(models.AbstractModel): GROUP BY partner_id, currency_id """ - _bucket_dates = { - 'today': fields.date.today(), - 'minus_30': fields.date.today() - timedelta(days=30), - 'minus_60': fields.date.today() - timedelta(days=60), - 'minus_90': fields.date.today() - timedelta(days=90), - 'minus_120': fields.date.today() - timedelta(days=120), - } + def _get_bucket_dates(self, date_end): + return { + 'date_end': date_end, + 'minus_30': date_end - timedelta(days=30), + 'minus_60': date_end - timedelta(days=60), + 'minus_90': date_end - timedelta(days=90), + 'minus_120': date_end - timedelta(days=120), + } def _get_account_show_buckets(self, company_id, partner_ids, date_end): res = dict(map(lambda x: (x, []), partner_ids)) partners = ', '.join([str(i) for i in partner_ids]) date_end = datetime.strptime( date_end, DEFAULT_SERVER_DATE_FORMAT).date() - self.env.cr.execute("""WITH Q1 AS (%s), Q2 AS (%s), - Q3 AS (%s), Q4 AS (%s) + full_dates = self._get_bucket_dates(date_end) + # pylint: disable=E8103 + self.env.cr.execute(""" + WITH Q0 AS (%s), Q1 AS (%s), Q2 AS (%s), Q3 AS (%s), Q4 AS (%s) SELECT partner_id, currency_id, current, b_1_30, b_30_60, b_60_90, b_90_120, b_over_120, current+b_1_30+b_30_60+b_60_90+b_90_120+b_over_120 @@ -258,13 +290,14 @@ class CustomerActivityStatement(models.AbstractModel): FROM Q4 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_q2( - self._bucket_dates['today'], - self._bucket_dates['minus_30'], - self._bucket_dates['minus_60'], - self._bucket_dates['minus_90'], - self._bucket_dates['minus_120']), + full_dates['date_end'], + full_dates['minus_30'], + full_dates['minus_60'], + full_dates['minus_90'], + full_dates['minus_120']), self._show_buckets_sql_q3(company_id), self._show_buckets_sql_q4())) for row in self.env.cr.dictfetchall(): diff --git a/customer_activity_statement/views/statement.xml b/customer_activity_statement/views/statement.xml index 1701cf4c..fcfa1aff 100644 --- a/customer_activity_statement/views/statement.xml +++ b/customer_activity_statement/views/statement.xml @@ -9,11 +9,11 @@ -

+

Activity Statement

- Date:
+ Date:
Partner ref:

@@ -22,7 +22,7 @@

- Activity Statement in : + Activity Statement between and in :

@@ -114,6 +114,9 @@
+

+ Aging Report at in : +

diff --git a/customer_activity_statement/wizard/customer_activity_statement_wizard.py b/customer_activity_statement/wizard/customer_activity_statement_wizard.py index a2a48c98..92367c13 100644 --- a/customer_activity_statement/wizard/customer_activity_statement_wizard.py +++ b/customer_activity_statement/wizard/customer_activity_statement_wizard.py @@ -3,7 +3,7 @@ # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from datetime import date, timedelta +from datetime import date from openerp import api, fields, models @@ -21,7 +21,7 @@ class CustomerActivityStatementWizard(models.TransientModel): date_start = fields.Date(required=True, default=fields.Date.to_string( - date.today()-timedelta(days=120))) + date(date.today().year, 1, 1))) date_end = fields.Date(required=True, default=fields.Date.to_string(date.today())) show_aging_buckets = fields.Boolean(string='Include Aging Buckets', From 03d8c47b4c6a71309712683591f0c8622d8e9909 Mon Sep 17 00:00:00 2001 From: mreficent Date: Mon, 26 Feb 2018 17:13:44 +0100 Subject: [PATCH 2/3] [FIX] Consider reconciled_date and fix aging report --- customer_outstanding_statement/__openerp__.py | 2 +- .../report/customer_outstanding_statement.py | 111 ++++++++++++++---- .../views/statement.xml | 9 +- 3 files changed, 94 insertions(+), 28 deletions(-) diff --git a/customer_outstanding_statement/__openerp__.py b/customer_outstanding_statement/__openerp__.py index 3e5aa4fc..0dfe1515 100644 --- a/customer_outstanding_statement/__openerp__.py +++ b/customer_outstanding_statement/__openerp__.py @@ -5,7 +5,7 @@ { 'name': 'Customer Outstanding Statement', - 'version': '9.0.1.0.0', + 'version': '9.0.1.1.0', 'category': 'Accounting & Finance', 'summary': 'OCA Financial Reports', 'author': "Eficent, Odoo Community Association (OCA)", diff --git a/customer_outstanding_statement/report/customer_outstanding_statement.py b/customer_outstanding_statement/report/customer_outstanding_statement.py index fe4ed5ca..989a4224 100644 --- a/customer_outstanding_statement/report/customer_outstanding_statement.py +++ b/customer_outstanding_statement/report/customer_outstanding_statement.py @@ -20,6 +20,31 @@ class CustomerOutstandingStatement(models.AbstractModel): date = datetime.strptime(str_date, DEFAULT_SERVER_DATE_FORMAT).date() return date.strftime(lang.date_format) + def _display_lines_sql_q0(self, date_end): + return """ + SELECT l1.id, + CASE WHEN l1.reconciled = TRUE and l1.balance > 0.0 + THEN max(pd.max_date) + WHEN l1.reconciled = TRUE and l1.balance < 0.0 + THEN max(pc.max_date) + ELSE null + END as reconciled_date + FROM account_move_line l1 + LEFT JOIN (SELECT pr.* + FROM account_partial_reconcile pr + INNER JOIN account_move_line l2 + ON pr.credit_move_id = l2.id + WHERE l2.date <= '%s' + ) as pd ON pd.debit_move_id = l1.id + LEFT JOIN (SELECT pr.* + FROM account_partial_reconcile pr + INNER JOIN account_move_line l2 + ON pr.debit_move_id = l2.id + WHERE l2.date <= '%s' + ) as pc ON pc.credit_move_id = l1.id + GROUP BY l1.id + """ % (date_end, date_end) + def _display_lines_sql_q1(self, partners, date_end): return """ SELECT m.name as move_id, l.partner_id, l.date, l.name, @@ -47,6 +72,7 @@ class CustomerOutstandingStatement(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) + LEFT JOIN Q0 ON Q0.id = l.id LEFT JOIN (SELECT pr.* FROM account_partial_reconcile pr INNER JOIN account_move_line l2 @@ -60,11 +86,13 @@ class CustomerOutstandingStatement(models.AbstractModel): WHERE l2.date <= '%s' ) as pc ON pc.credit_move_id = l.id WHERE l.partner_id IN (%s) AND at.type = 'receivable' - AND not l.reconciled AND l.date <= '%s' + AND (Q0.reconciled_date is null or + Q0.reconciled_date > '%s') + 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.balance, l.amount_currency, l.company_id - """ % (date_end, date_end, partners, date_end) + """ % (date_end, date_end, partners, date_end, date_end) def _display_lines_sql_q2(self): return """ @@ -92,11 +120,14 @@ class CustomerOutstandingStatement(models.AbstractModel): partners = ', '.join([str(i) for i in partner_ids]) date_end = datetime.strptime( date_end, DEFAULT_SERVER_DATE_FORMAT).date() - self.env.cr.execute("""WITH Q1 AS (%s), Q2 AS (%s), Q3 AS (%s) + # pylint: disable=E8103 + self.env.cr.execute(""" + WITH Q0 as (%s), Q1 AS (%s), Q2 AS (%s), Q3 AS (%s) SELECT partner_id, currency_id, move_id, date, date_maturity, debit, credit, amount, open_amount, name, ref, blocked FROM Q3 ORDER BY date, date_maturity, move_id""" % ( + self._display_lines_sql_q0(date_end), self._display_lines_sql_q1(partners, date_end), self._display_lines_sql_q2(), self._display_lines_sql_q3(company_id))) @@ -104,6 +135,31 @@ class CustomerOutstandingStatement(models.AbstractModel): res[row.pop('partner_id')].append(row) return res + def _show_buckets_sql_q0(self, date_end): + return """ + SELECT l1.id, + CASE WHEN l1.reconciled = TRUE and l1.balance > 0.0 + THEN max(pd.max_date) + WHEN l1.reconciled = TRUE and l1.balance < 0.0 + THEN max(pc.max_date) + ELSE null + END as reconciled_date + FROM account_move_line l1 + LEFT JOIN (SELECT pr.* + FROM account_partial_reconcile pr + INNER JOIN account_move_line l2 + ON pr.credit_move_id = l2.id + WHERE l2.date <= '%s' + ) as pd ON pd.debit_move_id = l1.id + LEFT JOIN (SELECT pr.* + FROM account_partial_reconcile pr + INNER JOIN account_move_line l2 + ON pr.debit_move_id = l2.id + WHERE l2.date <= '%s' + ) as pc ON pc.credit_move_id = l1.id + GROUP BY l1.id + """ % (date_end, date_end) + def _show_buckets_sql_q1(self, partners, date_end): return """ SELECT l.partner_id, l.currency_id, l.company_id, l.move_id, @@ -122,6 +178,7 @@ class CustomerOutstandingStatement(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) + LEFT JOIN Q0 ON Q0.id = l.id LEFT JOIN (SELECT pr.* FROM account_partial_reconcile pr INNER JOIN account_move_line l2 @@ -135,13 +192,15 @@ class CustomerOutstandingStatement(models.AbstractModel): WHERE l2.date <= '%s' ) as pc ON pc.credit_move_id = l.id WHERE l.partner_id IN (%s) AND at.type = 'receivable' - AND not l.reconciled AND not l.blocked + 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, partners, date_end, date_end) - def _show_buckets_sql_q2(self, today, minus_30, minus_60, minus_90, + def _show_buckets_sql_q2(self, date_end, minus_30, minus_60, minus_90, minus_120): return """ SELECT partner_id, currency_id, date_maturity, open_due, @@ -195,10 +254,10 @@ class CustomerOutstandingStatement(models.AbstractModel): FROM Q1 GROUP BY partner_id, currency_id, date_maturity, open_due, open_due_currency, move_id, company_id - """ % (today, today, minus_30, today, minus_30, today, minus_60, - minus_30, minus_60, minus_30, minus_90, minus_60, minus_90, - minus_60, minus_120, minus_90, minus_120, minus_90, minus_120, - minus_120) + """ % (date_end, date_end, minus_30, date_end, minus_30, date_end, + minus_60, minus_30, minus_60, minus_30, minus_90, minus_60, + minus_90, minus_60, minus_120, minus_90, minus_120, minus_90, + minus_120, minus_120) def _show_buckets_sql_q3(self, company_id): return """ @@ -222,21 +281,24 @@ class CustomerOutstandingStatement(models.AbstractModel): GROUP BY partner_id, currency_id """ - _bucket_dates = { - 'today': fields.date.today(), - 'minus_30': fields.date.today() - timedelta(days=30), - 'minus_60': fields.date.today() - timedelta(days=60), - 'minus_90': fields.date.today() - timedelta(days=90), - 'minus_120': fields.date.today() - timedelta(days=120), - } + def _get_bucket_dates(self, date_end): + return { + 'date_end': date_end, + 'minus_30': date_end - timedelta(days=30), + 'minus_60': date_end - timedelta(days=60), + 'minus_90': date_end - timedelta(days=90), + 'minus_120': date_end - timedelta(days=120), + } def _get_account_show_buckets(self, company_id, partner_ids, date_end): res = dict(map(lambda x: (x, []), partner_ids)) partners = ', '.join([str(i) for i in partner_ids]) date_end = datetime.strptime( date_end, DEFAULT_SERVER_DATE_FORMAT).date() - self.env.cr.execute("""WITH Q1 AS (%s), Q2 AS (%s), - Q3 AS (%s), Q4 AS (%s) + full_dates = self._get_bucket_dates(date_end) + # pylint: disable=E8103 + self.env.cr.execute(""" + WITH Q0 AS (%s), Q1 AS (%s), Q2 AS (%s), Q3 AS (%s), Q4 AS (%s) SELECT partner_id, currency_id, current, b_1_30, b_30_60, b_60_90, b_90_120, b_over_120, current+b_1_30+b_30_60+b_60_90+b_90_120+b_over_120 @@ -244,13 +306,14 @@ class CustomerOutstandingStatement(models.AbstractModel): FROM Q4 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_q2( - self._bucket_dates['today'], - self._bucket_dates['minus_30'], - self._bucket_dates['minus_60'], - self._bucket_dates['minus_90'], - self._bucket_dates['minus_120']), + full_dates['date_end'], + full_dates['minus_30'], + full_dates['minus_60'], + full_dates['minus_90'], + full_dates['minus_120']), self._show_buckets_sql_q3(company_id), self._show_buckets_sql_q4())) for row in self.env.cr.dictfetchall(): diff --git a/customer_outstanding_statement/views/statement.xml b/customer_outstanding_statement/views/statement.xml index 32a14e51..d084e842 100644 --- a/customer_outstanding_statement/views/statement.xml +++ b/customer_outstanding_statement/views/statement.xml @@ -9,11 +9,11 @@ -

+

Outstanding Statement

- Date:
+ Date:
Partner ref:

@@ -22,7 +22,7 @@

- Outstanding Statement in : + Outstanding Statement at in :

@@ -114,6 +114,9 @@
+

+ Aging Report at in : +

From 912d5b5e258e689f198e0743c3589ce01344bfa7 Mon Sep 17 00:00:00 2001 From: mreficent Date: Tue, 27 Feb 2018 20:45:25 +0100 Subject: [PATCH 3/3] [FIX] Workaround to obtain max_date in account_partial_reconcile --- .../report/customer_activity_statement.py | 42 ++++++++++++-- .../report/customer_outstanding_statement.py | 55 +++++++++++++++---- 2 files changed, 82 insertions(+), 15 deletions(-) diff --git a/customer_activity_statement/report/customer_activity_statement.py b/customer_activity_statement/report/customer_activity_statement.py index 52750c24..b4c2eae8 100644 --- a/customer_activity_statement/report/customer_activity_statement.py +++ b/customer_activity_statement/report/customer_activity_statement.py @@ -119,6 +119,35 @@ class CustomerActivityStatement(models.AbstractModel): res[row.pop('partner_id')].append(row) return res + def _get_credit_date(self): + return """ + SELECT apr.id, aml.date as credit_date + FROM account_partial_reconcile apr + LEFT JOIN account_move_line aml + ON aml.id = apr.credit_move_id + """ + + def _get_debit_date(self): + return """ + SELECT apr.id, aml.date as debit_date + FROM account_partial_reconcile apr + LEFT JOIN account_move_line aml + ON aml.id = apr.debit_move_id + """ + + def _get_reconcile_date(self): + return """ + SELECT pr2.id, + CASE WHEN Q0a.credit_date > Q0b.debit_date + THEN Q0a.credit_date + ELSE Q0b.debit_date + END AS max_date + FROM account_partial_reconcile pr2 + LEFT JOIN (%s) as Q0a ON Q0a.id = pr2.id + LEFT JOIN (%s) as Q0b ON Q0b.id = pr2.id + GROUP BY pr2.id, Q0a.credit_date, Q0b.debit_date + """ % (self._get_credit_date(), self._get_debit_date()) + def _show_buckets_sql_q0(self, date_end): return """ SELECT l1.id, @@ -129,20 +158,23 @@ class CustomerActivityStatement(models.AbstractModel): ELSE null END as reconciled_date FROM account_move_line l1 - LEFT JOIN (SELECT pr.* + LEFT JOIN (SELECT pr.*, Q0c.max_date FROM account_partial_reconcile pr INNER JOIN account_move_line l2 - ON pr.credit_move_id = l2.id + ON pr.credit_move_id = l2.id + LEFT JOIN (%s) as Q0c ON Q0c.id = pr.id WHERE l2.date <= '%s' ) as pd ON pd.debit_move_id = l1.id - LEFT JOIN (SELECT pr.* + LEFT JOIN (SELECT pr.*, Q0c.max_date FROM account_partial_reconcile pr INNER JOIN account_move_line l2 - ON pr.debit_move_id = l2.id + ON pr.debit_move_id = l2.id + LEFT JOIN (%s) as Q0c ON Q0c.id = pr.id WHERE l2.date <= '%s' ) as pc ON pc.credit_move_id = l1.id GROUP BY l1.id - """ % (date_end, date_end) + """ % (self._get_reconcile_date(), date_end, + self._get_reconcile_date(), date_end) def _show_buckets_sql_q1(self, partners, date_end): return """ diff --git a/customer_outstanding_statement/report/customer_outstanding_statement.py b/customer_outstanding_statement/report/customer_outstanding_statement.py index 989a4224..b2ed9fbc 100644 --- a/customer_outstanding_statement/report/customer_outstanding_statement.py +++ b/customer_outstanding_statement/report/customer_outstanding_statement.py @@ -30,20 +30,23 @@ class CustomerOutstandingStatement(models.AbstractModel): ELSE null END as reconciled_date FROM account_move_line l1 - LEFT JOIN (SELECT pr.* + LEFT JOIN (SELECT pr.*, Q0c.max_date FROM account_partial_reconcile pr INNER JOIN account_move_line l2 - ON pr.credit_move_id = l2.id + ON pr.credit_move_id = l2.id + LEFT JOIN (%s) as Q0c ON Q0c.id = pr.id WHERE l2.date <= '%s' ) as pd ON pd.debit_move_id = l1.id - LEFT JOIN (SELECT pr.* + LEFT JOIN (SELECT pr.*, Q0c.max_date FROM account_partial_reconcile pr INNER JOIN account_move_line l2 - ON pr.debit_move_id = l2.id + ON pr.debit_move_id = l2.id + LEFT JOIN (%s) as Q0c ON Q0c.id = pr.id WHERE l2.date <= '%s' ) as pc ON pc.credit_move_id = l1.id GROUP BY l1.id - """ % (date_end, date_end) + """ % (self._get_reconcile_date(), date_end, + self._get_reconcile_date(), date_end) def _display_lines_sql_q1(self, partners, date_end): return """ @@ -135,6 +138,35 @@ class CustomerOutstandingStatement(models.AbstractModel): res[row.pop('partner_id')].append(row) return res + def _get_credit_date(self): + return """ + SELECT apr.id, aml.date as credit_date + FROM account_partial_reconcile apr + LEFT JOIN account_move_line aml + ON aml.id = apr.credit_move_id + """ + + def _get_debit_date(self): + return """ + SELECT apr.id, aml.date as debit_date + FROM account_partial_reconcile apr + LEFT JOIN account_move_line aml + ON aml.id = apr.debit_move_id + """ + + def _get_reconcile_date(self): + return """ + SELECT pr2.id, + CASE WHEN Q0a.credit_date > Q0b.debit_date + THEN Q0a.credit_date + ELSE Q0b.debit_date + END AS max_date + FROM account_partial_reconcile pr2 + LEFT JOIN (%s) as Q0a ON Q0a.id = pr2.id + LEFT JOIN (%s) as Q0b ON Q0b.id = pr2.id + GROUP BY pr2.id, Q0a.credit_date, Q0b.debit_date + """ % (self._get_credit_date(), self._get_debit_date()) + def _show_buckets_sql_q0(self, date_end): return """ SELECT l1.id, @@ -145,20 +177,23 @@ class CustomerOutstandingStatement(models.AbstractModel): ELSE null END as reconciled_date FROM account_move_line l1 - LEFT JOIN (SELECT pr.* + LEFT JOIN (SELECT pr.*, Q0c.max_date FROM account_partial_reconcile pr INNER JOIN account_move_line l2 - ON pr.credit_move_id = l2.id + ON pr.credit_move_id = l2.id + LEFT JOIN (%s) as Q0c ON Q0c.id = pr.id WHERE l2.date <= '%s' ) as pd ON pd.debit_move_id = l1.id - LEFT JOIN (SELECT pr.* + LEFT JOIN (SELECT pr.*, Q0c.max_date FROM account_partial_reconcile pr INNER JOIN account_move_line l2 - ON pr.debit_move_id = l2.id + ON pr.debit_move_id = l2.id + LEFT JOIN (%s) as Q0c ON Q0c.id = pr.id WHERE l2.date <= '%s' ) as pc ON pc.credit_move_id = l1.id GROUP BY l1.id - """ % (date_end, date_end) + """ % (self._get_reconcile_date(), date_end, + self._get_reconcile_date(), date_end) def _show_buckets_sql_q1(self, partners, date_end): return """