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
=== modified file 'account_financial_report_webkit/__openerp__.py'
--- account_financial_report_webkit/__openerp__.py 2014-03-13 10:49:47 +0000
+++ account_financial_report_webkit/__openerp__.py 2014-03-18 15:55:27 +0000
@@ -30,7 +30,7 @@
30 - Partner ledger30 - Partner ledger
31 - Partner balance31 - Partner balance
32 - Open invoices report32 - Open invoices report
3333 - Aged Partner Balance
3434
35Main improvements per report:35Main improvements per report:
36-----------------------------36-----------------------------
@@ -100,6 +100,47 @@
100* Subtotal by account and partner100* Subtotal by account and partner
101* Alphabetical sorting (same as in partner balance)101* Alphabetical sorting (same as in partner balance)
102102
103
104Aged Partner Balance: Summary of aged open amount per partner
105
106This report is an accounting tool helping in various tasks.
107You can credit control or partner balance provisions computation for instance.
108
109The aged balance report allows you to print balances per partner
110like the trial balance but add an extra information :
111
112* It will split balances into due amounts
113 (due date not reached à the end date of the report) and overdue amounts
114 Overdue data are also split by period.
115* For each partner following columns will be displayed:
116
117 * Total balance (all figures must match with same date partner balance report).
118 This column equals the sum of all following columns)
119
120 * Due
121 * Overdue <= 30 days
122 * Overdue <= 60 days
123 * Overdue <= 90 days
124 * Overdue <= 120 days
125 * Older
126
127Hypothesis / Contraints of aged partner balance
128
129* Overdues columns will be by default be based on 30 days range fix number of days.
130 This can be changed by changes the RANGES constraint
131* All data will be displayed in company currency
132* When partial payments, the payment must appear in the same colums than the invoice
133 (Except if multiple payment terms)
134* Data granularity: partner (will not display figures at invoices level)
135* The report aggregate data per account with sub-totals
136* Initial balance must be calculated the same way that
137 the partner balance / Ignoring the opening entry
138 in special period (idem open invoice report)
139* Only accounts with internal type payable or receivable are considered
140 (idem open invoice report)
141* If maturity date is null then use move line date
142
143
103Limitations:144Limitations:
104------------145------------
105146
@@ -126,7 +167,7 @@
126the header and footer are created as text with arguments passed to167the header and footer are created as text with arguments passed to
127wkhtmltopdf. The texts are defined inside the report classes.168wkhtmltopdf. The texts are defined inside the report classes.
128""",169""",
129 'version': '1.0.2',170 'version': '1.1.0',
130 'author': 'Camptocamp',171 'author': 'Camptocamp',
131 'license': 'AGPL-3',172 'license': 'AGPL-3',
132 'category': 'Finance',173 'category': 'Finance',
@@ -147,6 +188,7 @@
147 'wizard/trial_balance_wizard_view.xml',188 'wizard/trial_balance_wizard_view.xml',
148 'wizard/partner_balance_wizard_view.xml',189 'wizard/partner_balance_wizard_view.xml',
149 'wizard/open_invoices_wizard_view.xml',190 'wizard/open_invoices_wizard_view.xml',
191 'wizard/aged_partner_balance_wizard.xml',
150 'wizard/print_journal_view.xml',192 'wizard/print_journal_view.xml',
151 'report_menus.xml',193 'report_menus.xml',
152 ],194 ],
@@ -155,7 +197,8 @@
155 'tests/partner_ledger.yml',197 'tests/partner_ledger.yml',
156 'tests/trial_balance.yml',198 'tests/trial_balance.yml',
157 'tests/partner_balance.yml',199 'tests/partner_balance.yml',
158 'tests/open_invoices.yml',],200 'tests/open_invoices.yml',
201 'tests/aged_trial_balance.yml'],
159 #'tests/account_move_line.yml'202 #'tests/account_move_line.yml'
160 'active': False,203 'active': False,
161 'installable': True,204 'installable': True,
162205
=== modified file 'account_financial_report_webkit/report/__init__.py'
--- account_financial_report_webkit/report/__init__.py 2013-09-12 20:53:27 +0000
+++ account_financial_report_webkit/report/__init__.py 2014-03-18 15:55:27 +0000
@@ -9,3 +9,4 @@
9from . import partner_balance9from . import partner_balance
10from . import open_invoices10from . import open_invoices
11from . import print_journal11from . import print_journal
12from . import aged_partner_balance
1213
=== added file 'account_financial_report_webkit/report/aged_partner_balance.py'
--- account_financial_report_webkit/report/aged_partner_balance.py 1970-01-01 00:00:00 +0000
+++ account_financial_report_webkit/report/aged_partner_balance.py 2014-03-18 15:55:27 +0000
@@ -0,0 +1,403 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from __future__ import division
22from datetime import datetime
23
24from openerp import pooler
25from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
26from openerp.tools.translate import _
27from .open_invoices import PartnersOpenInvoicesWebkit
28from .webkit_parser_header_fix import HeaderFooterTextWebKitParser
29
30
31def make_ranges(top, offset):
32 """Return sorted days ranges
33
34 :param top: maximum overdue day
35 :param offset: offset for ranges
36
37 :returns: list of sorted ranges tuples in days
38 eg. [(-100000, 0), (0, offset), (offset, n*offset), ... (top, 100000)]
39 """
40 ranges = [(n, min(n + offset, top)) for n in xrange(0, top, offset)]
41 ranges.insert(0, (-100000000000, 0))
42 ranges.append((top, 100000000000))
43 return ranges
44
45#list of overdue ranges
46RANGES = make_ranges(120, 30)
47
48
49def make_ranges_titles():
50 """Generates title to be used by mako"""
51 titles = [_('Due')]
52 titles += [_(u'Overdue ≤ %s d.') % x[1] for x in RANGES[1:-1]]
53 titles.append(_('Older'))
54 return titles
55
56#list of overdue ranges title
57RANGES_TITLES = make_ranges_titles()
58#list of payable journal types
59REC_PAY_TYPE = ('purchase', 'sale')
60#list of refund payable type
61REFUND_TYPE = ('purchase_refund', 'sale_refund')
62INV_TYPE = REC_PAY_TYPE + REFUND_TYPE
63
64
65class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit):
66 """Compute Aged Partner Balance based on result of Open Invoices"""
67
68 def __init__(self, cursor, uid, name, context=None):
69 """Constructor, refer to :class:`openerp.report.report_sxw.rml_parse`"""
70 super(AccountAgedTrialBalanceWebkit, self).__init__(cursor, uid, name,
71 context=context)
72 self.pool = pooler.get_pool(self.cr.dbname)
73 self.cursor = self.cr
74 company = self.pool.get('res.users').browse(self.cr, uid, uid,
75 context=context).company_id
76
77 header_report_name = ' - '.join((_('Aged Partner Balance'),
78 company.currency_id.name))
79
80 footer_date_time = self.formatLang(str(datetime.today()),
81 date_time=True)
82
83 self.localcontext.update({
84 'cr': cursor,
85 'uid': uid,
86 'company': company,
87 'ranges': self._get_ranges(),
88 'ranges_titles': self._get_ranges_titles(),
89 'report_name': _('Aged Partner Balance'),
90 'additional_args': [
91 ('--header-font-name', 'Helvetica'),
92 ('--footer-font-name', 'Helvetica'),
93 ('--header-font-size', '10'),
94 ('--footer-font-size', '6'),
95 ('--header-left', header_report_name),
96 ('--header-spacing', '2'),
97 ('--footer-left', footer_date_time),
98 ('--footer-right', ' '.join((_('Page'), '[page]', _('of'), '[topage]'))),
99 ('--footer-line',),
100 ],
101 })
102
103 def _get_ranges(self):
104 """:returns: :cons:`RANGES`"""
105 return RANGES
106
107 def _get_ranges_titles(self):
108 """:returns: :cons: `RANGES_TITLES`"""
109 return RANGES_TITLES
110
111 def set_context(self, objects, data, ids, report_type=None):
112 """Populate aged_lines, aged_balance, aged_percents attributes
113
114 on each account browse record that will be used by mako template
115 The browse record are store in :attr:`objects`
116
117 The computation are based on the ledger_lines attribute set on account
118 contained by :attr:`objects`
119
120 :attr:`objects` values were previously set by parent class
121 :class: `.open_invoices.PartnersOpenInvoicesWebkit`
122
123 :returns: parent :class:`.open_invoices.PartnersOpenInvoicesWebkit`
124 call to set_context
125
126 """
127 res = super(AccountAgedTrialBalanceWebkit, self).set_context(
128 objects,
129 data,
130 ids,
131 report_type=report_type
132 )
133
134 for acc in self.objects:
135 acc.aged_lines = {}
136 acc.agged_totals = {}
137 acc.agged_percents = {}
138 for part_id, partner_lines in acc.ledger_lines.items():
139 aged_lines = self.compute_aged_lines(part_id,
140 partner_lines,
141 data)
142 if aged_lines:
143 acc.aged_lines[part_id] = aged_lines
144 acc.aged_totals = totals = self.compute_totals(acc.aged_lines.values())
145 acc.aged_percents = self.compute_percents(totals)
146 #Free some memory
147 del(acc.ledger_lines)
148 return res
149
150 def compute_aged_lines(self, partner_id, ledger_lines, data):
151 """Add property aged_lines to accounts browse records
152
153 contained in :attr:`objects` for a given partner
154
155 :param: partner_id: current partner
156 :param ledger_lines: generated by parent
157 :class:`.open_invoices.PartnersOpenInvoicesWebkit`
158
159 :returns: dict of computed aged lines
160 eg {'balance': 1000.0,
161 'aged_lines': {(90, 120): 0.0, ...}
162
163 """
164 lines_to_age = self.filter_lines(partner_id, ledger_lines)
165 res = {}
166 end_date = self._get_end_date(data)
167 aged_lines = dict.fromkeys(RANGES, 0.0)
168 reconcile_lookup = self.get_reconcile_count_lookup(lines_to_age)
169 res['aged_lines'] = aged_lines
170 for line in lines_to_age:
171 compute_method = self.get_compute_method(reconcile_lookup,
172 partner_id,
173 line)
174 delay = compute_method(line, end_date, ledger_lines)
175 classification = self.classify_line(partner_id, delay)
176 aged_lines[classification] += line['debit'] - line['credit']
177 self.compute_balance(res, aged_lines)
178 return res
179
180 def _get_end_date(self, data):
181 """Retrieve end date to be used to compute delay.
182
183 :param data: data dict send to report contains form dict
184
185 :returns: end date to be used to compute overdue delay
186
187 """
188 end_date = None
189 date_to = data['form']['date_to']
190 period_to_id = data['form']['period_to']
191 fiscal_to_id = data['form']['fiscalyear_id']
192 if date_to:
193 end_date = date_to
194 elif period_to_id:
195 period_to = self.pool['account.period'].browse(self.cr,
196 self.uid,
197 period_to_id)
198 end_date = period_to.date_stop
199 elif fiscal_to_id:
200 fiscal_to = self.pool['account.fiscalyear'].browse(self.cr,
201 self.uid,
202 fiscal_to_id)
203 end_date = fiscal_to.date_stop
204 else:
205 raise ValueError('End date and end period not available')
206 return end_date
207
208 def _compute_delay_from_key(self, key, line, end_date):
209 """Compute overdue delay delta in days for line using attribute in key
210
211 delta = end_date - date of key
212
213 :param line: current ledger line
214 :param key: date key to be used to compute delta
215 :param end_date: end_date computed for wizard data
216
217 :returns: delta in days
218 """
219 from_date = datetime.strptime(line[key], DEFAULT_SERVER_DATE_FORMAT)
220 end_date = datetime.strptime(end_date, DEFAULT_SERVER_DATE_FORMAT)
221 delta = end_date - from_date
222 return delta.days
223
224 def compute_delay_from_maturity(self, line, end_date, ledger_lines):
225 """Compute overdue delay delta in days for line using attribute in key
226
227 delta = end_date - maturity date
228
229 :param line: current ledger line
230 :param end_date: end_date computed for wizard data
231 :param ledger_lines: generated by parent
232 :class:`.open_invoices.PartnersOpenInvoicesWebkit`
233
234 :returns: delta in days
235 """
236 return self._compute_delay_from_key('date_maturity',
237 line,
238 end_date)
239
240 def compute_delay_from_date(self, line, end_date, ledger_lines):
241 """Compute overdue delay delta in days for line using attribute in key
242
243 delta = end_date - date
244
245 :param line: current ledger line
246 :param end_date: end_date computed for wizard data
247 :param ledger_lines: generated by parent
248 :class:`.open_invoices.PartnersOpenInvoicesWebkit`
249
250 :returns: delta in days
251 """
252 return self._compute_delay_from_key('ldate',
253 line,
254 end_date)
255
256 def compute_delay_from_partial_rec(self, line, end_date, ledger_lines):
257 """Compute overdue delay delta in days for the case where move line
258
259 is related to a partial reconcile with more than one reconcile line
260
261 :param line: current ledger line
262 :param end_date: end_date computed for wizard data
263 :param ledger_lines: generated by parent
264 :class:`.open_invoices.PartnersOpenInvoicesWebkit`
265
266 :returns: delta in days
267 """
268 sale_lines = [x for x in ledger_lines if x['jtype'] in REC_PAY_TYPE and
269 line['rec_id'] == x['rec_id']]
270 refund_lines = [x for x in ledger_lines if x['jtype'] in REFUND_TYPE and
271 line['rec_id'] == x['rec_id']]
272 if len(sale_lines) == 1:
273 reference_line = sale_lines[0]
274 elif len(refund_lines) == 1:
275 reference_line = refund_lines[0]
276 else:
277 reference_line = line
278 key = 'date_maturity' if reference_line.get('date_maturity') else 'ldate'
279 return self._compute_delay_from_key(key,
280 reference_line,
281 end_date)
282
283 def get_compute_method(self, reconcile_lookup, partner_id, line):
284 """Get the function that should compute the delay for a given line
285
286 :param reconcile_lookup: dict of reconcile group by id and count
287 {rec_id: count of line related to reconcile}
288 :param partner_id: current partner_id
289 :param line: current ledger line generated by parent
290 :class:`.open_invoices.PartnersOpenInvoicesWebkit`
291
292 :returns: function bounded to :class:`.AccountAgedTrialBalanceWebkit`
293
294 """
295 if reconcile_lookup.get(line['rec_id'], 0.0) > 1:
296 return self.compute_delay_from_partial_rec
297 elif line['jtype'] in INV_TYPE and line.get('date_maturity'):
298 return self.compute_delay_from_maturity
299 else:
300 return self.compute_delay_from_date
301
302 def line_is_valid(self, partner_id, line):
303 """Predicate hook that allows to filter line to be treated
304
305 :param partner_id: current partner_id
306 :param line: current ledger line generated by parent
307 :class:`.open_invoices.PartnersOpenInvoicesWebkit`
308
309 :returns: boolean True if line is allowed
310 """
311 return True
312
313 def filter_lines(self, partner_id, lines):
314 """Filter ledger lines that have to be treated
315
316 :param partner_id: current partner_id
317 :param lines: ledger_lines related to current partner
318 and generated by parent
319 :class:`.open_invoices.PartnersOpenInvoicesWebkit`
320
321 :returns: list of allowed lines
322
323 """
324 return [x for x in lines if self.line_is_valid(partner_id, x)]
325
326 def classify_line(self, partner_id, overdue_days):
327 """Return the overdue range for a given delay
328
329 We loop from smaller range to higher
330 This should be the most effective solution as generaly
331 customer tend to have one or two month of delay
332
333 :param overdue_days: delay in days
334 :param partner_id: current partner_id
335
336 :returns: the correct range in :const:`RANGES`
337
338 """
339 for drange in RANGES:
340 if overdue_days <= drange[1]:
341 return drange
342 return drange
343
344 def compute_balance(self, res, aged_lines):
345 """Compute the total balance of aged line
346 for given account"""
347 res['balance'] = sum(aged_lines.values())
348
349 def compute_totals(self, aged_lines):
350 """Compute the totals for an account
351
352 :param aged_lines: dict of aged line taken from the
353 property added to account record
354
355 :returns: dict of total {'balance':1000.00, (30, 60): 3000,...}
356
357 """
358 totals = {}
359 totals['balance'] = sum(x.get('balance', 0.0) for
360 x in aged_lines)
361 aged_ranges = [x.get('aged_lines', {}) for x in aged_lines]
362 for drange in RANGES:
363 totals[drange] = sum(x.get(drange, 0.0) for x in aged_ranges)
364 return totals
365
366 def compute_percents(self, totals):
367 percents = {}
368 base = totals['balance'] or 1.0
369 for drange in RANGES:
370 percents[drange] = (totals[drange] / base) * 100.0
371 return percents
372
373 def get_reconcile_count_lookup(self, lines):
374 """Compute an lookup dict
375
376 It contains has partial reconcile id as key and the count of lines
377 related to the reconcile id
378
379 :param: a list of ledger lines generated by parent
380 :class:`.open_invoices.PartnersOpenInvoicesWebkit`
381
382 :retuns: lookup dict {ṛec_id: count}
383
384 """
385 # possible bang if l_ids is really long.
386 # We have the same weakness in common_report ...
387 # but it seems not really possible for a partner
388 # So I'll keep that option.
389 l_ids = tuple(x['id'] for x in lines)
390 sql = ("SELECT reconcile_partial_id, COUNT(*) FROM account_move_line"
391 " WHERE reconcile_partial_id IS NOT NULL"
392 " AND id in %s"
393 " GROUP BY reconcile_partial_id")
394 self.cr.execute(sql, (l_ids,))
395 res = self.cr.fetchall()
396 return dict((x[0], x[1]) for x in res)
397
398HeaderFooterTextWebKitParser(
399 'report.account.account_aged_trial_balance_webkit',
400 'account.account',
401 'addons/account_financial_report_webkit/report/templates/aged_trial_webkit.mako',
402 parser=AccountAgedTrialBalanceWebkit,
403)
0404
=== modified file 'account_financial_report_webkit/report/common_reports.py'
--- account_financial_report_webkit/report/common_reports.py 2013-12-17 16:16:37 +0000
+++ account_financial_report_webkit/report/common_reports.py 2014-03-18 15:55:27 +0000
@@ -30,7 +30,7 @@
3030
31_logger = logging.getLogger('financial.reports.webkit')31_logger = logging.getLogger('financial.reports.webkit')
3232
3333MAX_MONSTER_SLICE = 50000
34class CommonReportHeaderWebkit(common_report_header):34class CommonReportHeaderWebkit(common_report_header):
35 """Define common helper for financial report"""35 """Define common helper for financial report"""
3636
@@ -433,6 +433,14 @@
433 raise osv.except_osv(_('No valid filter'), _('Please set a valid time filter'))433 raise osv.except_osv(_('No valid filter'), _('Please set a valid time filter'))
434434
435 def _get_move_line_datas(self, move_line_ids, order='per.special DESC, l.date ASC, per.date_start ASC, m.name ASC'):435 def _get_move_line_datas(self, move_line_ids, order='per.special DESC, l.date ASC, per.date_start ASC, m.name ASC'):
436 # Possible bang if move_line_ids is too long
437 # We can not slice here as we have to do the sort.
438 # If slice has to be done it means that we have to reorder in python
439 # after all is finished. That quite crapy...
440 # We have a defective desing here (mea culpa) that should be fixed
441 #
442 # TODO improve that by making a better domain or if not possible
443 # by using python sort
436 if not move_line_ids:444 if not move_line_ids:
437 return []445 return []
438 if not isinstance(move_line_ids, list):446 if not isinstance(move_line_ids, list):
@@ -441,6 +449,7 @@
441SELECT l.id AS id,449SELECT l.id AS id,
442 l.date AS ldate,450 l.date AS ldate,
443 j.code AS jcode ,451 j.code AS jcode ,
452 j.type AS jtype,
444 l.currency_id,453 l.currency_id,
445 l.account_id,454 l.account_id,
446 l.amount_currency,455 l.amount_currency,
@@ -455,7 +464,8 @@
455 l.partner_id AS lpartner_id,464 l.partner_id AS lpartner_id,
456 p.name AS partner_name,465 p.name AS partner_name,
457 m.name AS move_name,466 m.name AS move_name,
458 COALESCE(partialrec.name, fullrec.name, '') AS rec_name,467 COALESCE(partialrec.name, fullrec.name, '') AS rec_name,
468 COALESCE(partialrec.id, fullrec.id, NULL) AS rec_id,
459 m.id AS move_id,469 m.id AS move_id,
460 c.name AS currency_code,470 c.name AS currency_code,
461 i.id AS invoice_id,471 i.id AS invoice_id,
462472
=== modified file 'account_financial_report_webkit/report/open_invoices.py'
--- account_financial_report_webkit/report/open_invoices.py 2013-11-03 12:55:27 +0000
+++ account_financial_report_webkit/report/open_invoices.py 2014-03-18 15:55:27 +0000
@@ -93,7 +93,6 @@
93 """Populate a ledger_lines attribute on each browse record that will be used93 """Populate a ledger_lines attribute on each browse record that will be used
94 by mako template"""94 by mako template"""
95 new_ids = data['form']['chart_account_id']95 new_ids = data['form']['chart_account_id']
96
97 # Account initial balance memoizer96 # Account initial balance memoizer
98 init_balance_memoizer = {}97 init_balance_memoizer = {}
99 # Reading form98 # Reading form
10099
=== modified file 'account_financial_report_webkit/report/report.xml'
--- account_financial_report_webkit/report/report.xml 2013-12-16 09:37:19 +0000
+++ account_financial_report_webkit/report/report.xml 2014-03-18 15:55:27 +0000
@@ -14,23 +14,16 @@
14 <field name="name">General Ledger Webkit</field>14 <field name="name">General Ledger Webkit</field>
15 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_general_ledger.mako</field>15 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_general_ledger.mako</field>
16 <field name="report_file">account_financial_report_webkit/report/templates/account_report_general_ledger.mako</field>16 <field name="report_file">account_financial_report_webkit/report/templates/account_report_general_ledger.mako</field>
17 </record> 17 </record>
18
18 <record id="property_account_report_general_ledger_webkit" model="ir.property">19 <record id="property_account_report_general_ledger_webkit" model="ir.property">
19 <field name="name">account_report_general_ledger_webkit</field>20 <field name="name">account_report_general_ledger_webkit</field>
20 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>21 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
21 <field eval="'ir.header_webkit,'+str(ref('account_financial_report_webkit.financial_landscape_header'))" model="ir.header_webkit" name="value"/>22 <field eval="'ir.header_webkit,'+str(ref('account_financial_report_webkit.financial_landscape_header'))" model="ir.header_webkit" name="value"/>
22 <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"/>23 <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"/>
23 </record>24 </record>
24 <!-- waiting the fix 25
25 <report auto="False" 26 <!-- we do not use report tag has we can not set header ref -->
26 id="account_report_partner_ledger_webkit"
27 model="account.account"
28 name="account.account_report_partner_ledger_webkit"
29 file="account_financial_report_webkit/report/templates/account_report_partner_ledger.mako"
30 string="General Ledger Webkit"
31 report_type="webkit"/> -->
32
33 <!-- we do not use report tag has we can not set header ref -->
34 <record id="account_report_partners_ledger_webkit" model="ir.actions.report.xml">27 <record id="account_report_partners_ledger_webkit" model="ir.actions.report.xml">
35 <field name="report_type">webkit</field>28 <field name="report_type">webkit</field>
36 <field name="report_name">account.account_report_partners_ledger_webkit</field>29 <field name="report_name">account.account_report_partners_ledger_webkit</field>
@@ -44,6 +37,7 @@
44 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_partners_ledger.mako</field>37 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_partners_ledger.mako</field>
45 <field name="report_file">account_financial_report_webkit/report/templates/account_report_partners_ledger.mako</field>38 <field name="report_file">account_financial_report_webkit/report/templates/account_report_partners_ledger.mako</field>
46 </record>39 </record>
40
47 <record id="property_account_report_partners_ledger_webkit" model="ir.property">41 <record id="property_account_report_partners_ledger_webkit" model="ir.property">
48 <field name="name">account_report_partners_ledger_webkit</field>42 <field name="name">account_report_partners_ledger_webkit</field>
49 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>43 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
@@ -64,6 +58,7 @@
64 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_trial_balance.mako</field>58 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_trial_balance.mako</field>
65 <field name="report_file">account_financial_report_webkit/report/templates/account_report_trial_balance.mako</field>59 <field name="report_file">account_financial_report_webkit/report/templates/account_report_trial_balance.mako</field>
66 </record>60 </record>
61
67 <record id="property_account_report_trial_balance_webkit" model="ir.property">62 <record id="property_account_report_trial_balance_webkit" model="ir.property">
68 <field name="name">account_report_trial_balance_webkit</field>63 <field name="name">account_report_trial_balance_webkit</field>
69 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>64 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
@@ -84,6 +79,7 @@
84 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_partner_balance.mako</field>79 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_partner_balance.mako</field>
85 <field name="report_file">account_financial_report_webkit/report/templates/account_report_partner_balance.mako</field>80 <field name="report_file">account_financial_report_webkit/report/templates/account_report_partner_balance.mako</field>
86 </record>81 </record>
82
87 <record id="property_account_report_partner_balance_webkit" model="ir.property">83 <record id="property_account_report_partner_balance_webkit" model="ir.property">
88 <field name="name">account_report_partner_balance_webkit</field>84 <field name="name">account_report_partner_balance_webkit</field>
89 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>85 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
@@ -104,6 +100,7 @@
104 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_open_invoices.mako</field>100 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_open_invoices.mako</field>
105 <field name="report_file">account_financial_report_webkit/report/templates/account_report_open_invoices.mako</field>101 <field name="report_file">account_financial_report_webkit/report/templates/account_report_open_invoices.mako</field>
106 </record>102 </record>
103
107 <record id="property_account_report_open_invoices_webkit" model="ir.property">104 <record id="property_account_report_open_invoices_webkit" model="ir.property">
108 <field name="name">account_report_open_invoices_webkit</field>105 <field name="name">account_report_open_invoices_webkit</field>
109 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>106 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
@@ -111,6 +108,31 @@
111 <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"/>108 <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"/>
112 </record>109 </record>
113110
111 <record id="account_report_aged_trial_blanance_webkit" model="ir.actions.report.xml">
112 <field name="report_type">webkit</field>
113 <field name="report_name">account.account_aged_trial_balance_webkit</field>
114 <field eval="[(6,0,[])]" name="groups_id"/>
115 <field eval="0" name="multi"/>
116 <field eval="0" name="auto"/>
117 <field eval="1" name="header"/>
118 <field name="model">account.account</field>
119 <field name="type">ir.actions.report.xml</field>
120 <field name="name">Aged Partner Balance</field>
121 <field name="report_rml">account_financial_report_webkit/report/templates/aged_trial_webkit.mako</field>
122 <field name="report_file">account_financial_report_webkit/report/templates/aged_trial_webkit.mako</field>
123 </record>
124
125 <record id="property_account_report_aged_trial_balance_webkit" model="ir.property">
126 <field name="name">account_aged_trial_balance_webkit</field>
127 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
128 <field eval="'ir.header_webkit,'+str(ref('account_financial_report_webkit.financial_landscape_header'))"
129 model="ir.header_webkit"
130 name="value"/>
131 <field eval="'ir.actions.report.xml,'+str(ref('account_financial_report_webkit.account_report_aged_trial_blanance_webkit'))"
132 model="ir.actions.report.xml"
133 name="res_id"/>
134 </record>
135
114 <record id="account_report_print_journal_webkit" model="ir.actions.report.xml">136 <record id="account_report_print_journal_webkit" model="ir.actions.report.xml">
115 <field name="report_type">webkit</field>137 <field name="report_type">webkit</field>
116 <field name="report_name">account.account_report_print_journal_webkit</field>138 <field name="report_name">account.account_report_print_journal_webkit</field>
@@ -124,6 +146,7 @@
124 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_print_journal.mako</field>146 <field name="report_rml">account_financial_report_webkit/report/templates/account_report_print_journal.mako</field>
125 <field name="report_file">account_financial_report_webkit/report/templates/account_report_print_journal.mako</field>147 <field name="report_file">account_financial_report_webkit/report/templates/account_report_print_journal.mako</field>
126 </record>148 </record>
149
127 <record id="property_account_report_print_journal_webkit" model="ir.property">150 <record id="property_account_report_print_journal_webkit" model="ir.property">
128 <field name="name">account_report_print_journal_webkit</field>151 <field name="name">account_report_print_journal_webkit</field>
129 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>152 <field name="fields_id" ref="report_webkit.field_ir_act_report_xml_webkit_header"/>
130153
=== added file 'account_financial_report_webkit/report/templates/aged_trial_webkit.mako'
--- account_financial_report_webkit/report/templates/aged_trial_webkit.mako 1970-01-01 00:00:00 +0000
+++ account_financial_report_webkit/report/templates/aged_trial_webkit.mako 2014-03-18 15:55:27 +0000
@@ -0,0 +1,155 @@
1## -*- coding: utf-8 -*-
2<!DOCTYPE html SYSTEM
3"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5 <head>
6 <style type="text/css">
7 .overflow_ellipsis {
8 text-overflow: ellipsis;
9 overflow: hidden;
10 white-space: nowrap;
11 }
12
13 .open_invoice_previous_line {
14 font-style: italic;
15 }
16
17 .percent_line {
18 font-style: italic;
19 }
20
21 .amount {
22 text-align:right;
23 }
24
25 .classif_title {
26 text-align:right;
27 }
28
29 .classif{
30 width: ${700/len(ranges)}px;
31 }
32 .total{
33 font-weight:bold;
34 }
35 ${css}
36 </style>
37 </head>
38
39 <%!
40 def amount(text):
41 # replace by a non-breaking hyphen (it will not word-wrap between hyphen and numbers)
42 return text.replace('-', '&#8209;')
43 %>
44 <body>
45 <%setLang(user.lang)%>
46
47 <div class="act_as_table data_table">
48 <div class="act_as_row labels">
49 <div class="act_as_cell">${_('Chart of Account')}</div>
50 <div class="act_as_cell">${_('Fiscal Year')}</div>
51 <div class="act_as_cell">
52 %if filter_form(data) == 'filter_date':
53 ${_('Dates Filter')}
54 %else:
55 ${_('Periods Filter')}
56 %endif
57 </div>
58 <div class="act_as_cell">${_('Clearance Date')}</div>
59 <div class="act_as_cell">${_('Accounts Filter')}</div>
60 <div class="act_as_cell">${_('Target Moves')}</div>
61
62 </div>
63 <div class="act_as_row">
64 <div class="act_as_cell">${ chart_account.name }</div>
65 <div class="act_as_cell">${ fiscalyear.name if fiscalyear else '-' }</div>
66 <div class="act_as_cell">
67 ${_('From:')}
68 %if filter_form(data) == 'filter_date':
69 ${formatLang(start_date, date=True) if start_date else u'' }
70 %else:
71 ${start_period.name if start_period else u''}
72 %endif
73 ${_('To:')}
74 %if filter_form(data) == 'filter_date':
75 ${ formatLang(stop_date, date=True) if stop_date else u'' }
76 %else:
77 ${stop_period.name if stop_period else u'' }
78 %endif
79 </div>
80 <div class="act_as_cell">${ formatLang(date_until, date=True) }</div>
81 <div class="act_as_cell">
82 %if partner_ids:
83 ${_('Custom Filter')}
84 %else:
85 ${ display_partner_account(data) }
86 %endif
87 </div>
88 <div class="act_as_cell">${ display_target_move(data) }</div>
89 </div>
90 </div>
91 %for acc in objects:
92 %if acc.aged_lines:
93 <div class="account_title bg" style="width: 1080px; margin-top: 20px; font-size: 12px;">${acc.code} - ${acc.name}</div>
94
95
96
97 <div class="act_as_table list_table" style="margin-top: 5px;">
98 <div class="act_as_thead">
99 <div class="act_as_row labels">
100 ## partner
101 <div class="act_as_cell first_column" style="width: 60px;">${_('Partner')}</div>
102 ## code
103 <div class="act_as_cell" style="width: 70px;">${_('code')}</div>
104 ## balance
105 <div class="act_as_cell classif_title" style="width: 70px;">${_('balance')}</div>
106 ## Classifications
107 %for title in ranges_titles:
108 <div class="act_as_cell classif classif_title">${title}</div>
109 %endfor
110 </div>
111 </div>
112 <div class="act_as_tbody">
113 %for partner_name, p_id, p_ref, p_name in acc.partners_order:
114 %if acc.aged_lines.get(p_id):
115 <div class="act_as_row lines">
116 <%line = acc.aged_lines[p_id]%>
117 <%percents = acc.aged_percents%>
118 <%totals = acc.aged_totals%>
119 <div class="act_as_cell first_column">${partner_name}</div>
120 <div class="act_as_cell">${p_ref or ''}</div>
121
122 <div class="act_as_cell amount">${formatLang(line.get('balance') or 0.0) | amount}</div>
123 %for classif in ranges:
124 <div class="act_as_cell classif amount">
125 ${formatLang(line['aged_lines'][classif] or 0.0) | amount}
126 </div>
127 %endfor
128 </div>
129 %endif
130 %endfor
131 <div class="act_as_row labels">
132 <div class="act_as_cell total">${_('Total')}</div>
133 <div class="act_as_cell"></div>
134 <div class="act_as_cell amount classif total">${formatLang(totals['balance']) | amount}</div>
135 %for classif in ranges:
136 <div class="act_as_cell amount classif total">${formatLang(totals[classif]) | amount}</div>
137 %endfor
138 </div>
139
140 <div class="act_as_row">
141 <div class="act_as_cell"><b>${_('Percents')}</b></div>
142 <div class="act_as_cell"></div>
143 <div class="act_as_cell"></div>
144 %for classif in ranges:
145 <div class="act_as_cell amount percent_line classif">${formatLang(percents[classif]) | amount}%</div>
146 %endfor
147 </div>
148 </div>
149 <br/>
150
151 %endif
152 %endfor
153 </div>
154 </body>
155</html>
0156
=== modified file 'account_financial_report_webkit/report/templates/open_invoices_inclusion.mako.html'
--- account_financial_report_webkit/report/templates/open_invoices_inclusion.mako.html 2013-11-21 15:55:29 +0000
+++ account_financial_report_webkit/report/templates/open_invoices_inclusion.mako.html 2014-03-18 15:55:27 +0000
@@ -9,7 +9,7 @@
9 %>9 %>
1010
11 <div class="account_title bg" style="width: 1080px; margin-top: 20px; font-size: 12px;">${account.code} - ${account.name}</div>11 <div class="account_title bg" style="width: 1080px; margin-top: 20px; font-size: 12px;">${account.code} - ${account.name}</div>
12 12
13 %for partner_name, p_id, p_ref, p_name in account.partners_order:13 %for partner_name, p_id, p_ref, p_name in account.partners_order:
14 <%14 <%
15 total_debit = 0.015 total_debit = 0.0
@@ -18,7 +18,7 @@
18 cumul_balance_curr = 0.018 cumul_balance_curr = 0.0
1919
20 part_cumul_balance = 0.020 part_cumul_balance = 0.0
21 part_cumul_balance_curr = 0.0 21 part_cumul_balance_curr = 0.0
22 %>22 %>
23 <div class="act_as_table list_table" style="margin-top: 5px;">23 <div class="act_as_table list_table" style="margin-top: 5px;">
24 <div class="act_as_caption account_title">24 <div class="act_as_caption account_title">
2525
=== modified file 'account_financial_report_webkit/report/webkit_parser_header_fix.py'
--- account_financial_report_webkit/report/webkit_parser_header_fix.py 2014-01-14 09:37:20 +0000
+++ account_financial_report_webkit/report/webkit_parser_header_fix.py 2014-03-18 15:55:27 +0000
@@ -160,7 +160,6 @@
160 # override needed to keep the attachments' storing procedure160 # override needed to keep the attachments' storing procedure
161 def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):161 def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None):
162 """generate the PDF"""162 """generate the PDF"""
163
164 if context is None:163 if context is None:
165 context={}164 context={}
166 htmls = []165 htmls = []
167166
=== modified file 'account_financial_report_webkit/report_menus.xml'
--- account_financial_report_webkit/report_menus.xml 2014-01-13 09:33:02 +0000
+++ account_financial_report_webkit/report_menus.xml 2014-03-18 15:55:27 +0000
@@ -18,6 +18,10 @@
18 parent="account.next_id_22" action="action_account_partner_balance_menu_webkit"18 parent="account.next_id_22" action="action_account_partner_balance_menu_webkit"
19 groups="account.group_account_manager,account.group_account_user" id="account.menu_account_partner_balance_report"/>19 groups="account.group_account_manager,account.group_account_user" id="account.menu_account_partner_balance_report"/>
2020
21 <menuitem icon="STOCK_PRINT" name="Aged Partner Balance"
22 parent="account.next_id_22" action="action_account_aged_trial_balance_menu_webkit"
23 groups="account.group_account_manager,account.group_account_user" id="account.menu_aged_trial_balance"/>
24
21 <menuitem icon="STOCK_PRINT" name="Open Invoices"25 <menuitem icon="STOCK_PRINT" name="Open Invoices"
22 parent="account.next_id_22" action="action_account_open_invoices_menu_webkit"26 parent="account.next_id_22" action="action_account_open_invoices_menu_webkit"
23 groups="account.group_account_manager,account.group_account_user" id="menu_account_open_invoices"/>27 groups="account.group_account_manager,account.group_account_user" id="menu_account_open_invoices"/>
2428
=== added file 'account_financial_report_webkit/tests/aged_trial_balance.yml'
--- account_financial_report_webkit/tests/aged_trial_balance.yml 1970-01-01 00:00:00 +0000
+++ account_financial_report_webkit/tests/aged_trial_balance.yml 2014-03-18 15:55:27 +0000
@@ -0,0 +1,60 @@
1-
2 In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with default setting
3-
4 !python {model: account.account}: |
5 from datetime import datetime
6 ctx={}
7 data_dict = {'chart_account_id':ref('account.chart0'), 'until_date': '%s-12-31' %(datetime.now().year)}
8 from tools import test_reports
9 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')
10
11-
12 In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filters and currency
13-
14 !python {model: account.account}: |
15 from datetime import datetime
16 ctx={}
17 data_dict = {'chart_account_id':ref('account.chart0'), 'fiscalyear_id': ref('account.data_fiscalyear'),
18 'until_date': '%s-12-31' %(datetime.now().year), 'target_move': 'posted',
19 'amount_currency': True, 'result_selection': 'customer_supplier'}
20 from tools import test_reports
21 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')
22
23-
24 In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filters on partners
25-
26 !python {model: account.account}: |
27 from datetime import datetime
28 ctx={}
29 data_dict = {'chart_account_id':ref('account.chart0'), 'fiscalyear_id': ref('account.data_fiscalyear'),
30 'until_date': '%s-12-31' %(datetime.now().year), 'target_move': 'posted',
31 'amount_currency': True, 'result_selection': 'customer_supplier',
32 'partner_ids': [ref('base.res_partner_2'), ref('base.res_partner_1')]}
33 from tools import test_reports
34 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')
35
36-
37 In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filters on periods
38-
39 !python {model: account.account}: |
40 from datetime import datetime
41 ctx={}
42 data_dict = {'chart_account_id':ref('account.chart0'), 'fiscalyear_id': ref('account.data_fiscalyear'),
43 'until_date': '%s-12-31' %(datetime.now().year), 'target_move': 'posted',
44 'amount_currency': True, 'result_selection': 'customer_supplier',
45 'filter': 'filter_period', 'period_from': ref('account.period_1'), 'period_to': ref('account.period_12')}
46 from tools import test_reports
47 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')
48
49-
50 In order to test the PDF Aged Partner Balance Report webkit wizard I will print report with filters on dates
51-
52 !python {model: account.account}: |
53 from datetime import datetime
54 ctx={}
55 data_dict = {'chart_account_id':ref('account.chart0'), 'fiscalyear_id': ref('account.data_fiscalyear'),
56 'until_date': '%s-12-31' %(datetime.now().year), 'target_move': 'posted',
57 'amount_currency': True, 'result_selection': 'customer_supplier',
58 'filter': 'filter_date', 'date_from': '%s-01-01' %(datetime.now().year), 'date_to': '%s-12-31' %(datetime.now().year)}
59 from tools import test_reports
60 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')
061
=== modified file 'account_financial_report_webkit/wizard/__init__.py'
--- account_financial_report_webkit/wizard/__init__.py 2013-09-12 20:53:27 +0000
+++ account_financial_report_webkit/wizard/__init__.py 2014-03-18 15:55:27 +0000
@@ -27,3 +27,4 @@
27from . import partner_balance_wizard27from . import partner_balance_wizard
28from . import open_invoices_wizard28from . import open_invoices_wizard
29from . import print_journal29from . import print_journal
30from . import aged_partner_balance_wizard
3031
=== added file 'account_financial_report_webkit/wizard/aged_partner_balance_wizard.py'
--- account_financial_report_webkit/wizard/aged_partner_balance_wizard.py 1970-01-01 00:00:00 +0000
+++ account_financial_report_webkit/wizard/aged_partner_balance_wizard.py 2014-03-18 15:55:27 +0000
@@ -0,0 +1,39 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi
5# Copyright 2014 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21from openerp.osv import orm
22
23
24class AccountAgedTrialBalance(orm.TransientModel):
25 """Will launch age partner balance report.
26 This report is based on Open Invoice Report
27 and share a lot of knowledge with him
28 """
29
30 _inherit = "open.invoices.webkit"
31 _name = "account.aged.trial.balance.webkit"
32 _description = "Aged partner balanced"
33
34 def _print_report(self, cr, uid, ids, data, context=None):
35 # we update form with display account value
36 data = self.pre_print_report(cr, uid, ids, data, context=context)
37 return {'type': 'ir.actions.report.xml',
38 'report_name': 'account.account_aged_trial_balance_webkit',
39 'datas': data}
040
=== added file 'account_financial_report_webkit/wizard/aged_partner_balance_wizard.xml'
--- account_financial_report_webkit/wizard/aged_partner_balance_wizard.xml 1970-01-01 00:00:00 +0000
+++ account_financial_report_webkit/wizard/aged_partner_balance_wizard.xml 2014-03-18 15:55:27 +0000
@@ -0,0 +1,72 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="account_aged_trial_balance_webkit" model="ir.ui.view">
6 <field name="name">Aged Partner Balance Report</field>
7 <field name="model">account.aged.trial.balance.webkit</field>
8 <field name="inherit_id" ref="account.account_common_report_view"/>
9 <field name="arch" type="xml">
10 <data>
11
12 <xpath expr="/form/label[@string='']" position="replace">
13 <separator string="Aged Partner Balance" colspan="4"/>
14 <label nolabel="1"
15 colspan="4"
16 string="This report list partner open balances and indicate when payment is (or was) supposed to be completed"/>
17 </xpath>
18 <field name="chart_account_id" position='attributes'>
19 <attribute name="colspan">4</attribute>
20 </field>
21 <xpath expr="//field[@name='target_move']" position="after">
22 <newline/>
23 <field name="result_selection" colspan="4"/>
24 </xpath>
25 <xpath expr="/form/notebook[1]" position="after">
26 <separator string="Clearance Analysis Options" colspan="4"/>
27 <newline/>
28 <field name="until_date"/>
29 </xpath>
30 <page name="filters" position="after">
31 <page string="Partners Filters" name="partners">
32 <separator string="Print only" colspan="4"/>
33 <field name="partner_ids" colspan="4" nolabel="1"/>
34 </page>
35 </page>
36 <page name="filters" position="attributes">
37 <attribute name="string">Time Filters</attribute>
38 </page>
39 <page name="journal_ids" position="attributes">
40 <attribute name="invisible">True</attribute>
41 </page>
42 <field name="fiscalyear_id" position="attributes">
43 <attribute name="on_change">onchange_fiscalyear(fiscalyear_id, period_to, date_to, until_date)</attribute>
44 </field>
45 <field name="date_to" position="attributes">
46 <attribute name="on_change">onchange_date_to(fiscalyear_id, period_to, date_to, until_date)</attribute>
47 </field>
48 <field name="period_to" position="attributes">
49 <attribute name="on_change">onchange_period_to(fiscalyear_id, period_to, date_to, until_date)</attribute>
50 </field>
51 <field name="period_from" position="attributes">
52 <attribute name="domain">[('fiscalyear_id', '=', fiscalyear_id), ('special', '=', False)]</attribute>
53 </field>
54 <field name="period_to" position="attributes">
55 <attribute name="domain">[('fiscalyear_id', '=', fiscalyear_id), ('special', '=', False)]</attribute>
56 </field>
57 </data>
58 </field>
59 </record>
60
61 <record id="action_account_aged_trial_balance_menu_webkit"
62 model="ir.actions.act_window">
63 <field name="name">Aged partner balance</field>
64 <field name="type">ir.actions.act_window</field>
65 <field name="res_model">account.aged.trial.balance.webkit</field>
66 <field name="view_type">form</field>
67 <field name="view_mode">form</field>
68 <field name="view_id" ref="account_aged_trial_balance_webkit"/>
69 <field name="target">new</field>
70 </record>
71 </data>
72</openerp>

Subscribers

People subscribed via source and target branches

to status/vote changes: