[IMP] mass_mailing: campaigns: some refactoring !
- state is now stage_id, many2one towaqrds a newly added stage model, allowing to tune your process of mailign campaigns. Todo: menu to configure stages + access rights. - cleaned campaign kanban view, to be smaller. - added statbuttons in form view of campaigns bzr revid: tde@openerp.com-20140404153432-b171x0frbfepyfkn
This commit is contained in:
parent
4f8ab3d03c
commit
f84a23ed5c
|
@ -19,5 +19,19 @@
|
||||||
<field name="category_id" ref="base.module_category_hidden"/>
|
<field name="category_id" ref="base.module_category_hidden"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<!-- Default stages of mass mailing campaigns -->
|
||||||
|
<record id="campaign_stage_1" model="mail.mass_mailing.stage">
|
||||||
|
<field name="name">Schedule</field>
|
||||||
|
<field name="sequence">10</field>
|
||||||
|
</record>
|
||||||
|
<record id="campaign_stage_2" model="mail.mass_mailing.stage">
|
||||||
|
<field name="name">Design</field>
|
||||||
|
<field name="sequence">20</field>
|
||||||
|
</record>
|
||||||
|
<record id="campaign_stage_3" model="mail.mass_mailing.stage">
|
||||||
|
<field name="name">Sent</field>
|
||||||
|
<field name="sequence">30</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
|
@ -101,7 +101,7 @@
|
||||||
</record>
|
</record>
|
||||||
<record id="mass_mail_campaign_1" model="mail.mass_mailing.campaign">
|
<record id="mass_mail_campaign_1" model="mail.mass_mailing.campaign">
|
||||||
<field name="name">Newsletter</field>
|
<field name="name">Newsletter</field>
|
||||||
<field name="state">design</field>
|
<field name="stage_id" ref="mass_mailing.campaign_stage_1"/>
|
||||||
<field name="user_id" eval="ref('base.user_root')"/>
|
<field name="user_id" eval="ref('base.user_root')"/>
|
||||||
<field name="category_id" eval="ref('mass_mailing.mass_mail_category_1')"/>
|
<field name="category_id" eval="ref('mass_mailing.mass_mail_category_1')"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
|
@ -210,6 +210,22 @@ class MassMailingList(osv.Model):
|
||||||
return model_to_domains
|
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'
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'name': fields.char('Name', required=True),
|
||||||
|
'sequence': fields.integer('Sequence'),
|
||||||
|
}
|
||||||
|
|
||||||
|
_defaults = {
|
||||||
|
'sequence': 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class MassMailingCampaign(osv.Model):
|
class MassMailingCampaign(osv.Model):
|
||||||
"""Model of mass mailing campaigns. """
|
"""Model of mass mailing campaigns. """
|
||||||
_name = "mail.mass_mailing.campaign"
|
_name = "mail.mass_mailing.campaign"
|
||||||
|
@ -231,17 +247,14 @@ class MassMailingCampaign(osv.Model):
|
||||||
'bounced': Statistics.search(cr, uid, [('mass_mailing_campaign_id', '=', cid), ('bounced', '!=', False)], count=True, context=context),
|
'bounced': Statistics.search(cr, uid, [('mass_mailing_campaign_id', '=', cid), ('bounced', '!=', False)], count=True, context=context),
|
||||||
}
|
}
|
||||||
results[cid]['delivered'] = results[cid]['sent'] - results[cid]['bounced']
|
results[cid]['delivered'] = results[cid]['sent'] - results[cid]['bounced']
|
||||||
|
results[cid]['received_ratio'] = 100.0 * results[cid]['delivered'] / (results[cid]['sent'] or 1)
|
||||||
|
results[cid]['opened_ratio'] = 100.0 * results[cid]['opened'] / (results[cid]['sent'] or 1)
|
||||||
|
results[cid]['replied_ratio'] = 100.0 * results[cid]['replied'] / (results[cid]['sent'] or 1)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def _get_state_list(self, cr, uid, context=None):
|
|
||||||
return [('draft', 'Schedule'), ('design', 'Design'), ('done', 'Sent')]
|
|
||||||
|
|
||||||
# indirections for inheritance
|
|
||||||
_state = lambda self, *args, **kwargs: self._get_state_list(*args, **kwargs)
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'name': fields.char('Name', required=True),
|
'name': fields.char('Name', required=True),
|
||||||
'state': fields.selection(_state, string='Status', required=True),
|
'stage_id': fields.many2one('mail.mass_mailing.stage', 'Stage', required=True),
|
||||||
'user_id': fields.many2one(
|
'user_id': fields.many2one(
|
||||||
'res.users', 'Responsible',
|
'res.users', 'Responsible',
|
||||||
required=True,
|
required=True,
|
||||||
|
@ -288,42 +301,29 @@ class MassMailingCampaign(osv.Model):
|
||||||
_get_statistics, string='Bounced',
|
_get_statistics, string='Bounced',
|
||||||
type='integer', multi='_get_statistics'
|
type='integer', multi='_get_statistics'
|
||||||
),
|
),
|
||||||
|
'received_ratio': fields.function(
|
||||||
|
_get_statistics, string='Received Ratio',
|
||||||
|
type='integer', multi='_get_statistics',
|
||||||
|
),
|
||||||
|
'opened_ratio': fields.function(
|
||||||
|
_get_statistics, string='Opened Ratio',
|
||||||
|
type='integer', multi='_get_statistics',
|
||||||
|
),
|
||||||
|
'replied_ratio': fields.function(
|
||||||
|
_get_statistics, string='Replied Ratio',
|
||||||
|
type='integer', multi='_get_statistics',
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'user_id': lambda self, cr, uid, ctx=None: uid,
|
'user_id': lambda self, cr, uid, ctx=None: uid,
|
||||||
'state': 'draft',
|
'stage_id': lambda self, cr, uid, ctx=None: self._get_default_stage_id(cr, uid, context=ctx),
|
||||||
}
|
}
|
||||||
|
|
||||||
#------------------------------------------------------
|
|
||||||
# Technical stuff
|
|
||||||
#------------------------------------------------------
|
|
||||||
|
|
||||||
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
|
|
||||||
""" 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)
|
|
||||||
read_group_all_states = [{
|
|
||||||
'__context': {'group_by': groupby[1:]},
|
|
||||||
'__domain': domain + [('state', '=', state_value)],
|
|
||||||
'state': state_value,
|
|
||||||
'state_count': 0,
|
|
||||||
} for state_value, state_name in states]
|
|
||||||
# Get standard results
|
|
||||||
read_group_res = super(MassMailingCampaign, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)
|
|
||||||
# Update standard results with default results
|
|
||||||
result = []
|
|
||||||
for state_value, state_name in states:
|
|
||||||
res = filter(lambda x: x['state'] == state_value, read_group_res)
|
|
||||||
if not res:
|
|
||||||
res = filter(lambda x: x['state'] == state_value, read_group_all_states)
|
|
||||||
res[0]['state'] = [state_value, state_name]
|
|
||||||
result.append(res[0])
|
|
||||||
return result
|
|
||||||
else:
|
|
||||||
return super(MassMailingCampaign, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)
|
|
||||||
|
|
||||||
#------------------------------------------------------
|
#------------------------------------------------------
|
||||||
# Actions
|
# Actions
|
||||||
#------------------------------------------------------
|
#------------------------------------------------------
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.openerp .oe_kanban_view .oe_kanban_mass_mailing_campaign {
|
.openerp .oe_kanban_view .oe_kanban_mass_mailing_campaign {
|
||||||
width: 360px;
|
width: 280px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.openerp .oe_kanban_view .oe_kanban_mass_mailing_campaign .oe_kanban_header_right {
|
.openerp .oe_kanban_view .oe_kanban_mass_mailing_campaign .oe_kanban_header_right {
|
||||||
|
|
|
@ -169,6 +169,8 @@
|
||||||
<field name="mass_mailing_campaign_id"/>
|
<field name="mass_mailing_campaign_id"/>
|
||||||
<field name="template_id"/>
|
<field name="template_id"/>
|
||||||
<group expand="0" string="Group By...">
|
<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"
|
<filter string="Campaign" name="group_mass_mailing_campaign_id"
|
||||||
groups="mass_mailing.group_mass_mailing_campaign"
|
groups="mass_mailing.group_mass_mailing_campaign"
|
||||||
context="{'group_by': 'mass_mailing_campaign_id'}"/>
|
context="{'group_by': 'mass_mailing_campaign_id'}"/>
|
||||||
|
@ -326,14 +328,14 @@
|
||||||
<t t-if="record.mass_mailing_campaign_id.raw_value" groups="mass_mailing.group_mass_mailing_campaign"> - </t><field name="date"/>
|
<t t-if="record.mass_mailing_campaign_id.raw_value" groups="mass_mailing.group_mass_mailing_campaign"> - </t><field name="date"/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div style="display: inline-block">
|
<div style="display: inline-block">
|
||||||
<field name="delivered" widget="gauge" style="width:120px; height: 90px;"
|
<field name="delivered" widget="gauge" style="width:120px; height: 90px;"
|
||||||
options="{'max_field': 'total'}"/>
|
options="{'max_field': 'total'}"/>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: inline-block; vertical-align: top;">
|
<div style="display: inline-block; vertical-align: top;">
|
||||||
<strong>Opened</strong> <field name="opened_ratio"/> %<br />
|
<strong>Opened</strong> <field name="opened_ratio"/> %<br />
|
||||||
<strong>Replied</strong> <field name="replied_ratio"/> %
|
<strong>Replied</strong> <field name="replied_ratio"/> %
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_clear"></div>
|
<div class="oe_clear"></div>
|
||||||
|
@ -389,6 +391,8 @@
|
||||||
<field name="category_id"/>
|
<field name="category_id"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<group expand="0" string="Group By...">
|
<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"
|
<filter string="Responsible" name="group_user_id"
|
||||||
context="{'group_by': 'user_id'}"/>
|
context="{'group_by': 'user_id'}"/>
|
||||||
<filter string="Category" name="group_category_id"
|
<filter string="Category" name="group_category_id"
|
||||||
|
@ -406,7 +410,7 @@
|
||||||
<tree string="Mass Mailing Campaigns">
|
<tree string="Mass Mailing Campaigns">
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="state"/>
|
<field name="stage_id"/>
|
||||||
<field name="category_id"/>
|
<field name="category_id"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
|
@ -419,7 +423,7 @@
|
||||||
<form string="Mass Mailing Campaign" version="7.0">
|
<form string="Mass Mailing Campaign" version="7.0">
|
||||||
<header>
|
<header>
|
||||||
<button name="action_new_mailing" type="object" class="oe_highlight" string="New Mailing"/>
|
<button name="action_new_mailing" type="object" class="oe_highlight" string="New Mailing"/>
|
||||||
<field name="state" widget="statusbar" clickable="True"/>
|
<field name="stage_id" widget="statusbar" clickable="True"/>
|
||||||
</header>
|
</header>
|
||||||
<sheet>
|
<sheet>
|
||||||
<group>
|
<group>
|
||||||
|
@ -430,27 +434,40 @@
|
||||||
<field name="ab_testing"/>
|
<field name="ab_testing"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<!-- <p>Here be some graphs</p> -->
|
<field name="total" invisible="1"/>
|
||||||
<field name="total"/>
|
<div class="oe_right oe_button_box" name="buttons"
|
||||||
<field name="sent" attrs="{'invisible': [('total', '=', 0)]}"/>
|
attrs="{'invisible': [('total', '=', 0)]}">
|
||||||
<field name="opened" attrs="{'invisible': [('total', '=', 0)]}"/>
|
<button name="%(action_mail_mass_mailing_report)d"
|
||||||
<field name="replied" attrs="{'invisible': [('total', '=', 0)]}"/>
|
type="action" class="oe_stat_button oe_inline">
|
||||||
|
<field name="received_ratio" widget="percentpie"/>
|
||||||
|
<span>Received</span>
|
||||||
|
</button>
|
||||||
|
<button name="%(action_mail_mass_mailing_report)d"
|
||||||
|
type="action" class="oe_stat_button oe_inline">
|
||||||
|
<field name="opened_ratio" widget="percentpie"/>
|
||||||
|
<span>Opened</span>
|
||||||
|
</button>
|
||||||
|
<button name="%(action_mail_mass_mailing_report)d"
|
||||||
|
type="action" class="oe_stat_button oe_inline">
|
||||||
|
<field name="replied_ratio" widget="percentpie"/>
|
||||||
|
<span>Replied</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<strong>Related Mailing(s)</strong>
|
||||||
<field name="mass_mailing_ids" readonly="1" string="Related Mailing(s)">
|
<field name="mass_mailing_ids" readonly="1" string="Related Mailing(s)">
|
||||||
<tree>
|
<tree>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="date"/>
|
<field name="date"/>
|
||||||
<field name="state"/>
|
<field name="state"/>
|
||||||
<field name="delivered"/>
|
<field name="delivered"/>
|
||||||
<field name="opened"/>
|
<field name="opened"/>
|
||||||
<field name="replied"/>
|
<field name="replied"/>
|
||||||
<field name="bounced"/>
|
<field name="bounced"/>
|
||||||
<button name="action_duplicate" type="object" string="Duplicate"/>
|
<button name="action_duplicate" type="object" string="Duplicate"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</group>
|
|
||||||
</sheet>
|
</sheet>
|
||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
|
@ -460,7 +477,7 @@
|
||||||
<field name="name">mail.mass_mailing.campaign.kanban</field>
|
<field name="name">mail.mass_mailing.campaign.kanban</field>
|
||||||
<field name="model">mail.mass_mailing.campaign</field>
|
<field name="model">mail.mass_mailing.campaign</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<kanban default_group_by='state'>
|
<kanban default_group_by='stage_id'>
|
||||||
<field name='total'/>
|
<field name='total'/>
|
||||||
<field name='color'/>
|
<field name='color'/>
|
||||||
<field name='user_id'/>
|
<field name='user_id'/>
|
||||||
|
@ -483,7 +500,7 @@
|
||||||
<div class="oe_kanban_content">
|
<div class="oe_kanban_content">
|
||||||
<div>
|
<div>
|
||||||
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)"
|
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)"
|
||||||
t-att-title="record.user_id.value" width="48" height="48o" class="oe_kanban_avatar oe_kanban_header_right"/>
|
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>
|
<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_id"/></span>
|
||||||
<a name="%(action_view_mass_mailings_from_campaign)d" type="action"
|
<a name="%(action_view_mass_mailings_from_campaign)d" type="action"
|
||||||
|
@ -493,16 +510,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_clear"></div>
|
<div class="oe_clear"></div>
|
||||||
<div>
|
<div>
|
||||||
<field name="total" widget="gauge" style="width:160px; height: 120px;"
|
<div style="display: inline-block">
|
||||||
options="{'max_field': 'total'}"/>
|
<field name="delivered" widget="gauge" style="width:120px; height: 90px;"
|
||||||
<field name="delivered" widget="gauge" style="width:160px; height: 120px;"
|
options="{'max_field': 'total'}"/>
|
||||||
options="{'max_field': 'total'}"/>
|
</div>
|
||||||
</div>
|
<div style="display: inline-block; vertical-align: top;">
|
||||||
<div>
|
<strong>Opened</strong> <field name="opened_ratio"/> %<br />
|
||||||
<field name="opened" widget="gauge" style="width:160px; height: 120px;"
|
<strong>Replied</strong> <field name="replied_ratio"/> %
|
||||||
options="{'max_field': 'total'}"/>
|
</div>
|
||||||
<field name="replied" widget="gauge" style="width:160px; height: 120px;"
|
|
||||||
options="{'max_field': 'total'}"/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_clear"></div>
|
<div class="oe_clear"></div>
|
||||||
|
|
Loading…
Reference in New Issue