jcoux
9 years ago
17 changed files with 788 additions and 148 deletions
-
3account_financial_report_qweb/README.rst
-
2account_financial_report_qweb/__openerp__.py
-
4account_financial_report_qweb/menuitems.xml
-
2account_financial_report_qweb/report/__init__.py
-
4account_financial_report_qweb/report/abstract_report_xlsx.py
-
2account_financial_report_qweb/report/general_ledger_xlsx.py
-
154account_financial_report_qweb/report/templates/trial_balance.xml
-
241account_financial_report_qweb/report/trial_balance.py
-
138account_financial_report_qweb/report/trial_balance_xlsx.py
-
22account_financial_report_qweb/reports.xml
-
1account_financial_report_qweb/tests/__init__.py
-
76account_financial_report_qweb/tests/test_trial_balance.py
-
2account_financial_report_qweb/wizard/__init__.py
-
62account_financial_report_qweb/wizard/balance_common_wizard.py
-
57account_financial_report_qweb/wizard/balance_common_wizard_view.xml
-
104account_financial_report_qweb/wizard/trial_balance_wizard.py
-
62account_financial_report_qweb/wizard/trial_balance_wizard_view.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> |
@ -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) |
@ -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 |
|||
) |
@ -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') |
@ -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 |
@ -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> |
@ -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) |
@ -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> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue