Merge lp:~camptocamp/account-financial-report/add_aged_partner_ledger-nbi into lp:~account-report-core-editor/account-financial-report/7.0

Proposed by Nicolas Bessi - Camptocamp
Status: Merged
Approved by: Yannick Vaucher @ Camptocamp
Approved revision: 102
Merged at revision: 86
Proposed branch: lp:~camptocamp/account-financial-report/add_aged_partner_ledger-nbi
Merge into: lp:~account-report-core-editor/account-financial-report/7.0
Diff against target: 1070 lines (+829/-20)
14 files modified
account_financial_report_webkit/__openerp__.py (+46/-3)
account_financial_report_webkit/report/__init__.py (+1/-0)
account_financial_report_webkit/report/aged_partner_balance.py (+403/-0)
account_financial_report_webkit/report/common_reports.py (+12/-2)
account_financial_report_webkit/report/open_invoices.py (+0/-1)
account_financial_report_webkit/report/report.xml (+34/-11)
account_financial_report_webkit/report/templates/aged_trial_webkit.mako (+155/-0)
account_financial_report_webkit/report/templates/open_invoices_inclusion.mako.html (+2/-2)
account_financial_report_webkit/report/webkit_parser_header_fix.py (+0/-1)
account_financial_report_webkit/report_menus.xml (+4/-0)
account_financial_report_webkit/tests/aged_trial_balance.yml (+60/-0)
account_financial_report_webkit/wizard/__init__.py (+1/-0)
account_financial_report_webkit/wizard/aged_partner_balance_wizard.py (+39/-0)
account_financial_report_webkit/wizard/aged_partner_balance_wizard.xml (+72/-0)
To merge this branch: bzr merge lp:~camptocamp/account-financial-report/add_aged_partner_ledger-nbi
Reviewer Review Type Date Requested Status
Stéphane Bidoul (Acsone) (community) test Approve
Frederic Clementi - Camptocamp functional Approve
Alexandre Fayolle - camptocamp lgtm Approve
Luc De Meyer (Noviat) Pending
Review via email: mp+211040@code.launchpad.net

Commit message

[ADD] Aged Partner Balance webkit report. Report inherit Open Invoice Report and uses previously computed ledger lines to determin aged lines

Description of the change

[ADD] Aged Partner Balance webkit report. Report inherit Open Invoice Report and uses previously computed ledger lines to determin aged linesAdd aged partner balance webkit report.

To post a comment you must log in.
97. By Nicolas Bessi - Camptocamp

[FIX] docstring syntax

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

quite a lot a code, and no test... :-(

Remarks:

* line 353 (in compute_delay_from_partial_rec): it would be nicer to move reference_line = line in the else clause of the if / elif statement (makes it clear that reference_line has avalue in all cases)

* line 381 and 383 (in get_compute_method) are the same. Can they be merged in the same branch?

* line 452: avoid the call to float() unless you have string in total[drange]. If you want to protect against int / int -> int, add from __future__ import division at the beginning of the module (and use // for integer division).

* line 472 and following (in get_reconcile_count_lookup): don't add \n in SQL statement.

* line 477 and following (in get_reconcile_count_lookup): the "if res" is useless, as well as the return {}.

98. By Nicolas Bessi - Camptocamp

[IMP] module revision number

99. By Nicolas Bessi - Camptocamp

[MRG] from head

100. By Nicolas Bessi - Camptocamp

[FIX] coding style

101. By Nicolas Bessi - Camptocamp

[FIX] use from __future__ import division instead of float casting

102. By Nicolas Bessi - Camptocamp

[FIX] add YML test on aged partner balance

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Hello,

Fixes done and basic tests added

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :
Download full text (3.4 KiB)

the tests are red here

 TEST test_70 openerp.tools.yaml_import: In order to test the PDF General Ledger webkit wizard I will print report with default setting
 ERROR test_70 openerp.tools.yaml_import: (u'No period found', '')

2014-03-18 16:14:12,556 23281 ERROR test_70 openerp.modules.loading: module account_financial_report_webkit: an exception occurred in a test
Traceback (most recent call last):
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/modules/loading.py", line 83, in load_test
    _load_data(cr, module_name, idref, mode, 'test')
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/modules/loading.py", line 122, in _load_data
    tools.convert_yaml_import(cr, module_name, fp, kind, idref, mode, noupdate, report)
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/tools/yaml_import.py", line 928, in yaml_import
    yaml_interpreter.process(yaml_string)
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/tools/yaml_import.py", line 864, in process
    self._process_node(node)
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/tools/yaml_import.py", line 877, in _process_node
    self.process_python(node)
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/tools/yaml_import.py", line 550, in process_python
    unsafe_eval(code_obj, {'ref': self.get_id}, code_context)
  File "/home/afayolle/work/oca/account-financial-reports/add_aged_partner_ledger-nbi/account_financial_report_webkit/tests/general_ledger.yml", line 5, in <module>
    ctx={}
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/tools/test_reports.py", line 294, in try_report_action
    result = _exec_action(action, datas, context)
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/tools/test_reports.py", line 278, in _exec_action
    res = try_report(cr, uid, 'report.'+action['report_name'], ids, datas, context, our_module=our_module)
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/tools/test_reports.py", line 53, in try_report
    res = netsvc.LocalService(rname).create(cr, uid, ids, data, context)
  File "/home/afayolle/work/oerp/addons/7.0/report_webkit/webkit_report.py", line 340, in create
    result = self.create_source_pdf(cursor, uid, ids, data, report_xml, context)
  File "/home/afayolle/work/oerp/openobject-server/7.0/openerp/report/report_sxw.py", line 513, in create_source_pdf
    return self.create_single_pdf(cr, uid, ids, data, report_xml, context)
  File "/home/afayolle/work/oca/account-financial-reports/add_aged_partner_ledger-nbi/account_financial_report_webkit/report/webkit_parser_header_fix.py", line 176, in create_single_pdf
    self.parser_instance.set_context(objs, data, ids, report_xml.report_type)
  File "/home/afayolle/work/oca/account-financial-reports/add_aged_partner_ledger-nbi/account_financial_report_webkit/report/general_ledger.py", line 90, in set_context
    start_period = self.get_first_fiscalyear_period(fiscalyear)
  File "/home/afayolle/work/oca/account-financial-reports/add_aged_partner_ledger-nbi/account_financial_report_webkit/report/common_reports.py", line 301, in get_first_fiscalyear_period
    return self._get_st_fiscaly...

Read more...

review: Needs Fixing
Revision history for this message
Stéphane Bidoul (Acsone) (sbi) wrote :

Alexandre, I think the fix for this one is in addons demo data (lp:1281579). Merged on OCB already.

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Hello,
Stéphan is right,

Test runs perfectly on OCB, that is the branches I used to developp communitiy addons.

Regards

Nicolas

2014-03-18 15:53:58,357 27853 INFO test_aged_partner openerp.modules.loading: module account_financial_report_webkit: loading tests/aged_trial_balance.yml
2014-03-18 15:53:58,364 27853 TEST test_aged_partner openerp.tools.yaml_import: In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with defau
lt setting
2014-03-18 15:53:58,815 27853 TEST test_aged_partner openerp.tools.yaml_import: In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filte
rs and currency
2014-03-18 15:53:59,269 27853 TEST test_aged_partner openerp.tools.yaml_import: In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filte
rs on partners
2014-03-18 15:53:59,706 27853 TEST test_aged_partner openerp.tools.yaml_import: In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filte
rs on periods
2014-03-18 15:54:00,145 27853 TEST test_aged_partner openerp.tools.yaml_import: In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filte
rs on dates
2014-03-18 15:54:00,597 27853 INFO test_aged_partner openerp.addons.base.ir.ir_translation: module account_financial_report_webkit: loading translation file (en_US) for language
 en_US
2014-03-18 15:54:00,597 27853 INFO test_aged_partner openerp.tools.translate: loading /home/nbessi/oe/predige_openerp/openerp_trunk_predige/parts/account-financial-report/accoun

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :
Download full text (5.5 KiB)

ok my bad. I generally run the OCA tests on the official branch...

Still with the OCB branch, the test requires some specific setup:

 here: http://code.google.com/p/wkhtmltopdf/downloads/list and set the path in the ir.config_parameter with the webkit_path key.Minimal version is 0.9.9')
Traceback (most recent call last):
  File "/home/afayolle/work/oerp/openobject-server/ocb-7.0/openerp/tools/yaml_import.py", line 864, in process
    self._process_node(node)
  File "/home/afayolle/work/oerp/openobject-server/ocb-7.0/openerp/tools/yaml_import.py", line 877, in _process_node
    self.process_python(node)
  File "/home/afayolle/work/oerp/openobject-server/ocb-7.0/openerp/tools/yaml_import.py", line 550, in process_python
    unsafe_eval(code_obj, {'ref': self.get_id}, code_context)
  File "/home/afayolle/work/oca/account-financial-reports/add_aged_partner_ledger-nbi/account_financial_report_webkit/tests/general_ledger.yml", line 5, in <module>
    ctx={}
  File "/home/afayolle/work/oerp/openobject-server/ocb-7.0/openerp/tools/test_reports.py", line 294, in try_report_action
    result = _exec_action(action, datas, context)
  File "/home/afayolle/work/oerp/openobject-server/ocb-7.0/openerp/tools/test_reports.py", line 278, in _exec_action
    res = try_report(cr, uid, 'report.'+action['report_name'], ids, datas, context, our_module=our_module)
  File "/home/afayolle/work/oerp/openobject-server/ocb-7.0/openerp/tools/test_reports.py", line 53, in try_report
    res = netsvc.LocalService(rname).create(cr, uid, ids, data, context)
  File "/home/afayolle/work/oerp/addons/ocb-7.0/report_webkit/webkit_report.py", line 340, in create
    result = self.create_source_pdf(cursor, uid, ids, data, report_xml, context)
  File "/home/afayolle/work/oerp/openobject-server/ocb-7.0/openerp/report/report_sxw.py", line 511, in create_source_pdf
    return self.create_single_pdf(cr, uid, ids, data, report_xml, context)
  File "/home/afayolle/work/oca/account-financial-reports/add_aged_partner_ledger-nbi/account_financial_report_webkit/report/webkit_parser_header_fix.py", line 244, in create_single_pdf
    bin = self.get_lib(cursor, uid)
  File "/home/afayolle/work/oerp/addons/ocb-7.0/report_webkit/webkit_report.py", line 96, in get_lib
    _('Please install executable on your system' \
except_osv: (u'Wkhtmltopdf library path is not set', u'Please install executable on your system (sudo apt-get install wkhtmltopdf) or download it from here: http://code.google.com/p/wkhtmltopdf/downloads/list and set the path in the ir.config_parameter with the webkit_path key.Minimal version is 0.9.9')
2014-03-19 07:51:04,798 10999 ERROR test_ocb70 openerp.modules.loading: module account_financial_report_webkit: an exception occurred in a test
Traceback (most recent call last):
  File "/home/afayolle/work/oerp/openobject-server/ocb-7.0/openerp/modules/loading.py", line 83, in load_test
    _load_data(cr, module_name, idref, mode, 'test')
  File "/home/afayolle/work/oerp/openobject-server/ocb-7.0/openerp/modules/loading.py", line 122, in _load_data
    tools.convert_yaml_import(cr, module_name, fp, kind, idref, mode, noupdate, report)
  File "/home/afayolle/work/oerp/openobject-serve...

Read more...

Revision history for this message
Frederic Clementi - Camptocamp (frederic-clementi) wrote :

I do not get what is the issue excactly however this report MUST work with the addons branch as well...

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Alexandre,

As for all webkit report if you do not set explicitly path to wkhtml2pdf in an ir.config.parameter you have to have a wkhtml2pdf command in your executable path.

Nicolas

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Frederic

The reports are functional on addons branch, only the tests failed because on official addons in demo data all periods are special.

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

ok setup problem on my test instance.

review: Approve (lgtm)
Revision history for this message
Frederic Clementi - Camptocamp (frederic-clementi) wrote :

All my uses cases works perfectely.

Ok for me

review: Approve (functional)
Revision history for this message
Stéphane Bidoul (Acsone) (sbi) wrote :

Hi Nicolas,

I did a quick test and found significant differences from the standard report which I need to investigate, so if you don't mind I'll put it Need Information so it does not get merged accidentally.

It is probably an issue in my test data, I'll get back to you as soon as possible.

Another question, is there a particular reason you did not implement the "period length" and leave it to 30 days?

review: Needs Information (test)
Revision history for this message
Christelle De Coninck (Acsone) (cde) wrote :

Hi Nicolas,

I'm working as a business analyst for Acsone and Stéphane Bidoul asked me to make a functional test regarding the new "Aged Partner Balance" report .

I noticed that the amounts are classified in the different columns (<30, <60, etc.) based on the clearance Date. By default, this clearance date is the end of the fiscal year (31/12/2014 in this case).

I tried to change this date but it is forbidden and I obtained the following error message:

ValidateError

Error occurred while validating the field(s) until_date: Clearance date must be the very last date of the last period or later.

In my opinion, it is interesting to let the user choose the clearance date he wants for his report. Furthermore, I think that current date is again more interesting as it permits to have a good representation of the actual situation.

An improvement to this report could thus be that the current date is used as default date and the user have the possibility to change it.

What do you think?

Thanks in advance for your answer

Revision history for this message
Frederic Clementi - Camptocamp (frederic-clementi) wrote :

Hi Christelle,

Very happy that you can test this new report.

FYI, I wrote a google doc here : http://bit.ly/1kwTyt0 and I explained in section 2.5 what is the clearance date on the 'open invoices report'. I need to update this doc but logic is the same for aged balance.

Do not hesitate to ask information if needed.

Frederic Clementi

Revision history for this message
Frederic Clementi - Camptocamp (frederic-clementi) wrote :

Just did a new tests (with clearance date) on production environement -> works fine. Result match with all other reports.

Revision history for this message
Christelle De Coninck (Acsone) (cde) wrote :

Hi Frederic,

Thanks a lot for your answer and for the google doc. It's more clear now.

So I redid my tests and for me, this report works fine.

Best regards,

Christelle

Revision history for this message
Stéphane Bidoul (Acsone) (sbi) wrote :

Report works fine provided the clearance date is set correctly.

My only remark is a usability issue as the most common use case (aged balance as of current date) requires fiddling with the date filters. As another MP resolving the usability issue is on its way, I approve this one.

Thanks!

review: Approve (test)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account_financial_report_webkit/__openerp__.py'
2--- account_financial_report_webkit/__openerp__.py 2014-03-13 10:49:47 +0000
3+++ account_financial_report_webkit/__openerp__.py 2014-03-18 15:55:27 +0000
4@@ -30,7 +30,7 @@
5 - Partner ledger
6 - Partner balance
7 - Open invoices report
8-
9+ - Aged Partner Balance
10
11 Main improvements per report:
12 -----------------------------
13@@ -100,6 +100,47 @@
14 * Subtotal by account and partner
15 * Alphabetical sorting (same as in partner balance)
16
17+
18+Aged Partner Balance: Summary of aged open amount per partner
19+
20+This report is an accounting tool helping in various tasks.
21+You can credit control or partner balance provisions computation for instance.
22+
23+The aged balance report allows you to print balances per partner
24+like the trial balance but add an extra information :
25+
26+* It will split balances into due amounts
27+ (due date not reached à the end date of the report) and overdue amounts
28+ Overdue data are also split by period.
29+* For each partner following columns will be displayed:
30+
31+ * Total balance (all figures must match with same date partner balance report).
32+ This column equals the sum of all following columns)
33+
34+ * Due
35+ * Overdue <= 30 days
36+ * Overdue <= 60 days
37+ * Overdue <= 90 days
38+ * Overdue <= 120 days
39+ * Older
40+
41+Hypothesis / Contraints of aged partner balance
42+
43+* Overdues columns will be by default be based on 30 days range fix number of days.
44+ This can be changed by changes the RANGES constraint
45+* All data will be displayed in company currency
46+* When partial payments, the payment must appear in the same colums than the invoice
47+ (Except if multiple payment terms)
48+* Data granularity: partner (will not display figures at invoices level)
49+* The report aggregate data per account with sub-totals
50+* Initial balance must be calculated the same way that
51+ the partner balance / Ignoring the opening entry
52+ in special period (idem open invoice report)
53+* Only accounts with internal type payable or receivable are considered
54+ (idem open invoice report)
55+* If maturity date is null then use move line date
56+
57+
58 Limitations:
59 ------------
60
61@@ -126,7 +167,7 @@
62 the header and footer are created as text with arguments passed to
63 wkhtmltopdf. The texts are defined inside the report classes.
64 """,
65- 'version': '1.0.2',
66+ 'version': '1.1.0',
67 'author': 'Camptocamp',
68 'license': 'AGPL-3',
69 'category': 'Finance',
70@@ -147,6 +188,7 @@
71 'wizard/trial_balance_wizard_view.xml',
72 'wizard/partner_balance_wizard_view.xml',
73 'wizard/open_invoices_wizard_view.xml',
74+ 'wizard/aged_partner_balance_wizard.xml',
75 'wizard/print_journal_view.xml',
76 'report_menus.xml',
77 ],
78@@ -155,7 +197,8 @@
79 'tests/partner_ledger.yml',
80 'tests/trial_balance.yml',
81 'tests/partner_balance.yml',
82- 'tests/open_invoices.yml',],
83+ 'tests/open_invoices.yml',
84+ 'tests/aged_trial_balance.yml'],
85 #'tests/account_move_line.yml'
86 'active': False,
87 'installable': True,
88
89=== modified file 'account_financial_report_webkit/report/__init__.py'
90--- account_financial_report_webkit/report/__init__.py 2013-09-12 20:53:27 +0000
91+++ account_financial_report_webkit/report/__init__.py 2014-03-18 15:55:27 +0000
92@@ -9,3 +9,4 @@
93 from . import partner_balance
94 from . import open_invoices
95 from . import print_journal
96+from . import aged_partner_balance
97
98=== added file 'account_financial_report_webkit/report/aged_partner_balance.py'
99--- account_financial_report_webkit/report/aged_partner_balance.py 1970-01-01 00:00:00 +0000
100+++ account_financial_report_webkit/report/aged_partner_balance.py 2014-03-18 15:55:27 +0000
101@@ -0,0 +1,403 @@
102+# -*- coding: utf-8 -*-
103+##############################################################################
104+#
105+# Author: Nicolas Bessi
106+# Copyright 2014 Camptocamp SA
107+#
108+# This program is free software: you can redistribute it and/or modify
109+# it under the terms of the GNU Affero General Public License as
110+# published by the Free Software Foundation, either version 3 of the
111+# License, or (at your option) any later version.
112+#
113+# This program is distributed in the hope that it will be useful,
114+# but WITHOUT ANY WARRANTY; without even the implied warranty of
115+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
116+# GNU Affero General Public License for more details.
117+#
118+# You should have received a copy of the GNU Affero General Public License
119+# along with this program. If not, see <http://www.gnu.org/licenses/>.
120+#
121+##############################################################################
122+from __future__ import division
123+from datetime import datetime
124+
125+from openerp import pooler
126+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
127+from openerp.tools.translate import _
128+from .open_invoices import PartnersOpenInvoicesWebkit
129+from .webkit_parser_header_fix import HeaderFooterTextWebKitParser
130+
131+
132+def make_ranges(top, offset):
133+ """Return sorted days ranges
134+
135+ :param top: maximum overdue day
136+ :param offset: offset for ranges
137+
138+ :returns: list of sorted ranges tuples in days
139+ eg. [(-100000, 0), (0, offset), (offset, n*offset), ... (top, 100000)]
140+ """
141+ ranges = [(n, min(n + offset, top)) for n in xrange(0, top, offset)]
142+ ranges.insert(0, (-100000000000, 0))
143+ ranges.append((top, 100000000000))
144+ return ranges
145+
146+#list of overdue ranges
147+RANGES = make_ranges(120, 30)
148+
149+
150+def make_ranges_titles():
151+ """Generates title to be used by mako"""
152+ titles = [_('Due')]
153+ titles += [_(u'Overdue ≤ %s d.') % x[1] for x in RANGES[1:-1]]
154+ titles.append(_('Older'))
155+ return titles
156+
157+#list of overdue ranges title
158+RANGES_TITLES = make_ranges_titles()
159+#list of payable journal types
160+REC_PAY_TYPE = ('purchase', 'sale')
161+#list of refund payable type
162+REFUND_TYPE = ('purchase_refund', 'sale_refund')
163+INV_TYPE = REC_PAY_TYPE + REFUND_TYPE
164+
165+
166+class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit):
167+ """Compute Aged Partner Balance based on result of Open Invoices"""
168+
169+ def __init__(self, cursor, uid, name, context=None):
170+ """Constructor, refer to :class:`openerp.report.report_sxw.rml_parse`"""
171+ super(AccountAgedTrialBalanceWebkit, self).__init__(cursor, uid, name,
172+ context=context)
173+ self.pool = pooler.get_pool(self.cr.dbname)
174+ self.cursor = self.cr
175+ company = self.pool.get('res.users').browse(self.cr, uid, uid,
176+ context=context).company_id
177+
178+ header_report_name = ' - '.join((_('Aged Partner Balance'),
179+ company.currency_id.name))
180+
181+ footer_date_time = self.formatLang(str(datetime.today()),
182+ date_time=True)
183+
184+ self.localcontext.update({
185+ 'cr': cursor,
186+ 'uid': uid,
187+ 'company': company,
188+ 'ranges': self._get_ranges(),
189+ 'ranges_titles': self._get_ranges_titles(),
190+ 'report_name': _('Aged Partner Balance'),
191+ 'additional_args': [
192+ ('--header-font-name', 'Helvetica'),
193+ ('--footer-font-name', 'Helvetica'),
194+ ('--header-font-size', '10'),
195+ ('--footer-font-size', '6'),
196+ ('--header-left', header_report_name),
197+ ('--header-spacing', '2'),
198+ ('--footer-left', footer_date_time),
199+ ('--footer-right', ' '.join((_('Page'), '[page]', _('of'), '[topage]'))),
200+ ('--footer-line',),
201+ ],
202+ })
203+
204+ def _get_ranges(self):
205+ """:returns: :cons:`RANGES`"""
206+ return RANGES
207+
208+ def _get_ranges_titles(self):
209+ """:returns: :cons: `RANGES_TITLES`"""
210+ return RANGES_TITLES
211+
212+ def set_context(self, objects, data, ids, report_type=None):
213+ """Populate aged_lines, aged_balance, aged_percents attributes
214+
215+ on each account browse record that will be used by mako template
216+ The browse record are store in :attr:`objects`
217+
218+ The computation are based on the ledger_lines attribute set on account
219+ contained by :attr:`objects`
220+
221+ :attr:`objects` values were previously set by parent class
222+ :class: `.open_invoices.PartnersOpenInvoicesWebkit`
223+
224+ :returns: parent :class:`.open_invoices.PartnersOpenInvoicesWebkit`
225+ call to set_context
226+
227+ """
228+ res = super(AccountAgedTrialBalanceWebkit, self).set_context(
229+ objects,
230+ data,
231+ ids,
232+ report_type=report_type
233+ )
234+
235+ for acc in self.objects:
236+ acc.aged_lines = {}
237+ acc.agged_totals = {}
238+ acc.agged_percents = {}
239+ for part_id, partner_lines in acc.ledger_lines.items():
240+ aged_lines = self.compute_aged_lines(part_id,
241+ partner_lines,
242+ data)
243+ if aged_lines:
244+ acc.aged_lines[part_id] = aged_lines
245+ acc.aged_totals = totals = self.compute_totals(acc.aged_lines.values())
246+ acc.aged_percents = self.compute_percents(totals)
247+ #Free some memory
248+ del(acc.ledger_lines)
249+ return res
250+
251+ def compute_aged_lines(self, partner_id, ledger_lines, data):
252+ """Add property aged_lines to accounts browse records
253+
254+ contained in :attr:`objects` for a given partner
255+
256+ :param: partner_id: current partner
257+ :param ledger_lines: generated by parent
258+ :class:`.open_invoices.PartnersOpenInvoicesWebkit`
259+
260+ :returns: dict of computed aged lines
261+ eg {'balance': 1000.0,
262+ 'aged_lines': {(90, 120): 0.0, ...}
263+
264+ """
265+ lines_to_age = self.filter_lines(partner_id, ledger_lines)
266+ res = {}
267+ end_date = self._get_end_date(data)
268+ aged_lines = dict.fromkeys(RANGES, 0.0)
269+ reconcile_lookup = self.get_reconcile_count_lookup(lines_to_age)
270+ res['aged_lines'] = aged_lines
271+ for line in lines_to_age:
272+ compute_method = self.get_compute_method(reconcile_lookup,
273+ partner_id,
274+ line)
275+ delay = compute_method(line, end_date, ledger_lines)
276+ classification = self.classify_line(partner_id, delay)
277+ aged_lines[classification] += line['debit'] - line['credit']
278+ self.compute_balance(res, aged_lines)
279+ return res
280+
281+ def _get_end_date(self, data):
282+ """Retrieve end date to be used to compute delay.
283+
284+ :param data: data dict send to report contains form dict
285+
286+ :returns: end date to be used to compute overdue delay
287+
288+ """
289+ end_date = None
290+ date_to = data['form']['date_to']
291+ period_to_id = data['form']['period_to']
292+ fiscal_to_id = data['form']['fiscalyear_id']
293+ if date_to:
294+ end_date = date_to
295+ elif period_to_id:
296+ period_to = self.pool['account.period'].browse(self.cr,
297+ self.uid,
298+ period_to_id)
299+ end_date = period_to.date_stop
300+ elif fiscal_to_id:
301+ fiscal_to = self.pool['account.fiscalyear'].browse(self.cr,
302+ self.uid,
303+ fiscal_to_id)
304+ end_date = fiscal_to.date_stop
305+ else:
306+ raise ValueError('End date and end period not available')
307+ return end_date
308+
309+ def _compute_delay_from_key(self, key, line, end_date):
310+ """Compute overdue delay delta in days for line using attribute in key
311+
312+ delta = end_date - date of key
313+
314+ :param line: current ledger line
315+ :param key: date key to be used to compute delta
316+ :param end_date: end_date computed for wizard data
317+
318+ :returns: delta in days
319+ """
320+ from_date = datetime.strptime(line[key], DEFAULT_SERVER_DATE_FORMAT)
321+ end_date = datetime.strptime(end_date, DEFAULT_SERVER_DATE_FORMAT)
322+ delta = end_date - from_date
323+ return delta.days
324+
325+ def compute_delay_from_maturity(self, line, end_date, ledger_lines):
326+ """Compute overdue delay delta in days for line using attribute in key
327+
328+ delta = end_date - maturity date
329+
330+ :param line: current ledger line
331+ :param end_date: end_date computed for wizard data
332+ :param ledger_lines: generated by parent
333+ :class:`.open_invoices.PartnersOpenInvoicesWebkit`
334+
335+ :returns: delta in days
336+ """
337+ return self._compute_delay_from_key('date_maturity',
338+ line,
339+ end_date)
340+
341+ def compute_delay_from_date(self, line, end_date, ledger_lines):
342+ """Compute overdue delay delta in days for line using attribute in key
343+
344+ delta = end_date - date
345+
346+ :param line: current ledger line
347+ :param end_date: end_date computed for wizard data
348+ :param ledger_lines: generated by parent
349+ :class:`.open_invoices.PartnersOpenInvoicesWebkit`
350+
351+ :returns: delta in days
352+ """
353+ return self._compute_delay_from_key('ldate',
354+ line,
355+ end_date)
356+
357+ def compute_delay_from_partial_rec(self, line, end_date, ledger_lines):
358+ """Compute overdue delay delta in days for the case where move line
359+
360+ is related to a partial reconcile with more than one reconcile line
361+
362+ :param line: current ledger line
363+ :param end_date: end_date computed for wizard data
364+ :param ledger_lines: generated by parent
365+ :class:`.open_invoices.PartnersOpenInvoicesWebkit`
366+
367+ :returns: delta in days
368+ """
369+ sale_lines = [x for x in ledger_lines if x['jtype'] in REC_PAY_TYPE and
370+ line['rec_id'] == x['rec_id']]
371+ refund_lines = [x for x in ledger_lines if x['jtype'] in REFUND_TYPE and
372+ line['rec_id'] == x['rec_id']]
373+ if len(sale_lines) == 1:
374+ reference_line = sale_lines[0]
375+ elif len(refund_lines) == 1:
376+ reference_line = refund_lines[0]
377+ else:
378+ reference_line = line
379+ key = 'date_maturity' if reference_line.get('date_maturity') else 'ldate'
380+ return self._compute_delay_from_key(key,
381+ reference_line,
382+ end_date)
383+
384+ def get_compute_method(self, reconcile_lookup, partner_id, line):
385+ """Get the function that should compute the delay for a given line
386+
387+ :param reconcile_lookup: dict of reconcile group by id and count
388+ {rec_id: count of line related to reconcile}
389+ :param partner_id: current partner_id
390+ :param line: current ledger line generated by parent
391+ :class:`.open_invoices.PartnersOpenInvoicesWebkit`
392+
393+ :returns: function bounded to :class:`.AccountAgedTrialBalanceWebkit`
394+
395+ """
396+ if reconcile_lookup.get(line['rec_id'], 0.0) > 1:
397+ return self.compute_delay_from_partial_rec
398+ elif line['jtype'] in INV_TYPE and line.get('date_maturity'):
399+ return self.compute_delay_from_maturity
400+ else:
401+ return self.compute_delay_from_date
402+
403+ def line_is_valid(self, partner_id, line):
404+ """Predicate hook that allows to filter line to be treated
405+
406+ :param partner_id: current partner_id
407+ :param line: current ledger line generated by parent
408+ :class:`.open_invoices.PartnersOpenInvoicesWebkit`
409+
410+ :returns: boolean True if line is allowed
411+ """
412+ return True
413+
414+ def filter_lines(self, partner_id, lines):
415+ """Filter ledger lines that have to be treated
416+
417+ :param partner_id: current partner_id
418+ :param lines: ledger_lines related to current partner
419+ and generated by parent
420+ :class:`.open_invoices.PartnersOpenInvoicesWebkit`
421+
422+ :returns: list of allowed lines
423+
424+ """
425+ return [x for x in lines if self.line_is_valid(partner_id, x)]
426+
427+ def classify_line(self, partner_id, overdue_days):
428+ """Return the overdue range for a given delay
429+
430+ We loop from smaller range to higher
431+ This should be the most effective solution as generaly
432+ customer tend to have one or two month of delay
433+
434+ :param overdue_days: delay in days
435+ :param partner_id: current partner_id
436+
437+ :returns: the correct range in :const:`RANGES`
438+
439+ """
440+ for drange in RANGES:
441+ if overdue_days <= drange[1]:
442+ return drange
443+ return drange
444+
445+ def compute_balance(self, res, aged_lines):
446+ """Compute the total balance of aged line
447+ for given account"""
448+ res['balance'] = sum(aged_lines.values())
449+
450+ def compute_totals(self, aged_lines):
451+ """Compute the totals for an account
452+
453+ :param aged_lines: dict of aged line taken from the
454+ property added to account record
455+
456+ :returns: dict of total {'balance':1000.00, (30, 60): 3000,...}
457+
458+ """
459+ totals = {}
460+ totals['balance'] = sum(x.get('balance', 0.0) for
461+ x in aged_lines)
462+ aged_ranges = [x.get('aged_lines', {}) for x in aged_lines]
463+ for drange in RANGES:
464+ totals[drange] = sum(x.get(drange, 0.0) for x in aged_ranges)
465+ return totals
466+
467+ def compute_percents(self, totals):
468+ percents = {}
469+ base = totals['balance'] or 1.0
470+ for drange in RANGES:
471+ percents[drange] = (totals[drange] / base) * 100.0
472+ return percents
473+
474+ def get_reconcile_count_lookup(self, lines):
475+ """Compute an lookup dict
476+
477+ It contains has partial reconcile id as key and the count of lines
478+ related to the reconcile id
479+
480+ :param: a list of ledger lines generated by parent
481+ :class:`.open_invoices.PartnersOpenInvoicesWebkit`
482+
483+ :retuns: lookup dict {ṛec_id: count}
484+
485+ """
486+ # possible bang if l_ids is really long.
487+ # We have the same weakness in common_report ...
488+ # but it seems not really possible for a partner
489+ # So I'll keep that option.
490+ l_ids = tuple(x['id'] for x in lines)
491+ sql = ("SELECT reconcile_partial_id, COUNT(*) FROM account_move_line"
492+ " WHERE reconcile_partial_id IS NOT NULL"
493+ " AND id in %s"
494+ " GROUP BY reconcile_partial_id")
495+ self.cr.execute(sql, (l_ids,))
496+ res = self.cr.fetchall()
497+ return dict((x[0], x[1]) for x in res)
498+
499+HeaderFooterTextWebKitParser(
500+ 'report.account.account_aged_trial_balance_webkit',
501+ 'account.account',
502+ 'addons/account_financial_report_webkit/report/templates/aged_trial_webkit.mako',
503+ parser=AccountAgedTrialBalanceWebkit,
504+)
505
506=== modified file 'account_financial_report_webkit/report/common_reports.py'
507--- account_financial_report_webkit/report/common_reports.py 2013-12-17 16:16:37 +0000
508+++ account_financial_report_webkit/report/common_reports.py 2014-03-18 15:55:27 +0000
509@@ -30,7 +30,7 @@
510
511 _logger = logging.getLogger('financial.reports.webkit')
512
513-
514+MAX_MONSTER_SLICE = 50000
515 class CommonReportHeaderWebkit(common_report_header):
516 """Define common helper for financial report"""
517
518@@ -433,6 +433,14 @@
519 raise osv.except_osv(_('No valid filter'), _('Please set a valid time filter'))
520
521 def _get_move_line_datas(self, move_line_ids, order='per.special DESC, l.date ASC, per.date_start ASC, m.name ASC'):
522+ # Possible bang if move_line_ids is too long
523+ # We can not slice here as we have to do the sort.
524+ # If slice has to be done it means that we have to reorder in python
525+ # after all is finished. That quite crapy...
526+ # We have a defective desing here (mea culpa) that should be fixed
527+ #
528+ # TODO improve that by making a better domain or if not possible
529+ # by using python sort
530 if not move_line_ids:
531 return []
532 if not isinstance(move_line_ids, list):
533@@ -441,6 +449,7 @@
534 SELECT l.id AS id,
535 l.date AS ldate,
536 j.code AS jcode ,
537+ j.type AS jtype,
538 l.currency_id,
539 l.account_id,
540 l.amount_currency,
541@@ -455,7 +464,8 @@
542 l.partner_id AS lpartner_id,
543 p.name AS partner_name,
544 m.name AS move_name,
545- COALESCE(partialrec.name, fullrec.name, '') AS rec_name,
546+ COALESCE(partialrec.name, fullrec.name, '') AS rec_name,
547+ COALESCE(partialrec.id, fullrec.id, NULL) AS rec_id,
548 m.id AS move_id,
549 c.name AS currency_code,
550 i.id AS invoice_id,
551
552=== modified file 'account_financial_report_webkit/report/open_invoices.py'
553--- account_financial_report_webkit/report/open_invoices.py 2013-11-03 12:55:27 +0000
554+++ account_financial_report_webkit/report/open_invoices.py 2014-03-18 15:55:27 +0000
555@@ -93,7 +93,6 @@
556 """Populate a ledger_lines attribute on each browse record that will be used
557 by mako template"""
558 new_ids = data['form']['chart_account_id']
559-
560 # Account initial balance memoizer
561 init_balance_memoizer = {}
562 # Reading form
563
564=== modified file 'account_financial_report_webkit/report/report.xml'
565--- account_financial_report_webkit/report/report.xml 2013-12-16 09:37:19 +0000
566+++ account_financial_report_webkit/report/report.xml 2014-03-18 15:55:27 +0000
567@@ -14,23 +14,16 @@
568 <field name="name">General Ledger Webkit</field>
569 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_general_ledger.mako</field>
570 <field name="report_file">account_financial_report_webkit/report/templates/account_report_general_ledger.mako</field>
571- </record>
572+ </record>
573+
574 <record id="property_account_report_general_ledger_webkit" model="ir.property">
575 <field name="name">account_report_general_ledger_webkit</field>
576 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
577 <field eval="'ir.header_webkit,'+str(ref('account_financial_report_webkit.financial_landscape_header'))" model="ir.header_webkit" name="value"/>
578 <field eval="'ir.actions.report.xml,'+str(ref('account_financial_report_webkit.account_report_general_ledger_webkit'))" model="ir.actions.report.xml" name="res_id"/>
579 </record>
580- <!-- waiting the fix
581- <report auto="False"
582- id="account_report_partner_ledger_webkit"
583- model="account.account"
584- name="account.account_report_partner_ledger_webkit"
585- file="account_financial_report_webkit/report/templates/account_report_partner_ledger.mako"
586- string="General Ledger Webkit"
587- report_type="webkit"/> -->
588-
589- <!-- we do not use report tag has we can not set header ref -->
590+
591+ <!-- we do not use report tag has we can not set header ref -->
592 <record id="account_report_partners_ledger_webkit" model="ir.actions.report.xml">
593 <field name="report_type">webkit</field>
594 <field name="report_name">account.account_report_partners_ledger_webkit</field>
595@@ -44,6 +37,7 @@
596 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_partners_ledger.mako</field>
597 <field name="report_file">account_financial_report_webkit/report/templates/account_report_partners_ledger.mako</field>
598 </record>
599+
600 <record id="property_account_report_partners_ledger_webkit" model="ir.property">
601 <field name="name">account_report_partners_ledger_webkit</field>
602 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
603@@ -64,6 +58,7 @@
604 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_trial_balance.mako</field>
605 <field name="report_file">account_financial_report_webkit/report/templates/account_report_trial_balance.mako</field>
606 </record>
607+
608 <record id="property_account_report_trial_balance_webkit" model="ir.property">
609 <field name="name">account_report_trial_balance_webkit</field>
610 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
611@@ -84,6 +79,7 @@
612 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_partner_balance.mako</field>
613 <field name="report_file">account_financial_report_webkit/report/templates/account_report_partner_balance.mako</field>
614 </record>
615+
616 <record id="property_account_report_partner_balance_webkit" model="ir.property">
617 <field name="name">account_report_partner_balance_webkit</field>
618 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
619@@ -104,6 +100,7 @@
620 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_open_invoices.mako</field>
621 <field name="report_file">account_financial_report_webkit/report/templates/account_report_open_invoices.mako</field>
622 </record>
623+
624 <record id="property_account_report_open_invoices_webkit" model="ir.property">
625 <field name="name">account_report_open_invoices_webkit</field>
626 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
627@@ -111,6 +108,31 @@
628 <field eval="'ir.actions.report.xml,'+str(ref('account_financial_report_webkit.account_report_open_invoices_webkit'))" model="ir.actions.report.xml" name="res_id"/>
629 </record>
630
631+ <record id="account_report_aged_trial_blanance_webkit" model="ir.actions.report.xml">
632+ <field name="report_type">webkit</field>
633+ <field name="report_name">account.account_aged_trial_balance_webkit</field>
634+ <field eval="[(6,0,[])]" name="groups_id"/>
635+ <field eval="0" name="multi"/>
636+ <field eval="0" name="auto"/>
637+ <field eval="1" name="header"/>
638+ <field name="model">account.account</field>
639+ <field name="type">ir.actions.report.xml</field>
640+ <field name="name">Aged Partner Balance</field>
641+ <field name="report_rml">account_financial_report_webkit/report/templates/aged_trial_webkit.mako</field>
642+ <field name="report_file">account_financial_report_webkit/report/templates/aged_trial_webkit.mako</field>
643+ </record>
644+
645+ <record id="property_account_report_aged_trial_balance_webkit" model="ir.property">
646+ <field name="name">account_aged_trial_balance_webkit</field>
647+ <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
648+ <field eval="'ir.header_webkit,'+str(ref('account_financial_report_webkit.financial_landscape_header'))"
649+ model="ir.header_webkit"
650+ name="value"/>
651+ <field eval="'ir.actions.report.xml,'+str(ref('account_financial_report_webkit.account_report_aged_trial_blanance_webkit'))"
652+ model="ir.actions.report.xml"
653+ name="res_id"/>
654+ </record>
655+
656 <record id="account_report_print_journal_webkit" model="ir.actions.report.xml">
657 <field name="report_type">webkit</field>
658 <field name="report_name">account.account_report_print_journal_webkit</field>
659@@ -124,6 +146,7 @@
660 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_print_journal.mako</field>
661 <field name="report_file">account_financial_report_webkit/report/templates/account_report_print_journal.mako</field>
662 </record>
663+
664 <record id="property_account_report_print_journal_webkit" model="ir.property">
665 <field name="name">account_report_print_journal_webkit</field>
666 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
667
668=== added file 'account_financial_report_webkit/report/templates/aged_trial_webkit.mako'
669--- account_financial_report_webkit/report/templates/aged_trial_webkit.mako 1970-01-01 00:00:00 +0000
670+++ account_financial_report_webkit/report/templates/aged_trial_webkit.mako 2014-03-18 15:55:27 +0000
671@@ -0,0 +1,155 @@
672+## -*- coding: utf-8 -*-
673+<!DOCTYPE html SYSTEM
674+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
675+<html xmlns="http://www.w3.org/1999/xhtml">
676+ <head>
677+ <style type="text/css">
678+ .overflow_ellipsis {
679+ text-overflow: ellipsis;
680+ overflow: hidden;
681+ white-space: nowrap;
682+ }
683+
684+ .open_invoice_previous_line {
685+ font-style: italic;
686+ }
687+
688+ .percent_line {
689+ font-style: italic;
690+ }
691+
692+ .amount {
693+ text-align:right;
694+ }
695+
696+ .classif_title {
697+ text-align:right;
698+ }
699+
700+ .classif{
701+ width: ${700/len(ranges)}px;
702+ }
703+ .total{
704+ font-weight:bold;
705+ }
706+ ${css}
707+ </style>
708+ </head>
709+
710+ <%!
711+ def amount(text):
712+ # replace by a non-breaking hyphen (it will not word-wrap between hyphen and numbers)
713+ return text.replace('-', '&#8209;')
714+ %>
715+ <body>
716+ <%setLang(user.lang)%>
717+
718+ <div class="act_as_table data_table">
719+ <div class="act_as_row labels">
720+ <div class="act_as_cell">${_('Chart of Account')}</div>
721+ <div class="act_as_cell">${_('Fiscal Year')}</div>
722+ <div class="act_as_cell">
723+ %if filter_form(data) == 'filter_date':
724+ ${_('Dates Filter')}
725+ %else:
726+ ${_('Periods Filter')}
727+ %endif
728+ </div>
729+ <div class="act_as_cell">${_('Clearance Date')}</div>
730+ <div class="act_as_cell">${_('Accounts Filter')}</div>
731+ <div class="act_as_cell">${_('Target Moves')}</div>
732+
733+ </div>
734+ <div class="act_as_row">
735+ <div class="act_as_cell">${ chart_account.name }</div>
736+ <div class="act_as_cell">${ fiscalyear.name if fiscalyear else '-' }</div>
737+ <div class="act_as_cell">
738+ ${_('From:')}
739+ %if filter_form(data) == 'filter_date':
740+ ${formatLang(start_date, date=True) if start_date else u'' }
741+ %else:
742+ ${start_period.name if start_period else u''}
743+ %endif
744+ ${_('To:')}
745+ %if filter_form(data) == 'filter_date':
746+ ${ formatLang(stop_date, date=True) if stop_date else u'' }
747+ %else:
748+ ${stop_period.name if stop_period else u'' }
749+ %endif
750+ </div>
751+ <div class="act_as_cell">${ formatLang(date_until, date=True) }</div>
752+ <div class="act_as_cell">
753+ %if partner_ids:
754+ ${_('Custom Filter')}
755+ %else:
756+ ${ display_partner_account(data) }
757+ %endif
758+ </div>
759+ <div class="act_as_cell">${ display_target_move(data) }</div>
760+ </div>
761+ </div>
762+ %for acc in objects:
763+ %if acc.aged_lines:
764+ <div class="account_title bg" style="width: 1080px; margin-top: 20px; font-size: 12px;">${acc.code} - ${acc.name}</div>
765+
766+
767+
768+ <div class="act_as_table list_table" style="margin-top: 5px;">
769+ <div class="act_as_thead">
770+ <div class="act_as_row labels">
771+ ## partner
772+ <div class="act_as_cell first_column" style="width: 60px;">${_('Partner')}</div>
773+ ## code
774+ <div class="act_as_cell" style="width: 70px;">${_('code')}</div>
775+ ## balance
776+ <div class="act_as_cell classif_title" style="width: 70px;">${_('balance')}</div>
777+ ## Classifications
778+ %for title in ranges_titles:
779+ <div class="act_as_cell classif classif_title">${title}</div>
780+ %endfor
781+ </div>
782+ </div>
783+ <div class="act_as_tbody">
784+ %for partner_name, p_id, p_ref, p_name in acc.partners_order:
785+ %if acc.aged_lines.get(p_id):
786+ <div class="act_as_row lines">
787+ <%line = acc.aged_lines[p_id]%>
788+ <%percents = acc.aged_percents%>
789+ <%totals = acc.aged_totals%>
790+ <div class="act_as_cell first_column">${partner_name}</div>
791+ <div class="act_as_cell">${p_ref or ''}</div>
792+
793+ <div class="act_as_cell amount">${formatLang(line.get('balance') or 0.0) | amount}</div>
794+ %for classif in ranges:
795+ <div class="act_as_cell classif amount">
796+ ${formatLang(line['aged_lines'][classif] or 0.0) | amount}
797+ </div>
798+ %endfor
799+ </div>
800+ %endif
801+ %endfor
802+ <div class="act_as_row labels">
803+ <div class="act_as_cell total">${_('Total')}</div>
804+ <div class="act_as_cell"></div>
805+ <div class="act_as_cell amount classif total">${formatLang(totals['balance']) | amount}</div>
806+ %for classif in ranges:
807+ <div class="act_as_cell amount classif total">${formatLang(totals[classif]) | amount}</div>
808+ %endfor
809+ </div>
810+
811+ <div class="act_as_row">
812+ <div class="act_as_cell"><b>${_('Percents')}</b></div>
813+ <div class="act_as_cell"></div>
814+ <div class="act_as_cell"></div>
815+ %for classif in ranges:
816+ <div class="act_as_cell amount percent_line classif">${formatLang(percents[classif]) | amount}%</div>
817+ %endfor
818+ </div>
819+ </div>
820+ <br/>
821+
822+ %endif
823+ %endfor
824+ </div>
825+ </body>
826+</html>
827
828=== modified file 'account_financial_report_webkit/report/templates/open_invoices_inclusion.mako.html'
829--- account_financial_report_webkit/report/templates/open_invoices_inclusion.mako.html 2013-11-21 15:55:29 +0000
830+++ account_financial_report_webkit/report/templates/open_invoices_inclusion.mako.html 2014-03-18 15:55:27 +0000
831@@ -9,7 +9,7 @@
832 %>
833
834 <div class="account_title bg" style="width: 1080px; margin-top: 20px; font-size: 12px;">${account.code} - ${account.name}</div>
835-
836+
837 %for partner_name, p_id, p_ref, p_name in account.partners_order:
838 <%
839 total_debit = 0.0
840@@ -18,7 +18,7 @@
841 cumul_balance_curr = 0.0
842
843 part_cumul_balance = 0.0
844- part_cumul_balance_curr = 0.0
845+ part_cumul_balance_curr = 0.0
846 %>
847 <div class="act_as_table list_table" style="margin-top: 5px;">
848 <div class="act_as_caption account_title">
849
850=== modified file 'account_financial_report_webkit/report/webkit_parser_header_fix.py'
851--- account_financial_report_webkit/report/webkit_parser_header_fix.py 2014-01-14 09:37:20 +0000
852+++ account_financial_report_webkit/report/webkit_parser_header_fix.py 2014-03-18 15:55:27 +0000
853@@ -160,7 +160,6 @@
854 # override needed to keep the attachments' storing procedure
855 def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
856 """generate the PDF"""
857-
858 if context is None:
859 context={}
860 htmls = []
861
862=== modified file 'account_financial_report_webkit/report_menus.xml'
863--- account_financial_report_webkit/report_menus.xml 2014-01-13 09:33:02 +0000
864+++ account_financial_report_webkit/report_menus.xml 2014-03-18 15:55:27 +0000
865@@ -18,6 +18,10 @@
866 parent="account.next_id_22" action="action_account_partner_balance_menu_webkit"
867 groups="account.group_account_manager,account.group_account_user" id="account.menu_account_partner_balance_report"/>
868
869+ <menuitem icon="STOCK_PRINT" name="Aged Partner Balance"
870+ parent="account.next_id_22" action="action_account_aged_trial_balance_menu_webkit"
871+ groups="account.group_account_manager,account.group_account_user" id="account.menu_aged_trial_balance"/>
872+
873 <menuitem icon="STOCK_PRINT" name="Open Invoices"
874 parent="account.next_id_22" action="action_account_open_invoices_menu_webkit"
875 groups="account.group_account_manager,account.group_account_user" id="menu_account_open_invoices"/>
876
877=== added file 'account_financial_report_webkit/tests/aged_trial_balance.yml'
878--- account_financial_report_webkit/tests/aged_trial_balance.yml 1970-01-01 00:00:00 +0000
879+++ account_financial_report_webkit/tests/aged_trial_balance.yml 2014-03-18 15:55:27 +0000
880@@ -0,0 +1,60 @@
881+-
882+ In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with default setting
883+-
884+ !python {model: account.account}: |
885+ from datetime import datetime
886+ ctx={}
887+ data_dict = {'chart_account_id':ref('account.chart0'), 'until_date': '%s-12-31' %(datetime.now().year)}
888+ from tools import test_reports
889+ test_reports.try_report_action(cr, uid, 'action_account_aged_trial_balance_menu_webkit',wiz_data=data_dict, context=ctx, our_module='account_financial_report_webkit')
890+
891+-
892+ In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filters and currency
893+-
894+ !python {model: account.account}: |
895+ from datetime import datetime
896+ ctx={}
897+ data_dict = {'chart_account_id':ref('account.chart0'), 'fiscalyear_id': ref('account.data_fiscalyear'),
898+ 'until_date': '%s-12-31' %(datetime.now().year), 'target_move': 'posted',
899+ 'amount_currency': True, 'result_selection': 'customer_supplier'}
900+ from tools import test_reports
901+ test_reports.try_report_action(cr, uid, 'action_account_aged_trial_balance_menu_webkit',wiz_data=data_dict, context=ctx, our_module='account_financial_report_webkit')
902+
903+-
904+ In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filters on partners
905+-
906+ !python {model: account.account}: |
907+ from datetime import datetime
908+ ctx={}
909+ data_dict = {'chart_account_id':ref('account.chart0'), 'fiscalyear_id': ref('account.data_fiscalyear'),
910+ 'until_date': '%s-12-31' %(datetime.now().year), 'target_move': 'posted',
911+ 'amount_currency': True, 'result_selection': 'customer_supplier',
912+ 'partner_ids': [ref('base.res_partner_2'), ref('base.res_partner_1')]}
913+ from tools import test_reports
914+ test_reports.try_report_action(cr, uid, 'action_account_aged_trial_balance_menu_webkit',wiz_data=data_dict, context=ctx, our_module='account_financial_report_webkit')
915+
916+-
917+ In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filters on periods
918+-
919+ !python {model: account.account}: |
920+ from datetime import datetime
921+ ctx={}
922+ data_dict = {'chart_account_id':ref('account.chart0'), 'fiscalyear_id': ref('account.data_fiscalyear'),
923+ 'until_date': '%s-12-31' %(datetime.now().year), 'target_move': 'posted',
924+ 'amount_currency': True, 'result_selection': 'customer_supplier',
925+ 'filter': 'filter_period', 'period_from': ref('account.period_1'), 'period_to': ref('account.period_12')}
926+ from tools import test_reports
927+ test_reports.try_report_action(cr, uid, 'action_account_aged_trial_balance_menu_webkit',wiz_data=data_dict, context=ctx, our_module='account_financial_report_webkit')
928+
929+-
930+ In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filters on dates
931+-
932+ !python {model: account.account}: |
933+ from datetime import datetime
934+ ctx={}
935+ data_dict = {'chart_account_id':ref('account.chart0'), 'fiscalyear_id': ref('account.data_fiscalyear'),
936+ 'until_date': '%s-12-31' %(datetime.now().year), 'target_move': 'posted',
937+ 'amount_currency': True, 'result_selection': 'customer_supplier',
938+ 'filter': 'filter_date', 'date_from': '%s-01-01' %(datetime.now().year), 'date_to': '%s-12-31' %(datetime.now().year)}
939+ from tools import test_reports
940+ test_reports.try_report_action(cr, uid, 'action_account_aged_trial_balance_menu_webkit',wiz_data=data_dict, context=ctx, our_module='account_financial_report_webkit')
941
942=== modified file 'account_financial_report_webkit/wizard/__init__.py'
943--- account_financial_report_webkit/wizard/__init__.py 2013-09-12 20:53:27 +0000
944+++ account_financial_report_webkit/wizard/__init__.py 2014-03-18 15:55:27 +0000
945@@ -27,3 +27,4 @@
946 from . import partner_balance_wizard
947 from . import open_invoices_wizard
948 from . import print_journal
949+from . import aged_partner_balance_wizard
950
951=== added file 'account_financial_report_webkit/wizard/aged_partner_balance_wizard.py'
952--- account_financial_report_webkit/wizard/aged_partner_balance_wizard.py 1970-01-01 00:00:00 +0000
953+++ account_financial_report_webkit/wizard/aged_partner_balance_wizard.py 2014-03-18 15:55:27 +0000
954@@ -0,0 +1,39 @@
955+# -*- coding: utf-8 -*-
956+##############################################################################
957+#
958+# Author: Nicolas Bessi
959+# Copyright 2014 Camptocamp SA
960+#
961+# This program is free software: you can redistribute it and/or modify
962+# it under the terms of the GNU Affero General Public License as
963+# published by the Free Software Foundation, either version 3 of the
964+# License, or (at your option) any later version.
965+#
966+# This program is distributed in the hope that it will be useful,
967+# but WITHOUT ANY WARRANTY; without even the implied warranty of
968+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
969+# GNU Affero General Public License for more details.
970+#
971+# You should have received a copy of the GNU Affero General Public License
972+# along with this program. If not, see <http://www.gnu.org/licenses/>.
973+#
974+##############################################################################
975+from openerp.osv import orm
976+
977+
978+class AccountAgedTrialBalance(orm.TransientModel):
979+ """Will launch age partner balance report.
980+ This report is based on Open Invoice Report
981+ and share a lot of knowledge with him
982+ """
983+
984+ _inherit = "open.invoices.webkit"
985+ _name = "account.aged.trial.balance.webkit"
986+ _description = "Aged partner balanced"
987+
988+ def _print_report(self, cr, uid, ids, data, context=None):
989+ # we update form with display account value
990+ data = self.pre_print_report(cr, uid, ids, data, context=context)
991+ return {'type': 'ir.actions.report.xml',
992+ 'report_name': 'account.account_aged_trial_balance_webkit',
993+ 'datas': data}
994
995=== added file 'account_financial_report_webkit/wizard/aged_partner_balance_wizard.xml'
996--- account_financial_report_webkit/wizard/aged_partner_balance_wizard.xml 1970-01-01 00:00:00 +0000
997+++ account_financial_report_webkit/wizard/aged_partner_balance_wizard.xml 2014-03-18 15:55:27 +0000
998@@ -0,0 +1,72 @@
999+<?xml version="1.0" encoding="utf-8"?>
1000+<openerp>
1001+ <data>
1002+
1003+ <record id="account_aged_trial_balance_webkit" model="ir.ui.view">
1004+ <field name="name">Aged Partner Balance Report</field>
1005+ <field name="model">account.aged.trial.balance.webkit</field>
1006+ <field name="inherit_id" ref="account.account_common_report_view"/>
1007+ <field name="arch" type="xml">
1008+ <data>
1009+
1010+ <xpath expr="/form/label[@string='']" position="replace">
1011+ <separator string="Aged Partner Balance" colspan="4"/>
1012+ <label nolabel="1"
1013+ colspan="4"
1014+ string="This report list partner open balances and indicate when payment is (or was) supposed to be completed"/>
1015+ </xpath>
1016+ <field name="chart_account_id" position='attributes'>
1017+ <attribute name="colspan">4</attribute>
1018+ </field>
1019+ <xpath expr="//field[@name='target_move']" position="after">
1020+ <newline/>
1021+ <field name="result_selection" colspan="4"/>
1022+ </xpath>
1023+ <xpath expr="/form/notebook[1]" position="after">
1024+ <separator string="Clearance Analysis Options" colspan="4"/>
1025+ <newline/>
1026+ <field name="until_date"/>
1027+ </xpath>
1028+ <page name="filters" position="after">
1029+ <page string="Partners Filters" name="partners">
1030+ <separator string="Print only" colspan="4"/>
1031+ <field name="partner_ids" colspan="4" nolabel="1"/>
1032+ </page>
1033+ </page>
1034+ <page name="filters" position="attributes">
1035+ <attribute name="string">Time Filters</attribute>
1036+ </page>
1037+ <page name="journal_ids" position="attributes">
1038+ <attribute name="invisible">True</attribute>
1039+ </page>
1040+ <field name="fiscalyear_id" position="attributes">
1041+ <attribute name="on_change">onchange_fiscalyear(fiscalyear_id, period_to, date_to, until_date)</attribute>
1042+ </field>
1043+ <field name="date_to" position="attributes">
1044+ <attribute name="on_change">onchange_date_to(fiscalyear_id, period_to, date_to, until_date)</attribute>
1045+ </field>
1046+ <field name="period_to" position="attributes">
1047+ <attribute name="on_change">onchange_period_to(fiscalyear_id, period_to, date_to, until_date)</attribute>
1048+ </field>
1049+ <field name="period_from" position="attributes">
1050+ <attribute name="domain">[('fiscalyear_id', '=', fiscalyear_id), ('special', '=', False)]</attribute>
1051+ </field>
1052+ <field name="period_to" position="attributes">
1053+ <attribute name="domain">[('fiscalyear_id', '=', fiscalyear_id), ('special', '=', False)]</attribute>
1054+ </field>
1055+ </data>
1056+ </field>
1057+ </record>
1058+
1059+ <record id="action_account_aged_trial_balance_menu_webkit"
1060+ model="ir.actions.act_window">
1061+ <field name="name">Aged partner balance</field>
1062+ <field name="type">ir.actions.act_window</field>
1063+ <field name="res_model">account.aged.trial.balance.webkit</field>
1064+ <field name="view_type">form</field>
1065+ <field name="view_mode">form</field>
1066+ <field name="view_id" ref="account_aged_trial_balance_webkit"/>
1067+ <field name="target">new</field>
1068+ </record>
1069+ </data>
1070+</openerp>

Subscribers

People subscribed via source and target branches

to status/vote changes: