Browse Source

Add OCA Trial Balance report PDF and XLSX

pull/211/head
jcoux 8 years ago
parent
commit
8ac8873bac
  1. 3
      account_financial_report_qweb/README.rst
  2. 2
      account_financial_report_qweb/__openerp__.py
  3. 4
      account_financial_report_qweb/menuitems.xml
  4. 2
      account_financial_report_qweb/report/__init__.py
  5. 4
      account_financial_report_qweb/report/abstract_report_xlsx.py
  6. 2
      account_financial_report_qweb/report/general_ledger_xlsx.py
  7. 154
      account_financial_report_qweb/report/templates/trial_balance.xml
  8. 241
      account_financial_report_qweb/report/trial_balance.py
  9. 138
      account_financial_report_qweb/report/trial_balance_xlsx.py
  10. 22
      account_financial_report_qweb/reports.xml
  11. 1
      account_financial_report_qweb/tests/__init__.py
  12. 76
      account_financial_report_qweb/tests/test_trial_balance.py
  13. 2
      account_financial_report_qweb/wizard/__init__.py
  14. 62
      account_financial_report_qweb/wizard/balance_common_wizard.py
  15. 57
      account_financial_report_qweb/wizard/balance_common_wizard_view.xml
  16. 104
      account_financial_report_qweb/wizard/trial_balance_wizard.py
  17. 62
      account_financial_report_qweb/wizard/trial_balance_wizard_view.xml

3
account_financial_report_qweb/README.rst

@ -23,7 +23,8 @@ Known issues / Roadmap
Some reports are being worked on and will be available at some point:
- Trial Balance
- Open Items (XLSX)
- Aged Partner Balance (XLSX)
Bug Tracker
===========

2
account_financial_report_qweb/__openerp__.py

@ -25,7 +25,6 @@
'wizard/aged_partner_balance_wizard_view.xml',
'wizard/general_ledger_wizard_view.xml',
'wizard/open_items_wizard_view.xml',
'wizard/balance_common_wizard_view.xml',
'wizard/trial_balance_wizard_view.xml',
'menuitems.xml',
'reports.xml',
@ -33,6 +32,7 @@
'report/templates/general_ledger.xml',
'report/templates/layouts.xml',
'report/templates/open_items.xml',
'report/templates/trial_balance.xml',
'view/account_view.xml'
],
'test': [

4
account_financial_report_qweb/menuitems.xml

@ -17,8 +17,8 @@
<menuitem
parent="menu_oca_reports"
action="action_account_trial_balance_wizard_view"
id="menu_account_trial_balance_report"
action="action_trial_balance_wizard"
id="menu_trial_balance_wizard"
sequence="20"
/>

2
account_financial_report_qweb/report/__init__.py

@ -9,3 +9,5 @@ from . import aged_partner_balance
from . import general_ledger
from . import general_ledger_xlsx
from . import open_items
from . import trial_balance
from . import trial_balance_xlsx

4
account_financial_report_qweb/report/abstract_report_xlsx.py

@ -40,7 +40,7 @@ class AbstractReportXslx(ReportXlsx):
report_name = self._get_report_name()
filters = self._get_report_filters(report)
self.columns = self._get_report_columns()
self.columns = self._get_report_columns(report)
self.sheet = workbook.add_worksheet(report_name[:31])
@ -175,7 +175,7 @@ class AbstractReportXslx(ReportXlsx):
"""
raise NotImplementedError()
def _get_report_columns(self):
def _get_report_columns(self, report):
"""
Allow to define the report columns
which will be used to generate report.

2
account_financial_report_qweb/report/general_ledger_xlsx.py

@ -24,7 +24,7 @@ class GeneralLedgerXslx(abstract_report_xlsx.AbstractReportXslx):
def _get_report_name(self):
return _('General Ledger')
def _get_report_columns(self):
def _get_report_columns(self, report):
return {
0: {'header': _('Date'), 'field': 'date', 'width': 11},
1: {'header': _('Entry'), 'field': 'entry', 'width': 18},

154
account_financial_report_qweb/report/templates/trial_balance.xml

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="account_financial_report_qweb.report_trial_balance_qweb">
<t t-call="report.html_container">
<t t-foreach="docs" t-as="o">
<!-- Saved flag fields into variables, used to define columns display -->
<t t-set="show_partner_details" t-value="o.show_partner_details"/>
<t t-call="account_financial_report_qweb.internal_layout">
<!-- Defines global variables used by internal layout -->
<t t-set="title">Trial Balance</t>
<t t-set="company_name" t-value="o.company_id.name"/>
<div class="page">
<!-- Display filters -->
<t t-call="account_financial_report_qweb.report_trial_balance_qweb_filters"/>
<div class="act_as_table list_table" style="margin-top: 10px;"/>
<!-- Display account lines -->
<t t-if="not show_partner_details">
<div class="act_as_table data_table" style="width: 1140px !important;">
<!-- Display account header -->
<t t-call="account_financial_report_qweb.report_trial_balance_qweb_lines_header"/>
<!-- Display each lines -->
<t t-foreach="o.account_ids" t-as="line">
<!-- Display account lines -->
<t t-call="account_financial_report_qweb.report_trial_balance_qweb_line"/>
</t>
</div>
</t>
<!-- Display partner lines -->
<t t-if="show_partner_details">
<t t-foreach="o.account_ids" t-as="account">
<div class="page_break">
<!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_caption account_title" style="width: 1141px !important;">
<span t-field="account.code"/> - <span t-field="account.name"/>
</div>
<div class="act_as_table data_table" style="width: 1140px !important;">
<!-- Display account/partner header -->
<t t-call="account_financial_report_qweb.report_trial_balance_qweb_lines_header"/>
<!-- Display each partners -->
<t t-foreach="account.partner_ids" t-as="line">
<!-- Display partner line -->
<t t-call="account_financial_report_qweb.report_trial_balance_qweb_line"/>
</t>
</div>
<!-- Display account footer -->
<t t-call="account_financial_report_qweb.report_trial_balance_qweb_account_footer"/>
</div>
</t>
</t>
</div>
</t>
</t>
</t>
</template>
<template id="account_financial_report_qweb.report_trial_balance_qweb_filters">
<div class="act_as_table data_table" style="width: 1140px !important;">
<div class="act_as_row labels">
<div class="act_as_cell">Date range filter</div>
<div class="act_as_cell">Target moves filter</div>
<div class="act_as_cell">Account balance at 0 filter</div>
</div>
<div class="act_as_row">
<div class="act_as_cell">
From: <span t-field="o.date_from"/> To: <span t-field="o.date_to"/>
</div>
<div class="act_as_cell">
<t t-if="o.only_posted_moves">All posted entries</t>
<t t-if="not o.only_posted_moves">All entries</t>
</div>
<div class="act_as_cell">
<t t-if="o.hide_account_balance_at_0">Hide</t>
<t t-if="not o.hide_account_balance_at_0">Show</t>
</div>
</div>
</div>
</template>
<template id="account_financial_report_qweb.report_trial_balance_qweb_lines_header">
<!-- Display table headers for lines -->
<div class="act_as_thead">
<div class="act_as_row labels">
<t t-if="not show_partner_details">
<!--## Code-->
<div class="act_as_cell" style="width: 100px;">Code</div>
<!--## Account-->
<div class="act_as_cell" style="width: 600px;">Account</div>
</t>
<t t-if="show_partner_details">
<!--## Partner-->
/<div class="act_as_cell" style="width: 700px;">Partner</div>
</t>
<!--## Initial balance-->
<div class="act_as_cell" style="width: 110px;">Initial balance</div>
<!--## Debit-->
<div class="act_as_cell" style="width: 110px;">Debit</div>
<!--## Credit-->
<div class="act_as_cell" style="width: 110px;">Credit</div>
<!--## Ending balance-->
<div class="act_as_cell" style="width: 110px;">Ending balance</div>
</div>
</div>
</template>
<template id="account_financial_report_qweb.report_trial_balance_qweb_line">
<!-- # line -->
<div class="act_as_row lines">
<t t-if="not show_partner_details">
<!--## Code-->
<div class="act_as_cell left"><span t-field="line.code"/></div>
</t>
<!--## Account/Partner-->
<div class="act_as_cell left"><span t-field="line.name"/></div>
<!--## Initial balance-->
<div class="act_as_cell amount"><span t-field="line.initial_balance"/></div>
<!--## Debit-->
<div class="act_as_cell amount"><span t-field="line.debit"/></div>
<!--## Credit-->
<div class="act_as_cell amount"><span t-field="line.credit"/></div>
<!--## Ending balance-->
<div class="act_as_cell amount"><span t-field="line.final_balance"/></div>
</div>
</template>
<template id="account_financial_report_qweb.report_trial_balance_qweb_account_footer">
<!-- Display account footer -->
<div class="act_as_table list_table" style="width: 1141px !important;">
<div class="act_as_row labels" style="font-weight: bold;">
<!--## Account-->
<div class="act_as_cell left" style="width: 700px;"><span t-field="account.code"/> - <span t-field="account.name"/></div>
<!--## Initial balance-->
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.initial_balance"/></div>
<!--## Debit-->
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.debit"/></div>
<!--## Credit-->
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.credit"/></div>
<!--## Ending balance-->
<div class="act_as_cell amount" style="width: 110px;"><span t-field="account.final_balance"/></div>
</div>
</div>
</template>
</odoo>

241
account_financial_report_qweb/report/trial_balance.py

@ -0,0 +1,241 @@
# -*- coding: utf-8 -*-
# © 2016 Julien Coux (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api
class TrialBalanceReport(models.TransientModel):
""" Here, we just define class fields.
For methods, go more bottom at this file.
The class hierarchy is :
* TrialBalanceReport
** TrialBalanceAccount
*** TrialBalancePartner
If "show_partner_details" is selected
"""
_name = 'report_trial_balance_qweb'
# Filters fields, used for data computation
date_from = fields.Date()
date_to = fields.Date()
fy_start_date = fields.Date()
only_posted_moves = fields.Boolean()
hide_account_balance_at_0 = fields.Boolean()
company_id = fields.Many2one(comodel_name='res.company')
filter_account_ids = fields.Many2many(comodel_name='account.account')
filter_partner_ids = fields.Many2many(comodel_name='res.partner')
show_partner_details = fields.Boolean()
# General Ledger Report Data fields,
# used as base for compute the data reports
general_ledger_id = fields.Many2one(
comodel_name='report_general_ledger_qweb'
)
# Data fields, used to browse report data
account_ids = fields.One2many(
comodel_name='report_trial_balance_qweb_account',
inverse_name='report_id'
)
class TrialBalanceAccount(models.TransientModel):
_name = 'report_trial_balance_qweb_account'
_order = 'code ASC'
report_id = fields.Many2one(
comodel_name='report_trial_balance_qweb',
ondelete='cascade',
index=True
)
# Data fields, used to keep link with real object
account_id = fields.Many2one(
'account.account',
index=True
)
# Data fields, used for report display
code = fields.Char()
name = fields.Char()
initial_balance = fields.Float(digits=(16, 2))
debit = fields.Float(digits=(16, 2))
credit = fields.Float(digits=(16, 2))
final_balance = fields.Float(digits=(16, 2))
# Data fields, used to browse report data
partner_ids = fields.One2many(
comodel_name='report_trial_balance_qweb_partner',
inverse_name='report_account_id'
)
class TrialPartnerAccount(models.TransientModel):
_name = 'report_trial_balance_qweb_partner'
report_account_id = fields.Many2one(
comodel_name='report_trial_balance_qweb_account',
ondelete='cascade',
index=True
)
# Data fields, used to keep link with real object
partner_id = fields.Many2one(
'res.partner',
index=True
)
# Data fields, used for report display
name = fields.Char()
initial_balance = fields.Float(digits=(16, 2))
debit = fields.Float(digits=(16, 2))
credit = fields.Float(digits=(16, 2))
final_balance = fields.Float(digits=(16, 2))
@api.model
def _generate_order_by(self, order_spec, query):
"""Custom order to display "No partner allocated" at last position."""
return """
ORDER BY
CASE
WHEN "report_trial_balance_qweb_partner"."partner_id" IS NOT NULL
THEN 0
ELSE 1
END,
"report_trial_balance_qweb_partner"."name"
"""
class TrialBalanceReportCompute(models.TransientModel):
""" Here, we just define methods.
For class fields, go more top at this file.
"""
_inherit = 'report_trial_balance_qweb'
@api.multi
def print_report(self, xlsx_report=False):
self.ensure_one()
self.compute_data_for_report()
if xlsx_report:
report_name = 'account_financial_report_qweb.' \
'report_trial_balance_xlsx'
else:
report_name = 'account_financial_report_qweb.' \
'report_trial_balance_qweb'
return self.env['report'].get_action(records=self,
report_name=report_name)
@api.multi
def compute_data_for_report(self):
self.ensure_one()
# Compute General Ledger Report Data.
# The data of Trial Balance Report
# are based on General Ledger Report data.
model = self.env['report_general_ledger_qweb']
self.general_ledger_id = model.create({
'date_from': self.date_from,
'date_to': self.date_to,
'only_posted_moves': self.only_posted_moves,
'hide_account_balance_at_0': self.hide_account_balance_at_0,
'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.filter_account_ids.ids)],
'filter_partner_ids': [(6, 0, self.filter_partner_ids.ids)],
'fy_start_date': self.fy_start_date,
})
self.general_ledger_id.compute_data_for_report()
# Compute report data
self._inject_account_values()
if self.show_partner_details:
self._inject_partner_values()
def _inject_account_values(self):
"""Inject report values for report_trial_balance_qweb_account"""
query_inject_account = """
INSERT INTO
report_trial_balance_qweb_account
(
report_id,
create_uid,
create_date,
account_id,
code,
name,
initial_balance,
debit,
credit,
final_balance
)
SELECT
%s AS report_id,
%s AS create_uid,
NOW() AS create_date,
rag.account_id,
rag.code,
rag.name,
rag.initial_balance AS initial_balance,
rag.final_debit - rag.initial_debit AS debit,
rag.final_credit - rag.initial_credit AS credit,
rag.final_balance AS final_balance
FROM
report_general_ledger_qweb_account rag
WHERE
rag.report_id = %s
"""
query_inject_account_params = (
self.id,
self.env.uid,
self.general_ledger_id.id,
)
self.env.cr.execute(query_inject_account, query_inject_account_params)
def _inject_partner_values(self):
"""Inject report values for report_trial_balance_qweb_partner"""
query_inject_partner = """
INSERT INTO
report_trial_balance_qweb_partner
(
report_account_id,
create_uid,
create_date,
partner_id,
name,
initial_balance,
debit,
credit,
final_balance
)
SELECT
ra.id AS report_account_id,
%s AS create_uid,
NOW() AS create_date,
rpg.partner_id,
rpg.name,
rpg.initial_balance AS initial_balance,
rpg.final_debit - rpg.initial_debit AS debit,
rpg.final_credit - rpg.initial_credit AS credit,
rpg.final_balance AS final_balance
FROM
report_general_ledger_qweb_partner rpg
INNER JOIN
report_general_ledger_qweb_account rag ON rpg.report_account_id = rag.id
INNER JOIN
report_trial_balance_qweb_account ra ON rag.code = ra.code
WHERE
rag.report_id = %s
AND ra.report_id = %s
"""
query_inject_partner_params = (
self.env.uid,
self.general_ledger_id.id,
self.id,
)
self.env.cr.execute(query_inject_partner, query_inject_partner_params)

138
account_financial_report_qweb/report/trial_balance_xlsx.py

@ -0,0 +1,138 @@
# -*- coding: utf-8 -*-
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import abstract_report_xlsx
from openerp.report import report_sxw
from openerp import _
class TrialBalanceXslx(abstract_report_xlsx.AbstractReportXslx):
def __init__(self, name, table, rml=False, parser=False, header=True,
store=False):
super(TrialBalanceXslx, self).__init__(
name, table, rml, parser, header, store)
# Custom values needed to generate report
self.col_pos_initial_balance_label = 5
self.col_count_final_balance_name = 5
self.col_pos_final_balance_label = 5
def _get_report_name(self):
return _('Trial Balance')
def _get_report_columns(self, report):
if not report.show_partner_details:
return {
0: {'header': _('Code'), 'field': 'code', 'width': 10},
1: {'header': _('Account'), 'field': 'name', 'width': 60},
2: {'header': _('Initial balance'),
'field': 'initial_balance',
'type': 'amount',
'width': 14},
3: {'header': _('Debit'),
'field': 'debit',
'type': 'amount',
'width': 14},
4: {'header': _('Credit'),
'field': 'credit',
'type': 'amount',
'width': 14},
5: {'header': _('Ending balance'),
'field': 'final_balance',
'type': 'amount',
'width': 14},
}
else:
return {
0: {'header': _('Partner'), 'field': 'name', 'width': 70},
1: {'header': _('Initial balance'),
'field': 'initial_balance',
'type': 'amount',
'width': 14},
2: {'header': _('Debit'),
'field': 'debit',
'type': 'amount',
'width': 14},
3: {'header': _('Credit'),
'field': 'credit',
'type': 'amount',
'width': 14},
4: {'header': _('Ending balance'),
'field': 'final_balance',
'type': 'amount',
'width': 14},
}
def _get_report_filters(self, report):
return [
[_('Date range filter'),
_('From: %s To: %s') % (report.date_from, report.date_to)],
[_('Target moves filter'),
_('All posted entries') if report.only_posted_moves
else _('All entries')],
[_('Account balance at 0 filter'),
_('Hide') if report.hide_account_balance_at_0 else _('Show')],
]
def _get_col_count_filter_name(self):
return 2
def _get_col_count_filter_value(self):
return 3
def _generate_report_content(self, workbook, report):
if not report.show_partner_details:
# Display array header for account lines
self.write_array_header()
# For each account
for account in report.account_ids:
if not report.show_partner_details:
# Display account lines
self.write_line(account)
else:
# Write account title
self.write_array_title(account.code + ' - ' + account.name)
# Display array header for partner lines
self.write_array_header()
# For each partner
for partner in account.partner_ids:
# Display partner lines
self.write_line(partner)
# Display account lines
self.write_account_footer(account,
account.code + ' - ' + account.name)
# Line break
self.row_pos += 2
def write_account_footer(self, account, name_value):
"""Specific function to write account footer for Trial Balance"""
for col_pos, column in self.columns.iteritems():
if column['field'] == 'name':
value = name_value
else:
value = getattr(account, column['field'])
cell_type = column.get('type', 'string')
if cell_type == 'string':
self.sheet.write_string(self.row_pos, col_pos, value or '',
self.format_header_left)
elif cell_type == 'amount':
self.sheet.write_number(self.row_pos, col_pos, float(value),
self.format_header_amount)
self.row_pos += 1
TrialBalanceXslx(
'report.account_financial_report_qweb.report_trial_balance_xlsx',
'report_trial_balance_qweb',
parser=report_sxw.rml_parse
)

22
account_financial_report_qweb/reports.xml

@ -12,6 +12,15 @@
file="account_financial_report_qweb.report_general_ledger_qweb"
/>
<report
id="action_report_trial_balance_qweb"
model="report_trial_balance_qweb"
string="Trial Balance"
report_type="qweb-pdf"
name="account_financial_report_qweb.report_trial_balance_qweb"
file="account_financial_report_qweb.report_trial_balance_qweb"
/>
<report
id="action_report_open_items_qweb"
model="report_open_items_qweb"
@ -52,6 +61,10 @@
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
<record id="action_report_trial_balance_qweb" model="ir.actions.report.xml">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
<record id="action_report_open_items_qweb" model="ir.actions.report.xml">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
@ -71,4 +84,13 @@
<field name="auto" eval="False"/>
</record>
<record id="action_report_trial_balance_xlsx" model="ir.actions.report.xml">
<field name="name">Trial Balance XLSX</field>
<field name="model">report_trial_balance_qweb</field>
<field name="type">ir.actions.report.xml</field>
<field name="report_name">account_financial_report_qweb.report_trial_balance_xlsx</field>
<field name="report_type">xlsx</field>
<field name="auto" eval="False"/>
</record>
</odoo>

1
account_financial_report_qweb/tests/__init__.py

@ -5,3 +5,4 @@
from . import test_aged_partner_balance
from . import test_general_ledger
from . import test_open_items
from . import test_trial_balance

76
account_financial_report_qweb/tests/test_trial_balance.py

@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import time
from openerp.tests.common import TransactionCase
class TestTrialBalance(TransactionCase):
def setUp(cls):
super(TestTrialBalance, cls).setUp()
env = cls.env
model = env['report_trial_balance_qweb']
main_company = env.ref('base.main_company')
cls.report = model.create({
'date_from': time.strftime('%Y-01-01'),
'date_to': time.strftime('%Y-12-31'),
'company_id': main_company.id,
'fy_start_date': time.strftime('%Y-01-01'),
})
def test_01_compute_data(self):
"""Check if data are computed"""
self.report.compute_data_for_report()
self.assertGreaterEqual(len(self.report.account_ids), 1)
def test_02_generation_report_qweb(self):
"""Check if report PDF/HTML is correctly generated"""
report_name = 'account_financial_report_qweb.' \
'report_trial_balance_qweb'
# Check if returned report action is correct
report_action = self.report.print_report(xlsx_report=False)
self.assertDictContainsSubset(
{
'type': 'ir.actions.report.xml',
'report_name': report_name,
'report_type': 'qweb-pdf',
},
report_action
)
# Check if report template is correct
report_html = self.env['report'].get_html(self.report, report_name)
self.assertRegexpMatches(report_html, 'Trial Balance')
self.assertRegexpMatches(report_html, self.report.account_ids[0].name)
def test_03_generation_report_xlsx(self):
"""Check if report XLSX is correctly generated"""
report_name = 'account_financial_report_qweb.' \
'report_trial_balance_xlsx'
# Check if returned report action is correct
report_action = self.report.print_report(xlsx_report=True)
self.assertDictContainsSubset(
{
'type': 'ir.actions.report.xml',
'report_name': report_name,
'report_type': 'xlsx',
},
report_action
)
# Check if report template is correct
action_name = 'account_financial_report_qweb.' \
'action_report_trial_balance_xlsx'
report_xlsx = self.env.ref(action_name).render_report(
self.report.ids,
report_name,
{'report_type': u'xlsx'}
)
self.assertGreaterEqual(len(report_xlsx[0]), 1)
self.assertEqual(report_xlsx[1], 'xlsx')

2
account_financial_report_qweb/wizard/__init__.py

@ -4,6 +4,6 @@
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import aged_partner_balance_wizard
from . import balance_common_wizard
from . import general_ledger_wizard
from . import open_items_wizard
from . import trial_balance_wizard

62
account_financial_report_qweb/wizard/balance_common_wizard.py

@ -1,62 +0,0 @@
# -*- coding: utf-8 -*-
# Author: Thomas Rehn, Guewen Baconnier
# Copyright 2016 initOS GmbH, camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api
class AccountBalanceCommonWizard(models.TransientModel):
"""Will launch some balance report wizards and pass required args"""
_inherit = "account.common.account.report"
_name = "account.common.balance.report"
_description = "Common Balance Report"
@api.model
def _get_account_ids(self):
context = self.env.context or {}
res = False
if context.get('active_model', False) == 'account.account' \
and context.get('active_ids', False):
res = context['active_ids']
return res
account_ids = fields.Many2many(
comodel_name='account.account',
string='Filter on accounts',
help="Only selected accounts will be printed. Leave empty to "
"print all accounts.",
default=_get_account_ids
)
date_range_id = fields.Many2one(
comodel_name='date.range',
string='Date Range',
)
comparison_date_range_id = fields.Many2one(
comodel_name='date.range',
string='Date Range',
)
comparison_date_start = fields.Datetime(
string='Start Date'
)
comparison_date_end = fields.Datetime(
string='End Date'
)
partner_ids = fields.Many2many(
comodel_name='res.partner',
string='Filter on partner',
help="Only selected partners will be printed. "
"Leave empty to print all partners."
)
debit_credit = fields.Boolean(
string='Display Debit/Credit Columns',
help="This option allows you to get more details about the way your "
"balances are computed. Because it is space consuming, "
"we do not allow to use it while doing a comparison."
)
def pre_print_report(self, cr, uid, ids, data, context=None):
data = super(AccountBalanceCommonWizard, self).pre_print_report(
cr, uid, ids, data, context)
return data

57
account_financial_report_qweb/wizard/balance_common_wizard_view.xml

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_balance_common_wizard_view" model="ir.ui.view">
<field name="name">Balance Common Wizard</field>
<field name="model">account.common.balance.report</field>
<field name="mode">primary</field>
<field name="inherit_id" ref="account.account_common_report_view"/>
<field name="arch" type="xml">
<data>
<field name="company_id" position='replace'>
<group name="main_info">
<field name="company_id" readonly="0"/>
</group>
</field>
<field name="target_move" position="after">
<field name="date_range_id"/>
<newline/>
</field>
<field name="date_to" position="after">
<newline/>
<field name="debit_credit"/>
</field>
<footer position="before">
<notebook>
<page string="Accounts Filters" name="accounts">
<separator string="Print only" colspan="4"/>
<field name="account_ids" colspan="4" nolabel="1" domain="[('type', 'in', ['receivable', 'payable'])]">
<tree>
<field name="code"/>
<field name="name"/>
<field name="user_type_id"/>
<field name="company_id"/>
</tree>
</field>
</page>
<page string="Partners Filters" name="partners">
<separator string="Print only" colspan="4"/>
<field name="partner_ids" colspan="4" nolabel="1"/>
</page>
<page string="Comparison" name="comparison">
<group>
<field name="comparison_date_range_id"/>
<field name="comparison_date_start"/>
<field name="comparison_date_end"/>
</group>
</page>
</notebook>
</footer>
<field name="journal_ids" position="attributes">
<attribute name="invisible">True</attribute>
</field>
</data>
</field>
</record>
</odoo>

104
account_financial_report_qweb/wizard/trial_balance_wizard.py

@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api
class TrialBalanceReportWizard(models.TransientModel):
"""Trial balance report wizard."""
_name = "trial.balance.report.wizard"
_description = "Trial Balance Report Wizard"
company_id = fields.Many2one(
comodel_name='res.company',
default=lambda self: self.env.user.company_id
)
date_range_id = fields.Many2one(comodel_name='date.range', required=True)
date_from = fields.Date(required=True)
date_to = fields.Date(required=True)
fy_start_date = fields.Date(required=True)
target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')],
string='Target Moves',
required=True,
default='all')
account_ids = fields.Many2many(
comodel_name='account.account',
string='Filter accounts',
)
hide_account_balance_at_0 = fields.Boolean(
string='Hide account ending balance at 0',
help='Use this filter to hide an account or a partner '
'with an ending balance at 0. '
'If partners are filtered, '
'debits and credits totals will not match the trial balance.',
default=False)
receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean()
show_partner_details = fields.Boolean()
partner_ids = fields.Many2many(
comodel_name='res.partner',
string='Filter partners',
)
@api.onchange('date_range_id')
def onchange_date_range_id(self):
"""Handle date range change."""
self.date_from = self.date_range_id.date_start
self.date_to = self.date_range_id.date_end
if self.date_from:
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('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.onchange('show_partner_details')
def onchange_show_partner_details(self):
"""Handle partners change."""
if self.show_partner_details:
self.receivable_accounts_only = self.payable_accounts_only = True
else:
self.receivable_accounts_only = self.payable_accounts_only = False
@api.multi
def button_export_pdf(self):
self.ensure_one()
return self._export()
@api.multi
def button_export_xlsx(self):
self.ensure_one()
return self._export(xlsx_report=True)
def _export(self, xlsx_report=False):
"""Default export is PDF."""
model = self.env['report_trial_balance_qweb']
report = model.create({
'date_from': self.date_from,
'date_to': self.date_to,
'only_posted_moves': self.target_move == 'posted',
'hide_account_balance_at_0': self.hide_account_balance_at_0,
'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)],
'filter_partner_ids': [(6, 0, self.partner_ids.ids)],
'fy_start_date': self.fy_start_date,
'show_partner_details': self.show_partner_details,
})
return report.print_report(xlsx_report)

62
account_financial_report_qweb/wizard/trial_balance_wizard_view.xml

@ -1,36 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_trial_balance_wizard_view" model="ir.ui.view">
<field name="name">Trial Balance Wizard</field>
<field name="model">account.common.balance.report</field>
<field name="mode">primary</field>
<field name="inherit_id" ref="account_balance_common_wizard_view"/>
<!-- TRIAL BALANCE -->
<record id="trial_balance_wizard" model="ir.ui.view">
<field name="name">Trial Balance</field>
<field name="model">trial.balance.report.wizard</field>
<field name="arch" type="xml">
<data>
<field name="company_id" position="before">
<label nolabel="1" colspan="4" string="This report allows you to print or generate a pdf of your trial balance allowing you to quickly check the balance of each of your accounts in a single report"/>
</field>
<field name="debit_credit" position="attributes">
<attribute name="invisible">True</attribute>
</field>
<page name="partners" position="attributes">
<attribute name="invisible">True</attribute>
</page>
</data>
<form>
<group name="main_info">
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group name="filters">
<group name="date_ranger">
<field name="date_range_id" domain="[('company_id','=',company_id)]"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="fy_start_date" invisible="1"/>
</group>
<group name="other_filters">
<field name="target_move" widget="radio"/>
<field name="hide_account_balance_at_0"/>
<field name="show_partner_details"/>
</group>
</group>
<label for="partner_ids" attrs="{'invisible':[('show_partner_details','!=',True)]}"/>
<field name="partner_ids" nolabel="1" attrs="{'invisible':[('show_partner_details','!=',True)]}"/>
<group attrs="{'invisible':[('show_partner_details','!=',True)]}"/>
<label for="account_ids"/>
<group col="4">
<field name="receivable_accounts_only"/>
<field name="payable_accounts_only"/>
</group>
<field name="account_ids" nolabel="1"/>
<footer>
<button name="button_export_pdf" string="Export PDF" type="object" default_focus="1" class="oe_highlight"/>
or
<button name="button_export_xlsx" string="Export XLSX" type="object"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_account_trial_balance_wizard_view" model="ir.actions.act_window">
<record id="action_trial_balance_wizard" model="ir.actions.act_window">
<field name="name">Trial Balance</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.common.balance.report</field>
<field name="res_model">trial.balance.report.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="account_trial_balance_wizard_view"/>
<field name="view_id" ref="trial_balance_wizard"/>
<field name="target">new</field>
<field name="context">{'balance_common': 'trial_balance'}</field>
</record>
</odoo>
Loading…
Cancel
Save