Fix contract expiration reminder:
- fix domains and check for 3 different type of expiration - use an email template instead of an hardcoded string bzr revid: al@openerp.com-20130214235330-bmgjq962vn76q39x
This commit is contained in:
parent
b069932671
commit
b1eba6c1ef
|
@ -20,7 +20,6 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import account_analytic_analysis
|
import account_analytic_analysis
|
||||||
import cron_account_analytic_account
|
|
||||||
import res_config
|
import res_config
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
|
||||||
from openerp.osv import osv, fields
|
from openerp.osv import osv, fields
|
||||||
from openerp.osv.orm import intersect, except_orm
|
from openerp.osv.orm import intersect, except_orm
|
||||||
|
@ -484,7 +486,41 @@ class account_analytic_account(osv.osv):
|
||||||
res['value']['to_invoice'] = template.to_invoice.id
|
res['value']['to_invoice'] = template.to_invoice.id
|
||||||
res['value']['pricelist_id'] = template.pricelist_id.id
|
res['value']['pricelist_id'] = template.pricelist_id.id
|
||||||
return res
|
return res
|
||||||
account_analytic_account()
|
|
||||||
|
def cron_account_analytic_account(self, cr, uid, context=None):
|
||||||
|
remind = {}
|
||||||
|
|
||||||
|
def fill_remind(key, domain, write_pending=False):
|
||||||
|
base_domain = [
|
||||||
|
('partner_id', '!=', False),
|
||||||
|
('manager_id', '!=', False),
|
||||||
|
('manager_id.email', '!=', False),
|
||||||
|
]
|
||||||
|
base_domain.extend(domain)
|
||||||
|
accounts_ids = self.search(cr, uid, base_domain, context=context, order='name asc')
|
||||||
|
accounts = self.browse(cr, uid, accounts_ids, context=context)
|
||||||
|
for account in accounts:
|
||||||
|
if write_pending:
|
||||||
|
account.write({'state' : 'pending'}, context=context)
|
||||||
|
remind_user = remind.setdefault(account.manager_id.id, {})
|
||||||
|
remind_type = remind_user.setdefault(key, {})
|
||||||
|
remind_partner = remind_type.setdefault(account.partner_id, []).append(account)
|
||||||
|
|
||||||
|
# Already expired
|
||||||
|
fill_remind("old", [('state', 'in', ['pending'])])
|
||||||
|
|
||||||
|
# Expires now
|
||||||
|
fill_remind("new", [('state', 'in', ['draft', 'open']), '|', '&', ('date', '!=', False), ('date', '<=', time.strftime('%Y-%m-%d')), ('is_overdue_quantity', '=', True)], True)
|
||||||
|
|
||||||
|
# Expires in less than 30 days
|
||||||
|
fill_remind("future", [('state', 'in', ['draft', 'open']), ('date', '!=', False), ('date', '<', (datetime.datetime.now() + datetime.timedelta(30)).strftime("%Y-%m-%d"))])
|
||||||
|
|
||||||
|
template_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_analytic_analysis', 'account_analytic_cron_email_template')[1]
|
||||||
|
for user_id, data in remind.items():
|
||||||
|
context["data"] = data
|
||||||
|
self.pool.get('email.template').send_mail(cr, uid, template_id, user_id, context=context)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
class account_analytic_account_summary_user(osv.osv):
|
class account_analytic_account_summary_user(osv.osv):
|
||||||
_name = "account_analytic_analysis.summary.user"
|
_name = "account_analytic_analysis.summary.user"
|
||||||
|
@ -538,8 +574,6 @@ class account_analytic_account_summary_user(osv.osv):
|
||||||
lu.user_id as "user",
|
lu.user_id as "user",
|
||||||
unit_amount
|
unit_amount
|
||||||
from lu, mu)''')
|
from lu, mu)''')
|
||||||
|
|
||||||
account_analytic_account_summary_user()
|
|
||||||
|
|
||||||
class account_analytic_account_summary_month(osv.osv):
|
class account_analytic_account_summary_month(osv.osv):
|
||||||
_name = "account_analytic_analysis.summary.month"
|
_name = "account_analytic_analysis.summary.month"
|
||||||
|
@ -600,6 +634,4 @@ class account_analytic_account_summary_month(osv.osv):
|
||||||
'GROUP BY d.month, d.account_id ' \
|
'GROUP BY d.month, d.account_id ' \
|
||||||
')')
|
')')
|
||||||
|
|
||||||
|
|
||||||
account_analytic_account_summary_month()
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -1,15 +1,77 @@
|
||||||
<?xml version="1.0" encoding='UTF-8'?>
|
<?xml version="1.0" encoding='UTF-8'?>
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
|
<record id="account_analytic_cron_email_template" model="email.template">
|
||||||
|
<field name="name">Contract expiration reminder</field>
|
||||||
|
<field name="email_from">${user.email or ''}</field>
|
||||||
|
<field name="subject">Contract expiration reminder ${user.company_id.name}</field>
|
||||||
|
<field name="email_to">${object.email}</field>
|
||||||
|
<field name="lang">${object.lang}</field>
|
||||||
|
<field name="model_id" ref="base.model_res_users"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
Hello ${user.name},
|
||||||
|
|
||||||
|
% macro account_table(values):
|
||||||
|
<table cellspacing="1" border="1" cellpadding="4">
|
||||||
|
<tr>
|
||||||
|
<th>Customer</th>
|
||||||
|
<th>Contract</th>
|
||||||
|
<th>Dates</th>
|
||||||
|
<th>Prepaid Units</th>
|
||||||
|
<th>Contact</th>
|
||||||
|
</tr>
|
||||||
|
% for partner, accounts in values:
|
||||||
|
% for account in accounts:
|
||||||
|
<tr>
|
||||||
|
<td>${partner.name}</td>
|
||||||
|
<td>${account.name}</td>
|
||||||
|
<td>${account.date_start} to ${account.date and account.date or '???'}</td>
|
||||||
|
<td>
|
||||||
|
% if account.quantity_max != 0.0:
|
||||||
|
${account.quantity}/${account.quantity_max} hours
|
||||||
|
% endif
|
||||||
|
</td>
|
||||||
|
<td>${account.partner_id.phone or ''}, ${account.partner_id.email or ''}</td>
|
||||||
|
</tr>
|
||||||
|
% endfor
|
||||||
|
% endfor
|
||||||
|
</table>
|
||||||
|
% endmacro
|
||||||
|
|
||||||
|
% if "new" in ctx["data"]:
|
||||||
|
<h2>The following contracts just expired: </h2>
|
||||||
|
${account_table(ctx["data"]["new"].iteritems())}
|
||||||
|
% endif
|
||||||
|
|
||||||
|
% if "old" in ctx["data"]:
|
||||||
|
<h2>The following expired contracts are still not processed: </h2>
|
||||||
|
${account_table(ctx["data"]["old"].iteritems())}
|
||||||
|
% endif
|
||||||
|
|
||||||
|
% if "future" in ctx["data"]:
|
||||||
|
<h2>The following contracts will expire in less than one month: </h2>
|
||||||
|
${account_table(ctx["data"]["future"].iteritems())}
|
||||||
|
% endif
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
<record model="ir.cron" id="account_analytic_cron">
|
<record model="ir.cron" id="account_analytic_cron">
|
||||||
<field name="name">Analytic Account Report for Sales</field>
|
<field name="name">Contract expiration reminder</field>
|
||||||
<field name="interval_number">1</field>
|
<field name="interval_number">1</field>
|
||||||
<field name="interval_type">weeks</field>
|
<field name="interval_type">weeks</field>
|
||||||
<field name="numbercall">-1</field>
|
<field name="numbercall">-1</field>
|
||||||
<field eval="False" name="doall"/>
|
<field name="doall" eval="False"/>
|
||||||
<field eval="'account.analytic.account'" name="model"/>
|
<field name="model" eval="'account.analytic.account'"/>
|
||||||
<field eval="'cron_account_analytic_account'" name="function"/>
|
<field name="function" eval="'cron_account_analytic_account'"/>
|
||||||
<field eval="'()'" name="args"/>
|
<field name="args" eval="'()'" />
|
||||||
</record>
|
</record>
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
from mako.template import Template
|
|
||||||
import time
|
|
||||||
try:
|
|
||||||
import cStringIO as StringIO
|
|
||||||
except ImportError:
|
|
||||||
import StringIO
|
|
||||||
|
|
||||||
from openerp import tools
|
|
||||||
from openerp.osv import osv
|
|
||||||
|
|
||||||
MAKO_TEMPLATE = u"""Hello ${user.name},
|
|
||||||
|
|
||||||
Here is a list of contracts that have to be renewed for two
|
|
||||||
possible reasons:
|
|
||||||
- the end of contract date is passed
|
|
||||||
- the customer consumed more hours than expected
|
|
||||||
|
|
||||||
Can you contact the customer in order to sell a new or renew its contract.
|
|
||||||
The contract has been set with a pending state, can you update the status
|
|
||||||
of the analytic account following this rule:
|
|
||||||
- Set Done: if the customer does not want to renew
|
|
||||||
- Set Open: if the customer purchased an extra contract
|
|
||||||
|
|
||||||
Here is the list of contracts to renew:
|
|
||||||
% for partner, accounts in partners.iteritems():
|
|
||||||
* ${partner.name}
|
|
||||||
% for account in accounts:
|
|
||||||
- Name: ${account.name}
|
|
||||||
% if account.quantity_max != 0.0:
|
|
||||||
- Quantity: ${account.quantity}/${account.quantity_max} hours
|
|
||||||
% endif
|
|
||||||
- Dates: ${account.date_start} to ${account.date and account.date or '???'}
|
|
||||||
- Contacts:
|
|
||||||
${account.partner_id.name}, ${account.partner_id.phone or ''}, ${account.partner_id.email or ''}
|
|
||||||
|
|
||||||
% endfor
|
|
||||||
% endfor
|
|
||||||
|
|
||||||
You can use the report in the menu: Sales > Invoicing > Overdue Accounts
|
|
||||||
|
|
||||||
Regards,
|
|
||||||
|
|
||||||
--
|
|
||||||
OpenERP
|
|
||||||
"""
|
|
||||||
|
|
||||||
class analytic_account(osv.osv):
|
|
||||||
_inherit = 'account.analytic.account'
|
|
||||||
|
|
||||||
def cron_account_analytic_account(self, cr, uid, context=None):
|
|
||||||
domain = [
|
|
||||||
('name', 'not ilike', 'maintenance'),
|
|
||||||
('partner_id', '!=', False),
|
|
||||||
('user_id', '!=', False),
|
|
||||||
('user_id.email', '!=', False),
|
|
||||||
('state', 'in', ('draft', 'open')),
|
|
||||||
'|', ('date', '<', time.strftime('%Y-%m-%d')), ('date', '=', False),
|
|
||||||
]
|
|
||||||
|
|
||||||
account_ids = self.search(cr, uid, domain, context=context, order='name asc')
|
|
||||||
accounts = self.browse(cr, uid, account_ids, context=context)
|
|
||||||
|
|
||||||
users = dict()
|
|
||||||
for account in accounts:
|
|
||||||
users.setdefault(account.user_id, dict()).setdefault(account.partner_id, []).append(account)
|
|
||||||
|
|
||||||
account.write({'state' : 'pending'}, context=context)
|
|
||||||
|
|
||||||
for user, data in users.iteritems():
|
|
||||||
subject = '[OPENERP] Reporting: Analytic Accounts'
|
|
||||||
body = Template(MAKO_TEMPLATE).render_unicode(user=user, partners=data)
|
|
||||||
tools.email_send('noreply@openerp.com', [user.email, ], subject, body)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
analytic_account()
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
Loading…
Reference in New Issue