From d2eeaaa7234e78ee13f1dec442b5492b05dd1e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 7 Sep 2017 18:40:32 +0200 Subject: [PATCH] Add from_date and to_date in Move.query_get Add those fields to the context of GeneralLegder and IncomeStatement. issue6692 review43361002 --- CHANGELOG | 2 + account.py | 76 +++++++++++- general_ledger.fodt | 37 ++++-- move.py | 122 ++++++++----------- trial_balance.fodt | 30 +++-- view/general_ledger_account_context_form.xml | 5 + view/income_statement_context_form.xml | 10 ++ 7 files changed, 186 insertions(+), 96 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8dd154a3ef..b2a3579eb4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Add from and to date to General Ledger and Income Statement +* Add move filtering on date range * Simplify default values for move line Version 4.4.0 - 2017-05-01 diff --git a/account.py b/account.py index 8fde970b09..817127c59d 100644 --- a/account.py +++ b/account.py @@ -14,7 +14,7 @@ from trytond.wizard import Wizard, StateView, StateAction, StateTransition, \ Button from trytond.report import Report from trytond.tools import reduce_ids, grouped_slice -from trytond.pyson import Eval, PYSONEncoder +from trytond.pyson import Eval, If, PYSONEncoder from trytond.transaction import Transaction from trytond.pool import Pool from trytond import backend @@ -1283,13 +1283,25 @@ class GeneralLedgerAccount(ModelSQL, ModelView): period_ids.append(period.id) return period_ids + @classmethod + def get_dates(cls, name): + context = Transaction().context + if name.startswith('start_'): + return None, context.get('from_date') + elif name.startswith('end_'): + return None, context.get('to_date') + return None, None + @classmethod def get_account(cls, records, name): pool = Pool() Account = pool.get('account.account') period_ids = cls.get_period_ids(name) - with Transaction().set_context(periods=period_ids): + from_date, to_date = cls.get_dates(name) + with Transaction().set_context( + periods=period_ids, + from_date=from_date, to_date=to_date): accounts = Account.browse(records) fname = name for test in ['start_', 'end_']: @@ -1335,6 +1347,20 @@ class GeneralLedgerAccountContext(ModelView): ('start_date', '>=', (Eval('start_period'), 'start_date')) ], depends=['fiscalyear', 'start_period']) + from_date = fields.Date("From Date", + domain=[ + If(Eval('to_date') & Eval('from_date'), + ('from_date', '<=', Eval('to_date')), + ()), + ], + depends=['to_date']) + to_date = fields.Date("To Date", + domain=[ + If(Eval('from_date') & Eval('to_date'), + ('to_date', '>=', Eval('from_date')), + ()), + ], + depends=['from_date']) company = fields.Many2One('company.company', 'Company', required=True) posted = fields.Boolean('Posted Move', help='Show only posted move') @@ -1363,6 +1389,14 @@ class GeneralLedgerAccountContext(ModelView): def default_posted(cls): return Transaction().context.get('posted', False) + @classmethod + def default_from_date(cls): + return Transaction().context.get('from_date') + + @classmethod + def default_to_date(cls): + return Transaction().context.get('to_date') + @fields.depends('fiscalyear', 'start_period', 'end_period') def on_change_fiscalyear(self): if (self.start_period @@ -1504,6 +1538,8 @@ class GeneralLedger(Report): report_context[period] = Period(context[period]) else: report_context[period] = None + report_context['from_date'] = context.get('from_date') + report_context['to_date'] = context.get('to_date') report_context['accounts'] = records return report_context @@ -1530,6 +1566,8 @@ class TrialBalance(Report): report_context[period] = Period(context[period]) else: report_context[period] = None + report_context['from_date'] = context.get('from_date') + report_context['to_date'] = context.get('to_date') report_context['accounts'] = records report_context['sum'] = cls.sum @@ -1602,6 +1640,20 @@ class IncomeStatementContext(ModelView): ('start_date', '>=', (Eval('start_period'), 'start_date')), ], depends=['start_period', 'fiscalyear']) + from_date = fields.Date("From Date", + domain=[ + If(Eval('to_date') & Eval('from_date'), + ('from_date', '<=', Eval('to_date')), + ()), + ], + depends=['to_date']) + to_date = fields.Date("To Date", + domain=[ + If(Eval('from_date') & Eval('to_date'), + ('to_date', '>=', Eval('from_date')), + ()), + ], + depends=['from_date']) company = fields.Many2One('company.company', 'Company', required=True) posted = fields.Boolean('Posted Move', help='Show only posted move') comparison = fields.Boolean('Comparison') @@ -1628,6 +1680,26 @@ class IncomeStatementContext(ModelView): 'invisible': ~Eval('comparison', False), }, depends=['start_period_cmp', 'fiscalyear_cmp']) + from_date_cmp = fields.Date("From Date", + domain=[ + If(Eval('to_date_cmp') & Eval('from_date_cmp'), + ('from_date_cmp', '<=', Eval('to_date_cmp')), + ()), + ], + states={ + 'invisible': ~Eval('comparison', False), + }, + depends=['to_date_cmp', 'comparison']) + to_date_cmp = fields.Date("To Date", + domain=[ + If(Eval('from_date_cmp') & Eval('to_date_cmp'), + ('to_date_cmp', '>=', Eval('from_date_cmp')), + ()), + ], + states={ + 'invisible': ~Eval('comparison', False), + }, + depends=['from_date_cmp', 'comparison']) @staticmethod def default_fiscalyear(): diff --git a/general_ledger.fodt b/general_ledger.fodt index fce08aba92..13d7db7849 100644 --- a/general_ledger.fodt +++ b/general_ledger.fodt @@ -1,24 +1,24 @@ - LibreOffice/5.2.7.2$Linux_X86_64 LibreOffice_project/20m0$Build-22008-06-07T15:26:412008-08-27T17:03:361PT0S + LibreOffice/5.2.7.2$Linux_X86_64 LibreOffice_project/20m0$Build-22008-06-07T15:26:412008-08-27T17:03:361PT0S 0 0 - 43760 - 21691 + 23440 + 21451 true false view2 - 19976 - 5443 + 16436 + 9798 0 0 - 43759 - 21689 + 23439 + 21449 0 0 false @@ -69,7 +69,7 @@ false false true - 3708925 + 3802205 false true false @@ -630,9 +630,18 @@ + + + + + + + + + @@ -672,7 +681,7 @@ User: <user.rec_name> - 4/4 + 3/3 @@ -689,9 +698,13 @@ General Ledger - Fiscal Year: <fiscalyear.rec_name> - From Period: <start_period.name if start_period else ''> - To Period: <end_period.name if end_period else ''> + Fiscal Year: <fiscalyear.rec_name> + <if test="start_period or end_period"> + From Period: <start_period.name if start_period else ''> To <end_period.name if end_period else ''> + </if> + <if test="from_date or to_date"> + From Date: <format_date(from_date, user.language) if from_date else ''> To <format_date(to_date, user.language) if to_date else ''> + </if> <for each="account in accounts"> diff --git a/move.py b/move.py index 96ad556668..3d1aab79d3 100644 --- a/move.py +++ b/move.py @@ -6,7 +6,7 @@ from itertools import groupby, combinations from operator import itemgetter from collections import defaultdict -from sql import Null +from sql import Null, Literal from sql.aggregate import Sum, Max from sql.conditionals import Coalesce, Case @@ -56,8 +56,8 @@ class Move(ModelSQL, ModelView): states=_MOVE_STATES, depends=_MOVE_DEPENDS + ['company'], select=True) journal = fields.Many2One('account.journal', 'Journal', required=True, states=_MOVE_STATES, depends=_MOVE_DEPENDS) - date = fields.Date('Effective Date', required=True, states=_MOVE_STATES, - depends=_MOVE_DEPENDS) + date = fields.Date('Effective Date', required=True, select=True, + states=_MOVE_STATES, depends=_MOVE_DEPENDS) post_date = fields.Date('Post Date', readonly=True) description = fields.Char('Description', states=_MOVE_STATES, depends=_MOVE_DEPENDS) @@ -953,83 +953,61 @@ class Line(ModelSQL, ModelView): Period = pool.get('account.period') move = Move.__table__() period = Period.__table__() + fiscalyear = FiscalYear.__table__() + context = Transaction().context + company = context.get('company') - if Transaction().context.get('date'): + fiscalyear_ids = [] + where = Literal(True) + + if context.get('posted'): + where &= move.state == 'posted' + + date = context.get('date') + from_date, to_date = context.get('from_date'), context.get('to_date') + fiscalyear_id = context.get('fiscalyear') + period_ids = context.get('periods') + if date: fiscalyears = FiscalYear.search([ - ('start_date', '<=', Transaction().context['date']), - ('end_date', '>=', Transaction().context['date']), - ('company', '=', Transaction().context.get('company')), + ('start_date', '<=', date), + ('end_date', '>=', date), + ('company', '=', company), ], limit=1) - - fiscalyear_id = fiscalyears and fiscalyears[0].id or 0 - - if Transaction().context.get('posted'): - return ((table.state != 'draft') - & table.move.in_(move.join(period, - condition=move.period == period.id - ).select(move.id, - where=(period.fiscalyear == fiscalyear_id) - & (move.date <= Transaction().context['date']) - & (move.state == 'posted'))), - [f.id for f in fiscalyears]) + if fiscalyears: + fiscalyear_id = fiscalyears[0].id else: - return ((table.state != 'draft') - & table.move.in_(move.join(period, - condition=move.period == period.id - ).select(move.id, - where=(period.fiscalyear == fiscalyear_id) - & (move.date <= Transaction().context['date']))), - [f.id for f in fiscalyears]) - - if Transaction().context.get('periods'): - if Transaction().context.get('fiscalyear'): - fiscalyear_ids = [Transaction().context['fiscalyear']] - else: - fiscalyear_ids = [] - if Transaction().context.get('posted'): - return ((table.state != 'draft') - & table.move.in_( - move.select(move.id, - where=move.period.in_( - Transaction().context['periods']) - & (move.state == 'posted'))), - fiscalyear_ids) - else: - return ((table.state != 'draft') - & table.move.in_( - move.select(move.id, - where=move.period.in_( - Transaction().context['periods']))), - fiscalyear_ids) + fiscalyear_id = -1 + fiscalyear_ids = map(int, fiscalyears) + where &= period.fiscalyear == fiscalyear_id + where &= move.date <= date + elif fiscalyear_id or period_ids or from_date or to_date: + if fiscalyear_id: + fiscalyear_ids = [fiscalyear_id] + where &= fiscalyear.id == fiscalyear_id + if period_ids: + where &= move.period.in_(period_ids) + if from_date: + where &= move.date >= from_date + if to_date: + where &= move.date <= to_date else: - if not Transaction().context.get('fiscalyear'): - fiscalyears = FiscalYear.search([ + where &= fiscalyear.state == 'open' + where &= fiscalyear.company == company + fiscalyears = FiscalYear.search([ ('state', '=', 'open'), - ('company', '=', Transaction().context.get('company')), + ('company', '=', company), ]) - fiscalyear_ids = [f.id for f in fiscalyears] or [0] - else: - fiscalyear_ids = [Transaction().context.get('fiscalyear')] + fiscalyear_ids = map(int, fiscalyears) - if Transaction().context.get('posted'): - return ((table.state != 'draft') - & table.move.in_( - move.select(move.id, - where=move.period.in_( - period.select(period.id, - where=period.fiscalyear.in_( - fiscalyear_ids))) - & (move.state == 'posted'))), - fiscalyear_ids) - else: - return ((table.state != 'draft') - & table.move.in_( - move.select(move.id, - where=move.period.in_( - period.select(period.id, - where=period.fiscalyear.in_( - fiscalyear_ids))))), - fiscalyear_ids) + # Use LEFT JOIN to allow database optimization + # if no joined table is used in the where clause. + return ((table.state != 'draft') + & table.move.in_(move + .join(period, 'LEFT', condition=move.period == period.id) + .join(fiscalyear, 'LEFT', + condition=period.fiscalyear == fiscalyear.id) + .select(move.id, where=where)), + fiscalyear_ids) @classmethod def on_write(cls, lines): diff --git a/trial_balance.fodt b/trial_balance.fodt index 2610766f94..2d6fbf9bd5 100644 --- a/trial_balance.fodt +++ b/trial_balance.fodt @@ -1,24 +1,24 @@ - LibreOffice/5.2.7.2$Linux_X86_64 LibreOffice_project/20m0$Build-22008-06-07T15:26:582008-08-27T17:08:381PT0S + LibreOffice/5.2.7.2$Linux_X86_64 LibreOffice_project/20m0$Build-22008-06-07T15:26:582008-08-27T17:08:381PT0S 0 0 - 43760 - 21691 + 23440 + 21451 true false view2 - 20262 - 5443 + 3784 + 10984 0 0 - 43759 - 21689 + 23439 + 21449 0 1 false @@ -69,7 +69,7 @@ false false true - 1456882 + 1470702 false true false @@ -376,6 +376,12 @@ + + + + + + @@ -436,8 +442,12 @@ Trial Balance Fiscal Year: <fiscalyear.rec_name> - From Period: <start_period.name if start_period else ''> - To Period: <end_period.name if end_period else ''> + <if test="start_period or end_period"> + From Period: <start_period.name if start_period else ''> To <end_period.name if end_period else ''> + </if> + <if test="from_date or to_date"> + From Date: <format_date(from_date, user.language) if from_date else ''> To <format_date(to_date, user.language) if to_date else ''> + </if> diff --git a/view/general_ledger_account_context_form.xml b/view/general_ledger_account_context_form.xml index a72eb8518d..3146fd7f2c 100644 --- a/view/general_ledger_account_context_form.xml +++ b/view/general_ledger_account_context_form.xml @@ -12,4 +12,9 @@ this repository contains the full copyright notices and license terms. -->