[IMP]: Create email template fot crm meeting instead of calender atttendee , and clean code

bzr revid: aja@tinyerp.com-20130802085607-pdnwpbqvycxm91di
This commit is contained in:
ajay javiya (OpenERP)
2013-08-02 14:26:07 +05:30
parent 8c816485e6
commit 23d2d1bb57
4 changed files with 170 additions and 131 deletions
+14 -54
View File
@@ -296,6 +296,7 @@ property or property parameter."),
multi='event_end_date'),
'ref': fields.reference('Event Ref', selection=_links_get, size=128),
'availability': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Free/Busy', readonly="True"),
}
_defaults = {
'state': 'needs-action',
@@ -403,22 +404,14 @@ property or property parameter."),
res = cal.serialize()
return res
def meeting_invitation(self, cr, uid, ids, context=None):
meeting_id = self.pool.get('crm.meeting').search(cr, uid, [('attendee_ids','in',ids)])
action_id = self.pool.get('ir.actions.act_window').search(cr, uid, [('res_model','=','crm.meeting')], context=context)
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://localhost:8069', context=context)
if action_id:
base_url += '/meeting/meeting_invitation?db=%s&token=%s&action=%s&id=%s' % (cr.dbname, ids,action_id[0],meeting_id[0]);
return base_url
def _send_mail(self, cr, uid, ids, mail_to, email_from=tools.config.get('email_from', False), context=None):
"""
Send mail for event invitation to event attendees.
@param email_from: email address for user sending the mail
@return: True
"""
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name
mail_id = []
local_context = context.copy()
color = {
'needs-action' : 'grey',
'accepted' :'green',
@@ -426,56 +419,23 @@ property or property parameter."),
'declined':'red',
'delegated':'grey'
}
image_cricle = "<div style='display:inline-block; border-radius: 50% %; width:10px; height:10px; background:%s;'> </div>"
for attendee in self.browse(cr, uid, ids, context=context):
res_obj = attendee.ref
data_pool = self.pool.get('ir.model.data')
if res_obj:
att = {}
att_info = [(image_cricle % color.get('needs-action')) + 'You', (image_cricle % color.get('accepted')) + res_obj.organizer+ '<span style= "color:#A9A9A9; ont-size: 9px">- Organizer </br></span>']
sub = res_obj.name
other_invitation_ids = self.search(cr, uid, [('ref', '=', res_obj._name + ',' + str(res_obj.id))])
other_invitation_ids.remove(attendee.id)
for att2 in self.browse(cr, uid, other_invitation_ids):
name = att2.user_id and att2.user_id.name or att2.partner_id and att2.partner_id.name or att2.email
att_info.append((image_cricle % color.get(att2.state)) + name)
tz = context.get('tz', pytz.timezone('UTC'))
allday = False
date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(res_obj.date, tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context)
date_deadline = fields.datetime.context_timestamp(cr, uid, datetime.strptime(res_obj.date_deadline, tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context)
if res_obj.allday:
time = "AllDay" + "," + date.strftime('%B-%d-%Y')
tz = ''
elif res_obj.duration < 24:
duration = date + timedelta(hours= res_obj.duration)
time = date.strftime('%B-%d-%Y') + " at (" + date.strftime('%H-%M') + " To " + duration.strftime('%H-%M') + ")"
else :
time = date.strftime('%B-%d-%Y') + " at " + date.strftime('%H-%M') + " To \n" + date_deadline.strftime('%B-%d-%Y') + " at " + date_deadline.strftime('%H-%M')
footer = self.meeting_invitation(cr, uid, attendee.id, context=context)
map_url = ''
if res_obj.location:
map_url = """<span style= "color:#A9A9A9; "> (<a href="http://maps.google.com/maps?oi=map&q=%s">View Map</a>)</span>""" % res_obj.location
body_vals = {'user':attendee.user_id and attendee.user_id.name,
'name': res_obj.name,
'responsible': res_obj.user_id and res_obj.user_id.name or 'OpenERP User',
'company': company,
'description': res_obj.description or '-',
'attendees': ',\n' .join(att_info),
'time': time,
'tz': tz,
'location': res_obj.location or '-',
'map' : map_url or '',
'organizer' : res_obj.organizer,
'url' : footer}
body_id = self.pool.get('email.template').search(cr, uid, [('subject', '=', 'Meeting Invitation')], context=context)
body = self.pool.get('email.template').browse(cr, uid, body_id[0], context=context).body_html % body_vals
model,template_id = data_pool.get_object_reference(cr, uid, 'base_calendar', "crm_email_template_meeting_invitation")
model,act_id = data_pool.get_object_reference(cr, uid, 'base_calendar', "view_crm_meeting_calendar")
action_id = self.pool.get('ir.actions.act_window').search(cr, uid, [('view_id','=',act_id)], context=context)
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://localhost:8069', context=context)
body = self.pool.get('email.template').browse(cr, uid, template_id, context=context).body_html
if attendee.email and email_from:
ics_file = self.get_ics_file(cr, uid, res_obj, context=context)
vals = {'email_from': email_from,
'email_to': attendee.email,
'state': 'outgoing',
'subject': sub,
'body_html': body,
'auto_delete': True}
local_context['att_obj'] = attendee
local_context['color'] = color
local_context['action_id'] = action_id[0]
local_context['dbname'] = cr.dbname
local_context['base_url'] = base_url
vals = self.pool.get('email.template').generate_email(cr, uid, template_id, res_obj.id, context=local_context)
if ics_file:
vals['attachment_ids'] = [(0,0,{'name': 'invitation.ics',
'datas_fname': 'invitation.ics',
@@ -135,60 +135,4 @@
<field eval="'(False,)'" name="args" />
</record>
</data>
<data>
<!--Email template -->
<record id="email_template_meeting_invitation" model="email.template">
<field name="name">Meeting Invitation</field>
<field name="email_from">${object.user_id.email or ''}</field>
<field name="subject">Meeting Invitation</field>
<field name="email_to" >${object.email}</field>
<field name="model_id" ref="base_calendar.model_calendar_attendee"/>
<field name="auto_delete" eval="True"/>
<field name="body_html"><![CDATA[<html><head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>%(name)s</title>
<style>
</style>
</head>
<body>
<table cellspacing="0" cellpadding="6" border="0" style = "margin: auto; display:block; border:2px solid #8E0000; background: #F8F8F8; border-radius: 2px; width: 600px; height: auto; ">
<tr>
<td style = "display: block; border: 2px solid #8E0000; height: 45px; width: auto; background : #8E0000; text-align: center; font-family: Arial, sans-serif; font-size: 20px; color:#FFFFFF; ">
<div style="text-align: center" > <b>%(name)s </b> </div> </td></tr>
<tr>
<td> <div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px" > <b> Hello %(user)s, </b> <br/>
%(organizer)s invited you for the %(name)s meeting of %(company)s. </div></td></tr>
<tr><td>
<table cellspacing="0" cellpadding="0" border="0" style="margin-top: 15px; margin-left: 10px; background: #F8F8F8">
<tr valign="top">
<td><div style = "height: 25px; width: 120px; background : # CCCCCC;font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px;"><b> When :</b></div></td>
<td colspan="1"> <div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px" >%(time)s <span style= " color:#A9A9A9; "> (%(tz)s) </span></div>
</td> </tr>
<tr valign="top">
<td> <div style = "height: 25px; width: 120px; background : # CCCCCC; font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px;"><b>Where :</b></div> </td>
<td colspan="1"> <div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px" >%(location)s %(map)s </div></td> </tr>
<tr valign="top">
<td> <div style = "height: 25px; width: 120px; background : # CCCCCC; font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px;"><b>What :</b></div> </td>
<td colspan="3"> <div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px" >%(description)s</div> </td> </tr>
<tr valign="top">
<td style = "height: 25px;width: 120px; background : # CCCCCC; font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px;"> <div><b>Attendees:<b></div> </td>
<td colspan="3"><div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 10px" > %(attendees)s </div> </td> </tr>
</table></td></tr>
<tr >
<td><div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 10px" ><span style= "margin-top: 50px; margin-left: 200px;" ><a href="%(url)s&view_type=form&status=accepted">Accept</a> | <a href="%(url)s&view_type=form&status=declined">Decline</a></span></div> </td>
<tr>
<td><div > -- </br> Sent by %(responsible)s from %(company)s.View this meeting detail <a href="%(url)s&view_type=calendar&status=">directly in OpenERP</a></div> </td>
</tr>
</table>
</body>
</html>
]]></field>
</record>
</data>
</openerp>
+48 -21
View File
@@ -26,6 +26,9 @@ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
from openerp.tools.translate import _
from base_calendar import get_real_ids, base_calendar_id2real_id
from openerp.addons.base_status.base_state import base_state
from datetime import datetime, timedelta, date
import pytz
from openerp import tools
#
# crm.meeting is defined here so that it may be used by modules other than crm,
# without forcing the installation of crm.
@@ -45,27 +48,48 @@ class crm_meeting(base_state, osv.Model):
_order = "id desc"
_inherit = ["calendar.event", "mail.thread", "ir.needaction_mixin"]
def _check_status(self, cr, uid, ids, context=None):
def _check_status(self, cr, uid, meeting_id, context=None):
attendee_pool = self.pool.get('calendar.attendee')
user = self.pool.get('res.users').read(cr,uid,uid,['partner_id'],context)
for attendee in self.browse(cr,uid,ids,context)[0].attendee_ids:
if user['partner_id'][0] == attendee_pool.read(cr,uid,attendee.id,['partner_id'],context)['partner_id'][0]:
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
for attendee in self.browse(cr,uid,meeting_id,context).attendee_ids:
if user.partner_id.id == attendee.partner_id.id:
return attendee
return False
def _check_attendee(self, cr, uid, ids, name, arg, context=None):
res = {}
res[ids[0]] = False
if self._check_status(cr, uid, ids, context):
res[ids[0]] = True
for meeting_id in ids:
res[meeting_id] = False
if self._check_status(cr, uid, meeting_id, context):
res[meeting_id] = True
return res
def _compute_status(self, cr, uid, ids, name, arg, context=None):
res = {}
res[ids[0]] = 'needs-action'
attendee = self._check_status(cr, uid, ids, context)
if attendee:
res[ids[0]] = attendee.state
for meeting_id in ids:
res[meeting_id] = 'needs-action'
attendee = self._check_status(cr, uid, meeting_id, context)
if attendee:
res[meeting_id] = attendee.state
return res
def _compute_time(self, cr, uid, ids, name, arg, context=None):
res = {}
tz = context.get('tz', pytz.timezone('UTC'))
for meeting in self.browse(cr, uid, ids, context=context):
date = fields.datetime.context_timestamp(cr, uid, datetime.strptime(meeting.date, tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context)
date_deadline = fields.datetime.context_timestamp(cr, uid, datetime.strptime(meeting.date_deadline, tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context)
event_date = date.strftime('%B-%d-%Y')
event_time = date.strftime('%H-%M')
res[meeting.id] = False
if meeting.allday:
time = _("AllDay , %s") % (date_event)
elif meeting.duration < 24:
duration = date + timedelta(hours= meeting.duration)
time = ("%s at ( %s To %s) (%s)") % (str(event_date), str(event_time), str(duration.strftime('%H-%M')), str(tz))
else :
time = ("%s at %s To\n %s at %s (%s)") % (event_date, event_time, date_deadline.strftime('%B-%d-%Y'), date_deadline.strftime('%H-%M'), tz)
res[meeting.id] = time
return res
_columns = {
@@ -89,6 +113,7 @@ class crm_meeting(base_state, osv.Model):
type="boolean"),
'attendee_status': fields.function(_compute_status, string='Attendee Status', \
type="selection"),
'event_time': fields.function(_compute_time, string='Event Time', type="char"),
}
_defaults = {
'state': 'open',
@@ -151,20 +176,22 @@ class crm_meeting(base_state, osv.Model):
def do_decline(self, cr, uid, ids, context=None, *args):
attendee_pool = self.pool.get('calendar.attendee')
attendee = self._check_status(cr, uid, ids, context)
if attendee:
if attendee.state != 'declined':
self.message_post(cr, uid, ids, body=_(("%s has Declined Invitation") % (attendee.cn)), context=context)
attendee_pool.write(cr, uid, attendee.id, {'state': 'declined'}, context)
for meeting_id in ids:
attendee = self._check_status(cr, uid, meeting_id, context)
if attendee:
if attendee.state != 'declined':
self.message_post(cr, uid, meeting_id, body=_(("%s has Declined Invitation") % (attendee.cn)), context=context)
attendee_pool.write(cr, uid, attendee.id, {'state': 'declined'}, context)
return True
def do_accept(self, cr, uid, ids, context=None, *args):
attendee_pool = self.pool.get('calendar.attendee')
attendee = self._check_status(cr, uid, ids, context)
if attendee:
if attendee.state != 'accepted':
self.message_post(cr, uid, ids, body=_(("%s has Accepted Invitation") % (attendee.cn)), context=context)
attendee_pool.write(cr, uid, attendee.id, {'state': 'accepted'}, context)
for meeting_id in ids:
attendee = self._check_status(cr, uid, meeting_id, context)
if attendee:
if attendee.state != 'accepted':
self.message_post(cr, uid, meeting_id, body=_(("%s has Accepted Invitation") % (attendee.cn)), context=context)
attendee_pool.write(cr, uid, attendee.id, {'state': 'accepted'}, context)
return True
class mail_message(osv.osv):
+108
View File
@@ -28,5 +28,113 @@
<field name="name">Meeting</field>
<field name="object">crm.meeting</field>
</record>
<record id="crm_email_template_meeting_invitation" model="email.template">
<field name="name">CRM Meeting Invitation</field>
<field name="email_from">${object.user_id.email or ''}</field>
<field name="subject">${object.name}</field>
<field name="email_to" >${ctx['att_obj'].email}</field>
<field name="model_id" ref="base_calendar.model_crm_meeting"/>
<field name="auto_delete" eval="True"/>
<field name="body_html"><![CDATA[
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>${object.name}</title>
</head>
<body>
<table cellspacing="0" cellpadding="6" border="0" style = "margin: auto; display:block; border:2px solid #8E0000; background: #F8F8F8; border-radius: 2px; width: 600px; height: auto; ">
<tr>
<td style = "display: block; border: 2px solid #8E0000; height: 45px; width: auto;background : #8E0000; text-align: center; font-family: Arial, sans-serif; font-size: 20px; color:#FFFFFF; ">
<div style="text-align: center" > <b>${object.name}</b> </div>
</td>
</tr>
<tr>
<td>
<div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px" > <b>Hello ${ctx['att_obj'].cn}, </b> <br/>
${object.organizer} invited you for the ${object.name} meeting of ${object.user_id.company_id.name}. </div>
</td>
</tr>
<tr>
<td>
<table cellspacing="0" cellpadding="0" border="0" style="margin-top: 15px; margin-left: 10px; background: #F8F8F8">
<tr valign="top">
<td>
<div style = "height: 25px; width: 120px; background : # CCCCCC;font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px;"><b> When :</b>
</div>
</td>
<td colspan="1">
<div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px" >
${object.event_time}
</div>
</td>
</tr>
<tr valign="top">
<td>
<div style = "height: 25px; width: 120px; background : # CCCCCC; font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px;"><b>Where :</b>
</div>
</td>
<td colspan="1">
<div style = "font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px" >
${object.location or ''}
% if object.location :
<span style= "color:#A9A9A9; ">
(<a href="http://maps.google.com/maps?oi=map&q=${object.location}">View Map</a>)
</span>
% endif
</div>
</td>
</tr>
<tr valign="top">
<td>
<div style = "height: 25px; width: 120px; background : # CCCCCC; font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px;"><b>What :</b>
</div>
</td>
<td colspan="3">
<div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px" >
${object.description or ''}
</div>
</td>
</tr>
<tr valign="top">
<td style = "height: 25px;width: 120px; background : # CCCCCC; font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px;">
<div><b>Attendees:<b></div>
</td>
<td colspan="3">
% for attendee in object.attendee_ids:
<div style='display:inline-block; border-radius: 50%; width:10px; height:10px;background:${ctx['color'][attendee.state]}'>
</div>
<span style="margin-left:5px">
${attendee.cn}
</span>
% endfor
</td>
</tr>
</table>
</td>
</tr>
<tr >
<td>
<div style = " font-family: Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 10px" >
<span style= "margin-top: 50px; margin-left: 200px;" >
<a href="${ctx['base_url']}/meeting/meeting_invitation?db=${ctx['dbname']}&token=${ctx['att_obj'].id}&action=${ctx['action_id']}&id=${object.id}&view_type=form&status=accepted">Accept</a> |
<a href="${ctx['base_url']}/meeting/meeting_invitation?db=${ctx['dbname']}&token=${ctx['att_obj'].id}&action=${ctx['action_id']}&id=${object.id}&view_type=form&status=declined">Declined</a>
</span>
</div>
</td>
</tr>
<tr>
<td>
<div >
-- </br> Sent by ${object.user_id.name} from ${object.user_id.company_id.name}. View this meeting detail
<a href="${ctx['base_url']}/meeting/meeting_invitation?db=${ctx['dbname']}&token=${ctx['att_obj'].id}&action=${ctx['action_id']}&id=${object.id}&view_type=calendar&status=">directly in OpenERP.</a>
</div>
</td>
</tr>
</table>
</body>
</html>
]]]></field>
</record>
</data>
</openerp>