Marc Cassuto
11 years ago
committed by
Maxime Chambreuil
13 changed files with 518 additions and 0 deletions
-
23account_partner_aged_statement_webkit/__init__.py
-
BINaccount_partner_aged_statement_webkit/__init__.pyc
-
59account_partner_aged_statement_webkit/__openerp__.py
-
71account_partner_aged_statement_webkit/partner_aged_statement.py
-
BINaccount_partner_aged_statement_webkit/partner_aged_statement.pyc
-
80account_partner_aged_statement_webkit/partner_aged_statement_data.xml
-
27account_partner_aged_statement_webkit/partner_aged_statement_report.xml
-
21account_partner_aged_statement_webkit/partner_aged_statement_view.xml
-
20account_partner_aged_statement_webkit/report/__init__.py
-
BINaccount_partner_aged_statement_webkit/report/__init__.pyc
-
164account_partner_aged_statement_webkit/report/partner_aged_statement.mako
-
53account_partner_aged_statement_webkit/report/partner_aged_statement_report.py
-
BINaccount_partner_aged_statement_webkit/report/partner_aged_statement_report.pyc
@ -0,0 +1,23 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
|
||||
|
############################################################################ |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from . import ( |
||||
|
partner_aged_statement, |
||||
|
report, |
||||
|
) |
@ -0,0 +1,59 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 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 |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
|
||||
|
{ |
||||
|
'name': 'Partner Aged Statement', |
||||
|
"version": "1.0", |
||||
|
'author': 'Savoir-faire Linux', |
||||
|
'website': 'http://www.savoirfairelinux.com', |
||||
|
'depends': [ |
||||
|
'account_financial_report_webkit_xls', |
||||
|
'report_webkit', |
||||
|
'base_headers_webkit', |
||||
|
'mail', |
||||
|
], |
||||
|
'category': 'Accounting', |
||||
|
'description': """ |
||||
|
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. |
||||
|
|
||||
|
So far the module does not drill down through pricelist items that are |
||||
|
based on another pricelist or based on purchase pricelists. |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
* Marc Cassuto (marc.cassuto@savoirfairelinux.com) |
||||
|
""", |
||||
|
'data': [ |
||||
|
'partner_aged_statement_report.xml', |
||||
|
'partner_aged_statement_view.xml', |
||||
|
'partner_aged_statement_data.xml', |
||||
|
], |
||||
|
'active': False, |
||||
|
'installable': True |
||||
|
} |
@ -0,0 +1,71 @@ |
|||||
|
# -*- 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 |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
|
||||
|
import time |
||||
|
from openerp.osv import orm |
||||
|
|
||||
|
|
||||
|
class PartnerAgedStatement(orm.Model): |
||||
|
_inherit = 'res.partner' |
||||
|
|
||||
|
def action_aged_statement_send(self, cr, uid, ids, context=None): |
||||
|
# This function opens a window to compose an email, |
||||
|
# with the partner aged statemen template message loaded by default |
||||
|
|
||||
|
# This option should only be used for a single id at a time. |
||||
|
assert len(ids) == 1 |
||||
|
|
||||
|
ir_model_data = self.pool.get('ir.model.data') |
||||
|
try: |
||||
|
template_id = ir_model_data.get_object_reference( |
||||
|
cr, uid, |
||||
|
'account_partner_aged_statement_webkit', |
||||
|
'email_template_aged_statement')[1] |
||||
|
except ValueError: |
||||
|
template_id = False |
||||
|
|
||||
|
try: |
||||
|
compose_form_id = ir_model_data.get_object_reference( |
||||
|
cr, uid, 'mail', 'email_compose_message_wizard_form')[1] |
||||
|
except ValueError: |
||||
|
compose_form_id = False |
||||
|
|
||||
|
ctx = dict(context) |
||||
|
ctx.update({ |
||||
|
'default_model': 'res.partner', |
||||
|
'default_res_id': ids[0], |
||||
|
'default_use_template': bool(template_id), |
||||
|
'default_template_id': template_id, |
||||
|
'default_composition_mode': 'comment', |
||||
|
}) |
||||
|
# Full explanation of this return is here : |
||||
|
# http://stackoverflow.com/questions/12634031 |
||||
|
return { |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'view_type': 'form', |
||||
|
'view_mode': 'form', |
||||
|
'res_model': 'mail.compose.message', |
||||
|
'views': [(compose_form_id, 'form')], |
||||
|
'view_id': compose_form_id, |
||||
|
'target': 'new', |
||||
|
'context': ctx, |
||||
|
} |
@ -0,0 +1,80 @@ |
|||||
|
<?xml version="1.0" ?> |
||||
|
<openerp> |
||||
|
<!-- Mail template is done in a NOUPDATE block |
||||
|
so users can freely customize/delete them --> |
||||
|
<data noupdate="1"> |
||||
|
|
||||
|
<!--Email template --> |
||||
|
<record id="email_template_aged_statement" model="email.template"> |
||||
|
<field name="name">Aged Statement Letter</field> |
||||
|
<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="auto_delete" eval="True"/> |
||||
|
<!-- |
||||
|
<field name="report_template" |
||||
|
ref="partner_aged_statement_report"/> |
||||
|
--> |
||||
|
<field name="report_name"> |
||||
|
${(object.name or '').replace('/','_')} |
||||
|
</field> |
||||
|
<field name="body_html"><![CDATA[ |
||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; "> |
||||
|
|
||||
|
<p>Dear Sir/Madam,</p> |
||||
|
|
||||
|
<p> Our records indicate that some payments on your account are still due. |
||||
|
<br/> |
||||
|
Please find in the attached document your aged balance |
||||
|
<br/> |
||||
|
If the amount has already been paid, please disregard this notice. |
||||
|
Otherwise, please forward us the total amount stated below. |
||||
|
</p> |
||||
|
|
||||
|
<p style="border-left: 1px solid #8e0000; margin-left: 30px;"> |
||||
|
<strong>REFERENCES</strong><br /> |
||||
|
Total overdue amount: ${object.credit} ${user.company_id.currency_id.name}<br/> |
||||
|
</p> |
||||
|
|
||||
|
<p>If you have any question, do not hesitate to contact us.</p> |
||||
|
<p>Best Regards,</p> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<div style="width: 375px; margin: 0px; padding: 0px; background-color: #8E0000; border-top-left-radius: 5px 5px; border-top-right-radius: 5px 5px; background-repeat: repeat no-repeat;"> |
||||
|
<h3 style="margin: 0px; padding: 2px 14px; font-size: 12px; color: #DDD;"> |
||||
|
<strong style="text-transform:uppercase;">${user.company_id.name}</strong></h3> |
||||
|
</div> |
||||
|
<div style="width: 347px; margin: 0px; padding: 5px 14px; line-height: 16px; background-color: #F2F2F2;"> |
||||
|
<span style="color: #222; margin-bottom: 5px; display: block; "> |
||||
|
% if user.company_id.street: |
||||
|
${user.company_id.street}<br/> |
||||
|
% endif |
||||
|
% if user.company_id.street2: |
||||
|
${user.company_id.street2}<br/> |
||||
|
% endif |
||||
|
% if user.company_id.city or user.company_id.zip: |
||||
|
${user.company_id.zip} ${user.company_id.city}<br/> |
||||
|
% endif |
||||
|
% if user.company_id.country_id: |
||||
|
${user.company_id.state_id and ('%s, ' % user.company_id.state_id.name) or ''} ${user.company_id.country_id.name or ''}<br/> |
||||
|
% endif |
||||
|
</span> |
||||
|
% if user.company_id.phone: |
||||
|
<div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "> |
||||
|
Phone: ${user.company_id.phone} |
||||
|
</div> |
||||
|
% endif |
||||
|
% if user.company_id.website: |
||||
|
<div> |
||||
|
Web : <a href="${user.company_id.website}">${user.company_id.website}</a> |
||||
|
</div> |
||||
|
%endif |
||||
|
<p></p> |
||||
|
</div> |
||||
|
</div> |
||||
|
]]></field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,27 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<!-- |
||||
|
<report |
||||
|
auto="False" |
||||
|
id="partner_aged_statement_report" |
||||
|
model="res.partner" |
||||
|
name="webkit.partner_aged_statement_report" |
||||
|
file="account_partner_aged_statement_webkit/report/partner_aged_statement.mako" |
||||
|
string="Partner Aged Statement" |
||||
|
webkit_header="base_headers_webkit.base_reports_portrait_header" |
||||
|
report_type="webkit"/> |
||||
|
--> |
||||
|
<report |
||||
|
auto="False" |
||||
|
id="partner_aged_statement_report" |
||||
|
model="res.partner" |
||||
|
name="webkit.partner_aged_statement_report" |
||||
|
file="account_partner_aged_statement_webkit/report/partner_aged_statement.mako" |
||||
|
string="Partner Aged Statement" |
||||
|
webkit_header="base_headers_webkit.base_reports_portrait_header" |
||||
|
report_type="webkit"/> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,21 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record id="partner_aged_statement_view" model="ir.ui.view"> |
||||
|
<field name="inherit_id" ref="base.view_partner_form"/> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//form/*[1]" position="before"> |
||||
|
<header> |
||||
|
<button |
||||
|
name="action_aged_statement_send" |
||||
|
type="object" string="Send Aged Statement" |
||||
|
class="oe_highlight"/> |
||||
|
</header> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,20 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
|
||||
|
############################################################################### |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
|
||||
|
from . import partner_aged_statement_report |
@ -0,0 +1,164 @@ |
|||||
|
## -*- coding: utf-8 -*- |
||||
|
<!DOCTYPE html SYSTEM |
||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
||||
|
<html xmlns="http://www.w3.org/1999/xhtml"> |
||||
|
<head> |
||||
|
<style type="text/css"> |
||||
|
.overflow_ellipsis { |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.open_invoice_previous_line { |
||||
|
font-style: italic; |
||||
|
} |
||||
|
|
||||
|
.percent_line { |
||||
|
font-style: italic; |
||||
|
} |
||||
|
|
||||
|
.amount { |
||||
|
text-align:right; |
||||
|
} |
||||
|
|
||||
|
.classif_title { |
||||
|
text-align:right; |
||||
|
} |
||||
|
<%doc> |
||||
|
.classif{ |
||||
|
width: ${700/len(ranges)}px; |
||||
|
} |
||||
|
</%doc> |
||||
|
.total{ |
||||
|
font-weight:bold; |
||||
|
} |
||||
|
${css} |
||||
|
</style> |
||||
|
</head> |
||||
|
|
||||
|
<%! |
||||
|
def amount(text): |
||||
|
# replace by a non-breaking hyphen (it will not word-wrap between hyphen and numbers) |
||||
|
return text.replace('-', '‑') |
||||
|
%> |
||||
|
<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> |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,53 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
|
||||
|
# ############################################################################## |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
|
||||
|
|
||||
|
import time |
||||
|
import operator |
||||
|
import itertools |
||||
|
|
||||
|
from openerp import pooler |
||||
|
from openerp.osv import orm |
||||
|
from openerp.report import report_sxw |
||||
|
from openerp.tools.translate import _ |
||||
|
|
||||
|
from openerp.addons.account_financial_report_webkit.report.aged_partner_balance import ( # noqa |
||||
|
AccountAgedTrialBalanceWebkit |
||||
|
) |
||||
|
|
||||
|
|
||||
|
class PartnerAgedStatementReport(report_sxw.rml_parse): |
||||
|
def __init__(self, cr, uid, name, context): |
||||
|
super(PartnerAgedStatementReport, self).__init__(cr, uid, name, |
||||
|
context=context) |
||||
|
self.localcontext.update({ |
||||
|
'time': time, |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
report_sxw.report_sxw( |
||||
|
'report.webkit.partner_aged_statement_report', |
||||
|
'account.account', |
||||
|
('addons/' |
||||
|
'account_partner_aged_statement_webkit/' |
||||
|
'report/' |
||||
|
'partner_aged_statement.mako'), |
||||
|
parser=PartnerAgedStatementReport) |
||||
|
|
||||
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
Write
Preview
Loading…
Cancel
Save
Reference in new issue