[IMP] clean email_template module, merge email_template and mail_gateway module, developed email_gateway module. task ID-2007.
bzr revid: ysa@tinyerp.com-20110201114308-nwb7qzj8ko99eerw
This commit is contained in:
parent
91ce37a2ef
commit
1513a9ae77
|
@ -19,8 +19,9 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import mail_gateway
|
||||
import emails
|
||||
import res_partner
|
||||
import email_smtp_server
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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': 'Email Gateway System',
|
||||
'version': '1.0',
|
||||
'category': 'Generic Modules/Mail Service',
|
||||
'description': """The generic email gateway system allows to send and receive emails
|
||||
* History for Emails
|
||||
* Easy Integration with any Module""",
|
||||
'author': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base', 'base_tools'],
|
||||
'init_xml': [],
|
||||
'update_xml': [
|
||||
"email_view.xml",
|
||||
"res_partner_view.xml",
|
||||
'email_smtp_server_view.xml',
|
||||
'security/ir.model.access.csv',
|
||||
# 'email_smtp_server_data.xml'
|
||||
|
||||
],
|
||||
'demo_xml': [],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
'certificate': '001056784984222247309',
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -65,11 +65,11 @@ def extract_emails_from_dict(addresses={}):
|
|||
result['all-recipients'].extend(emails)
|
||||
return result
|
||||
|
||||
class email_template_account(osv.osv):
|
||||
class email_smtp_server(osv.osv):
|
||||
"""
|
||||
Object to store email account settings
|
||||
"""
|
||||
_name = "email_template.account"
|
||||
_name = "email.smtp_server"
|
||||
_known_content_types = ['multipart/mixed',
|
||||
'multipart/alternative',
|
||||
'multipart/related',
|
||||
|
@ -81,14 +81,8 @@ class email_template_account(osv.osv):
|
|||
size=64, required=True,
|
||||
readonly=True, select=True,
|
||||
help="The description is used as the Sender name along with the provided From Email, \
|
||||
unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
||||
unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
||||
states={'draft':[('readonly', False)]}),
|
||||
'auto_delete': fields.boolean('Auto Delete', size=64, readonly=True,
|
||||
help="Permanently delete emails after sending",
|
||||
states={'draft':[('readonly', False)]}),
|
||||
'user':fields.many2one('res.users',
|
||||
'Related User', required=True,
|
||||
readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'email_id': fields.char('From Email',
|
||||
size=120, required=True,
|
||||
readonly=True, states={'draft':[('readonly', False)]} ,
|
||||
|
@ -112,33 +106,16 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
states={'draft':[('readonly', False)]}),
|
||||
'smtptls':fields.boolean('TLS',
|
||||
states={'draft':[('readonly', False)]}, readonly=True),
|
||||
|
||||
|
||||
'smtpssl':fields.boolean('SSL/TLS (only in python 2.6)',
|
||||
states={'draft':[('readonly', False)]}, readonly=True),
|
||||
'send_pref':fields.selection([
|
||||
('html', 'HTML, otherwise Text'),
|
||||
('text', 'Text, otherwise HTML'),
|
||||
('alternative', 'Both HTML & Text (Alternative)'),
|
||||
('mixed', 'Both HTML & Text (Mixed)')
|
||||
], 'Mail Format', required=True),
|
||||
'company':fields.selection([
|
||||
('yes', 'Yes'),
|
||||
('no', 'No')
|
||||
], 'Corporate',
|
||||
readonly=True,
|
||||
help="Select if this mail account does not belong " \
|
||||
"to specific user but to the organization as a whole. " \
|
||||
"eg: info@companydomain.com",
|
||||
required=True, states={
|
||||
'draft':[('readonly', False)]
|
||||
}),
|
||||
|
||||
'state':fields.selection([
|
||||
('draft', 'Initiated'),
|
||||
('suspended', 'Suspended'),
|
||||
('approved', 'Approved')
|
||||
],
|
||||
'State', required=True, readonly=True),
|
||||
'default': fields.boolean('Default', help="Only one account can be default at a time"),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -154,12 +131,9 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
'state':lambda * a:'draft',
|
||||
'smtpport':lambda *a:25,
|
||||
'smtpserver':lambda *a:'localhost',
|
||||
'company':lambda *a:'yes',
|
||||
'user':lambda self, cursor, user, context:user,
|
||||
'send_pref':lambda *a: 'html',
|
||||
'smtptls':lambda *a:True,
|
||||
}
|
||||
|
||||
|
||||
_sql_constraints = [
|
||||
(
|
||||
'email_uniq',
|
||||
|
@ -167,46 +141,34 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
'Another setting already exists with this email ID !')
|
||||
]
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
return [(a["id"], "%s (%s)" % (a['email_id'], a['name'])) for a in self.read(cr, uid, ids, ['name', 'email_id'], context=context)]
|
||||
|
||||
def _constraint_unique(self, cursor, user, ids, context=None):
|
||||
"""
|
||||
This makes sure that you dont give personal
|
||||
users two accounts with same ID (Validated in sql constaints)
|
||||
However this constraint exempts company accounts.
|
||||
Any no of co accounts for a user is allowed
|
||||
"""
|
||||
if self.read(cursor, user, ids, ['company'])[0]['company'] == 'no':
|
||||
accounts = self.search(cursor, user, [
|
||||
('user', '=', user),
|
||||
('company', '=', 'no')
|
||||
])
|
||||
if len(accounts) > 1 :
|
||||
return False
|
||||
else :
|
||||
return True
|
||||
def _constraint_unique(self, cr, uid, ids, context=None):
|
||||
default_ids = self.search(cr, uid, [('default','=',True)])
|
||||
if len(default_ids) > 1:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
_constraints = [
|
||||
(_constraint_unique,
|
||||
'Error: You are not allowed to have more than 1 account.',
|
||||
'Error: You are not allowed to set default more than 1 account.',
|
||||
[])
|
||||
]
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
return [(a["id"], "%s (%s)" % (a['email_id'], a['name'])) for a in self.read(cr, uid, ids, ['name', 'email_id'], context=context)]
|
||||
|
||||
def get_outgoing_server(self, cursor, user, ids, context=None):
|
||||
"""
|
||||
Returns the Out Going Connection (SMTP) object
|
||||
|
||||
|
||||
@attention: DO NOT USE except_osv IN THIS METHOD
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of current user
|
||||
@param ids: ID/list of ids of current object for
|
||||
@param ids: ID/list of ids of current object for
|
||||
which connection is required
|
||||
First ID will be chosen from lists
|
||||
@param context: Context
|
||||
|
||||
|
||||
@return: SMTP server object or Exception
|
||||
"""
|
||||
#Type cast ids to integer
|
||||
|
@ -214,7 +176,7 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
ids = ids[0]
|
||||
this_object = self.browse(cursor, user, ids, context=context)
|
||||
if this_object:
|
||||
if this_object.smtpserver and this_object.smtpport:
|
||||
if this_object.smtpserver and this_object.smtpport:
|
||||
try:
|
||||
if this_object.smtpssl:
|
||||
serv = smtplib.SMTP_SSL(this_object.smtpserver, this_object.smtpport)
|
||||
|
@ -234,14 +196,14 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
return serv
|
||||
raise Exception(_("SMTP SERVER or PORT not specified"))
|
||||
raise Exception(_("Core connection for the given ID does not exist"))
|
||||
|
||||
|
||||
def check_outgoing_connection(self, cursor, user, ids, context=None):
|
||||
"""
|
||||
checks SMTP credentials and confirms if outgoing connection works
|
||||
(Attached to button)
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of current user
|
||||
@param ids: list of ids of current object for
|
||||
@param ids: list of ids of current object for
|
||||
which connection is required
|
||||
@param context: Context
|
||||
"""
|
||||
|
@ -255,7 +217,7 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
_("Out going connection test failed"),
|
||||
_("Reason: %s") % error
|
||||
)
|
||||
|
||||
|
||||
def do_approval(self, cr, uid, ids, context=None):
|
||||
#TODO: Check if user has rights
|
||||
self.write(cr, uid, ids, {'state':'approved'}, context=context)
|
||||
|
@ -279,12 +241,12 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
else:
|
||||
logger.notifyChannel(_("Email Template"), netsvc.LOG_ERROR, _("Mail from Account %s failed. Probable Reason:Account not approved") % id)
|
||||
return False
|
||||
|
||||
|
||||
#**************************** MAIL SENDING FEATURES ***********************#
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def send_mail(self, cr, uid, ids, addresses, subject='', body=None, payload=None, message_id=None, context=None):
|
||||
#TODO: Replace all this with a single email object
|
||||
if body is None:
|
||||
|
@ -294,7 +256,7 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
if context is None:
|
||||
context = {}
|
||||
logger = netsvc.Logger()
|
||||
for id in ids:
|
||||
for id in ids:
|
||||
core_obj = self.browse(cr, uid, id, context)
|
||||
serv = self.smtp_connection(cr, uid, id)
|
||||
if serv:
|
||||
|
@ -307,7 +269,7 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
text_part = MIMEMultipart(_subtype=text_subtype)
|
||||
payload_part.attach(text_part)
|
||||
else:
|
||||
# otherwise a single multipart/mixed will do the whole job
|
||||
# otherwise a single multipart/mixed will do the whole job
|
||||
payload_part = text_part = MIMEMultipart(_subtype=text_subtype)
|
||||
|
||||
if subject:
|
||||
|
@ -322,7 +284,7 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
payload_part['From'] = sender_name + " <" + core_obj.email_id + ">"
|
||||
payload_part['Organization'] = tools.ustr(core_obj.user.company_id.name)
|
||||
payload_part['Date'] = formatdate()
|
||||
addresses_l = extract_emails_from_dict(addresses)
|
||||
addresses_l = extract_emails_from_dict(addresses)
|
||||
if addresses_l['To']:
|
||||
payload_part['To'] = u','.join(addresses_l['To'])
|
||||
if addresses_l['CC']:
|
||||
|
@ -430,28 +392,28 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
e)
|
||||
)
|
||||
return date_as_date
|
||||
|
||||
|
||||
def send_receive(self, cr, uid, ids, context=None):
|
||||
for id in ids:
|
||||
ctx = context.copy()
|
||||
ctx['filters'] = [('account_id', '=', id)]
|
||||
self.pool.get('email_template.mailbox').send_all_mail(cr, uid, [], context=ctx)
|
||||
return True
|
||||
|
||||
|
||||
def decode_header_text(self, text):
|
||||
""" Decode internationalized headers RFC2822.
|
||||
To, CC, BCC, Subject fields can contain
|
||||
To, CC, BCC, Subject fields can contain
|
||||
text slices with different encodes, like:
|
||||
=?iso-8859-1?Q?Enric_Mart=ED?= <enricmarti@company.com>,
|
||||
=?iso-8859-1?Q?Enric_Mart=ED?= <enricmarti@company.com>,
|
||||
=?Windows-1252?Q?David_G=F3mez?= <david@company.com>
|
||||
Sometimes they include extra " character at the beginning/
|
||||
end of the contact name, like:
|
||||
"=?iso-8859-1?Q?Enric_Mart=ED?=" <enricmarti@company.com>
|
||||
and decode_header() does not work well, so we use regular
|
||||
and decode_header() does not work well, so we use regular
|
||||
expressions (?= ? ? ?=) to split the text slices
|
||||
"""
|
||||
if not text:
|
||||
return text
|
||||
return text
|
||||
p = re.compile("(=\?.*?\?.\?.*?\?=)")
|
||||
text2 = ''
|
||||
try:
|
||||
|
@ -465,6 +427,6 @@ unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
|||
return text
|
||||
return text2
|
||||
|
||||
email_template_account()
|
||||
email_smtp_server()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -2,19 +2,19 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<menuitem name="Marketing" icon="terp-crm" id="base.marketing_menu" sequence="17"
|
||||
groups="marketing.group_marketing_user,marketing.group_marketing_manager"/>
|
||||
<menuitem name="Marketing" icon="terp-crm" id="base.marketing_menu" sequence="17"/>
|
||||
<menuitem name="Emails" id="base.menu_emails" parent="base.marketing_menu" sequence="5"/>
|
||||
<menuitem name="Email Template" id="menu_email_template" parent="base.menu_emails"/>
|
||||
<menuitem name="Email Smtp Server" id="menu_email_smtp" parent="base.menu_emails"/>
|
||||
|
||||
<record model="ir.ui.view" id="email_template_account_form">
|
||||
<field name="name">email_template.account.form</field>
|
||||
<field name="model">email_template.account</field>
|
||||
<record model="ir.ui.view" id="email_smtp_server_form">
|
||||
<field name="name">email.smtp_server.form</field>
|
||||
<field name="model">email.smtp_server</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email Account Configuration">
|
||||
<form string="Email Smtp Server Configuration">
|
||||
<group colspan="2">
|
||||
<field name="name" select="1" />
|
||||
<field name="default"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Outgoing">
|
||||
|
@ -25,18 +25,14 @@
|
|||
<field name="smtpport" select="2" />
|
||||
<field name="smtpssl" select="2" />
|
||||
<field name="smtptls" select="2" />
|
||||
<field name="auto_delete" />
|
||||
</group>
|
||||
<separator string="User Information" colspan="4" />
|
||||
<group col="2" colspan="2">
|
||||
<field name="email_id" select="1" colspan="2" />
|
||||
<field name="smtppass" password="True" colspan="2" />
|
||||
<field name="company" select="2" colspan="2" />
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<field name="smtpuname" select="1" colspan="2" />
|
||||
<field name="user" select="2" colspan="2" />
|
||||
<field name="send_pref" colspan="2" />
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
|
@ -51,53 +47,46 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="email_template_account_tree">
|
||||
<field name="name">email_template.account.tree</field>
|
||||
<field name="model">email_template.account</field>
|
||||
<record model="ir.ui.view" id="email_smtp_server_tree">
|
||||
<field name="name">email.smtp_server.tree</field>
|
||||
<field name="model">email.smtp_server</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('suspended','approved')" string="Email Accounts">
|
||||
<field name="name" />
|
||||
<field name="email_id" />
|
||||
<field name="smtpuname" />
|
||||
<field name="user" />
|
||||
<field name="smtpserver" />
|
||||
<field name="smtpport" />
|
||||
<field name="auto_delete" />
|
||||
<field name="state" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_email_template_account_search" model="ir.ui.view">
|
||||
<field name="name">email_template.account.search</field>
|
||||
<field name="model">email_template.account</field>
|
||||
<record id="view_email_smtp_server_search" model="ir.ui.view">
|
||||
<field name="name">email_smtp.server.search</field>
|
||||
<field name="model">email.smtp_server</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Email Accounts">
|
||||
<search string="Email Smtp Server">
|
||||
<filter icon="terp-document-new" string="Draft" name="draft" domain="[('state','=','draft')]"/>
|
||||
<filter icon="terp-camera_test" string="Approved" domain="[('state','=','approved')]"/>
|
||||
<filter icon="terp-emblem-important" string="Suspended" domain="[('state','=','suspended')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-home" string="Company Accounts" domain="[('company','=','yes')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="user" select="1">
|
||||
<filter icon="terp-personal" help="My Accounts" name="my" domain="[('user','=',uid)]"/>
|
||||
</field>
|
||||
<field name="name" select="1"/>
|
||||
<field name="email_id" select="1"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_template_account_tree_all">
|
||||
<field name="name">Accounts</field>
|
||||
<field name="res_model">email_template.account</field>
|
||||
<record model="ir.actions.act_window" id="action_email_smtp_server_tree_all">
|
||||
<field name="name">Smtp Server</field>
|
||||
<field name="res_model">email.smtp_server</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form,tree</field>
|
||||
<field name="view_id" ref="email_template_account_tree" />
|
||||
<field name="view_id" ref="email_smtp_server_tree" />
|
||||
<field name="context">{'group_by': [], 'search_default_draft': 1, 'search_default_my': 1}</field>
|
||||
<field name="search_view_id" ref="view_email_template_account_search"/>
|
||||
<field name="search_view_id" ref="view_email_smtp_server_search"/>
|
||||
</record>
|
||||
|
||||
<menuitem name="Configuration" parent="base.marketing_menu"
|
||||
|
@ -105,7 +94,7 @@
|
|||
|
||||
<menuitem name="Email Template" id="menu_email_template_configuration" parent="base.menu_marketing_config_root" />
|
||||
|
||||
<menuitem name="Email Accounts" id="menu_email_template_account_all" parent="menu_email_template_configuration" action="action_email_template_account_tree_all"/>
|
||||
<menuitem name="Email Smtp Server" id="menu_email_smtp_server_all" parent="menu_email_template_configuration" action="action_email_smtp_server_tree_all"/>
|
||||
|
||||
<menuitem name="Configuration" parent="base.menu_tools"
|
||||
id="base.menu_lunch_survey_root" sequence="20" />
|
||||
|
@ -113,8 +102,8 @@
|
|||
<menuitem name="Email Template" id="menu_email_template_config_tools"
|
||||
parent="base.menu_lunch_survey_root" />
|
||||
|
||||
<menuitem name="Email Accounts" id="menu_email_account_all_tools"
|
||||
parent="menu_email_template_config_tools" action="action_email_template_account_tree_all" />
|
||||
<menuitem name="Email Smtp Server" id="menu_email_account_all_tools"
|
||||
parent="menu_email_template_config_tools" action="action_email_smtp_server_tree_all" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<record id="email_smtp_server_administrator0" model="email.smtp_server">
|
||||
<field name="name">Administrator</field>
|
||||
<field eval="0" name="default"/>
|
||||
<field eval="1" name="smtptls"/>
|
||||
<field name="email_id">example@test.com</field>
|
||||
<field name="state">draft</field>
|
||||
<field eval="25" name="smtpport"/>
|
||||
<field name="smtpserver">localhost</field>
|
||||
<field eval="0" name="smtpssl"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -220,7 +220,7 @@ class mailgate_message(osv.osv):
|
|||
action_data = False
|
||||
action_pool = self.pool.get('ir.actions.act_window')
|
||||
message_pool = self.browse(cr ,uid, ids, context=context)[0]
|
||||
att_ids = [x.id for x in message_pool.attachment_ids]
|
||||
att_ids = [x.id for x in message_pool.attachment_ids]
|
||||
action_ids = action_pool.search(cr, uid, [('res_model', '=', 'ir.attachment')])
|
||||
if action_ids:
|
||||
action_data = action_pool.read(cr, uid, action_ids[0], context=context)
|
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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 email_gateway
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -28,11 +28,10 @@
|
|||
* Easy Integration with any Module""",
|
||||
'author': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base'],
|
||||
'depends': ['base','email'],
|
||||
'init_xml': [],
|
||||
'update_xml': [
|
||||
"mail_gateway_view.xml",
|
||||
"res_partner_view.xml",
|
||||
"email_gateway_view.xml",
|
||||
'security/ir.model.access.csv'
|
||||
|
||||
],
|
|
@ -0,0 +1,231 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>)
|
||||
#
|
||||
# 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 osv import osv, fields
|
||||
import time
|
||||
import tools
|
||||
import binascii
|
||||
import email
|
||||
from email.header import decode_header
|
||||
from email.utils import parsedate
|
||||
import base64
|
||||
import re
|
||||
from tools.translate import _
|
||||
import logging
|
||||
import xmlrpclib
|
||||
|
||||
_logger = logging.getLogger('mailgate')
|
||||
|
||||
def format_date_tz(date, tz=None):
|
||||
if not date:
|
||||
return 'n/a'
|
||||
format = tools.DEFAULT_SERVER_DATETIME_FORMAT
|
||||
return tools.server_to_local_timestamp(date, format, format, tz)
|
||||
|
||||
class email_message(osv.osv):
|
||||
'''
|
||||
Mailgateway Message
|
||||
'''
|
||||
def open_document(self, cr, uid, ids, context=None):
|
||||
""" To Open Document
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param ids: the ID of messages
|
||||
@param context: A standard dictionary
|
||||
"""
|
||||
action_data = False
|
||||
if ids:
|
||||
message_id = ids[0]
|
||||
mailgate_data = self.browse(cr, uid, message_id, context=context)
|
||||
model = mailgate_data.model
|
||||
res_id = mailgate_data.res_id
|
||||
|
||||
action_pool = self.pool.get('ir.actions.act_window')
|
||||
action_ids = action_pool.search(cr, uid, [('res_model', '=', model)])
|
||||
if action_ids:
|
||||
action_data = action_pool.read(cr, uid, action_ids[0], context=context)
|
||||
action_data.update({
|
||||
'domain' : "[('id','=',%d)]"%(res_id),
|
||||
'nodestroy': True,
|
||||
'context': {}
|
||||
})
|
||||
return action_data
|
||||
|
||||
def open_attachment(self, cr, uid, ids, context=None):
|
||||
""" To Open attachments
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param ids: the ID of messages
|
||||
@param context: A standard dictionary
|
||||
"""
|
||||
action_data = False
|
||||
action_pool = self.pool.get('ir.actions.act_window')
|
||||
message_pool = self.browse(cr ,uid, ids, context=context)[0]
|
||||
att_ids = [x.id for x in message_pool.attachment_ids]
|
||||
action_ids = action_pool.search(cr, uid, [('res_model', '=', 'ir.attachment')])
|
||||
if action_ids:
|
||||
action_data = action_pool.read(cr, uid, action_ids[0], context=context)
|
||||
action_data.update({
|
||||
'domain': [('id','in',att_ids)],
|
||||
'nodestroy': True
|
||||
})
|
||||
return action_data
|
||||
|
||||
def truncate_data(self, cr, uid, data, context=None):
|
||||
data_list = data and data.split('\n') or []
|
||||
if len(data_list) > 3:
|
||||
res = '\n\t'.join(data_list[:3]) + '...'
|
||||
else:
|
||||
res = '\n\t'.join(data_list)
|
||||
return res
|
||||
|
||||
def _get_display_text(self, cr, uid, ids, name, arg, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
tz = context.get('tz')
|
||||
result = {}
|
||||
for message in self.browse(cr, uid, ids, context=context):
|
||||
msg_txt = ''
|
||||
if message.history:
|
||||
msg_txt += (message.email_from or '/') + _(' wrote on ') + format_date_tz(message.date, tz) + ':\n\t'
|
||||
if message.description:
|
||||
msg_txt += self.truncate_data(cr, uid, message.description, context=context)
|
||||
else:
|
||||
msg_txt = (message.user_id.name or '/') + _(' on ') + format_date_tz(message.date, tz) + ':\n\t'
|
||||
if message.name == _('Opportunity'):
|
||||
msg_txt += _("Converted to Opportunity")
|
||||
elif message.name == _('Note'):
|
||||
msg_txt = (message.user_id.name or '/') + _(' added note on ') + format_date_tz(message.date, tz) + ':\n\t'
|
||||
msg_txt += self.truncate_data(cr, uid, message.description, context=context)
|
||||
elif message.name == _('Stage'):
|
||||
msg_txt += _("Changed Stage to: ") + message.description
|
||||
else:
|
||||
msg_txt += _("Changed Status to: ") + message.name
|
||||
result[message.id] = msg_txt
|
||||
return result
|
||||
|
||||
_name = 'email.message'
|
||||
_description = 'Email Message'
|
||||
_order = 'date desc'
|
||||
_columns = {
|
||||
'name':fields.text('Subject', readonly=True),
|
||||
'model': fields.char('Object Name', size=128, select=1, readonly=True),
|
||||
'res_id': fields.integer('Resource ID', select=1, readonly=True),
|
||||
'ref_id': fields.char('Reference Id', size=256, readonly=True, help="Message Id in Email Server.", select=True),
|
||||
'date': fields.datetime('Date', readonly=True),
|
||||
'history': fields.boolean('Is History?', readonly=True),
|
||||
'user_id': fields.many2one('res.users', 'User Responsible', readonly=True),
|
||||
'message': fields.text('Description', readonly=True),
|
||||
'email_from': fields.char('From', size=128, help="Email From", readonly=True),
|
||||
'email_to': fields.char('To', help="Email Recipients", size=256, readonly=True),
|
||||
'email_cc': fields.char('Cc', help="Carbon Copy Email Recipients", size=256, readonly=True),
|
||||
'email_bcc': fields.char('Bcc', help='Blind Carbon Copy Email Recipients', size=256, readonly=True),
|
||||
'message_id': fields.char('Message Id', size=1024, readonly=True, help="Message Id on Email.", select=True),
|
||||
'references': fields.text('References', readonly=True, help="References emails."),
|
||||
'description': fields.text('Description', readonly=True),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', required=False),
|
||||
'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel', 'message_id', 'attachment_id', 'Attachments', readonly=True),
|
||||
'display_text': fields.function(_get_display_text, method=True, type='text', size="512", string='Display Text'),
|
||||
'reply_to':fields.char('Reply-To', size=250, readonly=True),
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
cr.execute("""SELECT indexname
|
||||
FROM pg_indexes
|
||||
WHERE indexname = 'mailgate_message_res_id_model_idx'""")
|
||||
if not cr.fetchone():
|
||||
cr.execute("""CREATE INDEX mailgate_message_res_id_model_idx
|
||||
ON mailgate_message (model, res_id)""")
|
||||
|
||||
# def run_mail_scheduler(self, cursor, user, context=None):
|
||||
# """
|
||||
# This method is called by OpenERP Scheduler
|
||||
# to periodically send emails
|
||||
# """
|
||||
# try:
|
||||
# self.send_all_mail(cursor, user, context=context)
|
||||
# except Exception, e:
|
||||
# LOGGER.notifyChannel(
|
||||
# "Email Template",
|
||||
# netsvc.LOG_ERROR,
|
||||
# _("Error sending mail: %s") % e)
|
||||
#
|
||||
# def send_all_mail(self, cr, uid, ids=None, context=None):
|
||||
# if ids is None:
|
||||
# ids = []
|
||||
# if context is None:
|
||||
# context = {}
|
||||
# filters = [('folder', '=', 'outbox'), ('state', '!=', 'sending')]
|
||||
# if 'filters' in context.keys():
|
||||
# for each_filter in context['filters']:
|
||||
# filters.append(each_filter)
|
||||
# ids = self.search(cr, uid, filters, context=context)
|
||||
# self.write(cr, uid, ids, {'state':'sending'}, context)
|
||||
# self.send_this_mail(cr, uid, ids, context)
|
||||
# return True
|
||||
#
|
||||
# def send_this_mail(self, cr, uid, ids=None, context=None):
|
||||
# #previous method to send email (link with email account can be found at the revision 4172 and below
|
||||
# result = True
|
||||
# attachment_pool = self.pool.get('ir.attachment')
|
||||
# for id in (ids or []):
|
||||
# try:
|
||||
# account_obj = self.pool.get('email.smtp_server')
|
||||
# values = self.read(cr, uid, id, [], context)
|
||||
# payload = {}
|
||||
# if values['attachments_ids']:
|
||||
# for attid in values['attachments_ids']:
|
||||
# attachment = attachment_pool.browse(cr, uid, attid, context)#,['datas_fname','datas'])
|
||||
# payload[attachment.datas_fname] = attachment.datas
|
||||
# result = account_obj.send_mail(cr, uid,
|
||||
# [values['account_id'][0]],
|
||||
# {'To':values.get('email_to') or u'',
|
||||
# 'CC':values.get('email_cc') or u'',
|
||||
# 'BCC':values.get('email_bcc') or u'',
|
||||
# 'Reply-To':values.get('reply_to') or u''},
|
||||
# values['subject'] or u'',
|
||||
# {'text':values.get('body_text') or u'', 'html':values.get('body_html') or u''},
|
||||
# payload=payload,
|
||||
# message_id=values['message_id'],
|
||||
# context=context)
|
||||
# if result == True:
|
||||
# account = account_obj.browse(cr, uid, values['account_id'][0], context=context)
|
||||
# if account.auto_delete:
|
||||
# self.write(cr, uid, id, {'folder': 'trash'}, context=context)
|
||||
# self.unlink(cr, uid, [id], context=context)
|
||||
# # Remove attachments for this mail
|
||||
# attachment_pool.unlink(cr, uid, values['attachments_ids'], context=context)
|
||||
# else:
|
||||
# self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context)
|
||||
# else:
|
||||
# error = result['error_msg']
|
||||
#
|
||||
# except Exception, error:
|
||||
# logger = netsvc.Logger()
|
||||
# logger.notifyChannel("email-template", netsvc.LOG_ERROR, _("Sending of Mail %s failed. Probable Reason:Could not login to server\nError: %s") % (id, error))
|
||||
# self.write(cr, uid, id, {'state':'na'}, context)
|
||||
# return result
|
||||
|
||||
email_message()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view" id="view_email_message_form">
|
||||
<field name="name">email.message.form</field>
|
||||
<field name="model">email.message</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email message">
|
||||
<group colspan="4" col="6">
|
||||
<field name="name" string="Subject" required="1"/>
|
||||
<field name="date" required="1"/>
|
||||
<field name="user_id" string="Owner"/>
|
||||
<field name="partner_id" readonly="1" />
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Details">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Email Followers" colspan="4"/>
|
||||
<field name="email_from" />
|
||||
<field name="email_to"/>
|
||||
<field name="email_cc"/>
|
||||
<field name="email_bcc" groups="base.group_extended"/>
|
||||
<field name="reply_to"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Message Details" colspan="4"/>
|
||||
<field name="model" readonly="1"/>
|
||||
<group col="3" colspan="2">
|
||||
<field name="res_id" readonly="1"/>
|
||||
<button name="open_document" string="Open Document" type="object" icon="gtk-jump-to"/>
|
||||
</group>
|
||||
<field name="message_id"/>
|
||||
<field name="ref_id"/>
|
||||
</group>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="description" nolabel="1" colspan="4" />
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
<separator string="Attachments" colspan="4"/>
|
||||
<field name="attachment_ids" nolabel="1" colspan="4" readonly="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_email_message_tree">
|
||||
<field name="name">email.message.tree</field>
|
||||
<field name="model">email.message</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Emails">
|
||||
<field name="date" />
|
||||
<field name="name" string="Subject"/>
|
||||
<field name="email_from" string="From"/>
|
||||
<field name="user_id" string="Owner"/>
|
||||
<field name="message_id" string="Message" invisible="1"/>
|
||||
<field name="partner_id" invisible="1"/>
|
||||
<button name="open_document" string="Open Document" type="object" icon="gtk-jump-to"/>
|
||||
<button name="open_attachment" string="Open Attachments" type="object" icon="gtk-jump-to"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_email_message_search">
|
||||
<field name="name">email.message.search</field>
|
||||
<field name="model">email.message</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Email Search">
|
||||
<field name="name" string="Subject"/>
|
||||
<field name="date" />
|
||||
<field name="user_id" string="Owner"/>
|
||||
<field name="partner_id" string="Partner Name"/>
|
||||
<newline/>
|
||||
<group expand="0" string="Group By..." groups="base.group_extended">
|
||||
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
|
||||
<filter string="Owner" name="User" icon="terp-personal" context="{'group_by':'user_id'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Thread" icon="terp-mail-" domain="[]" context="{'group_by':'message_id'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Month" help="Creation Month" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_mail_message" model="ir.actions.act_window">
|
||||
<field name="name">Messages</field>
|
||||
<field name="res_model">email.message</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_email_message_search"/>
|
||||
</record>
|
||||
|
||||
<act_window domain="[('partner_id', '=', active_id), ('history', '=', True)]"
|
||||
id="act_res_partner_emails" name="Emails"
|
||||
res_model="mailgate.message"
|
||||
src_model="res.partner"
|
||||
view_id="view_email_message_tree"/>
|
||||
|
||||
<act_window
|
||||
id="act_res_partner_open_email" name="Attachments"
|
||||
res_model="ir.attachment"
|
||||
src_model="mailgate.message"
|
||||
domain="[('res_id', '=', res_id),('res_model','=',model)]"/>
|
||||
|
||||
<menuitem name="Email Template" id="menu_email_template_tools"
|
||||
parent="base.menu_tools" />
|
||||
|
||||
<menuitem name="Emails"
|
||||
id="menu_email_message"
|
||||
parent="menu_email_template_tools"
|
||||
action="action_view_mail_message" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1 @@
|
|||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
|
|
@ -20,8 +20,6 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import email_template_account
|
||||
import email_template
|
||||
import email_template_mailbox
|
||||
import wizard
|
||||
|
||||
|
|
|
@ -26,18 +26,16 @@
|
|||
"author" : "Openlabs",
|
||||
"website" : "http://openerp.com",
|
||||
"category" : "Added functionality",
|
||||
"depends" : ['marketing', 'base_tools'],
|
||||
"depends" : ['marketing', 'base_tools', 'email'],
|
||||
"description": """
|
||||
Email Template is extraction of Power Email basically just to send the emails.
|
||||
""",
|
||||
"init_xml": ['email_template_scheduler_data.xml'],
|
||||
"update_xml": [
|
||||
'security/email_template_security.xml',
|
||||
'email_template_workflow.xml',
|
||||
'email_template_account_view.xml',
|
||||
'email_template_view.xml',
|
||||
'email_template_mailbox_view.xml',
|
||||
'wizard/email_template_send_wizard_view.xml',
|
||||
'wizard/email_template_preview_view.xml',
|
||||
'security/ir.model.access.csv'
|
||||
],
|
||||
"installable": True,
|
||||
|
|
|
@ -36,17 +36,6 @@ try:
|
|||
TEMPLATE_ENGINES.append(('mako', 'Mako Templates'))
|
||||
except ImportError:
|
||||
logging.getLogger('init').warning("module email_template: Mako templates not installed")
|
||||
|
||||
try:
|
||||
from django.template import Context, Template as DjangoTemplate
|
||||
#Workaround for bug:
|
||||
#http://code.google.com/p/django-tagging/issues/detail?id=110
|
||||
from django.conf import settings
|
||||
settings.configure()
|
||||
#Workaround ends
|
||||
TEMPLATE_ENGINES.append(('django', 'Django Template'))
|
||||
except ImportError:
|
||||
logging.getLogger('init').warning("module email_template: Django templates not installed")
|
||||
|
||||
import tools
|
||||
import pooler
|
||||
|
@ -117,7 +106,7 @@ class email_template(osv.osv):
|
|||
'object_name':fields.many2one('ir.model', 'Resource'),
|
||||
'model_int_name':fields.char('Model Internal Name', size=200,),
|
||||
'from_account':fields.many2one(
|
||||
'email_template.account',
|
||||
'email.smtp_server',
|
||||
string="Email Account",
|
||||
help="Emails will be sent from this approved account."),
|
||||
'def_to':fields.char(
|
||||
|
@ -250,7 +239,8 @@ This is useful for CRM leads for example"),
|
|||
TEMPLATE_ENGINES,
|
||||
'Templating Language',
|
||||
required=True
|
||||
)
|
||||
),
|
||||
'auto_delete': fields.boolean('Auto Delete', help="Permanently delete emails after sending"),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -542,7 +532,7 @@ This is useful for CRM leads for example"),
|
|||
context = {}
|
||||
#If account to send from is in context select it, else use enforced account
|
||||
if 'account_id' in context.keys():
|
||||
from_account = self.pool.get('email_template.account').read(
|
||||
from_account = self.pool.get('email.smtp_server').read(
|
||||
cursor,
|
||||
user,
|
||||
context.get('account_id'),
|
||||
|
@ -708,115 +698,7 @@ This is useful for CRM leads for example"),
|
|||
|
||||
email_template()
|
||||
|
||||
|
||||
## FIXME: this class duplicates a lot of features of the email template send wizard,
|
||||
## one of the 2 should inherit from the other!
|
||||
|
||||
class email_template_preview(osv.osv_memory):
|
||||
_name = "email_template.preview"
|
||||
_description = "Email Template Preview"
|
||||
|
||||
def _get_model_recs(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
#Fills up the selection box which allows records from the selected object to be displayed
|
||||
self.context = context
|
||||
if 'template_id' in context:
|
||||
ref_obj_id = self.pool.get('email.template').read(cr, uid, context['template_id'], ['object_name'], context)
|
||||
ref_obj_name = self.pool.get('ir.model').read(cr, uid, ref_obj_id['object_name'][0], ['model'], context)['model']
|
||||
model_obj = self.pool.get(ref_obj_name)
|
||||
ref_obj_ids = model_obj.search(cr, uid, [], 0, 20, 'id', context=context)
|
||||
if not ref_obj_ids:
|
||||
ref_obj_ids = []
|
||||
|
||||
# also add the default one if requested, otherwise it won't be available for selection:
|
||||
default_id = context.get('default_rel_model_ref')
|
||||
if default_id and default_id not in ref_obj_ids:
|
||||
ref_obj_ids.insert(0, default_id)
|
||||
return model_obj.name_get(cr, uid, ref_obj_ids, context)
|
||||
return []
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = super(email_template_preview, self).default_get(cr, uid, fields, context=context)
|
||||
if (not fields or 'rel_model_ref' in fields) and 'template_id' in context \
|
||||
and not result.get('rel_model_ref'):
|
||||
selectables = self._get_model_recs(cr, uid, context=context)
|
||||
result['rel_model_ref'] = selectables and selectables[0][0] or False
|
||||
return result
|
||||
|
||||
def _default_model(self, cursor, user, context=None):
|
||||
"""
|
||||
Returns the default value for model field
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of current user
|
||||
@param context: OpenERP Context
|
||||
"""
|
||||
return self.pool.get('email.template').read(
|
||||
cursor,
|
||||
user,
|
||||
context['template_id'],
|
||||
['object_name'],
|
||||
context).get('object_name', False)
|
||||
|
||||
_columns = {
|
||||
'ref_template':fields.many2one(
|
||||
'email.template',
|
||||
'Template', readonly=True),
|
||||
'rel_model':fields.many2one('ir.model', 'Model', readonly=True),
|
||||
'rel_model_ref':fields.selection(_get_model_recs, 'Referred Document'),
|
||||
'to':fields.char('To', size=250, readonly=True),
|
||||
'cc':fields.char('CC', size=250, readonly=True),
|
||||
'bcc':fields.char('BCC', size=250, readonly=True),
|
||||
'reply_to':fields.char('Reply-To',
|
||||
size=250,
|
||||
help="The address recipients should reply to,"
|
||||
" if different from the From address."
|
||||
" Placeholders can be used here."),
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
help="The Message-ID header value, if you need to"
|
||||
"specify it, for example to automatically recognize the replies later."
|
||||
" Placeholders can be used here."),
|
||||
'subject':fields.char('Subject', size=200, readonly=True),
|
||||
'body_text':fields.text('Body', readonly=True),
|
||||
'body_html':fields.text('Body', readonly=True),
|
||||
'report':fields.char('Report Name', size=100, readonly=True),
|
||||
}
|
||||
_defaults = {
|
||||
'ref_template': lambda self, cr, uid, ctx:ctx['template_id'] or False,
|
||||
'rel_model': _default_model,
|
||||
}
|
||||
def on_change_ref(self, cr, uid, ids, rel_model_ref, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if not rel_model_ref:
|
||||
return {}
|
||||
vals = {}
|
||||
if context == {}:
|
||||
context = self.context
|
||||
template = self.pool.get('email.template').browse(cr, uid, context['template_id'], context)
|
||||
#Search translated template
|
||||
lang = get_value(cr, uid, rel_model_ref, template.lang, template, context)
|
||||
if lang:
|
||||
ctx = context.copy()
|
||||
ctx.update({'lang':lang})
|
||||
template = self.pool.get('email.template').browse(cr, uid, context['template_id'], ctx)
|
||||
vals['to'] = get_value(cr, uid, rel_model_ref, template.def_to, template, context)
|
||||
vals['cc'] = get_value(cr, uid, rel_model_ref, template.def_cc, template, context)
|
||||
vals['bcc'] = get_value(cr, uid, rel_model_ref, template.def_bcc, template, context)
|
||||
vals['reply_to'] = get_value(cr, uid, rel_model_ref, template.reply_to, template, context)
|
||||
if template.message_id:
|
||||
vals['message_id'] = get_value(cr, uid, rel_model_ref, template.message_id, template, context)
|
||||
elif template.track_campaign_item:
|
||||
vals['message_id'] = tools.misc.generate_tracking_message_id(rel_model_ref)
|
||||
vals['subject'] = get_value(cr, uid, rel_model_ref, template.def_subject, template, context)
|
||||
vals['body_text'] = get_value(cr, uid, rel_model_ref, template.def_body_text, template, context)
|
||||
vals['body_html'] = get_value(cr, uid, rel_model_ref, template.def_body_html, template, context)
|
||||
vals['report'] = get_value(cr, uid, rel_model_ref, template.file_name, template, context)
|
||||
return {'value':vals}
|
||||
|
||||
email_template_preview()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,213 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
import time
|
||||
import netsvc
|
||||
from tools.translate import _
|
||||
import tools
|
||||
|
||||
LOGGER = netsvc.Logger()
|
||||
|
||||
class email_template_mailbox(osv.osv):
|
||||
_name = "email_template.mailbox"
|
||||
_description = 'Email Mailbox'
|
||||
_rec_name = "subject"
|
||||
_order = "date_mail desc"
|
||||
|
||||
def run_mail_scheduler(self, cursor, user, context=None):
|
||||
"""
|
||||
This method is called by OpenERP Scheduler
|
||||
to periodically send emails
|
||||
"""
|
||||
try:
|
||||
self.send_all_mail(cursor, user, context=context)
|
||||
except Exception, e:
|
||||
LOGGER.notifyChannel(
|
||||
"Email Template",
|
||||
netsvc.LOG_ERROR,
|
||||
_("Error sending mail: %s") % e)
|
||||
|
||||
def send_all_mail(self, cr, uid, ids=None, context=None):
|
||||
if ids is None:
|
||||
ids = []
|
||||
if context is None:
|
||||
context = {}
|
||||
filters = [('folder', '=', 'outbox'), ('state', '!=', 'sending')]
|
||||
if 'filters' in context.keys():
|
||||
for each_filter in context['filters']:
|
||||
filters.append(each_filter)
|
||||
ids = self.search(cr, uid, filters, context=context)
|
||||
self.write(cr, uid, ids, {'state':'sending'}, context)
|
||||
self.send_this_mail(cr, uid, ids, context)
|
||||
return True
|
||||
|
||||
def send_this_mail(self, cr, uid, ids=None, context=None):
|
||||
#previous method to send email (link with email account can be found at the revision 4172 and below
|
||||
result = True
|
||||
attachment_pool = self.pool.get('ir.attachment')
|
||||
for id in (ids or []):
|
||||
try:
|
||||
account_obj = self.pool.get('email_template.account')
|
||||
values = self.read(cr, uid, id, [], context)
|
||||
payload = {}
|
||||
if values['attachments_ids']:
|
||||
for attid in values['attachments_ids']:
|
||||
attachment = attachment_pool.browse(cr, uid, attid, context)#,['datas_fname','datas'])
|
||||
payload[attachment.datas_fname] = attachment.datas
|
||||
result = account_obj.send_mail(cr, uid,
|
||||
[values['account_id'][0]],
|
||||
{'To':values.get('email_to') or u'',
|
||||
'CC':values.get('email_cc') or u'',
|
||||
'BCC':values.get('email_bcc') or u'',
|
||||
'Reply-To':values.get('reply_to') or u''},
|
||||
values['subject'] or u'',
|
||||
{'text':values.get('body_text') or u'', 'html':values.get('body_html') or u''},
|
||||
payload=payload,
|
||||
message_id=values['message_id'],
|
||||
context=context)
|
||||
if result == True:
|
||||
account = account_obj.browse(cr, uid, values['account_id'][0], context=context)
|
||||
if account.auto_delete:
|
||||
self.write(cr, uid, id, {'folder': 'trash'}, context=context)
|
||||
self.unlink(cr, uid, [id], context=context)
|
||||
# Remove attachments for this mail
|
||||
attachment_pool.unlink(cr, uid, values['attachments_ids'], context=context)
|
||||
else:
|
||||
self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context)
|
||||
self.historise(cr, uid, [id], "Email sent successfully", context)
|
||||
else:
|
||||
error = result['error_msg']
|
||||
self.historise(cr, uid, [id], error, context)
|
||||
|
||||
except Exception, error:
|
||||
logger = netsvc.Logger()
|
||||
logger.notifyChannel("email-template", netsvc.LOG_ERROR, _("Sending of Mail %s failed. Probable Reason:Could not login to server\nError: %s") % (id, error))
|
||||
self.historise(cr, uid, [id], error, context)
|
||||
self.write(cr, uid, id, {'state':'na'}, context)
|
||||
return result
|
||||
|
||||
def historise(self, cr, uid, ids, message='', context=None):
|
||||
for id in ids:
|
||||
history = self.read(cr, uid, id, ['history'], context).get('history', '')
|
||||
self.write(cr, uid, id, {'history': (history or '' )+ "\n" + time.strftime("%Y-%m-%d %H:%M:%S") + ": " + tools.ustr(message)}, context)
|
||||
|
||||
_columns = {
|
||||
'email_from':fields.char(
|
||||
'From',
|
||||
size=64),
|
||||
'email_to':fields.char(
|
||||
'Recipient (To)',
|
||||
size=250,),
|
||||
'email_cc':fields.char(
|
||||
'CC',
|
||||
size=250),
|
||||
'email_bcc':fields.char(
|
||||
'BCC',
|
||||
size=250),
|
||||
'reply_to':fields.char(
|
||||
'Reply-To',
|
||||
size=250),
|
||||
'message_id':fields.char(
|
||||
'Message-ID',
|
||||
size=250),
|
||||
'subject':fields.char(
|
||||
'Subject',
|
||||
size=200,),
|
||||
'body_text':fields.text(
|
||||
'Standard Body (Text)'),
|
||||
'body_html':fields.text(
|
||||
'Body (Rich Text Clients Only)'),
|
||||
'attachments_ids':fields.many2many(
|
||||
'ir.attachment',
|
||||
'mail_attachments_rel',
|
||||
'mail_id',
|
||||
'att_id',
|
||||
'Attachments'),
|
||||
'account_id' :fields.many2one(
|
||||
'email_template.account',
|
||||
'User account',
|
||||
required=True),
|
||||
'user':fields.related(
|
||||
'account_id',
|
||||
'user',
|
||||
type="many2one",
|
||||
relation="res.users",
|
||||
string="User"),
|
||||
'server_ref':fields.integer(
|
||||
'Server Reference of mail',
|
||||
help="Applicable for inward items only"),
|
||||
'mail_type':fields.selection([
|
||||
('multipart/mixed',
|
||||
'Has Attachments'),
|
||||
('multipart/alternative',
|
||||
'Plain Text & HTML with no attachments'),
|
||||
('multipart/related',
|
||||
'Intermixed content'),
|
||||
('text/plain',
|
||||
'Plain Text'),
|
||||
('text/html',
|
||||
'HTML Body'),
|
||||
], 'Mail Contents'),
|
||||
#I like GMAIL which allows putting same mail in many folders
|
||||
#Lets plan it for 0.9
|
||||
'folder':fields.selection([
|
||||
('drafts', 'Drafts'),
|
||||
('outbox', 'Outbox'),
|
||||
('trash', 'Trash'),
|
||||
('sent', 'Sent Items'),
|
||||
], 'Folder', required=True),
|
||||
'state':fields.selection([
|
||||
('na', 'Not Applicable'),
|
||||
('sending', 'Sending'),
|
||||
], 'Status', required=True),
|
||||
'date_mail':fields.datetime('Rec/Sent Date', help="Date on which Email Sent or Received"),
|
||||
'history':fields.text(
|
||||
'History',
|
||||
readonly=True,
|
||||
store=True)
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': lambda * a: 'na',
|
||||
'folder': lambda * a: 'outbox',
|
||||
}
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
It just changes the folder of the item to "Trash", if it is no in Trash folder yet,
|
||||
or completely deletes it if it is already in Trash.
|
||||
"""
|
||||
to_update = []
|
||||
to_remove = []
|
||||
for mail in self.browse(cr, uid, ids, context=context):
|
||||
if mail.folder == 'trash':
|
||||
to_remove.append(mail.id)
|
||||
else:
|
||||
to_update.append(mail.id)
|
||||
# Changes the folder to trash
|
||||
self.write(cr, uid, to_update, {'folder': 'trash'}, context=context)
|
||||
return super(email_template_mailbox, self).unlink(cr, uid, to_remove, context=context)
|
||||
|
||||
email_template_mailbox()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,134 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Email Template-->
|
||||
<record model="ir.ui.view" id="email_template_mailbox_form">
|
||||
<field name="name">email_template.mailbox.form</field>
|
||||
<field name="model">email_template.mailbox</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Emails">
|
||||
<group col="4" colspan="4" name="headers">
|
||||
<field name="email_from" select="1"/>
|
||||
<field name="email_to" required="1" select="1" />
|
||||
<field name="reply_to" select="2"/>
|
||||
<field name="email_cc" select="1"/>
|
||||
<field name="email_bcc" select="2"/>
|
||||
<field name="date_mail" select="2"/>
|
||||
<field name="subject" colspan="4" select="1"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Standard Body">
|
||||
<separator colspan="4" string="Standard Body" />
|
||||
<notebook colspan="4">
|
||||
<page string="Standard Body (Text)">
|
||||
<field name="body_text" nolabel="1" colspan="4" select="1"/>
|
||||
</page>
|
||||
<page string="Body (HTML-Web Client Only)">
|
||||
<field name="body_html" nolabel="1" colspan="4" />
|
||||
</page>
|
||||
</notebook>
|
||||
<separator colspan="4" string="" />
|
||||
<group col="4" colspan="4">
|
||||
<field name="state" readonly="1" string="State"/>
|
||||
<button name="send_this_mail" type="object" string="Send Mail" icon="terp-mail-message-new"/>
|
||||
</group>
|
||||
</page>
|
||||
|
||||
<page string="Attachments">
|
||||
<separator colspan="4" string="Attachments" />
|
||||
<field name="attachments_ids" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
<page string="Advanced">
|
||||
<field name="account_id" colspan="2" />
|
||||
<field name="server_ref" colspan="2" />
|
||||
<field name="mail_type" colspan="2" />
|
||||
<field name="folder" colspan="2" select="2"/>
|
||||
<field name="message_id" select="2"/>
|
||||
<separator string="History" colspan="4" />
|
||||
<field name="history" nolabel="1" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--============================================= TREE VIEWS =============================================-->
|
||||
<record id="view_email_template_mailbox_tree" model="ir.ui.view">
|
||||
<field name="name">email_template.mailbox.tree</field>
|
||||
<field name="model">email_template.mailbox</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Emails" colors="blue:folder=='drafts';grey:folder=='trash'">
|
||||
<field name="subject" select="1" />
|
||||
<field name="user" />
|
||||
<field name="email_from" select="1" />
|
||||
<field name="email_to"/>
|
||||
<field name="date_mail" select="2" />
|
||||
<field name="attachments_ids" select="2" />
|
||||
<field name="folder" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_email_template_mailbox_search" model="ir.ui.view">
|
||||
<field name="name">email_template.mailbox.search</field>
|
||||
<field name="model">email_template.mailbox</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Emails">
|
||||
<filter icon="terp-document-new" string="Drafts" name="draft" domain="[('folder','=','drafts')]"/>
|
||||
<filter icon="terp-mail-" string="Outbox" name="outbox" domain="[('folder','=','outbox')]"/>
|
||||
<filter icon="terp-camera_test" string="Sent" domain="[('folder','=','sent')]"/>
|
||||
<filter icon="terp-mail_delete" string="Trash" domain="[('folder','=','trash')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-personal+" string="Personal Emails" name="personal" domain="[('account_id.company','=','no')]"/>
|
||||
<filter icon="terp-go-home" string="Company Emails" name="company" domain="[('account_id.company','=','yes')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="subject"/>
|
||||
<field name="email_from"/>
|
||||
<field name="user">
|
||||
<filter icon="terp-personal"
|
||||
string="My Emails" help="My Emails" name="myemails"
|
||||
domain="[('account_id.user','=', uid)]" />
|
||||
</field>
|
||||
<newline/>
|
||||
<field name="email_to"/>
|
||||
<field name="date_mail"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_template_mailbox">
|
||||
<field name="name">Emails</field>
|
||||
<field name="res_model">email_template.mailbox</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_email_template_mailbox_tree" />
|
||||
<field name="context">{'group_by': [], 'search_default_outbox': 1}</field>
|
||||
<field name="help">An email template is an email document that will be sent as part of a marketing campaign. You can personalize it according to specific customer profile fields, so that a partner name or other partner related information may be inserted automatically.</field>
|
||||
<field name="search_view_id" ref="view_email_template_mailbox_search"/>
|
||||
</record>
|
||||
|
||||
<!--======================================== MENUS ========================================-->
|
||||
|
||||
<menuitem name="Emails"
|
||||
id="menu_email_template_personal_mails"
|
||||
parent="menu_email_template"
|
||||
action="action_email_template_mailbox" />
|
||||
|
||||
<!-- Mailbox menu in Tools -->
|
||||
<menuitem name="Email Template" id="menu_email_template_tools"
|
||||
parent="base.menu_tools" />
|
||||
|
||||
<menuitem name="Emails"
|
||||
id="menu_email_template_mails_tools"
|
||||
parent="menu_email_template_tools"
|
||||
action="action_email_template_mailbox" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,50 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Email Template Preview -->
|
||||
<record model="ir.ui.view" id="email_template_preview_form">
|
||||
<field name="name">email_template.preview.form</field>
|
||||
<field name="model">email_template.preview</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email Preview">
|
||||
<group col="4" colspan="4">
|
||||
<field name="rel_model" />
|
||||
<field name="rel_model_ref" on_change="on_change_ref(rel_model_ref, context)"/>
|
||||
</group>
|
||||
<group col="8" colspan="4">
|
||||
<field name="to" />
|
||||
<field name="cc" />
|
||||
<field name="bcc" />
|
||||
<field name="reply_to" />
|
||||
<field name="message_id" attrs="{'invisible':[('message_id','=',False)]}" groups="base.group_extended"/>
|
||||
<field name="subject" colspan="8"/>
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<separator string= "Body(Text)" colspan="2"/>
|
||||
<separator string= "Body(Html)" colspan="2"/>
|
||||
<newline/>
|
||||
<field name="body_text" nolabel="1" colspan="2"/>
|
||||
<field name="body_html" nolabel="1" colspan="2"/>
|
||||
</group>
|
||||
<field name="report" colspan="2"/>
|
||||
<button icon="gtk-ok" special="cancel" string="OK" colspan="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="wizard_email_template_preview" model="ir.actions.act_window">
|
||||
<field name="name">Template Preview</field>
|
||||
<field name="res_model">email_template.preview</field>
|
||||
<field name="src_model">email_template.preview</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="auto_refresh" eval="1" />
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'template_id':active_id}</field>
|
||||
</record>
|
||||
<!--EMail client Form view -->
|
||||
|
||||
<record model="ir.ui.view" id="email_template_form">
|
||||
|
@ -124,6 +80,7 @@
|
|||
<group colspan="2" col="2">
|
||||
<separator string="Advanced Options" colspan="2"/>
|
||||
<field name="message_id"/>
|
||||
<field name="auto_delete"/>
|
||||
</group>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
|
@ -201,11 +158,11 @@
|
|||
</record>
|
||||
|
||||
<menuitem name="Email Templates" id="menu_email_template_all"
|
||||
parent="menu_email_template_configuration" action="action_email_template_tree_all" />
|
||||
parent="email.menu_email_template_configuration" action="action_email_template_tree_all" />
|
||||
|
||||
<!-- Email Template menu in Tools -->
|
||||
<menuitem name="Email Templates" id="menu_email_template_all_tools"
|
||||
parent="menu_email_template_config_tools" action="action_email_template_tree_all" />
|
||||
parent="email.menu_email_template_config_tools" action="action_email_template_tree_all" />
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="wkf_email_template_setting" model="workflow">
|
||||
<field name="name">Email Template Workflow</field>
|
||||
<field name="osv">email_template.account</field>
|
||||
<field name="on_create">True</field>
|
||||
</record>
|
||||
|
||||
<!--Activity -->
|
||||
|
||||
<record id="act_draft" model="workflow.activity">
|
||||
<field name="wkf_id" ref="wkf_email_template_setting"/>
|
||||
<field name="flow_start">True</field>
|
||||
<field name="name">draft</field>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'state':'draft'})</field>
|
||||
</record>
|
||||
|
||||
<record id="act_approved" model="workflow.activity">
|
||||
<field name="name">approval</field>
|
||||
<field name="wkf_id" ref="wkf_email_template_setting"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">do_approval()</field>
|
||||
</record>
|
||||
|
||||
<record id="act_suspended" model="workflow.activity">
|
||||
<field name="name">suspended</field>
|
||||
<field name="wkf_id" ref="wkf_email_template_setting"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'state':'suspended'})</field>
|
||||
</record>
|
||||
<record id="act_dummy" model="workflow.activity">
|
||||
<field name="name">dummy</field>
|
||||
<field name="wkf_id" ref="wkf_email_template_setting"/>
|
||||
<field name="flow_stop">True</field>
|
||||
</record>
|
||||
|
||||
<!-- Transition -->
|
||||
|
||||
<record id="trans_awaiting_approved" model="workflow.transition">
|
||||
<field name="act_from" ref="act_draft"/>
|
||||
<field name="act_to" ref="act_approved"/>
|
||||
<field name="signal">button_approval</field>
|
||||
</record>
|
||||
|
||||
<record id="trans_approved_suspended" model="workflow.transition">
|
||||
<field name="act_from" ref="act_approved"/>
|
||||
<field name="act_to" ref="act_suspended"/>
|
||||
<field name="signal">button_suspended</field>
|
||||
</record>
|
||||
<record id="trans_suspended_reapproved" model="workflow.transition">
|
||||
<field name="act_from" ref="act_suspended"/>
|
||||
<field name="act_to" ref="act_draft"/>
|
||||
<field name="signal">get_reapprove</field>
|
||||
</record>
|
||||
<record id="trans_suspended_dummy" model="workflow.transition">
|
||||
<field name="act_from" ref="act_suspended"/>
|
||||
<field name="act_to" ref="act_dummy"/>
|
||||
<field name="signal">get_never</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -1,10 +1,7 @@
|
|||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
"access_email_template_account","email_template.account","model_email_template_account","marketing.group_marketing_user",1,0,0,0
|
||||
"access_email_template","email.template","model_email_template","marketing.group_marketing_user",1,0,0,0
|
||||
"access_email_template_mailbox","email_template.mailbox","model_email_template_mailbox","marketing.group_marketing_user",1,1,1,1
|
||||
"access_email_template_account_system","email_template.account system","model_email_template_account","base.group_system",1,1,1,1
|
||||
"access_email_template_system","email.template system","model_email_template","base.group_system",1,1,1,1
|
||||
"access_email_template_mailbox_system","email_template.mailbox system","model_email_template_mailbox","base.group_system",1,0,0,0
|
||||
"access_email_template_account_manager","email_template.account","model_email_template_account","marketing.group_marketing_manager",1,1,1,1
|
||||
"access_email_template_manager","email.template","model_email_template","marketing.group_marketing_manager",1,1,1,1
|
||||
"access_email_template_mailbox_manager","email_template.mailbox","model_email_template_mailbox","marketing.group_marketing_manager",1,1,1,1
|
||||
|
|
|
|
@ -21,3 +21,4 @@
|
|||
##############################################################################
|
||||
|
||||
import email_template_send_wizard
|
||||
import email_template_preview
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2009 Sharoon Thomas
|
||||
# Copyright (C) 2010-2010 OpenERP SA (<http://www.openerp.com>)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
from tools.translate import _
|
||||
from email_template.email_template import get_value
|
||||
|
||||
|
||||
class email_template_preview(osv.osv_memory):
|
||||
_name = "email_template.preview"
|
||||
_description = "Email Template Preview"
|
||||
|
||||
def _get_model_recs(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
#Fills up the selection box which allows records from the selected object to be displayed
|
||||
self.context = context
|
||||
if 'template_id' in context:
|
||||
ref_obj_id = self.pool.get('email.template').read(cr, uid, context['template_id'], ['object_name'], context)
|
||||
ref_obj_name = self.pool.get('ir.model').read(cr, uid, ref_obj_id['object_name'][0], ['model'], context)['model']
|
||||
model_obj = self.pool.get(ref_obj_name)
|
||||
ref_obj_ids = model_obj.search(cr, uid, [], 0, 20, 'id', context=context)
|
||||
if not ref_obj_ids:
|
||||
ref_obj_ids = []
|
||||
|
||||
# also add the default one if requested, otherwise it won't be available for selection:
|
||||
default_id = context.get('default_rel_model_ref')
|
||||
if default_id and default_id not in ref_obj_ids:
|
||||
ref_obj_ids.insert(0, default_id)
|
||||
return model_obj.name_get(cr, uid, ref_obj_ids, context)
|
||||
return []
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
result = super(email_template_preview, self).default_get(cr, uid, fields, context=context)
|
||||
if (not fields or 'rel_model_ref' in fields) and 'template_id' in context \
|
||||
and not result.get('rel_model_ref'):
|
||||
selectables = self._get_model_recs(cr, uid, context=context)
|
||||
result['rel_model_ref'] = selectables and selectables[0][0] or False
|
||||
return result
|
||||
|
||||
def _default_model(self, cursor, user, context=None):
|
||||
"""
|
||||
Returns the default value for model field
|
||||
@param cursor: Database Cursor
|
||||
@param user: ID of current user
|
||||
@param context: OpenERP Context
|
||||
"""
|
||||
return self.pool.get('email.template').read(
|
||||
cursor,
|
||||
user,
|
||||
context['template_id'],
|
||||
['object_name'],
|
||||
context).get('object_name', False)
|
||||
|
||||
_columns = {
|
||||
'ref_template':fields.many2one(
|
||||
'email.template',
|
||||
'Template', readonly=True),
|
||||
'rel_model':fields.many2one('ir.model', 'Model', readonly=True),
|
||||
'rel_model_ref':fields.selection(_get_model_recs, 'Referred Document'),
|
||||
'to':fields.char('To', size=250, readonly=True),
|
||||
'cc':fields.char('CC', size=250, readonly=True),
|
||||
'bcc':fields.char('BCC', size=250, readonly=True),
|
||||
'reply_to':fields.char('Reply-To',
|
||||
size=250,
|
||||
help="The address recipients should reply to,"
|
||||
" if different from the From address."
|
||||
" Placeholders can be used here."),
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
help="The Message-ID header value, if you need to"
|
||||
"specify it, for example to automatically recognize the replies later."
|
||||
" Placeholders can be used here."),
|
||||
'subject':fields.char('Subject', size=200, readonly=True),
|
||||
'body_text':fields.text('Body', readonly=True),
|
||||
'body_html':fields.text('Body', readonly=True),
|
||||
'report':fields.char('Report Name', size=100, readonly=True),
|
||||
}
|
||||
_defaults = {
|
||||
'ref_template': lambda self, cr, uid, ctx:ctx['template_id'] or False,
|
||||
'rel_model': _default_model,
|
||||
}
|
||||
def on_change_ref(self, cr, uid, ids, rel_model_ref, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if not rel_model_ref:
|
||||
return {}
|
||||
vals = {}
|
||||
if context == {}:
|
||||
context = self.context
|
||||
template = self.pool.get('email.template').browse(cr, uid, context['template_id'], context)
|
||||
#Search translated template
|
||||
lang = get_value(cr, uid, rel_model_ref, template.lang, template, context)
|
||||
if lang:
|
||||
ctx = context.copy()
|
||||
ctx.update({'lang':lang})
|
||||
template = self.pool.get('email.template').browse(cr, uid, context['template_id'], ctx)
|
||||
vals['to'] = get_value(cr, uid, rel_model_ref, template.def_to, template, context)
|
||||
vals['cc'] = get_value(cr, uid, rel_model_ref, template.def_cc, template, context)
|
||||
vals['bcc'] = get_value(cr, uid, rel_model_ref, template.def_bcc, template, context)
|
||||
vals['reply_to'] = get_value(cr, uid, rel_model_ref, template.reply_to, template, context)
|
||||
if template.message_id:
|
||||
vals['message_id'] = get_value(cr, uid, rel_model_ref, template.message_id, template, context)
|
||||
elif template.track_campaign_item:
|
||||
vals['message_id'] = tools.misc.generate_tracking_message_id(rel_model_ref)
|
||||
vals['subject'] = get_value(cr, uid, rel_model_ref, template.def_subject, template, context)
|
||||
vals['body_text'] = get_value(cr, uid, rel_model_ref, template.def_body_text, template, context)
|
||||
vals['body_html'] = get_value(cr, uid, rel_model_ref, template.def_body_html, template, context)
|
||||
vals['report'] = get_value(cr, uid, rel_model_ref, template.file_name, template, context)
|
||||
return {'value':vals}
|
||||
|
||||
email_template_preview()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Email Template Preview -->
|
||||
<record model="ir.ui.view" id="email_template_preview_form">
|
||||
<field name="name">email_template.preview.form</field>
|
||||
<field name="model">email_template.preview</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Email Preview">
|
||||
<group col="4" colspan="4">
|
||||
<field name="rel_model" />
|
||||
<field name="rel_model_ref" on_change="on_change_ref(rel_model_ref, context)"/>
|
||||
</group>
|
||||
<group col="8" colspan="4">
|
||||
<field name="to" />
|
||||
<field name="cc" />
|
||||
<field name="bcc" />
|
||||
<field name="reply_to" />
|
||||
<field name="message_id" attrs="{'invisible':[('message_id','=',False)]}" groups="base.group_extended"/>
|
||||
<field name="subject" colspan="8"/>
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<separator string= "Body(Text)" colspan="2"/>
|
||||
<separator string= "Body(Html)" colspan="2"/>
|
||||
<newline/>
|
||||
<field name="body_text" nolabel="1" colspan="2"/>
|
||||
<field name="body_html" nolabel="1" colspan="2"/>
|
||||
</group>
|
||||
<field name="report" colspan="2"/>
|
||||
<button icon="gtk-ok" special="cancel" string="OK" colspan="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="wizard_email_template_preview" model="ir.actions.act_window">
|
||||
<field name="name">Template Preview</field>
|
||||
<field name="res_model">email_template.preview</field>
|
||||
<field name="src_model">email_template.preview</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="auto_refresh" eval="1" />
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'template_id':active_id}</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
@ -51,9 +51,9 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
if template.from_account:
|
||||
return [(template.from_account.id, '%s (%s)' % (template.from_account.name, template.from_account.email_id))]
|
||||
else:
|
||||
account_id = self.pool.get('email_template.account').search(cr,uid,[('company','=','no'),('user','=',uid)], context=context)
|
||||
account_id = self.pool.get('email.smtp_server').search(cr,uid,[('company','=','no'),('user','=',uid)], context=context)
|
||||
if account_id:
|
||||
account = self.pool.get('email_template.account').browse(cr,uid,account_id, context)
|
||||
account = self.pool.get('email.smtp_server').browse(cr,uid,account_id, context)
|
||||
return [(r.id,r.name + " (" + r.email_id + ")") for r in account]
|
||||
else:
|
||||
logger.notifyChannel(_("email-template"), netsvc.LOG_ERROR, _("No personal email accounts are configured for you. \nEither ask admin to enforce an account for this template or get yourself a personal email account."))
|
||||
|
@ -66,7 +66,7 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
if not id:
|
||||
id = context['src_rec_ids'][0]
|
||||
return get_value(cursor, user, id, message, template, context)
|
||||
|
||||
|
||||
def _get_template(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
@ -116,13 +116,13 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
'to':fields.char('To',size=250,required=True),
|
||||
'cc':fields.char('CC',size=250,),
|
||||
'bcc':fields.char('BCC',size=250,),
|
||||
'reply_to':fields.char('Reply-To',
|
||||
size=250,
|
||||
'reply_to':fields.char('Reply-To',
|
||||
size=250,
|
||||
help="The address recipients should reply to,"
|
||||
" if different from the From address."
|
||||
" Placeholders can be used here."),
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
help="The Message-ID header value, if you need to"
|
||||
"specify it, for example to automatically recognize the replies later."
|
||||
" Placeholders can be used here."),
|
||||
|
@ -133,12 +133,12 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
'signature':fields.boolean('Attach my signature to mail'),
|
||||
#'filename':fields.text('File Name'),
|
||||
'requested':fields.integer('No of requested Mails',readonly=True),
|
||||
'generated':fields.integer('No of generated Mails',readonly=True),
|
||||
'generated':fields.integer('No of generated Mails',readonly=True),
|
||||
'full_success':fields.boolean('Complete Success',readonly=True),
|
||||
'attachment_ids': fields.many2many('ir.attachment','send_wizard_attachment_rel', 'wizard_id', 'attachment_id', 'Attachments'),
|
||||
}
|
||||
|
||||
#FIXME: probably better by overriding default_get directly
|
||||
#FIXME: probably better by overriding default_get directly
|
||||
_defaults = {
|
||||
'state': lambda self,cr,uid,ctx: len(ctx['src_rec_ids']) > 1 and 'multi' or 'single',
|
||||
'rel_model': lambda self,cr,uid,ctx: self.pool.get('ir.model').search(cr,uid,[('model','=',ctx['src_model'])],context=ctx)[0],
|
||||
|
@ -156,7 +156,7 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
'reply_to': lambda self,cr,uid,ctx: self._get_template_value(cr, uid, 'reply_to', ctx),
|
||||
'requested':lambda self,cr,uid,ctx: len(ctx['src_rec_ids']),
|
||||
'full_success': False,
|
||||
'attachment_ids': [],
|
||||
'attachment_ids': [],
|
||||
}
|
||||
|
||||
def fields_get(self, cr, uid, fields=None, context=None, write_access=True):
|
||||
|
@ -200,7 +200,7 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
else:
|
||||
raise osv.except_osv(_("Email Template"),_("Email sending failed for one or more objects."))
|
||||
return True
|
||||
|
||||
|
||||
def save_to_mailbox(self, cr, uid, ids, context=None):
|
||||
def get_end_value(id, value):
|
||||
if len(context['src_rec_ids']) > 1: # Multiple Mail: Gets value from the template
|
||||
|
@ -214,7 +214,7 @@ class email_template_send_wizard(osv.osv_memory):
|
|||
template = self._get_template(cr, uid, context)
|
||||
for id in context['src_rec_ids']:
|
||||
screen_vals = self.read(cr, uid, ids[0], [],context)
|
||||
account = self.pool.get('email_template.account').read(cr, uid, screen_vals['from'], context=context)
|
||||
account = self.pool.get('email.smtp_server').read(cr, uid, screen_vals['from'], context=context)
|
||||
vals = {
|
||||
'email_from': tools.ustr(account['name']) + "<" + tools.ustr(account['email_id']) + ">",
|
||||
'email_to': get_end_value(id, screen_vals['to']),
|
||||
|
|
Loading…
Reference in New Issue