Browse Source

[ADD] new module account_partner_aged_statement

pull/9/head
Marc Cassuto 10 years ago
committed by Maxime Chambreuil
parent
commit
233a8f4e30
  1. 23
      account_partner_aged_statement_webkit/__init__.py
  2. BIN
      account_partner_aged_statement_webkit/__init__.pyc
  3. 59
      account_partner_aged_statement_webkit/__openerp__.py
  4. 71
      account_partner_aged_statement_webkit/partner_aged_statement.py
  5. BIN
      account_partner_aged_statement_webkit/partner_aged_statement.pyc
  6. 80
      account_partner_aged_statement_webkit/partner_aged_statement_data.xml
  7. 27
      account_partner_aged_statement_webkit/partner_aged_statement_report.xml
  8. 21
      account_partner_aged_statement_webkit/partner_aged_statement_view.xml
  9. 20
      account_partner_aged_statement_webkit/report/__init__.py
  10. BIN
      account_partner_aged_statement_webkit/report/__init__.pyc
  11. 164
      account_partner_aged_statement_webkit/report/partner_aged_statement.mako
  12. 53
      account_partner_aged_statement_webkit/report/partner_aged_statement_report.py
  13. BIN
      account_partner_aged_statement_webkit/report/partner_aged_statement_report.pyc

23
account_partner_aged_statement_webkit/__init__.py

@ -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,
)

BIN
account_partner_aged_statement_webkit/__init__.pyc

59
account_partner_aged_statement_webkit/__openerp__.py

@ -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
}

71
account_partner_aged_statement_webkit/partner_aged_statement.py

@ -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,
}

BIN
account_partner_aged_statement_webkit/partner_aged_statement.pyc

80
account_partner_aged_statement_webkit/partner_aged_statement_data.xml

@ -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;">
&nbsp;&nbsp;<strong>REFERENCES</strong><br />
&nbsp;&nbsp;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:&nbsp; ${user.company_id.phone}
</div>
% endif
% if user.company_id.website:
<div>
Web :&nbsp;<a href="${user.company_id.website}">${user.company_id.website}</a>
</div>
%endif
<p></p>
</div>
</div>
]]></field>
</record>
</data>
</openerp>

27
account_partner_aged_statement_webkit/partner_aged_statement_report.xml

@ -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>

21
account_partner_aged_statement_webkit/partner_aged_statement_view.xml

@ -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>

20
account_partner_aged_statement_webkit/report/__init__.py

@ -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

BIN
account_partner_aged_statement_webkit/report/__init__.pyc

164
account_partner_aged_statement_webkit/report/partner_aged_statement.mako

@ -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('-', '&#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>
</body>
</html>

53
account_partner_aged_statement_webkit/report/partner_aged_statement_report.py

@ -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:

BIN
account_partner_aged_statement_webkit/report/partner_aged_statement_report.pyc

Loading…
Cancel
Save