Browse Source

[IMP] Improve Aged Partner Balance report

- Add a boolean that allow the user to generate an aged partner balance report with invoice details
- Allow the user to choose the aging method : from Due Date (default) or Invoice Date
pull/118/head
Agathe Mollé 9 years ago
parent
commit
682184f371
  1. 1775
      account_financial_report_webkit/i18n/account_financial_report_webkit.pot
  2. 1133
      account_financial_report_webkit/i18n/fr.po
  3. 79
      account_financial_report_webkit/report/aged_partner_balance.py
  4. 96
      account_financial_report_webkit/report/templates/aged_trial_webkit.mako
  5. 32
      account_financial_report_webkit/wizard/aged_partner_balance_wizard.py
  6. 4
      account_financial_report_webkit/wizard/aged_partner_balance_wizard.xml

1775
account_financial_report_webkit/i18n/account_financial_report_webkit.pot
File diff suppressed because it is too large
View File

1133
account_financial_report_webkit/i18n/fr.po
File diff suppressed because it is too large
View File

79
account_financial_report_webkit/report/aged_partner_balance.py

@ -113,7 +113,8 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit):
return RANGES_TITLES
def set_context(self, objects, data, ids, report_type=None):
"""Populate aged_lines, aged_balance, aged_percents attributes
"""Populate aged_lines, aged_lines_by_invoice, aged_balance,
aged_percents attributes
on each account browse record that will be used by mako template
The browse record are store in :attr:`objects`
@ -134,17 +135,23 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit):
ids,
report_type=report_type
)
self.localcontext.update({
'aging_method': data['form']['aging_method']
})
for acc in self.objects:
acc.aged_lines = {}
acc.aged_lines_by_invoice = {}
acc.agged_totals = {}
acc.agged_percents = {}
for part_id, partner_lines in acc.ledger_lines.items():
aged_lines = self.compute_aged_lines(part_id,
partner_lines,
data)
if aged_lines:
acc.aged_lines[part_id] = aged_lines
partner_aged_lines, invoice_aged_lines = \
self.compute_aged_lines(part_id,
partner_lines,
data)
if partner_aged_lines:
acc.aged_lines[part_id] = partner_aged_lines
if data['form']['detailed_by_invoice']:
acc.aged_lines_by_invoice[part_id] = invoice_aged_lines
acc.aged_totals = totals = self.compute_totals(
acc.aged_lines.values())
acc.aged_percents = self.compute_percents(totals)
@ -161,26 +168,58 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit):
:param ledger_lines: generated by parent
:class:`.open_invoices.PartnersOpenInvoicesWebkit`
:returns: dict of computed aged lines
:returns:
- dict of computed aged lines
eg {'balance': 1000.0,
'aged_lines': {(90, 120): 0.0, ...}
'aged_lines': {(90, 120): 0.0, ...}
}
- dict of computed aged lines by invoice
eg {'SAJ/2015/003': {'balance: 700.0
'aged_lines': {(90, 120): 0.0, ...},
'SAJ/2015/004': {'balance: 300.0
'aged_lines': {(90, 120): 300.0, ...},
}
"""
detailed_by_invoice = data['form']['detailed_by_invoice']
aging_method = data['form']['aging_method']
lines_to_age = self.filter_lines(partner_id, ledger_lines)
res = {}
res_by_partner = {}
res_by_invoice = {}
end_date = self._get_end_date(data)
aged_lines = dict.fromkeys(RANGES, 0.0)
partner_aged_lines = dict.fromkeys(RANGES, 0.0)
reconcile_lookup = self.get_reconcile_count_lookup(lines_to_age)
res['aged_lines'] = aged_lines
res_by_partner['aged_lines'] = partner_aged_lines
for line in lines_to_age:
compute_method = self.get_compute_method(reconcile_lookup,
partner_id,
line)
line,
aging_method)
delay = compute_method(line, end_date, ledger_lines)
classification = self.classify_line(partner_id, delay)
aged_lines[classification] += line['debit'] - line['credit']
self.compute_balance(res, aged_lines)
return res
amount = line['debit'] - line['credit']
partner_aged_lines[classification] += amount
# Populate the aged_lines_by_invoice dictionary if the option has
# been chosen in the wizard
if detailed_by_invoice:
invoice = line['invoice_number']
if invoice not in res_by_invoice:
res_by_invoice[invoice] = {
'aged_lines': dict.fromkeys(RANGES, 0.0),
}
res_by_invoice[invoice][
'aged_lines'][classification] += amount
if detailed_by_invoice:
for invoice in res_by_invoice:
self.compute_balance(
res_by_invoice[invoice],
res_by_invoice[invoice]['aged_lines']
)
self.compute_balance(res_by_partner, partner_aged_lines)
return res_by_partner, res_by_invoice
def _get_end_date(self, data):
"""Retrieve end date to be used to compute delay.
@ -286,7 +325,8 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit):
reference_line,
end_date)
def get_compute_method(self, reconcile_lookup, partner_id, line):
def get_compute_method(self, reconcile_lookup, partner_id, line,
aging_method):
"""Get the function that should compute the delay for a given line
:param reconcile_lookup: dict of reconcile group by id and count
@ -300,7 +340,8 @@ class AccountAgedTrialBalanceWebkit(PartnersOpenInvoicesWebkit):
"""
if reconcile_lookup.get(line['rec_id'], 0.0) > 1:
return self.compute_delay_from_partial_rec
elif line['jtype'] in INV_TYPE and line.get('date_maturity'):
elif line['jtype'] in INV_TYPE and line.get('date_maturity') \
and aging_method == 'due_date':
return self.compute_delay_from_maturity
else:
return self.compute_delay_from_date

96
account_financial_report_webkit/report/templates/aged_trial_webkit.mako

@ -48,6 +48,7 @@
<div class="act_as_row labels" style="page-break-inside: avoid">
<div class="act_as_cell">${_('Chart of Account')}</div>
<div class="act_as_cell">${_('Fiscal Year')}</div>
<div class="act_as_cell">${_('Aged From')}</div>
<div class="act_as_cell">
%if filter_form(data) == 'filter_date':
${_('Dates Filter')}
@ -63,6 +64,13 @@
<div class="act_as_row" style="page-break-inside: avoid">
<div class="act_as_cell">${ chart_account.name }</div>
<div class="act_as_cell">${ fiscalyear.name if fiscalyear else '-' }</div>
<div class="act_as_cell">
%if aging_method == 'due_date':
${_('Due Date')}
%else:
${_('Invoice Date')}
%endif
</div>
<div class="act_as_cell">
${_('From:')}
%if filter_form(data) == 'filter_date':
@ -101,6 +109,10 @@
<div class="act_as_cell first_column" style="width: 60px;">${_('Partner')}</div>
## code
<div class="act_as_cell" style="width: 70px;">${_('code')}</div>
## invoice for detailed reports
%if acc.aged_lines_by_invoice:
<div class="act_as_cell" style="width: 70px;">${_('Invoice')}</div>
%endif
## balance
<div class="act_as_cell classif_title" style="width: 70px;">${_('balance')}</div>
## Classifications
@ -110,27 +122,74 @@
</div>
</div>
<div class="act_as_tbody">
%for partner_name, p_id, p_ref, p_name in acc.partners_order:
%if acc.aged_lines.get(p_id):
<div class="act_as_row lines" style="page-break-inside: avoid">
<%line = acc.aged_lines[p_id]%>
<%percents = acc.aged_percents%>
<%totals = acc.aged_totals%>
<div class="act_as_cell first_column">${partner_name}</div>
<div class="act_as_cell">${p_ref or ''}</div>
%if not acc.aged_lines_by_invoice:
%for partner_name, p_id, p_ref, p_name in acc.partners_order:
%if acc.aged_lines.get(p_id):
<div class="act_as_row lines" style="page-break-inside: avoid">
<%line = acc.aged_lines[p_id]%>
<%percents = acc.aged_percents%>
<%totals = acc.aged_totals%>
<div class="act_as_cell first_column">${partner_name}</div>
<div class="act_as_cell">${p_ref or ''}</div>
<div class="act_as_cell amount">${formatLang(line.get('balance') or 0.0) | amount}</div>
%for classif in ranges:
<div class="act_as_cell classif amount">
${formatLang(line['aged_lines'][classif] or 0.0) | amount}
</div>
%endfor
</div>
%endif
%endfor
<div class="act_as_cell amount">${formatLang(line.get('balance') or 0.0) | amount}</div>
%for classif in ranges:
<div class="act_as_cell classif amount">
${formatLang(line['aged_lines'][classif] or 0.0) | amount}
</div>
%endfor
</div>
%endif
%endfor
%else:
%for partner_name, p_id, p_ref, p_name in acc.partners_order:
%if acc.aged_lines.get(p_id):
<div class="act_as_row lines" style="page-break-inside: avoid">
<%line = acc.aged_lines[p_id]%>
<%percents = acc.aged_percents%>
<%totals = acc.aged_totals%>
<div class="act_as_cell first_column">${partner_name}</div>
<div class="act_as_cell">${p_ref or ''}</div>
<div class="act_as_cell"></div>
<div class="act_as_cell amount"></div>
%for classif in ranges:
<div class="act_as_cell classif amount"></div>
%endfor
</div>
%for invoice in acc.aged_lines_by_invoice[p_id]:
<%invoice_line = acc.aged_lines_by_invoice[p_id][invoice]%>
<div class="act_as_row lines" style="page-break-inside: avoid">
<div class="act_as_cell first_column"></div>
<div class="act_as_cell"></div>
<div class="act_as_cell">${invoice}</div>
<div class="act_as_cell amount">${formatLang(invoice_line.get('balance') or 0.0) | amount}</div>
%for classif in ranges:
<div class="act_as_cell classif amount">
${formatLang(invoice_line['aged_lines'][classif] or 0.0) | amount}
</div>
%endfor
</div>
%endfor
<div class="act_as_row lines" style="page-break-inside: avoid">
<div class="act_as_cell first_column"></div>
<div class="act_as_cell"></div>
<div class="act_as_cell total">Total</div>
<div class="act_as_cell amount total">${formatLang(line.get('balance') or 0.0) | amount}</div>
%for classif in ranges:
<div class="act_as_cell classif amount total">
${formatLang(line['aged_lines'][classif] or 0.0) | amount}
</div>
%endfor
</div>
%endif
%endfor
%endif
<div class="act_as_row labels" style="page-break-inside: avoid">
<div class="act_as_cell total">${_('Total')}</div>
<div class="act_as_cell"></div>
%if acc.aged_lines_by_invoice:
<div class="act_as_cell"></div>
%endif
<div class="act_as_cell amount classif total">${formatLang(totals['balance']) | amount}</div>
%for classif in ranges:
<div class="act_as_cell amount classif total">${formatLang(totals[classif]) | amount}</div>
@ -140,6 +199,9 @@
<div class="act_as_row" style="page-break-inside: avoid">
<div class="act_as_cell"><b>${_('Percents')}</b></div>
<div class="act_as_cell"></div>
%if acc.aged_lines_by_invoice:
<div class="act_as_cell"></div>
%endif
<div class="act_as_cell"></div>
%for classif in ranges:
<div class="act_as_cell amount percent_line classif">${formatLang(percents[classif]) | amount}%</div>

32
account_financial_report_webkit/wizard/aged_partner_balance_wizard.py

@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm
from openerp.osv import orm, fields
class AccountAgedTrialBalance(orm.TransientModel):
@ -31,6 +31,36 @@ class AccountAgedTrialBalance(orm.TransientModel):
_name = "account.aged.trial.balance.webkit"
_description = "Aged partner balanced"
_columns = {
'detailed_by_invoice': fields.boolean(
"Detailed by Invoice",
help="Provide an aged partner balance report with invoice "
"details"
),
'aging_method': fields.selection(
[('due_date', 'Due Date'),
('invoice_date', 'Invoice Date')],
'Aged from',
required=True
),
}
_defaults = {
'aging_method': 'due_date',
}
def pre_print_report(self, cr, uid, ids, data, context=None):
data = super(AccountAgedTrialBalance, self).pre_print_report(
cr, uid, ids, data, context)
# will be used to attach the report on the main account
data['ids'] = [data['form']['chart_account_id']]
vals = self.read(cr, uid, ids,
['detailed_by_invoice',
'aging_method'],
context=context)[0]
data['form'].update(vals)
return data
def _print_report(self, cr, uid, ids, data, context=None):
# we update form with display account value
data = self.pre_print_report(cr, uid, ids, data, context=context)

4
account_financial_report_webkit/wizard/aged_partner_balance_wizard.xml

@ -18,9 +18,13 @@
<field name="chart_account_id" position='attributes'>
<attribute name="colspan">4</attribute>
</field>
<field name="chart_account_id" position='after'>
<field name="detailed_by_invoice" colspan="4"/>
</field>
<xpath expr="//field[@name='target_move']" position="after">
<newline/>
<field name="result_selection" colspan="4"/>
<field name="aging_method" colspan="4"/>
</xpath>
<xpath expr="/form/notebook[1]" position="after">
<separator string="Clearance Analysis Options" colspan="4"/>

Loading…
Cancel
Save