[MERGE] Merged fp's refactoring branch.
bzr revid: tde@openerp.com-20140414131109-7ijlz4gybjd2b2oj
This commit is contained in:
commit
55266ab25d
|
@ -44,7 +44,6 @@ professional emails and reuse templates in a few clicks.
|
|||
'data/mass_mailing_data.xml',
|
||||
'wizard/mail_compose_message_view.xml',
|
||||
'wizard/test_mailing.xml',
|
||||
'wizard/mailing_list_confirm.xml',
|
||||
'views/mass_mailing_report.xml',
|
||||
'views/mass_mailing.xml',
|
||||
'views/res_config.xml',
|
||||
|
@ -55,7 +54,9 @@ professional emails and reuse templates in a few clicks.
|
|||
'js': [
|
||||
'static/src/js/mass_mailing.js',
|
||||
],
|
||||
'qweb': [],
|
||||
'qweb' : [
|
||||
'static/src/xml/*.xml',
|
||||
],
|
||||
'css': [
|
||||
'static/src/css/mass_mailing.css',
|
||||
'static/src/css/email_template.css'
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
<field name="auto_delete" eval="False"/>
|
||||
<field name="partner_to">${object.id}</field>
|
||||
<field name="reply_to"><![CDATA[Info <info@yourcompany.example.com>]]></field>
|
||||
<field name="use_in_mass_mailing" eval="True"/>
|
||||
<field name="use_default_to" eval="True"/>
|
||||
<field name="attachment_ids" eval="[(4, ref('mass_mail_attach_1'))]"/>
|
||||
<field name="body_html"><![CDATA[<div data-snippet-id="big-picture" style="padding:0px; margin:0px">
|
||||
|
@ -69,29 +68,26 @@
|
|||
<!-- Create mailing lists -->
|
||||
<record id="mass_mail_list_1" model="mail.mass_mailing.list">
|
||||
<field name="name">Imported Contacts</field>
|
||||
<field name="model">mail.mass_mailing.contact</field>
|
||||
</record>
|
||||
<record id="mass_mail_list_2" model="mail.mass_mailing.list">
|
||||
<field name="name">Customers</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="domain">[('customer', '=', True)]</field>
|
||||
</record>
|
||||
|
||||
<!-- Create Contacts -->
|
||||
<record id="mass_mail_contact_1" model="mail.mass_mailing.contact">
|
||||
<field name="name">Aristide Antario</field>
|
||||
<field name="email">aa@example.com</field>
|
||||
<field name="list_id" eval="ref('mass_mail_list_1')"/>
|
||||
<field name="list_id" ref="mass_mailing.mass_mail_list_1"/>
|
||||
</record>
|
||||
<record id="mass_mail_contact_2" model="mail.mass_mailing.contact">
|
||||
<field name="name">Beverly Bridge</field>
|
||||
<field name="email">bb@example.com</field>
|
||||
<field name="list_id" eval="ref('mass_mail_list_1')"/>
|
||||
<field name="list_id" ref="mass_mailing.mass_mail_list_1"/>
|
||||
</record>
|
||||
<record id="mass_mail_contact_3" model="mail.mass_mailing.contact">
|
||||
<field name="name">Carol Cartridge</field>
|
||||
<field name="email">cc@example.com</field>
|
||||
<field name="list_id" eval="ref('mass_mail_list_1')"/>
|
||||
<field name="list_id" ref="mass_mailing.mass_mail_list_1"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
|
||||
|
@ -103,13 +99,12 @@
|
|||
<field name="name">Newsletter</field>
|
||||
<field name="stage_id" ref="mass_mailing.campaign_stage_1"/>
|
||||
<field name="user_id" eval="ref('base.user_root')"/>
|
||||
<field name="category_id" eval="ref('mass_mailing.mass_mail_category_1')"/>
|
||||
<field name="category_ids" eval="[(6,0,[ref('mass_mailing.mass_mail_category_1')])]"/>
|
||||
</record>
|
||||
|
||||
<record id="mass_mail_1" model="mail.mass_mailing">
|
||||
<field name="name">First Newsletter</field>
|
||||
<field name="state">done</field>
|
||||
<field name="template_id" eval="ref('mass_mail_template_1')"/>
|
||||
<field name="date" eval="(DateTime.today() - relativedelta(days=5)).strftime('%Y-%m-%d %H:%M:%S')"/>
|
||||
<field name="mass_mailing_campaign_id" eval="ref('mass_mail_campaign_1')"/>
|
||||
<field name="contact_list_ids" eval="[(4, ref('mass_mail_list_2'))]"/>
|
||||
|
@ -117,7 +112,6 @@
|
|||
<record id="mass_mail_2" model="mail.mass_mailing">
|
||||
<field name="name">Second Newsletter</field>
|
||||
<field name="state">test</field>
|
||||
<field name="template_id" eval="ref('mass_mail_template_1')"/>
|
||||
<field name="date" eval="(DateTime.today() - relativedelta(days=3)).strftime('%Y-%m-%d %H:%M:%S')"/>
|
||||
<field name="mass_mailing_campaign_id" eval="ref('mass_mail_campaign_1')"/>
|
||||
</record>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import mass_mailing
|
||||
import mass_mailing_stats
|
||||
import mail_mail
|
||||
import mail_thread
|
||||
import email_template
|
||||
import res_config
|
||||
import mass_mailing_report
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp.tools.translate import _
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
|
||||
class EmailTemplate(osv.Model):
|
||||
"""Add the mass mailing campaign data to mail"""
|
||||
_name = 'email.template'
|
||||
_inherit = ['email.template']
|
||||
|
||||
_columns = {
|
||||
'use_in_mass_mailing': fields.boolean('Available for marketing and mailing'),
|
||||
}
|
||||
|
||||
def action_new_mailing(self, cr, uid, ids, context=None):
|
||||
template = self.browse(cr, uid, ids[0], context=context)
|
||||
ctx = dict(context)
|
||||
ctx.update({
|
||||
'default_mailing_model': template.model,
|
||||
'default_template_id': ids[0],
|
||||
})
|
||||
return {
|
||||
'name': _('Create a Mass Mailing'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.mass_mailing',
|
||||
'views': [(False, 'form')],
|
||||
'context': ctx,
|
||||
}
|
||||
|
||||
|
||||
class email_template_preview(osv.TransientModel):
|
||||
""" Reinitialize email template preview model to have access to all email.template
|
||||
new fields. """
|
||||
_name = "email_template.preview"
|
||||
_inherit = ['email.template', 'email_template.preview']
|
|
@ -22,10 +22,7 @@
|
|||
from datetime import datetime
|
||||
from dateutil import relativedelta
|
||||
import random
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import json
|
||||
import json
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
|
@ -40,6 +37,7 @@ class MassMailingCategory(osv.Model):
|
|||
"""Model of categories of mass mailing, i.e. marketing, newsletter, ... """
|
||||
_name = 'mail.mass_mailing.category'
|
||||
_description = 'Mass Mailing Category'
|
||||
_order = 'name'
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True),
|
||||
|
@ -50,19 +48,29 @@ class MassMailingContact(osv.Model):
|
|||
"""Model of a contact. This model is different from the partner model
|
||||
because it holds only some basic information: name, email. The purpose is to
|
||||
be able to deal with large contact list to email without bloating the partner
|
||||
database. """
|
||||
base."""
|
||||
_name = 'mail.mass_mailing.contact'
|
||||
_description = 'Mass Mailing Contact'
|
||||
_order = 'email'
|
||||
_rec_name = 'email'
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True),
|
||||
'name': fields.char('Name'),
|
||||
'email': fields.char('Email', required=True),
|
||||
'create_date': fields.datetime('Create Date'),
|
||||
'list_id': fields.many2one(
|
||||
'mail.mass_mailing.list', string='Mailing List',
|
||||
domain=[('model', '=', 'mail.mass_mailing.contact')],
|
||||
ondelete='cascade',
|
||||
ondelete='cascade', required=True,
|
||||
),
|
||||
'opt_out': fields.boolean('Opt Out', help='The contact has chosen not to receive news anymore from this mailing list'),
|
||||
'opt_out': fields.boolean('Opt Out', help='The contact has chosen not to receive mails anymore from this list'),
|
||||
}
|
||||
|
||||
def _get_latest_list(self, cr, uid, context={}):
|
||||
lid = self.pool.get('mail.mass_mailing.list').search(cr, uid, [], limit=1, order='id desc', context=context)
|
||||
return lid and lid[0] or False
|
||||
|
||||
_defaults = {
|
||||
'list_id': _get_latest_list
|
||||
}
|
||||
|
||||
def name_create(self, cr, uid, name, context=None):
|
||||
|
@ -78,150 +86,33 @@ class MassMailingContact(osv.Model):
|
|||
class MassMailingList(osv.Model):
|
||||
"""Model of a contact list. """
|
||||
_name = 'mail.mass_mailing.list'
|
||||
_description = 'Contact List'
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
"""Override default_get to handle active_domain coming from the list view. """
|
||||
res = super(MassMailingList, self).default_get(cr, uid, fields, context=context)
|
||||
if 'domain' in fields:
|
||||
if not 'model' in res and context.get('active_model'):
|
||||
res['model'] = context['active_model']
|
||||
if 'active_domain' in context:
|
||||
res['domain'] = '%s' % context['active_domain']
|
||||
elif 'active_ids' in context:
|
||||
res['domain'] = '%s' % [('id', 'in', context['active_ids'])]
|
||||
else:
|
||||
res['domain'] = False
|
||||
return res
|
||||
_order = 'name'
|
||||
_description = 'Mailing List'
|
||||
|
||||
def _get_contact_nbr(self, cr, uid, ids, name, arg, context=None):
|
||||
"""Compute the number of contacts linked to the mailing list. """
|
||||
results = dict.fromkeys(ids, 0)
|
||||
for contact_list in self.browse(cr, uid, ids, context=context):
|
||||
results[contact_list.id] = self.pool[contact_list.model].search(
|
||||
cr, uid,
|
||||
self._get_domain(cr, uid, [contact_list.id], context=context)[contact_list.id],
|
||||
count=True, context=context
|
||||
)
|
||||
return results
|
||||
|
||||
def _get_model_list(self, cr, uid, context=None):
|
||||
return self.pool['mail.mass_mailing']._get_mailing_model(cr, uid, context=context)
|
||||
|
||||
# indirections for inheritance
|
||||
_model_list = lambda self, *args, **kwargs: self._get_model_list(*args, **kwargs)
|
||||
result = dict.fromkeys(ids, 0)
|
||||
Contacts = self.pool.get('mail.mass_mailing.contact')
|
||||
for group in Contacts.read_group(cr, uid, [('list_id', 'in', ids), ('opt_out', '!=', True)], ['list_id'], ['list_id'], context=context):
|
||||
result[group['list_id'][0]] = group['list_id_count']
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True),
|
||||
'name': fields.char('Mailing List', required=True),
|
||||
'contact_nbr': fields.function(
|
||||
_get_contact_nbr, type='integer',
|
||||
string='Contact Number',
|
||||
string='Number of Contacts',
|
||||
),
|
||||
'model': fields.selection(
|
||||
_model_list, type='char', required=True,
|
||||
string='Applies To'
|
||||
),
|
||||
'filter_id': fields.many2one(
|
||||
'ir.filters', string='Custom Filter',
|
||||
domain="[('model_id.model', '=', model)]",
|
||||
),
|
||||
'domain': fields.text('Domain'),
|
||||
}
|
||||
|
||||
def on_change_model(self, cr, uid, ids, model, context=None):
|
||||
return {'value': {'filter_id': False}}
|
||||
|
||||
def on_change_filter_id(self, cr, uid, ids, filter_id, context=None):
|
||||
values = {}
|
||||
if filter_id:
|
||||
ir_filter = self.pool['ir.filters'].browse(cr, uid, filter_id, context=context)
|
||||
values['domain'] = ir_filter.domain
|
||||
return {'value': values}
|
||||
|
||||
def on_change_domain(self, cr, uid, ids, domain, model, context=None):
|
||||
if domain is False:
|
||||
return {'value': {'contact_nbr': 0}}
|
||||
else:
|
||||
domain = eval(domain)
|
||||
return {'value': {'contact_nbr': self.pool[model].search(cr, uid, domain, context=context, count=True)}}
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
new_id = super(MassMailingList, self).create(cr, uid, values, context=context)
|
||||
if values.get('model') == 'mail.mass_mailing.contact' and (not context or not context.get('no_contact_to_list')):
|
||||
domain = values.get('domain')
|
||||
if domain is None or domain is False:
|
||||
return new_id
|
||||
contact_ids = self.pool['mail.mass_mailing.contact'].search(cr, uid, eval(domain), context=context)
|
||||
self.pool['mail.mass_mailing.contact'].write(cr, uid, contact_ids, {'list_id': new_id}, context=context)
|
||||
self.pool['mail.mass_mailing.list'].write(cr, uid, [new_id], {'domain': [('list_id', '=', new_id)]}, context=context)
|
||||
return new_id
|
||||
|
||||
def action_see_records(self, cr, uid, ids, context=None):
|
||||
contact_list = self.browse(cr, uid, ids[0], context=context)
|
||||
ctx = dict(context)
|
||||
ctx['search_default_not_opt_out'] = True
|
||||
return {
|
||||
'name': _('See Contact List'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': contact_list.model,
|
||||
'views': [(False, 'tree'), (False, 'form')],
|
||||
'view_id': False,
|
||||
'target': 'current',
|
||||
'context': ctx,
|
||||
'domain': contact_list.domain,
|
||||
}
|
||||
|
||||
def action_add_to_mailing(self, cr, uid, ids, context=None):
|
||||
mass_mailing_id = context.get('default_mass_mailing_id')
|
||||
if not mass_mailing_id:
|
||||
return False
|
||||
self.pool['mail.mass_mailing'].write(cr, uid, [mass_mailing_id], {'contact_list_ids': [(4, list_id) for list_id in ids]}, context=context)
|
||||
return {
|
||||
'name': _('Mass Mailing'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.mass_mailing',
|
||||
'res_id': mass_mailing_id,
|
||||
'context': context,
|
||||
}
|
||||
|
||||
def _get_domain(self, cr, uid, ids, context=None):
|
||||
domains = {}
|
||||
for contact_list in self.browse(cr, uid, ids, context=context):
|
||||
if contact_list.domain is False or contact_list.domain is None: # domain is a string like False or None -> void list
|
||||
domain = [('id', '=', '0')]
|
||||
else:
|
||||
domain = eval(contact_list.domain)
|
||||
domains[contact_list.id] = domain
|
||||
return domains
|
||||
|
||||
def get_global_domain(self, cr, uid, ids, context=None):
|
||||
model_to_domains = dict((mailing_model[0], list())
|
||||
for mailing_model in self.pool['mail.mass_mailing']._get_mailing_model(cr, uid, context=context))
|
||||
for contact_list in self.browse(cr, uid, ids, context=context):
|
||||
domain = self._get_domain(cr, uid, [contact_list.id], context=context)[contact_list.id]
|
||||
if domain is not False:
|
||||
model_to_domains[contact_list.model].append(domain)
|
||||
for model, domains in model_to_domains.iteritems():
|
||||
if domains:
|
||||
final_domain = ['|'] * (len(domains) - 1) + [leaf for dom in domains for leaf in dom]
|
||||
else:
|
||||
final_domain = [('id', '=', '0')]
|
||||
model_to_domains[model] = final_domain
|
||||
return model_to_domains
|
||||
|
||||
|
||||
class MassMailingStage(osv.Model):
|
||||
"""Stage for mass mailing campaigns. """
|
||||
_name = 'mail.mass_mailing.stage'
|
||||
_description = 'Mass Mailing Campaign Stage'
|
||||
_order = 'sequence ASC'
|
||||
_order = 'sequence'
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True),
|
||||
'name': fields.char('Name', required=True, translate=True),
|
||||
'sequence': fields.integer('Sequence'),
|
||||
}
|
||||
|
||||
|
@ -264,9 +155,9 @@ class MassMailingCampaign(osv.Model):
|
|||
'res.users', 'Responsible',
|
||||
required=True,
|
||||
),
|
||||
'category_id': fields.many2one(
|
||||
'mail.mass_mailing.category', 'Category',
|
||||
help='Category'),
|
||||
'category_ids': fields.many2many(
|
||||
'mail.mass_mailing.category', 'mail_mass_mailing_category_rel',
|
||||
'category_id', 'campaign_id', string='Categories'),
|
||||
'mass_mailing_ids': fields.one2many(
|
||||
'mail.mass_mailing', 'mass_mailing_campaign_id',
|
||||
'Mass Mailings',
|
||||
|
@ -326,32 +217,13 @@ class MassMailingCampaign(osv.Model):
|
|||
|
||||
def _get_default_stage_id(self, cr, uid, context=None):
|
||||
stage_ids = self.pool['mail.mass_mailing.stage'].search(cr, uid, [], limit=1, context=context)
|
||||
return stage_ids and stage_ids[0]
|
||||
return stage_ids and stage_ids[0] or False
|
||||
|
||||
_defaults = {
|
||||
'user_id': lambda self, cr, uid, ctx=None: uid,
|
||||
'stage_id': lambda self, cr, uid, ctx=None: self._get_default_stage_id(cr, uid, context=ctx),
|
||||
'stage_id': lambda self, *args: self._get_default_stage_id(*args),
|
||||
}
|
||||
|
||||
#------------------------------------------------------
|
||||
# Actions
|
||||
#------------------------------------------------------
|
||||
|
||||
def action_new_mailing(self, cr, uid, ids, context=None):
|
||||
return {
|
||||
'name': _('Create a Mass Mailing for the Campaign'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.mass_mailing',
|
||||
'views': [(False, 'form')],
|
||||
'context': dict(context, default_mass_mailing_campaign_id=ids[0]),
|
||||
}
|
||||
|
||||
#------------------------------------------------------
|
||||
# API
|
||||
#------------------------------------------------------
|
||||
|
||||
def get_recipients(self, cr, uid, ids, model=None, context=None):
|
||||
"""Return the recipints of a mailing campaign. This is based on the statistics
|
||||
build for each mailing. """
|
||||
|
@ -448,15 +320,14 @@ class MassMailing(osv.Model):
|
|||
def _get_contact_nbr(self, cr, uid, ids, name, arg, context=None):
|
||||
res = dict.fromkeys(ids, False)
|
||||
for mailing in self.browse(cr, uid, ids, context=context):
|
||||
val = {'contact_nbr': 0, 'contact_ab_nbr': 0, 'contact_ab_done': 0}
|
||||
val = {'contact_nbr': 0, 'contact_ab_nbr': 0} # 'contact_ab_done': 0
|
||||
val['contact_nbr'] = self.pool[mailing.mailing_model].search(
|
||||
cr, uid,
|
||||
self.pool['mail.mass_mailing.list'].get_global_domain(cr, uid, [c.id for c in mailing.contact_list_ids], context=context)[mailing.mailing_model],
|
||||
cr, uid, eval(mailing.mailing_domain),
|
||||
count=True, context=context
|
||||
)
|
||||
val['contact_ab_nbr'] = int(val['contact_nbr'] * mailing.contact_ab_pc / 100.0)
|
||||
if mailing.mass_mailing_campaign_id and mailing.ab_testing:
|
||||
val['contact_ab_done'] = len(self.pool['mail.mass_mailing.campaign'].get_recipients(cr, uid, [mailing.mass_mailing_campaign_id.id], context=context)[mailing.mass_mailing_campaign_id.id])
|
||||
# val['contact_ab_nbr'] = int(val['contact_nbr'] * mailing.contact_ab_pc / 100.0)
|
||||
# if mailing.mass_mailing_campaign_id and mailing.ab_testing:
|
||||
# val['contact_ab_done'] = len(self.pool['mail.mass_mailing.campaign'].get_recipients(cr, uid, [mailing.mass_mailing_campaign_id.id], context=context)[mailing.mass_mailing_campaign_id.id])
|
||||
res[mailing.id] = val
|
||||
return res
|
||||
|
||||
|
@ -471,42 +342,32 @@ class MassMailing(osv.Model):
|
|||
|
||||
def _get_mailing_model(self, cr, uid, context=None):
|
||||
return [
|
||||
('res.partner', 'Customers'),
|
||||
('mail.mass_mailing.contact', 'Contacts')
|
||||
('res.partner', _('Customers')),
|
||||
('mail.mass_mailing.contact', _('Mailing List'))
|
||||
]
|
||||
|
||||
def _get_state_list(self, cr, uid, context=None):
|
||||
return [('draft', 'Schedule'), ('test', 'Tested'), ('done', 'Sent')]
|
||||
|
||||
# indirections for inheritance
|
||||
_mailing_model = lambda self, *args, **kwargs: self._get_mailing_model(*args, **kwargs)
|
||||
_state = lambda self, *args, **kwargs: self._get_state_list(*args, **kwargs)
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Subject', required=True),
|
||||
'email_from': fields.char('From', required=True),
|
||||
'date': fields.datetime('Date'),
|
||||
'state': fields.selection(
|
||||
_state, string='Status', required=True,
|
||||
),
|
||||
'template_id': fields.many2one(
|
||||
'email.template', 'Email Template',
|
||||
domain="[('use_in_mass_mailing', '=', True), ('model', '=', mailing_model)]",
|
||||
),
|
||||
'body_html': fields.html('Body'),
|
||||
'mass_mailing_campaign_id': fields.many2one(
|
||||
'mail.mass_mailing.campaign', 'Mass Mailing Campaign',
|
||||
ondelete='set null',
|
||||
),
|
||||
'ab_testing': fields.related(
|
||||
'mass_mailing_campaign_id', 'ab_testing',
|
||||
type='boolean', string='AB Testing'
|
||||
'state': fields.selection(
|
||||
[('draft', 'Draft'), ('test', 'Tested'), ('done', 'Sent')],
|
||||
string='Status', required=True,
|
||||
),
|
||||
'color': fields.related(
|
||||
'mass_mailing_campaign_id', 'color',
|
||||
type='integer', string='Color Index',
|
||||
),
|
||||
# mailing options
|
||||
'email_from': fields.char('From'),
|
||||
# TODO: simplify these 4 fields
|
||||
'reply_in_thread': fields.boolean('Reply in thread'),
|
||||
'reply_specified': fields.boolean('Specific Reply-To'),
|
||||
'auto_reply_to_available': fields.function(
|
||||
|
@ -514,11 +375,12 @@ class MassMailing(osv.Model):
|
|||
type='boolean', string='Reply in thread available'
|
||||
),
|
||||
'reply_to': fields.char('Reply To'),
|
||||
'mailing_model': fields.selection(_mailing_model, string='Type', required=True),
|
||||
# Target Emails
|
||||
'mailing_model': fields.selection(_mailing_model, string='Recipients Model', required=True),
|
||||
'mailing_domain': fields.char('Domain'),
|
||||
'contact_list_ids': fields.many2many(
|
||||
'mail.mass_mailing.list', 'mail_mass_mailing_list_rel',
|
||||
string='Mailing Lists',
|
||||
domain="[('model', '=', mailing_model)]",
|
||||
),
|
||||
'contact_nbr': fields.function(
|
||||
_get_contact_nbr, type='integer', multi='_get_contact_nbr',
|
||||
|
@ -528,14 +390,6 @@ class MassMailing(osv.Model):
|
|||
'AB Testing percentage',
|
||||
help='Percentage of the contacts that will be mailed. Recipients will be taken randomly.'
|
||||
),
|
||||
'contact_ab_nbr': fields.function(
|
||||
_get_contact_nbr, type='integer', multi='_get_contact_nbr',
|
||||
string='Contact Number in AB Testing'
|
||||
),
|
||||
'contact_ab_done': fields.function(
|
||||
_get_contact_nbr, type='integer', multi='_get_contact_nbr',
|
||||
string='Number of already mailed contacts'
|
||||
),
|
||||
# statistics data
|
||||
'statistics_ids': fields.one2many(
|
||||
'mail.mail.statistics', 'mass_mailing_id',
|
||||
|
@ -602,7 +456,7 @@ class MassMailing(osv.Model):
|
|||
'state': 'draft',
|
||||
'date': fields.datetime.now,
|
||||
'email_from': lambda self, cr, uid, ctx=None: self.pool['mail.message']._get_default_from(cr, uid, context=ctx),
|
||||
'mailing_model': 'res.partner',
|
||||
'mailing_model': 'mail.mass_mailing.contact',
|
||||
'contact_ab_pc': 100,
|
||||
}
|
||||
|
||||
|
@ -617,7 +471,6 @@ class MassMailing(osv.Model):
|
|||
default.update({
|
||||
'state': 'draft',
|
||||
'statistics_ids': [],
|
||||
'state': 'draft',
|
||||
'name': _('%s (duplicate)') % mailing.name,
|
||||
})
|
||||
return super(MassMailing, self).copy_data(cr, uid, id, default, context=context)
|
||||
|
@ -626,7 +479,8 @@ class MassMailing(osv.Model):
|
|||
""" Override read_group to always display all states. """
|
||||
if groupby and groupby[0] == "state":
|
||||
# Default result structure
|
||||
states = self._get_state_list(cr, uid, context=context)
|
||||
# states = self._get_state_list(cr, uid, context=context)
|
||||
states = [('draft', 'Draft'), ('test', 'Tested'), ('done', 'Sent')]
|
||||
read_group_all_states = [{
|
||||
'__context': {'group_by': groupby[1:]},
|
||||
'__domain': domain + [('state', '=', state_value)],
|
||||
|
@ -651,16 +505,20 @@ class MassMailing(osv.Model):
|
|||
# Views & Actions
|
||||
#------------------------------------------------------
|
||||
|
||||
def on_change_mailing_model(self, cr, uid, ids, mailing_model, context=None):
|
||||
values = {
|
||||
'contact_list_ids': [],
|
||||
'template_id': False,
|
||||
'contact_nbr': 0,
|
||||
'auto_reply_to_available': not mailing_model in self._get_private_models(context),
|
||||
'reply_in_thread': not mailing_model in self._get_private_models(context),
|
||||
'reply_specified': mailing_model in self._get_private_models(context)
|
||||
}
|
||||
return {'value': values}
|
||||
def on_change_model(self, cr, uid, ids, mailing_model, list_ids, context=None):
|
||||
value = {}
|
||||
if mailing_model=='mail.mass_mailing.contact':
|
||||
if list_ids and list_ids[0][0]==6 and list_ids[0][2]:
|
||||
value['mailing_domain'] = "[('list_id', 'in', ["+','.join(map(str, list_ids[0][2]))+"])]"
|
||||
else:
|
||||
value['mailing_domain'] = "[('list_id', '=', False)]"
|
||||
value['contact_nbr'] = self.pool[mailing_model].search(
|
||||
cr, uid, eval(value['mailing_domain']), count=True, context=context
|
||||
)
|
||||
else:
|
||||
value['mailing_domain'] = False
|
||||
value['contact_nbr'] = 0
|
||||
return {'value': value}
|
||||
|
||||
def on_change_reply_specified(self, cr, uid, ids, reply_specified, reply_in_thread, context=None):
|
||||
if reply_specified == reply_in_thread:
|
||||
|
@ -680,30 +538,13 @@ class MassMailing(osv.Model):
|
|||
list_ids += command[2]
|
||||
if list_ids:
|
||||
values['contact_nbr'] = self.pool[mailing_model].search(
|
||||
cr, uid,
|
||||
self.pool['mail.mass_mailing.list'].get_global_domain(cr, uid, list_ids, context=context)[mailing_model],
|
||||
cr, uid, [('list_id', 'in', list_ids), ('opt_out','!=',1)],
|
||||
count=True, context=context
|
||||
)
|
||||
return {'value': values}
|
||||
|
||||
def on_change_template_id(self, cr, uid, ids, template_id, context=None):
|
||||
values = {}
|
||||
if template_id:
|
||||
template = self.pool['email.template'].browse(cr, uid, template_id, context=context)
|
||||
if template.email_from:
|
||||
values['email_from'] = template.email_from
|
||||
if template.reply_to:
|
||||
values['reply_to'] = template.reply_to
|
||||
values['body_html'] = template.body_html
|
||||
else:
|
||||
values['email_from'] = self.pool['mail.message']._get_default_from(cr, uid, context=context)
|
||||
values['reply_to'] = False
|
||||
values['body_html'] = False
|
||||
values['contact_nbr'] = 0
|
||||
return {'value': values}
|
||||
|
||||
def on_change_contact_ab_pc(self, cr, uid, ids, contact_ab_pc, contact_nbr, context=None):
|
||||
return {'value': {'contact_ab_nbr': contact_nbr * contact_ab_pc / 100.0}}
|
||||
|
||||
def action_duplicate(self, cr, uid, ids, context=None):
|
||||
copy_id = None
|
||||
for mid in ids:
|
||||
|
@ -719,27 +560,14 @@ class MassMailing(osv.Model):
|
|||
}
|
||||
return False
|
||||
|
||||
def _get_model_to_list_action_id(self, cr, uid, model, context=None):
|
||||
if model == 'res.partner':
|
||||
return self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, 'mass_mailing.action_partner_to_mailing_list')
|
||||
else:
|
||||
return self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, 'mass_mailing.action_contact_to_mailing_list')
|
||||
|
||||
def action_new_list(self, cr, uid, ids, context=None):
|
||||
mailing = self.browse(cr, uid, ids[0], context=context)
|
||||
action_id = self._get_model_to_list_action_id(cr, uid, mailing.mailing_model, context=context)
|
||||
ctx = dict(context,
|
||||
search_default_not_opt_out=True,
|
||||
view_manager_highlight=[action_id],
|
||||
default_name=mailing.name,
|
||||
default_mass_mailing_id=ids[0],
|
||||
default_model=mailing.mailing_model)
|
||||
def action_test_mailing(self, cr, uid, ids, context=None):
|
||||
ctx = dict(context, default_mass_mailing_id=ids[0])
|
||||
return {
|
||||
'name': _('Choose Recipients'),
|
||||
'name': _('Test Mailing'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': mailing.mailing_model,
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.mass_mailing.test',
|
||||
'target': 'new',
|
||||
'context': ctx,
|
||||
}
|
||||
|
||||
|
@ -757,19 +585,11 @@ class MassMailing(osv.Model):
|
|||
'context': context,
|
||||
}
|
||||
|
||||
def action_test_mailing(self, cr, uid, ids, context=None):
|
||||
ctx = dict(context, default_mass_mailing_id=ids[0])
|
||||
return {
|
||||
'name': _('Test Mailing'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.mass_mailing.test',
|
||||
'target': 'new',
|
||||
'context': ctx,
|
||||
}
|
||||
|
||||
def action_edit_html(self, cr, uid, ids, context=None):
|
||||
url = '/website_mail/email_designer?model=mail.mass_mailing&res_id=%d' % ids[0]
|
||||
# fixme: assert is not correct
|
||||
assert len(ids)==1, "One and only one ID allowed for this action"
|
||||
mail = self.browse(cr, uid, ids[0], context=context)
|
||||
url = '/website_mail/email_designer?model=mail.mass_mailing&res_id=%d&field_body=body_html&field_from=email_form&field_subject=name&template_model=%s' % (ids[0], mail.mailing_model)
|
||||
return {
|
||||
'name': _('Open with Visual Editor'),
|
||||
'type': 'ir.actions.act_url',
|
||||
|
@ -791,13 +611,14 @@ class MassMailing(osv.Model):
|
|||
return dict((partner.id, {'partner_id': partner.id, 'name': partner.name, 'email': partner.email}) for partner in partners)
|
||||
|
||||
def get_recipients(self, cr, uid, mailing, context=None):
|
||||
domain = self.pool['mail.mass_mailing.list'].get_global_domain(
|
||||
cr, uid, [l.id for l in mailing.contact_list_ids], context=context
|
||||
)[mailing.mailing_model]
|
||||
domain = eval(mailing.mailing_domain)
|
||||
# self.pool['mail.mass_mailing.list'].get_global_domain(
|
||||
# cr, uid, [l.id for l in mailing.contact_list_ids], context=context
|
||||
# )[mailing.mailing_model]
|
||||
res_ids = self.pool[mailing.mailing_model].search(cr, uid, domain, context=context)
|
||||
|
||||
# randomly choose a fragment
|
||||
if mailing.contact_ab_pc != 100:
|
||||
if mailing.contact_ab_pc < 100:
|
||||
topick = mailing.contact_ab_nbr
|
||||
if mailing.mass_mailing_campaign_id and mailing.ab_testing:
|
||||
already_mailed = self.pool['mail.mass_mailing.campaign'].get_recipients(cr, uid, [mailing.mass_mailing_campaign_id.id], context=context)[mailing.mass_mailing_campaign_id.id]
|
||||
|
@ -846,80 +667,3 @@ class MassMailing(osv.Model):
|
|||
return True
|
||||
|
||||
|
||||
class MailMailStats(osv.Model):
|
||||
""" MailMailStats models the statistics collected about emails. Those statistics
|
||||
are stored in a separated model and table to avoid bloating the mail_mail table
|
||||
with statistics values. This also allows to delete emails send with mass mailing
|
||||
without loosing the statistics about them. """
|
||||
|
||||
_name = 'mail.mail.statistics'
|
||||
_description = 'Email Statistics'
|
||||
_rec_name = 'message_id'
|
||||
_order = 'message_id'
|
||||
|
||||
_columns = {
|
||||
'mail_mail_id': fields.integer(
|
||||
'Mail ID',
|
||||
help='ID of the related mail_mail. This field is an integer field because'
|
||||
'the related mail_mail can be deleted separately from its statistics.'
|
||||
),
|
||||
'message_id': fields.char('Message-ID'),
|
||||
'model': fields.char('Document model'),
|
||||
'res_id': fields.integer('Document ID'),
|
||||
# campaign / wave data
|
||||
'mass_mailing_id': fields.many2one(
|
||||
'mail.mass_mailing', 'Mass Mailing',
|
||||
ondelete='set null',
|
||||
),
|
||||
'mass_mailing_campaign_id': fields.related(
|
||||
'mass_mailing_id', 'mass_mailing_campaign_id',
|
||||
type='many2one', ondelete='set null',
|
||||
relation='mail.mass_mailing.campaign',
|
||||
string='Mass Mailing Campaign',
|
||||
store=True, readonly=True,
|
||||
),
|
||||
'template_id': fields.related(
|
||||
'mass_mailing_id', 'template_id',
|
||||
type='many2one', ondelete='set null',
|
||||
relation='email.template',
|
||||
string='Email Template',
|
||||
store=True, readonly=True,
|
||||
),
|
||||
# Bounce and tracking
|
||||
'scheduled': fields.datetime('Scheduled', help='Date when the email has been created'),
|
||||
'sent': fields.datetime('Sent', help='Date when the email has been sent'),
|
||||
'exception': fields.datetime('Exception', help='Date of technical error leading to the email not being sent'),
|
||||
'opened': fields.datetime('Opened', help='Date when the email has been opened the first time'),
|
||||
'replied': fields.datetime('Replied', help='Date when this email has been replied for the first time.'),
|
||||
'bounced': fields.datetime('Bounced', help='Date when this email has bounced.'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'scheduled': fields.datetime.now,
|
||||
}
|
||||
|
||||
def _get_ids(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, domain=None, context=None):
|
||||
if not ids and mail_mail_ids:
|
||||
base_domain = [('mail_mail_id', 'in', mail_mail_ids)]
|
||||
elif not ids and mail_message_ids:
|
||||
base_domain = [('message_id', 'in', mail_message_ids)]
|
||||
else:
|
||||
base_domain = [('id', 'in', ids or [])]
|
||||
if domain:
|
||||
base_domain = ['&'] + domain + base_domain
|
||||
return self.search(cr, uid, base_domain, context=context)
|
||||
|
||||
def set_opened(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('opened', '=', False)], context)
|
||||
self.write(cr, uid, stat_ids, {'opened': fields.datetime.now()}, context=context)
|
||||
return stat_ids
|
||||
|
||||
def set_replied(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('replied', '=', False)], context)
|
||||
self.write(cr, uid, stat_ids, {'replied': fields.datetime.now()}, context=context)
|
||||
return stat_ids
|
||||
|
||||
def set_bounced(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('bounced', '=', False)], context)
|
||||
self.write(cr, uid, stat_ids, {'bounced': fields.datetime.now()}, context=context)
|
||||
return stat_ids
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013-today 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 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 datetime import datetime
|
||||
from dateutil import relativedelta
|
||||
import random
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import json
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
from openerp import tools
|
||||
from openerp.exceptions import Warning
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
from openerp.tools.translate import _
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
|
||||
class MailMailStats(osv.Model):
|
||||
""" MailMailStats models the statistics collected about emails. Those statistics
|
||||
are stored in a separated model and table to avoid bloating the mail_mail table
|
||||
with statistics values. This also allows to delete emails send with mass mailing
|
||||
without loosing the statistics about them. """
|
||||
|
||||
_name = 'mail.mail.statistics'
|
||||
_description = 'Email Statistics'
|
||||
_rec_name = 'message_id'
|
||||
_order = 'message_id'
|
||||
|
||||
_columns = {
|
||||
'mail_mail_id': fields.integer(
|
||||
'Mail ID',
|
||||
help='ID of the related mail_mail. This field is an integer field because'
|
||||
'the related mail_mail can be deleted separately from its statistics.'
|
||||
),
|
||||
'message_id': fields.char('Message-ID'),
|
||||
'model': fields.char('Document model'),
|
||||
'res_id': fields.integer('Document ID'),
|
||||
# campaign / wave data
|
||||
'mass_mailing_id': fields.many2one(
|
||||
'mail.mass_mailing', 'Mass Mailing',
|
||||
ondelete='set null',
|
||||
),
|
||||
'mass_mailing_campaign_id': fields.related(
|
||||
'mass_mailing_id', 'mass_mailing_campaign_id',
|
||||
type='many2one', ondelete='set null',
|
||||
relation='mail.mass_mailing.campaign',
|
||||
string='Mass Mailing Campaign',
|
||||
store=True, readonly=True,
|
||||
),
|
||||
# Bounce and tracking
|
||||
'scheduled': fields.datetime('Scheduled', help='Date when the email has been created'),
|
||||
'sent': fields.datetime('Sent', help='Date when the email has been sent'),
|
||||
'exception': fields.datetime('Exception', help='Date of technical error leading to the email not being sent'),
|
||||
'opened': fields.datetime('Opened', help='Date when the email has been opened the first time'),
|
||||
'replied': fields.datetime('Replied', help='Date when this email has been replied for the first time.'),
|
||||
'bounced': fields.datetime('Bounced', help='Date when this email has bounced.'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'scheduled': fields.datetime.now,
|
||||
}
|
||||
|
||||
def _get_ids(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, domain=None, context=None):
|
||||
if not ids and mail_mail_ids:
|
||||
base_domain = [('mail_mail_id', 'in', mail_mail_ids)]
|
||||
elif not ids and mail_message_ids:
|
||||
base_domain = [('message_id', 'in', mail_message_ids)]
|
||||
else:
|
||||
base_domain = [('id', 'in', ids or [])]
|
||||
if domain:
|
||||
base_domain = ['&'] + domain + base_domain
|
||||
return self.search(cr, uid, base_domain, context=context)
|
||||
|
||||
def set_opened(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('opened', '=', False)], context)
|
||||
self.write(cr, uid, stat_ids, {'opened': fields.datetime.now()}, context=context)
|
||||
return stat_ids
|
||||
|
||||
def set_replied(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('replied', '=', False)], context)
|
||||
self.write(cr, uid, stat_ids, {'replied': fields.datetime.now()}, context=context)
|
||||
return stat_ids
|
||||
|
||||
def set_bounced(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('bounced', '=', False)], context)
|
||||
self.write(cr, uid, stat_ids, {'bounced': fields.datetime.now()}, context=context)
|
||||
return stat_ids
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
openerp.mass_mailing = function(openerp) {
|
||||
openerp.mass_mailing = function (instance) {
|
||||
var _t = instance.web._t;
|
||||
|
||||
openerp.web_kanban.KanbanRecord.include({
|
||||
on_card_clicked: function (event) {
|
||||
|
@ -10,4 +11,65 @@ openerp.mass_mailing = function(openerp) {
|
|||
},
|
||||
});
|
||||
|
||||
instance.web.form.CharDomainButton = instance.web.form.AbstractField.extend({
|
||||
template: 'CharDomainButton',
|
||||
init: function(field_manager, node) {
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
start: function() {
|
||||
var self=this;
|
||||
this._super.apply(this, arguments);
|
||||
$('button', this.$el).on('click', self.on_click);
|
||||
this.set_button();
|
||||
},
|
||||
set_button: function() {
|
||||
var self = this;
|
||||
// debugger
|
||||
if (this.get('value')) {
|
||||
// TODO: rpc to copute X
|
||||
var domain = instance.web.pyeval.eval('domain', this.get('value'));
|
||||
var relation = this.getParent().fields.mailing_model.get('value')[0];
|
||||
var ds = new instance.web.DataSetStatic(self, relation, self.build_context());
|
||||
ds.call('search_count', [domain]).then(function (results) {
|
||||
$('.oe_domain_count', self.$el).text(results + ' records selected');
|
||||
$('button span', self.$el).text(' Change selection');
|
||||
});
|
||||
} else {
|
||||
$('.oe_domain_count', this.$el).text('0 record selected');
|
||||
$('button span', this.$el).text(' Select records');
|
||||
};
|
||||
},
|
||||
on_click: function(ev) {
|
||||
var self = this;
|
||||
var model = this.options.model || this.field_manager.get_field_value(this.options.model_field);
|
||||
this.pop = new instance.web.form.SelectCreatePopup(this);
|
||||
this.pop.select_element(
|
||||
model, {title: 'Select records...'},
|
||||
[], this.build_context());
|
||||
this.pop.on("elements_selected", self, function() {
|
||||
var self2 = this;
|
||||
var search_data = this.pop.searchview.build_search_data()
|
||||
instance.web.pyeval.eval_domains_and_contexts({
|
||||
domains: search_data.domains,
|
||||
contexts: search_data.contexts,
|
||||
group_by_seq: search_data.groupbys || []
|
||||
}).then(function (results) {
|
||||
// if selected IDS change domain
|
||||
var domain = self2.pop.dataset.domain.concat(results.domain || []);
|
||||
self.set_value(JSON.stringify(domain))
|
||||
});
|
||||
});
|
||||
event.preventDefault();
|
||||
},
|
||||
set_value: function(value_) {
|
||||
var self = this;
|
||||
this.set('value', value_ || false);
|
||||
this.set_button();
|
||||
},
|
||||
});
|
||||
|
||||
instance.web.form.widgets = instance.web.form.widgets.extend(
|
||||
{'char_domain': 'instance.web.form.CharDomainButton'}
|
||||
);
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<template>
|
||||
<t t-name="CharDomainButton">
|
||||
<div class="oe_form_field">
|
||||
<span class="oe_domain_count"/>
|
||||
<button class="oe_button oe_link" type="button"
|
||||
t-att-style="widget.node.attrs.style"
|
||||
t-att-accesskey="widget.node.attrs.accesskey">
|
||||
<span class="fa fa-arrow-right"/>
|
||||
</button>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
|
@ -3,17 +3,6 @@
|
|||
<data>
|
||||
|
||||
<!-- Email Templates -->
|
||||
<record id="email_template_form_mass_mailing" model="ir.ui.view">
|
||||
<field name="name">email.template.form.mass.mailing</field>
|
||||
<field name="model">email.template</field>
|
||||
<field name="inherit_id" ref="email_template.email_template_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='model_id']" position="after">
|
||||
<field name="use_in_mass_mailing"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="email_template_form_minimal">
|
||||
<field name="name">email.template.form.minimal</field>
|
||||
<field name="model">email.template</field>
|
||||
|
@ -29,7 +18,6 @@
|
|||
domain="[('model', 'in', ['res.partner', 'mail.mass_mailing.contact'])]"/>
|
||||
<field name="model" invisible="True"/>
|
||||
<field name="use_default_to" invisible="1"/>
|
||||
<field name="use_in_mass_mailing" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
|
@ -37,8 +25,8 @@
|
|||
type="action" target="new"
|
||||
context="{'template_id':active_id}"/>
|
||||
<br />
|
||||
<field name="website_link" widget='html' radonly='1'
|
||||
style='margin: 0px; padding: 0px;'/>
|
||||
<!-- <field name="website_link" widget='html' radonly='1'
|
||||
style='margin: 0px; padding: 0px;'/> -->
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
|
@ -53,19 +41,6 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_email_template_search_mass_mailing" model="ir.ui.view">
|
||||
<field name="name">email.template.search.mass.mailing</field>
|
||||
<field name="model">email.template</field>
|
||||
<field name="inherit_id" ref="email_template.view_email_template_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='model_id']" position="after">
|
||||
<separator/>
|
||||
<filter string="Available for Marketing and Mailing" name="use_in_mass_mailing" domain="[('use_in_mass_mailing', '=', 1)]"
|
||||
help="Available for use in mass mailings"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_email_template_kanban">
|
||||
<field name="name">email.template.kanban</field>
|
||||
<field name="model">email.template</field>
|
||||
|
@ -78,9 +53,6 @@
|
|||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<span class="oe_e">i</span>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t>
|
||||
<li><a name="action_new_mailing" type="object">New Mailing</a></li>
|
||||
</t>
|
||||
<t t-if="widget.view.is_action_enabled('edit')">
|
||||
<li><a type="edit">Edit</a></li>
|
||||
</t>
|
||||
|
@ -110,11 +82,9 @@
|
|||
<field name="res_model">email.template</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">kanban,tree,form</field>
|
||||
<field name="domain" eval="[('use_in_mass_mailing', '=', True)]"/>
|
||||
<field name="context">{
|
||||
'form_view_ref': 'mass_mailing.email_template_form_minimal',
|
||||
'default_use_default_to': True,
|
||||
'default_use_in_mass_mailing': True,
|
||||
}</field>
|
||||
</record>
|
||||
|
||||
|
@ -124,4 +94,4 @@
|
|||
action="action_email_template_marketing"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -6,25 +6,26 @@
|
|||
<menuitem name="Mass Mailing" id="mass_mailing_campaign"
|
||||
parent="base.marketing_menu" sequence="1"/>
|
||||
<!-- Marketing / Mailing Lists -->
|
||||
<menuitem name="Contact Lists" id="mass_mailing_list"
|
||||
<menuitem name="Mailing Lists" id="mass_mailing_list"
|
||||
parent="base.marketing_menu" sequence="2"/>
|
||||
<!-- Marketing / Configuration -->
|
||||
<menuitem name="Configuration" id="marketing_configuration"
|
||||
parent="base.marketing_menu" sequence="99"/>
|
||||
|
||||
<!-- MASS MAILING CONTACT !-->
|
||||
<!-- MASS MAILING CONTACT -->
|
||||
<record model="ir.ui.view" id="view_mail_mass_mailing_contact_search">
|
||||
<field name="name">mail.mass_mailing.contact.search</field>
|
||||
<field name="model">mail.mass_mailing.contact</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Mass Mailings">
|
||||
<search string="Mailing Lists Subscribers">
|
||||
<field name="name"/>
|
||||
<field name="email"/>
|
||||
<field name="list_id"/>
|
||||
<separator/>
|
||||
<filter string="Available for Mass Mailing" name="not_opt_out" domain="[('opt_out', '=', False)]"
|
||||
help="Contact is not opt-out"/>
|
||||
<filter string="Exclude Opt Out" name="not_opt_out" domain="[('opt_out', '=', False)]"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Creation Date" name="group_create_date"
|
||||
context="{'group_by': 'create_date'}"/>
|
||||
<filter string="Mailing Lists" name="group_list_id"
|
||||
context="{'group_by': 'list_id'}"/>
|
||||
</group>
|
||||
|
@ -37,67 +38,48 @@
|
|||
<field name="model">mail.mass_mailing.contact</field>
|
||||
<field name="priority">10</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Mass Mailings">
|
||||
<field name="name"/>
|
||||
<tree string="Mailing Lists Subscribers" editable="top">
|
||||
<field name="email"/>
|
||||
<field name="name"/>
|
||||
<field name="list_id"/>
|
||||
<field name="opt_out"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_mail_mass_mailing_contact_form">
|
||||
<field name="name">mail.mass_mailing.contact.form</field>
|
||||
<field name="model">mail.mass_mailing.contact</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Mass Mailing" version="7.0">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="email"/>
|
||||
<field name="list_id"/>
|
||||
<field name="opt_out"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_mass_mailing_contacts" model="ir.actions.act_window">
|
||||
<field name="name">Mass Mailing Contacts</field>
|
||||
<field name="name">Mailing List Subscribers</field>
|
||||
<field name="res_model">mail.mass_mailing.contact</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="context">{'search_default_not_opt_out': 1}</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Contacts" id="menu_email_mass_mailing_contacts" groups="base.group_no_one"
|
||||
<record id="action_view_mass_mailing_contacts_from_list" model="ir.actions.act_window">
|
||||
<field name="name">Recipients</field>
|
||||
<field name="res_model">mail.mass_mailing.contact</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="context">{'search_default_list_id': active_id, 'search_default_not_opt_out': 1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a recipient.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Contacts" id="menu_email_mass_mailing_contacts"
|
||||
parent="mass_mailing_list" sequence="50"
|
||||
action="action_view_mass_mailing_contacts"/>
|
||||
|
||||
<!-- Create a Mailing List from Contacts -->
|
||||
<act_window name="Create Mailing List"
|
||||
res_model="mail.mass_mailing.list.confirm"
|
||||
src_model="mail.mass_mailing.contact"
|
||||
view_mode="form"
|
||||
multi="True"
|
||||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="action_contact_to_mailing_list"
|
||||
context="{
|
||||
'default_mass_mailing_id': context.get('default_mass_mailing_id'),
|
||||
'default_model': context.get('default_model', 'mail.mass_mailing.contact'),
|
||||
'default_name': context.get('default_name', False)}"/>
|
||||
|
||||
<!-- MASS MAILING LIST !-->
|
||||
<!-- MASS MAILING LIST -->
|
||||
<record model="ir.ui.view" id="view_mail_mass_mailing_list_search">
|
||||
<field name="name">mail.mass_mailing.list.search</field>
|
||||
<field name="model">mail.mass_mailing.list</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Mass Mailings">
|
||||
<field name="name"/>
|
||||
<separator/>
|
||||
</search>
|
||||
<search string="Mailing Lists">
|
||||
<field name="name"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
@ -106,9 +88,8 @@
|
|||
<field name="model">mail.mass_mailing.list</field>
|
||||
<field name="priority">10</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Contact Lists">
|
||||
<tree string="Mailing Lists">
|
||||
<field name="name"/>
|
||||
<field name="model"/>
|
||||
<field name="contact_nbr"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -119,27 +100,19 @@
|
|||
<field name="model">mail.mass_mailing.list</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contact List" version="7.0">
|
||||
<header>
|
||||
<button name="action_add_to_mailing" type="object"
|
||||
class="oe_highlight" string="Continue to Mailing"
|
||||
invisible="not context.get('default_mass_mailing_id')"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name" string="Mailing List Name"/>
|
||||
<label for="contact_nbr"/>
|
||||
<div>
|
||||
<field name="contact_nbr" nolabel="1" class="oe_inline"/>
|
||||
<field name="model" class="oe_inline"
|
||||
on_change="on_change_model(model, context)" nolabel="1"/>
|
||||
<button string="See Recipients" class="oe_inline oe_link" style="margin-left: 8px;"
|
||||
name="action_see_records" type="object"/>
|
||||
</div>
|
||||
<field name="filter_id" groups="base.group_no_one"
|
||||
on_change="on_change_filter_id(filter_id, context)"/>
|
||||
<field name="domain" groups="base.group_no_one"
|
||||
on_change="on_change_domain(domain, model, context)"/>
|
||||
</group>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<button name="%(mass_mailing.action_view_mass_mailing_contacts_from_list)d"
|
||||
type="action" icon="fa-user" class="oe_stat_button pull-right">
|
||||
<field name="contact_nbr" string="Recipients" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
</div>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -150,15 +123,16 @@
|
|||
<field name="res_model">mail.mass_mailing.list</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click here to create a new mailing list.
|
||||
</p><p>
|
||||
Mailing lists allows you to to manage customers and contacts easily and to send to mailings in a single click.
|
||||
Mailing lists allows you to to manage customers and
|
||||
contacts easily and to send to mailings in a single click.
|
||||
</p></field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Contact Lists" id="menu_email_mass_mailing_lists"
|
||||
<menuitem name="Mailing Lists" id="menu_email_mass_mailing_lists"
|
||||
parent="mass_mailing_list" sequence="40"
|
||||
action="action_view_mass_mailing_lists"/>
|
||||
|
||||
|
@ -170,15 +144,12 @@
|
|||
<search string="Mass Mailings">
|
||||
<field name="name" string="Mailings"/>
|
||||
<field name="mass_mailing_campaign_id"/>
|
||||
<field name="template_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="State" name="group_state"
|
||||
context="{'group_by': 'state'}"/>
|
||||
<filter string="Campaign" name="group_mass_mailing_campaign_id"
|
||||
groups="mass_mailing.group_mass_mailing_campaign"
|
||||
context="{'group_by': 'mass_mailing_campaign_id'}"/>
|
||||
<filter string="Template" name="group_template_id"
|
||||
context="{'group_by': 'template_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
@ -197,7 +168,6 @@
|
|||
<field name="replied"/>
|
||||
<field name="mass_mailing_campaign_id"
|
||||
groups="mass_mailing.group_mass_mailing_campaign"/>
|
||||
<field name="template_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -209,127 +179,129 @@
|
|||
<form string="Mass Mailing" version="7.0">
|
||||
<header>
|
||||
<button name="action_test_mailing" type="object"
|
||||
class="oe_highlight" string="Test Mailing"/>
|
||||
<button name="send_mail" type="object"
|
||||
class="oe_highlight" string="Test Mailing" states="draft"/>
|
||||
<button name="send_mail" type="object" states="draft,test"
|
||||
class="oe_highlight" string="Send to All"/>
|
||||
<field name="state" widget="statusbar" clickable="True"/>
|
||||
<button name="action_test_mailing" type="object" states="test,done"
|
||||
string="Send Test Sample"/>
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<div class="oe_form_box_info oe_text_center" attrs="{'invisible': [('scheduled', '=', 0)]}">
|
||||
<p><strong>
|
||||
<field name="scheduled" class="oe_inline"/>
|
||||
emails are in queue and will be sent soon.
|
||||
</strong></p>
|
||||
</div>
|
||||
<sheet>
|
||||
<div colspan="2" class="oe_form_box_info oe_text_center"
|
||||
attrs="{'invisible': [('scheduled', '=', 0)]}">
|
||||
<p>
|
||||
<strong><field name="scheduled" class="oe_inline"/>emails are in queue
|
||||
and will be sent soon.</strong>
|
||||
</p>
|
||||
<div class="oe_button_box pull-right" attrs="{'invisible': [('state', 'in', ('draft','test'))]}">
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="received_ratio" string="Received" widget="percentpie"/>
|
||||
</button>
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="opened_ratio" string="Opened" widget="percentpie"/>
|
||||
</button>
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="replied_ratio" string="Replied" widget="percentpie"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_button_box" attrs="{'invisible': [('state', 'in', ('draft','test'))]}" style="margin-bottom: 32px">
|
||||
<button name="action_see_recipients" type="object"
|
||||
icon="fa-user" class="oe_stat_button">
|
||||
<field name="contact_nbr" string="Recipients" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="%(action_mail_mass_mailing_report)d" type="action"
|
||||
icon="fa-envelope-o" class="oe_stat_button">
|
||||
<field name="total" string="Emails" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_button_box"
|
||||
style="margin-top: 8px;"
|
||||
attrs="{'invisible': [('total', '=', 0)]}">
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button oe_inline">
|
||||
<field name="opened_dayly" string="Opened Daily" widget="barchart"/>
|
||||
</button>
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button oe_inline">
|
||||
<field name="replied_dayly" string="Replied Daily" widget="barchart"/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<group>
|
||||
<group>
|
||||
<field name="email_from"/>
|
||||
<field name="name"/>
|
||||
</group>
|
||||
<group>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<div>
|
||||
<button name="action_see_recipients" type="object"
|
||||
icon="fa-user" class="oe_stat_button">
|
||||
<field name="contact_nbr" string="Recipients" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="%(action_mail_mass_mailing_report)d" type="action"
|
||||
icon="fa-envelope-o" class="oe_stat_button">
|
||||
<field name="total" string="Emails" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<div style="margin-top: 8px;"
|
||||
attrs="{'invisible': [('total', '=', 0)]}">
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="received_ratio" string="Received" widget="percentpie"/>
|
||||
</button>
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="opened_ratio" string="Opened" widget="percentpie"/>
|
||||
</button>
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="replied_ratio" string="Replied" widget="percentpie"/>
|
||||
</button>
|
||||
</div>
|
||||
<div style="margin-top: 8px;"
|
||||
attrs="{'invisible': [('total', '=', 0)]}">
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button oe_inline">
|
||||
<field name="opened_dayly" string="Opened Daily" widget="barchart"/>
|
||||
</button>
|
||||
<button name="%(action_mail_mass_mailing_report)d"
|
||||
type="action" class="oe_stat_button oe_inline">
|
||||
<field name="replied_dayly" string="Replied Daily" widget="barchart"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<label for="reply_to"/>
|
||||
<div>
|
||||
<field name="auto_reply_to_available" invisible="1"/>
|
||||
<field name="reply_in_thread" class="oe_inline"
|
||||
on_change="on_change_reply_in_thread(reply_specified, reply_in_thread, context)"
|
||||
attrs="{'readonly': [('auto_reply_to_available', '=', False)]}"/>
|
||||
<span attrs="{'invisible': [('auto_reply_to_available', '=', False)]}">
|
||||
Replies go into the original document
|
||||
</span>
|
||||
<span class="oe_grey" attrs="{'invisible': [('auto_reply_to_available', '=', True)]}">
|
||||
Replies go into the original document (not available for those recipients)
|
||||
</span>
|
||||
<br />
|
||||
<field name="reply_specified" class="oe_inline"
|
||||
on_change="on_change_reply_specified(reply_specified, reply_in_thread, context)"/> Use a specific reply-to address
|
||||
<field name="reply_to" class="oe_inline"
|
||||
style="margin-left: 8px;"
|
||||
attrs="{'required': [('reply_specified', '=', True)]}"/>
|
||||
</div>
|
||||
<field name="email_from"/>
|
||||
<field name="name"/>
|
||||
<label for="mailing_model" string="Recipients"/>
|
||||
<div>
|
||||
<field name="mailing_model" widget="radio"
|
||||
on_change='on_change_mailing_model(mailing_model, context)'/>
|
||||
<field name="mailing_model" widget="radio" style="margin-bottom: 8px"
|
||||
on_change="on_change_model(mailing_model, contact_list_ids)"/>
|
||||
|
||||
<label for="contact_list_ids" string="Mailing Lists" style="display: inline-block; min-width: 90px;"/>
|
||||
<field name="contact_list_ids" widget="many2many_tags" options="{'no_create': True}"
|
||||
class="oe_inline" placeholder="Choose mailing lists"
|
||||
on_change="on_change_contact_list_ids(mailing_model, contact_list_ids, context)"/>
|
||||
<span style="margin-left: 8px; margin-right: 8px">or</span>
|
||||
<button string='Create a New List' class="oe_link" type='object' name='action_new_list'/><br />
|
||||
<field name="mailing_domain" widget="char_domain"
|
||||
attrs="{'invisible': [('mailing_model', '=', 'mail.mass_mailing.contact')]}"
|
||||
placeholder="Select recipients"
|
||||
options="{'model_field': 'mailing_model'}"/>
|
||||
|
||||
<div groups="mass_mailing.group_mass_mailing_campaign" style="display: inline;">
|
||||
<field name="ab_testing" invisible="1"/>
|
||||
<label for="contact_ab_pc" string="AB Testing" style="display: inline-block; min-width: 90px;"/>
|
||||
Email <field name="contact_ab_pc" class="oe_inline"
|
||||
on_change="on_change_contact_ab_pc(contact_ab_pc, contact_nbr, context)"/>
|
||||
<strong>%</strong> of recipients
|
||||
(<field name="contact_ab_nbr" class="oe_inline"/> recipients)
|
||||
<div attrs="{'invisible': [('ab_testing', '=', False)]}" style="display: inline;">
|
||||
<span>(</span>
|
||||
<field name="contact_ab_done" class="oe_inline"
|
||||
attrs="{'invisible': [('ab_testing', '=', False)]}"/> already mailed
|
||||
<span>)</span>
|
||||
</div>
|
||||
<div attrs="{'invisible': [('mailing_model', '<>', 'mail.mass_mailing.contact')]}">
|
||||
<label for="contact_list_ids" string="Select mailing lists:" class="oe_edit_only"/>
|
||||
<field name="contact_list_ids" widget="many2many_tags"
|
||||
placeholder="Select mailing lists..." class="oe_inline"
|
||||
on_change="on_change_model(mailing_model, contact_list_ids)"/>
|
||||
</div>
|
||||
<div attrs="{'invisible': [('contact_nbr', '<', 1)]}">
|
||||
<strong>
|
||||
<field name="contact_nbr" class="oe_inline"/> Recipients
|
||||
</strong>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<field name="date" readonly="True" groups="mass_mailing.group_mass_mailing_campaign"
|
||||
attrs="{'invisible': [('state', '!=', 'done')]}"/>
|
||||
<field name="mass_mailing_campaign_id" groups="mass_mailing.group_mass_mailing_campaign"/>
|
||||
<label for="body_html" string="Email"/>
|
||||
<div>
|
||||
<label for="template_id" string="Template"/>
|
||||
<field name="template_id" string="Select Template"
|
||||
class="oe_inline" options="{'no_create': True, 'no_open': True}"
|
||||
on_change="on_change_template_id(template_id, context)"/><br />
|
||||
<button name="action_edit_html" type="object" string="Edit Mail Content"
|
||||
class="oe_link" style="margin-left: 8px"/>
|
||||
<field name="body_html"/>
|
||||
</div>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Mail Body">
|
||||
<button name="action_edit_html" type="object" string="Design Email" class="oe_highlight" states="draft"/>
|
||||
<button name="action_edit_html" type="object" string="Change Email Design" states="test"/>
|
||||
<div attrs="{'invisible' : ['|', ('body_html','!=',False), ('mailing_domain', '!=', False)]}" class="oe_view_nocontent oe_clear">
|
||||
<p class="oe_view_nocontent_create oe_edit_only">
|
||||
Click to design your email.
|
||||
</p>
|
||||
</div>
|
||||
<field name="body_html" readonly="1"/>
|
||||
</page>
|
||||
<page string="Options">
|
||||
<group>
|
||||
<group string="Campaign" groups="mass_mailing.group_mass_mailing_campaign">
|
||||
<field name="mass_mailing_campaign_id"/>
|
||||
<label for="contact_ab_pc"/>
|
||||
<div>
|
||||
<field name="contact_ab_pc" class="oe_inline"/> %
|
||||
</div>
|
||||
</group><group>
|
||||
<field name="date"/>
|
||||
</group><group>
|
||||
<label for="reply_to"/>
|
||||
<div>
|
||||
<field name="auto_reply_to_available" invisible="1"/>
|
||||
<field name="reply_in_thread" class="oe_inline"
|
||||
on_change="on_change_reply_in_thread(reply_specified, reply_in_thread, context)"
|
||||
attrs="{'readonly': [('auto_reply_to_available', '=', False)]}"/>
|
||||
<span attrs="{'invisible': [('auto_reply_to_available', '=', False)]}">
|
||||
Replies go into the original document
|
||||
</span>
|
||||
<span class="oe_grey" attrs="{'invisible': [('auto_reply_to_available', '=', True)]}">
|
||||
Replies go into the original document (not available for those recipients)
|
||||
</span>
|
||||
<br />
|
||||
<field name="reply_specified" class="oe_inline"
|
||||
on_change="on_change_reply_specified(reply_specified, reply_in_thread, context)"/> Use a specific reply-to address
|
||||
<field name="reply_to" class="oe_inline"
|
||||
style="margin-left: 8px;"
|
||||
attrs="{'required': [('reply_specified', '=', True)]}"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -429,28 +401,12 @@
|
|||
<field name="model">mail.mass_mailing.stage</field>
|
||||
<field name="priority">10</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Mass Mailings">
|
||||
<tree string="Mass Mailings" editable="top">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="sequence"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_mail_mass_mailing_stage_form">
|
||||
<field name="name">mail.mass_mailing.stage.form</field>
|
||||
<field name="model">mail.mass_mailing.stage</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Mass Mailing" version="7.0">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="sequence"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_mass_mailing_stages" model="ir.actions.act_window">
|
||||
<field name="name">Mass Mailing Stages</field>
|
||||
<field name="res_model">mail.mass_mailing.stage</field>
|
||||
|
@ -460,6 +416,7 @@
|
|||
|
||||
<menuitem name="Campaign Stages" id="menu_view_mass_mailing_stages"
|
||||
parent="marketing_configuration" sequence="1"
|
||||
groups="mass_mailing.group_mass_mailing_campaign"
|
||||
action="action_view_mass_mailing_stages"/>
|
||||
|
||||
<!-- MASS MAILING CAMPAIGNS !-->
|
||||
|
@ -469,15 +426,13 @@
|
|||
<field name="arch" type="xml">
|
||||
<search string="Mass Mailing Campaigns">
|
||||
<field name="name" string="Campaigns"/>
|
||||
<field name="category_id"/>
|
||||
<field name="category_ids"/>
|
||||
<field name="user_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Stage" name="group_stage_id"
|
||||
context="{'group_by': 'stage_id'}"/>
|
||||
<filter string="Responsible" name="group_user_id"
|
||||
context="{'group_by': 'user_id'}"/>
|
||||
<filter string="Category" name="group_category_id"
|
||||
context="{'group_by': 'category_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
@ -492,18 +447,20 @@
|
|||
<field name="name"/>
|
||||
<field name="user_id"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="category_id"/>
|
||||
<field name="category_ids"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_mail_mass_mailing_campaign_form">
|
||||
<field name="name">mail.mass_mailing.campaign.form</field>
|
||||
<field name="model">mail.mass_mailing.campaign</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Mass Mailing Campaign" version="7.0">
|
||||
<header>
|
||||
<button name="action_new_mailing" type="object" class="oe_highlight" string="New Mailing"/>
|
||||
<button name="%(action_view_mass_mailings_from_campaign)d" type="action" class="oe_highlight" string="New Mailing"/>
|
||||
<field name="stage_id" widget="statusbar" clickable="True"/>
|
||||
</header>
|
||||
<sheet>
|
||||
|
@ -511,8 +468,7 @@
|
|||
<group>
|
||||
<field name="name"/>
|
||||
<field name="user_id"/>
|
||||
<field name="category_id"/>
|
||||
<field name="ab_testing"/>
|
||||
<field name="category_ids"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="total" invisible="1"/>
|
||||
|
@ -583,7 +539,7 @@
|
|||
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)"
|
||||
t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar oe_kanban_header_right"/>
|
||||
<h3 style="margin-bottom: 8px;"><field name="name"/></h3>
|
||||
<span class="oe_tag"><field name="category_id"/></span>
|
||||
<span class="oe_tag"><field name="category_ids"/></span>
|
||||
<a name="%(action_view_mass_mailings_from_campaign)d" type="action"
|
||||
class="oe_mailings">
|
||||
<h4 style="margin-top: 8px;"><t t-raw="record.mass_mailing_ids.raw_value.length"/> Mailings</h4>
|
||||
|
@ -673,7 +629,6 @@
|
|||
<group>
|
||||
<field name="mass_mailing_id"/>
|
||||
<field name="mass_mailing_campaign_id"/>
|
||||
<field name="template_id"/>
|
||||
<field name="model"/>
|
||||
<field name="res_id"/>
|
||||
</group>
|
||||
|
@ -694,11 +649,5 @@
|
|||
parent="base.menu_email" sequence="50"
|
||||
action="action_view_mail_mail_statistics"/>
|
||||
|
||||
<!-- MISC -->
|
||||
<!-- Mailing List Create Wizard -->
|
||||
<menuitem name="Create a new List" id="menu_mail_mass_mailing_create"
|
||||
parent="mass_mailing_list" sequence="10"
|
||||
action="action_mail_mass_mailing_create"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -2,19 +2,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Create a Mailing List from Partners -->
|
||||
<act_window name="Create Mailing List"
|
||||
res_model="mail.mass_mailing.list.confirm"
|
||||
src_model="res.partner"
|
||||
view_mode="form"
|
||||
multi="True"
|
||||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="action_partner_to_mailing_list"
|
||||
context="{
|
||||
'default_mass_mailing_id': context.get('default_mass_mailing_id'),
|
||||
'default_model': context.get('default_model', 'res.partner'),
|
||||
'default_name': context.get('default_name', False)}"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -2,4 +2,3 @@
|
|||
|
||||
import test_mailing
|
||||
import mail_compose_message
|
||||
import mailing_list_confirm
|
||||
|
|
|
@ -50,15 +50,16 @@ class MailComposeMessage(osv.TransientModel):
|
|||
if wizard.composition_mode == 'mass_mail' and \
|
||||
(wizard.mass_mailing_name or wizard.mass_mailing_id) and \
|
||||
wizard.model in [item[0] for item in self.pool['mail.mass_mailing']._get_mailing_model(cr, uid, context=context)]:
|
||||
if wizard.mailing_list_ids:
|
||||
list_ids = [l.id for l in wizard.mailing_list_ids]
|
||||
if not list_ids:
|
||||
list_ids = [self.pool['mail.mass_mailing.list'].create(
|
||||
cr, uid, {
|
||||
'name': wizard.mass_mailing_name,
|
||||
'model': wizard.model,
|
||||
'domain': wizard.active_domain,
|
||||
}, context=context)]
|
||||
# list_ids = None
|
||||
# if wizard.mailing_list_ids:
|
||||
# list_ids = [l.id for l in wizard.mailing_list_ids]
|
||||
# if not list_ids:
|
||||
# list_ids = [self.pool['mail.mass_mailing.list'].create(
|
||||
# cr, uid, {
|
||||
# 'name': wizard.mass_mailing_name,
|
||||
# 'model': wizard.model,
|
||||
# 'domain': wizard.active_domain,
|
||||
# }, context=context)]
|
||||
mass_mailing = wizard.mass_mailing_id
|
||||
if not mass_mailing:
|
||||
mass_mailing_id = self.pool['mail.mass_mailing'].create(
|
||||
|
@ -68,7 +69,7 @@ class MailComposeMessage(osv.TransientModel):
|
|||
'template_id': wizard.template_id and wizard.template_id.id or False,
|
||||
'state': 'done',
|
||||
'mailing_type': wizard.model,
|
||||
'contact_list_ids': [(4, list_id) for list_id in list_ids],
|
||||
# 'contact_list_ids': [(4, list_id) for list_id in list_ids],
|
||||
}, context=context)
|
||||
mass_mailing = self.pool['mail.mass_mailing'].browse(cr, uid, mass_mailing_id, context=context)
|
||||
recipient_values = self.pool['mail.mass_mailing'].get_recipients_data(cr, uid, mass_mailing, res_ids, context=context)
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp.osv import osv, fields
|
||||
from openerp.tools.translate import _
|
||||
|
||||
|
||||
class MailingListConfirm(osv.TransientModel):
|
||||
"""A wizard that acts as a confirmation when creating a new mailing list coming
|
||||
from a list view. This allows to have a lightweight flow to create mailing
|
||||
lists without having to go through multiple screens."""
|
||||
|
||||
_inherit = 'mail.mass_mailing.list'
|
||||
_name = 'mail.mass_mailing.list.confirm'
|
||||
|
||||
_columns = {
|
||||
'mass_mailing_id': fields.many2one('mail.mass_mailing', 'Mailing'),
|
||||
}
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
context.update(no_contact_to_list=True)
|
||||
return super(MailingListConfirm, self).create(cr, uid, values, context=context)
|
||||
|
||||
def action_confirm(self, cr, uid, ids, context=None):
|
||||
wizard = self.browse(cr, uid, ids[0], context=context)
|
||||
mailing_list_id = self.pool['mail.mass_mailing.list'].create(
|
||||
cr, uid, {'name': wizard.name, 'model': wizard.model}, context=context)
|
||||
res = self.pool['mail.mass_mailing.list'].action_add_to_mailing(cr, uid, [mailing_list_id], context=context)
|
||||
if not res:
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'mail.mass_mailing.list',
|
||||
'res_id': mailing_list_id,
|
||||
'context': context,
|
||||
}
|
||||
return res
|
||||
|
||||
def action_new_list(self, cr, uid, ids, context=None):
|
||||
wizard = self.browse(cr, uid, ids[0], context=context)
|
||||
action_id = self.pool['mail.mass_mailing']._get_model_to_list_action_id(cr, uid, wizard.model, context=context)
|
||||
if wizard.model == 'mail.mass_mailing.contact':
|
||||
domain = [('list_id', '=', False)]
|
||||
else:
|
||||
domain = []
|
||||
ctx = dict(context, search_default_not_opt_out=True, view_manager_highlight=[action_id], default_name=wizard.name, default_model=wizard.model)
|
||||
return {
|
||||
'name': _('Choose Recipients'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': wizard.model,
|
||||
'context': ctx,
|
||||
'domain': domain,
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view" id="view_mail_mass_mailing_list_confirm_form">
|
||||
<field name="name">mail.mass_mailing.list.confirm.form</field>
|
||||
<field name="model">mail.mass_mailing.list.confirm</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Confirm Mailing List" version="7.0">
|
||||
<group>
|
||||
<field name="model" invisible="1"/>
|
||||
<field name="domain" invisible="1"
|
||||
on_change="on_change_domain(domain, model, context)"/>
|
||||
<div attrs="{'invisible': [('mass_mailing_id', '=', False)]}" colspan="2">
|
||||
Adding <field name="contact_nbr" class="oe_inline"/> contacts
|
||||
to the mailing <field name="mass_mailing_id" class="oe_inline" readonly="1"/>.
|
||||
</div>
|
||||
<field name="name" attrs="{'invisible': [('mass_mailing_id', '!=', False)]}"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Confirm" name="action_confirm" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_mail_mass_mailing_list_create_form">
|
||||
<field name="name">mail.mass_mailing.list.confirm.form</field>
|
||||
<field name="model">mail.mass_mailing.list.confirm</field>
|
||||
<field name="priority">32</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create a Mailing List" version="7.0">
|
||||
<header>
|
||||
<button string='Create a New List' class="oe_highlight"
|
||||
type='object' name='action_new_list'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="model" widget="radio"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_mail_mass_mailing_list_confirm" model="ir.actions.act_window">
|
||||
<field name="name">Create a Mailing List</field>
|
||||
<field name="res_model">mail.mass_mailing.list.confirm</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<record id="action_mail_mass_mailing_create" model="ir.actions.act_window">
|
||||
<field name="name">Create a Mailing List</field>
|
||||
<field name="res_model">mail.mass_mailing.list.confirm</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_mail_mass_mailing_list_create_form"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -6,27 +6,26 @@ from openerp.osv import osv, fields
|
|||
|
||||
class TestMassMailing(osv.TransientModel):
|
||||
_name = 'mail.mass_mailing.test'
|
||||
_description = 'Tets Mailing Wizard'
|
||||
_description = 'Sample Mail Wizard'
|
||||
|
||||
_columns = {
|
||||
'email_to': fields.char(
|
||||
'Emails', required=True,
|
||||
'email_to': fields.char('Recipients', required=True,
|
||||
help='Comma-separated list of email addresses.'),
|
||||
'mass_mailing_id': fields.many2one('mail.mass_mailing', 'Mailing', required=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'email_to': lambda self, cr, uid, ctx=None: self.pool['mail.message']._get_default_from(cr, uid, context=ctx),
|
||||
}
|
||||
|
||||
def send_mail_test(self, cr, uid, ids, context=None):
|
||||
Mail = self.pool['mail.mail']
|
||||
for wizard in self.browse(cr, uid, ids, context=context):
|
||||
mailing = wizard.mass_mailing_id
|
||||
if not mailing.template_id:
|
||||
raise Warning('Please specify on your mailing the template to use.')
|
||||
test_emails = tools.email_split(wizard.email_to)
|
||||
if not test_emails:
|
||||
raise Warning('Please specify test email adresses.')
|
||||
mail_ids = []
|
||||
for test_mail in test_emails:
|
||||
body = mailing.template_id.body_html
|
||||
body = mailing.body_html
|
||||
unsubscribe_url = self.pool['mail.mass_mailing'].get_unsubscribe_url(cr, uid, mailing.id, 0, email=test_mail, context=context)
|
||||
body = tools.append_content_to_html(body, unsubscribe_url, plaintext=False, container_tag='p')
|
||||
mail_values = {
|
||||
|
|
|
@ -6,12 +6,15 @@
|
|||
<field name="name">mail.mass_mailing.test.form</field>
|
||||
<field name="model">mail.mass_mailing.test</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Mailing Test" version="7.0">
|
||||
<form string="Send a Sample Mail" version="7.0">
|
||||
<p class="text-muted">
|
||||
Send a sample of this mailing to the above of email addresses for test purpose.
|
||||
</p>
|
||||
<group>
|
||||
<field name="email_to"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Test Mailing" name="send_mail_test" type="object" class="oe_highlight"/>
|
||||
<button string="Send Sample Mail" name="send_mail_test" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
|
|
|
@ -8,20 +8,32 @@ from openerp.addons.web.http import request
|
|||
class WebsiteEmailDesigner(http.Controller):
|
||||
|
||||
@http.route('/website_mail/email_designer', type='http', auth="user", website=True, multilang=True)
|
||||
def index(self, model=None, res_id=None, **kw):
|
||||
def index(self, model, res_id, template_model, field_body='body', field_from='email_from', field_subject='name', **kw):
|
||||
if not model or not model in request.registry or not res_id:
|
||||
return request.redirect('/')
|
||||
if not 'body' in request.registry[model]._all_columns and not 'body_html' in request.registry[model]._all_columns:
|
||||
return request.redirect('/')
|
||||
# if not 'body' in request.registry[model]._all_columns and not 'body_html' in request.registry[model]._all_columns:
|
||||
# return request.redirect('/')
|
||||
obj_ids = request.registry[model].exists(request.cr, request.uid, [res_id], context=request.context)
|
||||
if not obj_ids:
|
||||
return request.redirect('/')
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
tmpl_obj = request.registry['email.template']
|
||||
res_id = int(res_id)
|
||||
|
||||
tids = tmpl_obj.search(cr, uid, [('model','=',template_model)], context=context)
|
||||
templates = tmpl_obj.browse(cr, uid, tids, context=context)
|
||||
|
||||
print templates
|
||||
values = {
|
||||
'object': request.registry[model].browse(request.cr, request.uid, obj_ids[0], context=request.context),
|
||||
'model': request.registry[model],
|
||||
'model_name': model,
|
||||
'object': request.registry[model].browse(cr, uid, res_id, context=context),
|
||||
'templates': templates,
|
||||
'model': model,
|
||||
'res_id': res_id,
|
||||
'field_body': field_body,
|
||||
'field_from': field_from,
|
||||
'field_subject': field_subject,
|
||||
}
|
||||
print '*', values
|
||||
return request.website.render("website_mail.designer_index", values)
|
||||
|
||||
@http.route(['/website_mail/snippets'], type='json', auth="user", website=True)
|
||||
|
|
|
@ -26,13 +26,13 @@ from openerp.tools.translate import _
|
|||
class EmailTemplate(osv.Model):
|
||||
_inherit = 'email.template'
|
||||
|
||||
def _get_website_link(self, cr, uid, ids, name, args, context=None):
|
||||
return dict((id, _('<a href="website_mail/email_designer?model=email.template&res_id=%d">Open with visual editor</a>') % id) for id in ids)
|
||||
|
||||
_columns = {
|
||||
'website_link': fields.function(
|
||||
_get_website_link, type='text',
|
||||
string='Website Link',
|
||||
help='Link to the website',
|
||||
),
|
||||
}
|
||||
def action_edit_html(self, cr, uid, ids, name, args, context=None):
|
||||
# tde fixme: avoid asserts
|
||||
assert len(ids)==1, "One and only one ID allowed for this action"
|
||||
url = '/website_mail/email_designer?model=email.template&res_id=%d&field_body=body_html&field_from=email_form&field_subject=name' % (ids[0],)
|
||||
return {
|
||||
'name': _('Edit Template'),
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': url,
|
||||
'target': 'self',
|
||||
}
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
.js_follow[data-follow='on'] .js_follow_btn ,
|
||||
.js_follow[data-follow='off'] .js_unfollow_btn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.email_preview_border {
|
||||
overflow: hidden !important;
|
||||
border: 2px solid grey;
|
||||
height: 300px;
|
||||
}
|
||||
.email_preview {
|
||||
-webkit-transform: scale(.50);
|
||||
-ms-transform: scale(.50);
|
||||
transform: scale(.50);
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
margin: 0 0px -300px 0;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
var website = openerp.website;
|
||||
|
||||
website.snippet.BuildingBlock.include({
|
||||
|
||||
// init: function (parent) {
|
||||
// this._super.apply(this, arguments);
|
||||
// },
|
||||
|
||||
_get_snippet_url: function () {
|
||||
return '/website_mail/snippets';
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Copy the template to the body of the email
|
||||
$(document).ready(function () {
|
||||
$('.js_template_set').click(function(ev) {
|
||||
$('#email_designer').show();
|
||||
$('#email_template').hide();
|
||||
$(".js_content", $(this).parent()).children().clone().appendTo('#email_body');
|
||||
|
||||
// Todo: switch to edit mode
|
||||
event.preventDefault();
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
<field name="inherit_id" ref="email_template.email_template_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//h1" position="after">
|
||||
<br />
|
||||
<field name="website_link" widget='html' radonly='1'
|
||||
style='margin: 0px; padding: 0px;'/>
|
||||
<button string="Edit Template" name="action_edit_html" type="object"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -8,47 +8,56 @@
|
|||
<t t-set="head">
|
||||
<script type="text/javascript" src="/website_mail/static/src/js/website_email_designer.js"></script>
|
||||
</t>
|
||||
<div id="wrap">
|
||||
<div class="container">
|
||||
<div id="wrap" class="container" t-ignore="True">
|
||||
<div id="email_template" t-att-style="(object.body_html and len(templates)>0) and 'display: none'" class="mb32">
|
||||
<a class="mt16 btn btn-default pull-right"
|
||||
t-attf-href="/web#return_label=Website&model=#{model}&id=#{res_id}&view_type=form">
|
||||
Back
|
||||
</a>
|
||||
<h1 class="page-header mt16">
|
||||
Choose an Email Template
|
||||
</h1>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<a class="pull-right mt32"
|
||||
t-att-href="'/web#return_label=Website&model=%s&id=%s&view_type=form' % (model_name, res_id)">
|
||||
<button class="btn btn-primary">Back to Form</button>
|
||||
</a>
|
||||
<h1 t-field="object.name"/>
|
||||
<div class="row" style="width: 600px;">
|
||||
<div t-if="'email_from' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>Email From</b></div>
|
||||
<div class="col-lg-9"><span t-field="object.email_from"/></div>
|
||||
</div>
|
||||
|
||||
<div t-if="'email_to' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>To (Email)</b></div>
|
||||
<div class="col-lg-9"><span t-field="object.email_to"/></div>
|
||||
</div>
|
||||
|
||||
<div t-if="'partner_to' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>To (Partners)</b></div>
|
||||
<div class="col-lg-9"><span t-field="object.partner_to"/></div>
|
||||
</div>
|
||||
|
||||
<div t-if="'reply_to' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>Reply To</b></div>
|
||||
<div class="col-lg-9"><span t-field="object.reply_to"/></div>
|
||||
</div>
|
||||
|
||||
<div t-if="'subject' in model._all_columns" class="row">
|
||||
<div class="col-lg-3"><b>Subject</b></div>
|
||||
<div class="col-lg-9"><span t-field="object.subject"/></div>
|
||||
</div>
|
||||
|
||||
<div class="row well">
|
||||
<div t-field="object.body_html" style="position: relative;"/>
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-4 text-center img-border">
|
||||
<div class="email_preview_border">
|
||||
<div class="email_preview js_content"/>
|
||||
</div>
|
||||
<h4>New Template</h4>
|
||||
<button class="btn btn-primary js_template_set">Select</button>
|
||||
</div>
|
||||
<div t-foreach="templates" t-as="template" class="col-md-3 col-sm-4 text-center">
|
||||
<div class="email_preview_border">
|
||||
<div t-field="template.body_html" class="email_preview js_content"/>
|
||||
</div>
|
||||
<h4 t-field="template.name"/>
|
||||
<button class="btn btn-primary js_template_set">Select</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="email_designer" t-att-style="not (object.body_html and len(templates)> 0) and 'display: none'" class="mb32">
|
||||
<a class="mt16 btn btn-primary pull-right"
|
||||
t-attf-href="/web#return_label=Website&model=#{model}&id=#{res_id}&view_type=form">
|
||||
Save and Continue
|
||||
</a>
|
||||
<h1 class="page-header mt16">
|
||||
Design Your Email
|
||||
</h1>
|
||||
<div class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">From:</label>
|
||||
<div class="col-sm-7">
|
||||
<span t-field="object.email_from" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">Subject:</label>
|
||||
<div class="col-sm-7">
|
||||
<span t-field="object.name" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div t-field="object.body_html" id="email_body"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
|
Loading…
Reference in New Issue