Bugfixes and improvement CRM cases and email gateway
Escalation system bzr revid: fp@tinyerp.com-5a31ad4e106c8c421875ccf91bb227df8960ee9b
This commit is contained in:
parent
a6b34be4d7
commit
3e42bfae81
|
@ -30,6 +30,7 @@ import tools
|
||||||
from osv import fields,osv,orm
|
from osv import fields,osv,orm
|
||||||
|
|
||||||
import mx.DateTime
|
import mx.DateTime
|
||||||
|
import base64
|
||||||
|
|
||||||
MAX_LEVEL = 15
|
MAX_LEVEL = 15
|
||||||
AVAILABLE_STATES = [
|
AVAILABLE_STATES = [
|
||||||
|
@ -182,6 +183,7 @@ class crm_case_rule(osv.osv):
|
||||||
|
|
||||||
'act_remind_partner': fields.boolean('Remind partner'),
|
'act_remind_partner': fields.boolean('Remind partner'),
|
||||||
'act_remind_user': fields.boolean('Remind responsible'),
|
'act_remind_user': fields.boolean('Remind responsible'),
|
||||||
|
'act_remind_attach': fields.boolean('Remind with attachment'),
|
||||||
|
|
||||||
'act_mail_to_user': fields.boolean('Mail to responsible'),
|
'act_mail_to_user': fields.boolean('Mail to responsible'),
|
||||||
'act_mail_to_partner': fields.boolean('Mail to partner'),
|
'act_mail_to_partner': fields.boolean('Mail to partner'),
|
||||||
|
@ -333,9 +335,9 @@ class crm_case(osv.osv):
|
||||||
self.write(cr, uid, [case.id], write, context)
|
self.write(cr, uid, [case.id], write, context)
|
||||||
caseobj = self.pool.get('crm.case')
|
caseobj = self.pool.get('crm.case')
|
||||||
if action.act_remind_user:
|
if action.act_remind_user:
|
||||||
caseobj.remind_user(cr, uid, [case.id], context)
|
caseobj.remind_user(cr, uid, [case.id], context, attach=action.act_remind_attach)
|
||||||
if action.act_remind_partner:
|
if action.act_remind_partner:
|
||||||
caseobj.remind_partner(cr, uid, [case.id], context)
|
caseobj.remind_partner(cr, uid, [case.id], context, attach=action.act_remind_attach)
|
||||||
if action.act_method:
|
if action.act_method:
|
||||||
getattr(caseobj, 'act_method')(cr, uid, [case.id], action, context)
|
getattr(caseobj, 'act_method')(cr, uid, [case.id], action, context)
|
||||||
emails = []
|
emails = []
|
||||||
|
@ -408,26 +410,35 @@ class crm_case(osv.osv):
|
||||||
self._action(cr,uid, cases, 'draft')
|
self._action(cr,uid, cases, 'draft')
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def remind_partner(self, cr, uid, ids, *args):
|
def remind_partner(self, cr, uid, ids, context={}, attach=False):
|
||||||
for case in self.browse(cr, uid, ids):
|
return self.remind_user(cr, uid, ids, context, attach, destination=False)
|
||||||
if case.user_id and case.user_id.address_id and case.user_id.address_id.email and case.email_from:
|
|
||||||
tools.email_send(
|
|
||||||
case.user_id.address_id.email,
|
|
||||||
[case.email_from],
|
|
||||||
'Reminder: '+'['+str(case.id)+']'+' '+case.name,
|
|
||||||
case.email_last or case.description, reply_to=case.section_id.reply_to
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def remind_user(self, cr, uid, ids, *args):
|
def remind_user(self, cr, uid, ids, context={}, attach=False, destination=True):
|
||||||
for case in self.browse(cr, uid, ids):
|
for case in self.browse(cr, uid, ids):
|
||||||
if case.user_id and case.user_id.address_id and case.user_id.address_id.email and case.email_from:
|
if case.user_id and case.user_id.address_id and case.user_id.address_id.email and case.email_from:
|
||||||
tools.email_send(
|
src = case.email_from
|
||||||
case.email_from,
|
dest = case.user_id.address_id.email
|
||||||
[case.user_id.address_id.email],
|
if not destination:
|
||||||
'Reminder: '+'['+str(case.id)+']'+' '+case.name,
|
src,dest = dest,src
|
||||||
case.email_last or case.description, reply_to=case.section_id.reply_to
|
dest = [dest]
|
||||||
)
|
if not attach:
|
||||||
|
tools.email_send(
|
||||||
|
src,
|
||||||
|
dest,
|
||||||
|
'Reminder: '+'['+str(case.id)+']'+' '+case.name,
|
||||||
|
case.email_last or case.description, reply_to=case.section_id.reply_to
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model','=','crm.case'),('res_id','=',case.id)])
|
||||||
|
res = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname','datas'])
|
||||||
|
res = map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), res)
|
||||||
|
tools.email_send_attach(
|
||||||
|
src,
|
||||||
|
dest,
|
||||||
|
'Reminder: '+'['+str(case.id)+']'+' '+case.name,
|
||||||
|
case.email_last or case.description, reply_to=case.section_id.reply_to,
|
||||||
|
attach=res
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def case_log(self, cr, uid, ids, *args):
|
def case_log(self, cr, uid, ids, *args):
|
||||||
|
|
|
@ -148,13 +148,14 @@
|
||||||
<field name="act_priority"/>
|
<field name="act_priority"/>
|
||||||
<field name="act_remind_user"/>
|
<field name="act_remind_user"/>
|
||||||
<field name="act_remind_partner"/>
|
<field name="act_remind_partner"/>
|
||||||
|
<field name="act_remind_attach"/>
|
||||||
<field name="act_email_cc" colspan="3"/>
|
<field name="act_email_cc" colspan="3"/>
|
||||||
<!--
|
<!--
|
||||||
<field name="act_method" colspan="3" readonly="1"/>
|
<field name="act_method" colspan="3" readonly="1"/>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
</page><page string="E-Mail Information">
|
</page><page string="E-Mail Information">
|
||||||
<separator string="Email to send"/>
|
<separator string="Email to send" colspan="3"/>
|
||||||
<field name="act_mail_to_user"/>
|
<field name="act_mail_to_user"/>
|
||||||
<field name="act_mail_to_partner"/>
|
<field name="act_mail_to_partner"/>
|
||||||
<field name="act_mail_to_watchers"/>
|
<field name="act_mail_to_watchers"/>
|
||||||
|
@ -233,9 +234,7 @@
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="General Information">
|
<page string="General Information">
|
||||||
<field name="name" select="1"/>
|
<field name="name" select="1"/>
|
||||||
<field name="id" select="1"/>
|
|
||||||
<field name="section_id"/>
|
<field name="section_id"/>
|
||||||
<field name="categ_id" select="1" on_change="onchange_categ_id(categ_id)"/>
|
|
||||||
<field name="date" select="1"/>
|
<field name="date" select="1"/>
|
||||||
<field name="priority"/>
|
<field name="priority"/>
|
||||||
<field name="partner_id" select="1" on_change="onchange_partner_id(partner_id, email_from)"/>
|
<field name="partner_id" select="1" on_change="onchange_partner_id(partner_id, email_from)"/>
|
||||||
|
@ -255,8 +254,8 @@
|
||||||
<field name="date_deadline" select="1"/>
|
<field name="date_deadline" select="1"/>
|
||||||
|
|
||||||
<group col="2" colspan="2">
|
<group col="2" colspan="2">
|
||||||
<button name="case_log" string="Silent Process" states="open" type="object"/>
|
<button name="case_log_reply" string="Send" states="open" type="object"/>
|
||||||
<button name="case_log_reply" string="Reply & Process" states="open" type="object"/>
|
<button name="case_log" string="Clear" states="open" type="object"/>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<field name="state" select="1"/>
|
<field name="state" select="1"/>
|
||||||
|
@ -269,6 +268,8 @@
|
||||||
<button name="case_reset" string="Reset to Draft" states="done,cancel" type="object"/>
|
<button name="case_reset" string="Reset to Draft" states="done,cancel" type="object"/>
|
||||||
</group>
|
</group>
|
||||||
</page><page string="References">
|
</page><page string="References">
|
||||||
|
<field name="id" select="1"/>
|
||||||
|
<field name="categ_id" select="1" on_change="onchange_categ_id(categ_id)"/>
|
||||||
<field name="date_closed"/>
|
<field name="date_closed"/>
|
||||||
<field name="active" select="1"/>
|
<field name="active" select="1"/>
|
||||||
<field name="ref" colspan="3"/>
|
<field name="ref" colspan="3"/>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# .fetchmailrc
|
# .fetchmailrc
|
||||||
|
|
||||||
poll pop.tiny.be proto pop3:
|
poll pop.tiny.be proto pop3:
|
||||||
username efl@tiny.be password fle843 mda "/home/pinky/code/terp/trunk/server/bin/addons/crm/scripts/tinyerp-mailgate/tinyerp-mailgate.py -u3 -padmin -ssupport -eefl@tiny.be -mfp@tiny.be -dterp"
|
username testcli@tiny.be password tiny mda "/home/pinky/code/terp/trunk/server/bin/addons/crm/scripts/tinyerp-mailgate/tinyerp-mailgate.py -u3 -padmin -ssupport -etestcli@tiny.be -mfp@tiny.be -dterp"
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class rpc_proxy(object):
|
||||||
|
|
||||||
def __call__(self, *request):
|
def __call__(self, *request):
|
||||||
print self.dbname, self.user_id, self.passwd
|
print self.dbname, self.user_id, self.passwd
|
||||||
|
print request
|
||||||
return self.rpc.execute(self.dbname, self.user_id, self.passwd, *request)
|
return self.rpc.execute(self.dbname, self.user_id, self.passwd, *request)
|
||||||
|
|
||||||
class email_parser(object):
|
class email_parser(object):
|
||||||
|
@ -74,10 +75,10 @@ class email_parser(object):
|
||||||
return ''.join(map(lambda x:x[0].decode(x[1] or 'ascii', 'replace'), s))
|
return ''.join(map(lambda x:x[0].decode(x[1] or 'ascii', 'replace'), s))
|
||||||
|
|
||||||
def msg_new(self, msg):
|
def msg_new(self, msg):
|
||||||
message = self.msg_body_get(msg);
|
message = self.msg_body_get(msg)
|
||||||
data = {
|
data = {
|
||||||
'name': self._decode_header(msg['Subject']),
|
'name': self._decode_header(msg['Subject']),
|
||||||
'description': message['body'],
|
'description': '> '+message['body'].replace('\n','\n> '),
|
||||||
'section_id': self.section_id,
|
'section_id': self.section_id,
|
||||||
'email_from': self._decode_header(msg['From']),
|
'email_from': self._decode_header(msg['From']),
|
||||||
'email_cc': self._decode_header(msg['Cc'] or ''),
|
'email_cc': self._decode_header(msg['Cc'] or ''),
|
||||||
|
@ -86,18 +87,18 @@ class email_parser(object):
|
||||||
try:
|
try:
|
||||||
data.update(self.partner_get(self._decode_header(msg['From'])))
|
data.update(self.partner_get(self._decode_header(msg['From'])))
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print e;
|
print e
|
||||||
#end try
|
#end try
|
||||||
|
|
||||||
id = self.rpc('crm.case', 'create', data)
|
id = self.rpc('crm.case', 'create', data)
|
||||||
attachments = message['attachment'];
|
attachments = message['attachment']
|
||||||
|
|
||||||
for attach in attachments:
|
for attach in attachments or []:
|
||||||
data_attach = {
|
data_attach = {
|
||||||
'name': 'Attachment : ' + str(attach),
|
'name': str(attach),
|
||||||
'datas':binascii.b2a_base64(str(attachments[attach])),
|
'datas':binascii.b2a_base64(str(attachments[attach])),
|
||||||
'datas_fname': attach,
|
'datas_fname': attach,
|
||||||
'description': 'Attachment comes with mail ',
|
'description': 'Mail attachment',
|
||||||
'res_model': 'crm.case',
|
'res_model': 'crm.case',
|
||||||
'res_id': id
|
'res_id': id
|
||||||
}
|
}
|
||||||
|
@ -117,46 +118,46 @@ class email_parser(object):
|
||||||
# }
|
# }
|
||||||
# #
|
# #
|
||||||
def msg_body_get(self, msg):
|
def msg_body_get(self, msg):
|
||||||
message = {};
|
message = {}
|
||||||
message['body'] = False;
|
message['body'] = ''
|
||||||
message['attachment'] = {};
|
message['attachment'] = {}
|
||||||
attachment = message['attachment'];
|
attachment = message['attachment']
|
||||||
file_name = 1;
|
file_name = 1
|
||||||
if msg.is_multipart():
|
if msg.is_multipart():
|
||||||
for part in msg.get_payload():
|
for part in msg.get_payload():
|
||||||
if part.get_content_maintype()=='application' or part.get_content_maintype()=='image':
|
if part.get_content_maintype()=='application' or part.get_content_maintype()=='image':
|
||||||
filename = part.get_filename();
|
filename = part.get_filename()
|
||||||
if filename != None:
|
if filename != None:
|
||||||
attachment[filename] = part.get_payload(decode=1);
|
attachment[filename] = part.get_payload(decode=1)
|
||||||
else:
|
else:
|
||||||
filename = 'attach_file'+str(file_name);
|
filename = 'attach_file'+str(file_name)
|
||||||
file_name += 1;
|
file_name += 1
|
||||||
attachment[filename] = part.get_payload(decode=1);
|
attachment[filename] = part.get_payload(decode=1)
|
||||||
#end if
|
#end if
|
||||||
#attachment[filename] = part.get_payload(decode=1);
|
#attachment[filename] = part.get_payload(decode=1)
|
||||||
# fp = open(os.path.join('/home/admin/test-src/', filename), 'wb')
|
# fp = open(os.path.join('/home/admin/test-src/', filename), 'wb')
|
||||||
# fp.write(part.get_payload(decode=1))
|
# fp.write(part.get_payload(decode=1))
|
||||||
# fp.close()
|
# fp.close()
|
||||||
elif(part.get_content_maintype()=='text') and (part.get_content_subtype()=='plain'):
|
elif(part.get_content_maintype()=='text') and (part.get_content_subtype()=='plain'):
|
||||||
message['body'] += part.get_payload(decode=1);
|
message['body'] += part.get_payload(decode=1).decode(part.get_charsets()[0])
|
||||||
#end if
|
#end if
|
||||||
#end for
|
#end for
|
||||||
message['attachment'] = attachment;
|
message['attachment'] = attachment
|
||||||
else:
|
else:
|
||||||
message['body'] = msg.get_payload(decode=1).decode(msg.get_charsets()[0])
|
message['body'] = msg.get_payload(decode=1).decode(msg.get_charsets()[0])
|
||||||
message['attachment'] = None;
|
message['attachment'] = None
|
||||||
return message
|
return message
|
||||||
|
|
||||||
def msg_user(self, msg, id):
|
def msg_user(self, msg, id):
|
||||||
body = self.msg_body_get(msg)
|
body = self.msg_body_get(msg)
|
||||||
data = {
|
data = {
|
||||||
'description': body['body'],
|
'description': '> '+body['body'].replace('\n','\n> '),
|
||||||
'email_last': body['body']
|
'email_last': body['body']
|
||||||
}
|
}
|
||||||
|
|
||||||
# handle email body commands (ex: Set-State: Draft)
|
# handle email body commands (ex: Set-State: Draft)
|
||||||
actions = {}
|
actions = {}
|
||||||
for line in body.split('\n'):
|
for line in body['body'].split('\n'):
|
||||||
res = command_re.match(line)
|
res = command_re.match(line)
|
||||||
if res:
|
if res:
|
||||||
actions[res.group(1).lower()] = res.group(2).lower()
|
actions[res.group(1).lower()] = res.group(2).lower()
|
||||||
|
@ -198,23 +199,19 @@ class email_parser(object):
|
||||||
if 'Cc' in msg:
|
if 'Cc' in msg:
|
||||||
del msg['Cc']
|
del msg['Cc']
|
||||||
msg['Cc'] = ','.join(emails[1:])
|
msg['Cc'] = ','.join(emails[1:])
|
||||||
msg['Reply-To'] = msg['From'] + ',' + self.email
|
msg['Reply-To'] = self.email
|
||||||
if priority:
|
if priority:
|
||||||
msg['X-Priority'] = priorities.get(priority, '3 (Normal)')
|
msg['X-Priority'] = priorities.get(priority, '3 (Normal)')
|
||||||
s = smtplib.SMTP()
|
s = smtplib.SMTP()
|
||||||
print '1'
|
|
||||||
s.connect()
|
s.connect()
|
||||||
print '2'
|
|
||||||
s.sendmail(self.email, emails[0], msg.as_string())
|
s.sendmail(self.email, emails[0], msg.as_string())
|
||||||
print '3'
|
|
||||||
s.close()
|
s.close()
|
||||||
print '4'
|
print 'Email Sent To', emails[0], emails
|
||||||
print 'Email Sent To', emails[0], emails[1:]
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def msg_partner(self, msg, id):
|
def msg_partner(self, msg, id):
|
||||||
message = self.msg_body_get(msg)
|
message = self.msg_body_get(msg)
|
||||||
body = message['body'];
|
body = message['body']
|
||||||
act = 'case_open'
|
act = 'case_open'
|
||||||
self.rpc('crm.case', act, [id])
|
self.rpc('crm.case', act, [id])
|
||||||
body2 = '\n'.join(map(lambda l: '> '+l, (body or '').split('\n')))
|
body2 = '\n'.join(map(lambda l: '> '+l, (body or '').split('\n')))
|
||||||
|
@ -232,33 +229,35 @@ class email_parser(object):
|
||||||
return (int(case_str), emails)
|
return (int(case_str), emails)
|
||||||
|
|
||||||
def parse(self, msg):
|
def parse(self, msg):
|
||||||
try:
|
case_str = project_re.search(msg.get('Subject', ''))
|
||||||
case_str = project_re.search(msg.get('Subject', ''))
|
(case_id, emails) = self.msg_test(msg, case_str and case_str.group(1))
|
||||||
(case_id, emails) = self.msg_test(msg, case_str and case_str.group(1))
|
if case_id:
|
||||||
if case_id:
|
if emails[0] and self.email_get(emails[0])==self.email_get(self._decode_header(msg['From'])):
|
||||||
if emails[0] and self.email_get(emails[0])==self.email_get(self._decode_header(msg['From'])):
|
print 'From User', case_id
|
||||||
print 'From User', case_id
|
self.msg_user(msg, case_id)
|
||||||
self.msg_user(msg, case_id)
|
|
||||||
else:
|
|
||||||
print 'From Partner', case_id
|
|
||||||
self.msg_partner(msg, case_id)
|
|
||||||
else:
|
else:
|
||||||
case_id = self.msg_new(msg)
|
print 'From Partner', case_id
|
||||||
if msg.get('Subject', ''):
|
self.msg_partner(msg, case_id)
|
||||||
del msg['Subject']
|
else:
|
||||||
msg['Subject'] = '['+str(case_id)+'] '+self._decode_header(msg['subject'])
|
case_id = self.msg_new(msg)
|
||||||
print 'Case', case_id, 'created...'
|
subject = self._decode_header(msg['subject'])
|
||||||
|
if msg.get('Subject', ''):
|
||||||
|
del msg['Subject']
|
||||||
|
msg['Subject'] = '['+str(case_id)+'] '+subject
|
||||||
|
print 'Case', case_id, 'created...'
|
||||||
|
|
||||||
emails = self.rpc('crm.case', 'emails_get', case_id)
|
emails = self.rpc('crm.case', 'emails_get', case_id)
|
||||||
priority = emails[3]
|
priority = emails[3]
|
||||||
em = [emails[0], emails[1]] + (emails[2] or '').split(',')
|
em = [emails[0], emails[1]] + (emails[2] or '').split(',')
|
||||||
emails = map(self.email_get, filter(None, em))
|
emails = map(self.email_get, filter(None, em))
|
||||||
|
|
||||||
mm = [self._decode_header(msg['From']), self._decode_header(msg['To'])]+self._decode_header(msg.get('Cc','')).split(',')
|
mm = [self._decode_header(msg['From']), self._decode_header(msg['To'])]+self._decode_header(msg.get('Cc','')).split(',')
|
||||||
msg_mails = map(self.email_get, filter(None, mm))
|
msg_mails = map(self.email_get, filter(None, mm))
|
||||||
|
|
||||||
emails = filter(lambda m: m and m not in msg_mails, emails)
|
emails = filter(lambda m: m and m not in msg_mails, emails)
|
||||||
self.msg_send(msg, emails, priority)
|
self.msg_send(msg, emails, priority)
|
||||||
|
try:
|
||||||
|
pass
|
||||||
except:
|
except:
|
||||||
print 'Sending mail to default address', self.email_default
|
print 'Sending mail to default address', self.email_default
|
||||||
if self.email_default:
|
if self.email_default:
|
||||||
|
@ -288,13 +287,11 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
parser = email_parser(options.userid, options.password, options.section, options.email, options.default, dbname=options.dbname)
|
parser = email_parser(options.userid, options.password, options.section, options.email, options.default, dbname=options.dbname)
|
||||||
print
|
msg_txt = email.message_from_file(sys.stdin)
|
||||||
print '-.- ICI'
|
|
||||||
#msg_txt = email.message_from_file(sys.stdin)
|
|
||||||
|
|
||||||
fp = open('/home/admin/Desktop/email1.eml');
|
#fp = open('/home/admin/Desktop/email1.eml')
|
||||||
msg_txt = email.message_from_file(fp)
|
#msg_txt = email.message_from_file(fp)
|
||||||
fp.close()
|
#fp.close()
|
||||||
|
|
||||||
print 'Mail Sent to ', parser.parse(msg_txt)
|
print 'Mail Sent to ', parser.parse(msg_txt)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue