diff --git a/CHANGELOG b/CHANGELOG
index 3f2abdf2af..6c4ac3e633 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,4 @@
+* Add report for income statement and balance sheet
* Allow filtering general ledger by journal
* Add journal context to Move.query_get
* Add reconciliation to general ledger line
diff --git a/__init__.py b/__init__.py
index e31ec2bf0a..3b0a5cf2d9 100644
--- a/__init__.py
+++ b/__init__.py
@@ -111,6 +111,7 @@ def register():
fiscalyear.RenewFiscalYear,
module='account', type_='wizard')
Pool.register(
+ account.AccountTypeStatement,
account.GeneralLedger,
account.TrialBalance,
account.AgedBalanceReport,
diff --git a/account.py b/account.py
index 901314b48a..1c04f4535e 100644
--- a/account.py
+++ b/account.py
@@ -3,6 +3,7 @@
from decimal import Decimal
import datetime
import operator
+from itertools import zip_longest
from functools import wraps
from dateutil.relativedelta import relativedelta
@@ -424,6 +425,31 @@ class OpenType(Wizard):
do_ledger_account = open_action
+class AccountTypeStatement(Report):
+ __name__ = 'account.account.type.statement'
+
+ @classmethod
+ def get_context(cls, records, header, data):
+ pool = Pool()
+ Company = pool.get('company.company')
+ context = Transaction().context
+
+ report_context = super().get_context(records, header, data)
+ report_context['company'] = Company(context['company'])
+
+ if data.get('model_context') is not None:
+ Context = pool.get(data['model_context'])
+ values = {}
+ for field in Context._fields:
+ if field in context:
+ values[field] = context[field]
+ report_context['ctx'] = Context(**values)
+
+ report_context['types'] = zip_longest(
+ records, data.get('paths') or [], fillvalue=[])
+ return report_context
+
+
def AccountMixin(template=False):
class Mixin:
diff --git a/account.xml b/account.xml
index ef82fac244..786ed94d6c 100644
--- a/account.xml
+++ b/account.xml
@@ -223,6 +223,19 @@ this repository contains the full copyright notices and license terms. -->
+
+ Statement
+ listed
+ account.account.type
+ account.account.type.statement
+ account/type_statement.fodt
+
+
+ form_print
+ account.account.type,-1
+
+
+
account.account.template
form
@@ -495,6 +508,7 @@ this repository contains the full copyright notices and license terms. -->
General Ledger
+ listed
account.general_ledger.account
account.general_ledger
account/general_ledger.fodt
@@ -507,6 +521,7 @@ this repository contains the full copyright notices and license terms. -->
Trial Balance
+ listed
account.general_ledger.account
account.trial_balance
account/trial_balance.fodt
diff --git a/doc/design/account.rst b/doc/design/account.rst
index fb0f24e407..3c76f8641a 100644
--- a/doc/design/account.rst
+++ b/doc/design/account.rst
@@ -91,6 +91,17 @@ accounts balance is in credit, or debit, respectively.
Accounts Types can be created from
`Account Type Templates `.
+Reports
+-------
+
+.. _report-account.account.type.statement:
+
+Statement
+^^^^^^^^^
+
+The *Statement* report is used to get a printed copy of the open parts
+of the balance sheet and income statements.
+
.. _model-account.account.party:
Account Party
diff --git a/tests/scenario_reports.rst b/tests/scenario_reports.rst
index 1bee2cfddf..16e30bcc7b 100644
--- a/tests/scenario_reports.rst
+++ b/tests/scenario_reports.rst
@@ -180,6 +180,10 @@ Print some reports::
... })
>>> _ = trial_balance.execute(gl_accounts)
+ >>> Type = Model.get('account.account.type')
+ >>> statement = Report('account.account.type.statement')
+ >>> _ = statement.execute(Type.find([]))
+
>>> AgedBalance = Model.get('account.aged_balance')
>>> context = {
... 'company': company.id,
diff --git a/type_statement.fodt b/type_statement.fodt
new file mode 100644
index 0000000000..08801caf57
--- /dev/null
+++ b/type_statement.fodt
@@ -0,0 +1,588 @@
+
+
+
+ LibreOffice/6.4.7.2$Linux_X86_64 LibreOffice_project/40$Build-22008-06-07T15:26:412008-08-27T17:03:361PT0S
+
+
+ 0
+ 0
+ 25640
+ 24052
+ true
+ false
+
+
+ view2
+ 4025
+ 14263
+ 0
+ 0
+ 25638
+ 24051
+ 0
+ 0
+ false
+ 100
+ false
+ false
+
+
+
+
+ false
+ false
+
+
+ false
+ false
+ 0
+ false
+ false
+ 1
+ false
+ false
+ false
+ false
+ true
+ false
+ false
+ true
+ true
+ false
+ false
+ false
+ false
+ false
+ false
+ high-resolution
+ false
+ 0
+ false
+ true
+ false
+ false
+ false
+
+ false
+ true
+
+ false
+ false
+ false
+
+ false
+ true
+ false
+ true
+ false
+ false
+ 4046554
+ false
+ false
+ true
+ false
+
+ false
+ 2070049
+ false
+ true
+ true
+ false
+ true
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ true
+ true
+ true
+ false
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+
+ true
+ true
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Company: <company.rec_name>
+
+
+ Statement
+
+
+ Print Date: <format_date(datetime.date.today(), user.language)>at <datetime.datetime.now().strftime('%H:%M:%S')>
+
+
+
+
+
+
+
+
+
+
+ User: <user.rec_name>
+
+
+ 2/2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <choose>
+ <when test="data.get('model_context') == 'account.income_statement.context'">
+ Income Statement
+ Fiscal Year: <ctx.fiscalyear.rec_name>
+ <if test="ctx.start_period or ctx.end_period">
+ From Period: <ctx.start_period.name if ctx.start_period else ''>To <ctx.end_period.name if ctx.end_period else ''>
+ </if>
+ <if test="ctx.from_date or ctx.to_date">
+ From Date: <format_date(ctx.from_date, user.language) if ctx.from_date else ''>To <format_date(ctx.to_date, user.language) if ctx.to_date else ''>
+ </if>
+ </when>
+ <when test="data.get('model_context') in ['account.balance_sheet.context', 'account.balance_sheet.comparision.context']">
+ Balance Sheet
+ Date: <format_date(ctx.date, user.language) if ctx.date else ''>
+ </when>
+ <otherwise>
+ Statement
+ </otherwise>
+ </choose>
+
+
+
+
+
+ <for each="type, path in types">
+
+
+
+
+
+
+
+ <choose>
+ <when test="len(path) <= 1">
+ <type.name>
+ </when>
+ <when test="len(path) == 2">
+ <for each="_ in range(len(path) -1)"></for><type.name>
+ </when>
+ <otherwise>
+ <for each="_ in range(len(path) -1)"></for><type.name>
+ </otherwise>
+ </choose>
+
+
+ <format_currency(type.amount, user.language, company.currency)>
+
+
+
+
+ </for>
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file