Browse Source

account_partner_aged_statement_webkit - add the following :

* the summary per period
 * the list of invoices per period
 * the invoices are also shown with the foreign currency
pull/9/head
Marc Cassuto 10 years ago
committed by Maxime Chambreuil
parent
commit
66a35a93db
  1. 16
      account_partner_aged_statement_webkit/__openerp__.py
  2. 8
      account_partner_aged_statement_webkit/partner_aged_statement_data.xml
  3. 11
      account_partner_aged_statement_webkit/partner_aged_statement_report.xml
  4. 262
      account_partner_aged_statement_webkit/report/partner_aged_statement.mako
  5. 103
      account_partner_aged_statement_webkit/report/partner_aged_statement_report.py

16
account_partner_aged_statement_webkit/__openerp__.py

@ -26,6 +26,8 @@
'author': 'Savoir-faire Linux',
'website': 'http://www.savoirfairelinux.com',
'depends': [
'report_webkit',
'base_headers_webkit',
'mail',
'account',
],
@ -36,16 +38,20 @@ Print & Send Partner Aged Statement by email
This module adds in the system :
* a new mail template "Aged Statement Letter";
* the abitlity to print the partner aged statement;
* a button "Send by email" in the pricelist form view which load the template
and attache the pricelist to the email.
* the ability to print the partner aged statement;
* a button "Send by email" in the partner form view which load the template
and attach the statement to the email.
So far the module does not drill down through pricelist items that are
based on another pricelist or based on purchase pricelists.
Comparing to 'Overdue Payment' report provided with OpenERP, this one adds more
informations :
* the summary per period
* the list of invoices per period
* the invoices are also shown with the foreign currency
Contributors
------------
* Marc Cassuto (marc.cassuto@savoirfairelinux.com)
* Vincent Vinet (vincent.vinet@savoirfairelinux.com)
""",
'data': [
'partner_aged_statement_report.xml',

8
account_partner_aged_statement_webkit/partner_aged_statement_data.xml

@ -2,7 +2,7 @@
<openerp>
<!-- Mail template is done in a NOUPDATE block
so users can freely customize/delete them -->
<data noupdate="0">
<data noupdate="1">
<!--Email template -->
<record id="email_template_aged_statement" model="email.template">
@ -10,11 +10,9 @@
<field name="email_from">${(user.email or '')|safe}</field>
<field name="subject">${object.company_id.name} - Your aged balance</field>
<field name="email_recipients">${object.id or ''|safe}</field>
<field name="model_id"
ref="account.model_res_partner"/>
<field name="model_id" ref="account.model_res_partner"/>
<field name="auto_delete" eval="True"/>
<field name="report_template"
ref="partner_aged_statement_report"/>
<field name="report_template" ref="partner_aged_statement_report"/>
<field name="report_name">
${(object.name or '').replace('/','_')}
</field>

11
account_partner_aged_statement_webkit/partner_aged_statement_report.xml

@ -6,11 +6,16 @@
auto="False"
id="partner_aged_statement_report"
model="res.partner"
name="account.aged_trial_balance_partner"
file="account/report/account_aged_partner_balance.rml"
string="Partner Aged Statement"
report_type="pdf"
name="webkit.partner_aged_statement_report"
file="account_partner_aged_statement_webkit/report/partner_aged_statement.mako"
report_type="webkit"
webkit_header="base_headers_webkit.base_reports_portrait_header"
/>
<!-- name="account.aged_trial_balance_partner"
file="account/report/account_aged_partner_balance.rml"
report_type="pdf"-->
</data>
</openerp>

262
account_partner_aged_statement_webkit/report/partner_aged_statement.mako

@ -25,14 +25,10 @@
.classif_title {
text-align:right;
}
<%doc>
.classif{
width: ${700/len(ranges)}px;
}
</%doc>
.total{
font-weight:bold;
}
${css}
</style>
</head>
@ -43,122 +39,144 @@
return text.replace('-', '&#8209;')
%>
<body>
<%setLang(user.lang)%>
<div class="act_as_table data_table">
<div class="act_as_row labels">
<div class="act_as_cell">${_('Chart of Account')}</div>
<div class="act_as_cell">${_('Fiscal Year')}</div>
<%doc>
<div class="act_as_cell">
%if filter_form(data) == 'filter_date':
${_('Dates Filter')}
%else:
${_('Periods Filter')}
%endif
</div>
</%doc>
<div class="act_as_cell">${_('Clearance Date')}</div>
<div class="act_as_cell">${_('Accounts Filter')}</div>
<div class="act_as_cell">${_('Target Moves')}</div>
</div>
<%doc>
<div class="act_as_row">
<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">
${_('From:')}
%if filter_form(data) == 'filter_date':
${formatLang(start_date, date=True) if start_date else u'' }
%else:
${start_period.name if start_period else u''}
%endif
${_('To:')}
%if filter_form(data) == 'filter_date':
${ formatLang(stop_date, date=True) if stop_date else u'' }
%else:
${stop_period.name if stop_period else u'' }
%endif
</div>
<div class="act_as_cell">${ formatLang(date_until, date=True) }</div>
<div class="act_as_cell">
%if partner_ids:
${_('Custom Filter')}
%else:
${ display_partner_account(data) }
%endif
</div>
<div class="act_as_cell">${ display_target_move(data) }</div>
</div>
</div>
%for acc in objects:
%if acc.aged_lines:
<div class="account_title bg" style="width: 1080px; margin-top: 20px; font-size: 12px;">${acc.code} - ${acc.name}</div>
<div class="act_as_table list_table" style="margin-top: 5px;">
<div class="act_as_thead">
<div class="act_as_row labels">
## partner
<div class="act_as_cell first_column" style="width: 60px;">${_('Partner')}</div>
## code
<div class="act_as_cell" style="width: 70px;">${_('code')}</div>
## balance
<div class="act_as_cell classif_title" style="width: 70px;">${_('balance')}</div>
## Classifications
%for title in ranges_titles:
<div class="act_as_cell classif classif_title">${title}</div>
%endfor
</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">
<%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_row labels">
<div class="act_as_cell total">${_('Total')}</div>
<div class="act_as_cell"></div>
<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>
%endfor
</div>
<div class="act_as_row">
<div class="act_as_cell"><b>${_('Percents')}</b></div>
<div class="act_as_cell"></div>
<div class="act_as_cell"></div>
%for classif in ranges:
<div class="act_as_cell amount percent_line classif">${formatLang(percents[classif]) | amount}%</div>
%endfor
</div>
</div>
<br/>
%endif
%endfor
</%doc>
</div>
%for partner in objects:
<%setLang(partner.lang)%>
<br/>
<br/>
<%from datetime import date %>
${_('Date')}: ${formatLang(str(date.today()), date=True)}
<br>
${_('Partner')}: ${partner.name}
<br>
${_('Subject')}: <b>${_('Overdue Statement')}</b>
<br/>
<br/>
%for message_line in message(partner, company):
<p>
${message_line}
</p>
%endfor
<br>
${user.name}
<br>
<br>
%if (partner.credit + partner.debit == 0) :
<div class="title">${_('Nothing due for this partner')}</div>
%else:
<div class="title">${_('Aged Balance')}</div>
<br>
%for l in get_lines(data['form']):
%if l:
<table class=basic_table style="width: 100%;">
<tr>
<th>${_('Not Due')}</th>
<th>${_('0-30')}</th>
<th>${_('30-60')}</th>
<th>${_('60-90')}</th>
<th>${_('90-120')}</th>
<th>${_('+120')}</th>
<th>${_('Total')}</th>
</tr>
<tr>
<td>${ formatLang(l['direction'], currency_obj=company.currency_id) }</td>
<td>${ formatLang(l['4'], currency_obj=company.currency_id) }</td>
<td>${ formatLang(l['3'], currency_obj=company.currency_id) }</td>
<td>${ formatLang(l['2'], currency_obj=company.currency_id) }</td>
<td>${ formatLang(l['1'], currency_obj=company.currency_id) }</td>
<td>${ formatLang(l['0'], currency_obj=company.currency_id) }</td>
<td>${ formatLang(l['total'], currency_obj=company.currency_id) }</td>
</tr>
</table>
%endif ## if l
%endfor ## for l in get_lines(data['form'])
<br>
<br>
<div class="title">${_('List of Due Invoices')}</div>
<br>
%if getLines30(partner):
<div class="total">${_('0-30')}</div>
<table class=basic_table style="width: 100%;">
<tr>
<th>${_('Date')}</th>
<th>${_('Description')}</th>
<th>${_('Reference')}</th>
<th>${_('Due date')}</th>
<th>${_('Amount')}</th>
<th>${_('Paid')}</th>
<th>${_('Total')}<br/>(${company.currency_id.name})</th>
<th>${_('Total')}<br/>(fgn. cur.)</th>
</tr>
%for line in getLines30(partner):
<tr>
<td>${ formatLang(line.date, date=True) }</td>
<td>${ line.name }</td>
<td>${ line.ref }</td>
<td>${ line.date_maturity and formatLang(line.date_maturity,date=True) or '' }</td>
<td>${ formatLang(line.debit) or 0 }</td>
<td>${ formatLang(line.credit) or 0 }</td>
<td>${ formatLang(line.debit - line.credit, currency_obj = company.currency_id) }</td>
<td>${ line.amount_currency and formatLang(line.amount_currency, currency_obj = line.currency_id) or '' }</td>
</tr>
%endfor ## for line in getLines30(partner)
</table>
%endif ## if getLines30(partner)
<br/>
%if getLines3060(partner):
<div class="total">${_('30-60')}</div>
<table class=basic_table style="width: 100%;">
<tr>
<th>${_('Date')}</th>
<th>${_('Description')}</th>
<th>${_('Reference')}</th>
<th>${_('Due date')}</th>
<th>${_('Amount')}</th>
<th>${_('Paid')}</th>
<th>${_('Total')}<br/>(${company.currency_id.name})</th>
<th>${_('Total')}<br/>(fgn. cur.)</th>
</tr>
%for line in getLines3060(partner):
<tr>
<td>${ formatLang(line.date, date=True) }</td>
<td>${ line.name }</td>
<td>${ line.ref }</td>
<td>${ line.date_maturity and formatLang(line.date_maturity,date=True) or '' }</td>
<td>${ formatLang(line.debit) or 0 }</td>
<td>${ formatLang(line.credit) or 0 }</td>
<td>${ formatLang(line.debit - line.credit, currency_obj = company.currency_id) }</td>
<td>${ line.amount_currency and formatLang(line.amount_currency, currency_obj = line.currency_id) or '' }</td>
</tr>
%endfor ## for line in getLines3060(partner)
</table>
%endif ## if getLines3060(partner)
<br/>
%if getLines60(partner):
<div class="total">${_('+60')}</div>
<table class=basic_table style="width: 100%;">
<tr>
<th>${_('Date')}</th>
<th>${_('Description')}</th>
<th>${_('Reference')}</th>
<th>${_('Due date')}</th>
<th>${_('Amount')}</th>
<th>${_('Paid')}</th>
<th>${_('Total')}<br/>(${company.currency_id.name})</th>
<th>${_('Total')}<br/>(fgn. cur.)</th>
</tr>
%for line in getLines60(partner):
<tr>
<td>${ formatLang(line.date, date=True) }</td>
<td>${ line.name }</td>
<td>${ line.ref }</td>
<td>${ line.date_maturity and formatLang(line.date_maturity,date=True) or '' }</td>
<td>${ formatLang(line.debit) or 0 }</td>
<td>${ formatLang(line.credit) or 0 }</td>
<td>${ formatLang(line.debit - line.credit, currency_obj = company.currency_id) }</td>
<td>${ line.amount_currency and formatLang(line.amount_currency, currency_obj = line.currency_id) or '' }</td>
</tr>
%endfor ## for line in getLines60(partner)
</table>
%endif ## if getLines60(partner)
%endif ## if (partner.credit + partner.debit == 0)
%endfor ## for partner in objects
</body>
</html>

103
account_partner_aged_statement_webkit/report/partner_aged_statement_report.py

@ -1,6 +1,9 @@
# -*- encoding: utf-8 -*-
# ##############################################################################
###############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2010 - 2014 Savoir-faire Linux
# (<http://www.savoirfairelinux.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@ -17,7 +20,6 @@
#
###############################################################################
import time
from datetime import datetime
@ -40,16 +42,80 @@ class PartnerAgedTrialReport(aged_trial_report):
self._company = current_user.company_id
if self.localcontext.get("active_model", "") == "res.partner":
self._partner = self.localcontext["active_id"]
self.localcontext.update({
'message': self._message,
'getLines30': self._lines_get30,
'getLines3060': self._lines_get_30_60,
'getLines60': self._lines_get60,
})
def _lines_get30(self, obj):
today = datetime.now()
stop = today - relativedelta(days=30)
moveline_obj = pooler.get_pool(self.cr.dbname)['account.move.line']
movelines = moveline_obj.search(
self.cr, self.uid,
[('partner_id', '=', obj.id),
('account_id.type', 'in', ['receivable', 'payable']),
('state', '<>', 'draft'), ('reconcile_id', '=', False),
'|',
'&', ('date_maturity', '<=', today), ('date_maturity', '>', stop),
'&', ('date_maturity', '=', False),
'&', ('date', '<=', today), ('date', '>', stop)],
context=self.localcontext)
movelines = moveline_obj.browse(self.cr, self.uid, movelines)
return movelines
def _lines_get_30_60(self, obj):
start = datetime.now() - relativedelta(days=30)
stop = start - relativedelta(days=30)
moveline_obj = pooler.get_pool(self.cr.dbname)['account.move.line']
movelines = moveline_obj.search(
self.cr, self.uid,
[('partner_id', '=', obj.id),
('account_id.type', 'in', ['receivable', 'payable']),
('state', '<>', 'draft'), ('reconcile_id', '=', False),
'|',
'&', ('date_maturity', '<=', start), ('date_maturity', '>', stop),
'&', ('date_maturity', '=', False),
'&', ('date', '<=', start), ('date', '>', stop)],
context=self.localcontext)
movelines = moveline_obj.browse(self.cr, self.uid, movelines)
return movelines
def _lines_get60(self, obj):
start = datetime.now() - relativedelta(days=60)
moveline_obj = pooler.get_pool(self.cr.dbname)['account.move.line']
movelines = moveline_obj.search(
self.cr, self.uid,
[('partner_id', '=', obj.id),
('account_id.type', 'in', ['receivable', 'payable']),
('state', '<>', 'draft'), ('reconcile_id', '=', False),
'|', ('date_maturity', '<=', start),
('date_maturity', '=', False), ('date', '<=', start)],
context=self.localcontext)
movelines = moveline_obj.browse(self.cr, self.uid, movelines)
return movelines
def _message(self, obj, company):
company_pool = pooler.get_pool(self.cr.dbname)['res.company']
message = company_pool.browse(
self.cr, self.uid, company.id, {'lang': obj.lang}).overdue_msg
return message.split('\n')
def _get_fiscalyear(self, data):
now = data['form']['date_from']
now = data['fInvoicesorm']['date_from']
domain = [
('company_id', '=', self._company.id),
('date_start', '<', now),
('date_stop', '>', now),
]
fiscalyears_obj = pooler.get_pool(self.cr.dbname).get('account.fiscalyear')
fiscalyears = fiscalyears_obj.search(self.cr, self.uid, domain, limit=1)
fiscalyears_obj = pooler.get_pool(self.cr.dbname)['account.fiscalyear']
fiscalyears = fiscalyears_obj.search(
self.cr, self.uid, domain, limit=1, context=self.localcontext)
if fiscalyears:
return fiscalyears_obj.browse(
self.cr, self.uid, fiscalyears[0], context=self.localcontext
@ -62,12 +128,11 @@ class PartnerAgedTrialReport(aged_trial_report):
accounts = account_obj.search(
self.cr, self.uid,
[('parent_id', '=', False), ('company_id', '=', self._company.id)],
limit=1,
)
limit=1, context=self.localcontext)
if accounts:
return account_obj.browse(
self.cr, self.uid, accounts[0], context=self.localcontext
).name
self.cr, self.uid, accounts[0],
context=self.localcontext).name
else:
return ''
@ -77,7 +142,10 @@ class PartnerAgedTrialReport(aged_trial_report):
def _get_journal(self, data):
codes = []
if data.get('form', False) and data['form'].get('journal_ids', False):
self.cr.execute('select code from account_journal where id IN %s', (tuple(data['form']['journal_ids']),))
self.cr.execute(
'select code from account_journal where id IN %s',
(tuple(data['form']['journal_ids']),)
)
codes = [x for x, in self.cr.fetchall()]
return codes
@ -110,13 +178,18 @@ class PartnerAgedTrialReport(aged_trial_report):
res = super(PartnerAgedTrialReport, self).set_context(
objects, data, ids, report_type=report_type)
if self._partner is not None:
self.query = "{0} AND l.partner_id = {1}".format(self.query, self._partner)
self.query = "{0} AND l.partner_id = {1}".format(
self.query,
self._partner)
return res
report_sxw.report_sxw(
'report.account.aged_trial_balance_partner',
'report.webkit.partner_aged_statement_report',
'res.partner',
'addons/account/report/account_aged_partner_balance.rml',
('addons/'
'account_partner_aged_statement_webkit/'
'report/'
'partner_aged_statement.mako'),
parser=PartnerAgedTrialReport,
header="internal landscape")
)
Loading…
Cancel
Save