[IMP] mail, email_template, mass_mailing: improvev mass mailing management in mail.compose.message + form view cleanings + some fixes in mail_mail about set_opened/replied/bounced, now checking that ids effectively exist

bzr revid: tde@openerp.com-20130910151901-nhuwvtrkbwekyh7x
This commit is contained in:
Thibault Delavallée 2013-09-10 17:19:01 +02:00
parent 2982257521
commit ce8c987089
12 changed files with 96 additions and 29 deletions

View File

@ -11,7 +11,7 @@
<label string="Template Recipients" for="partner_to" <label string="Template Recipients" for="partner_to"
groups="base.group_no_one" groups="base.group_no_one"
attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/> attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/>
<div groups="base.group_no_one" <div groups="base.group_no_one" name="template_recipients"
attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"> attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}">
<group class="oe_grey"> <group class="oe_grey">
<!-- <label string="Partners" for="partner_to"/> --> <!-- <label string="Partners" for="partner_to"/> -->

View File

@ -108,21 +108,24 @@ class mail_mail(osv.Model):
def set_opened(self, cr, uid, ids, context=None): def set_opened(self, cr, uid, ids, context=None):
""" Set as opened """ """ Set as opened """
for mail in self.browse(cr, uid, ids, context=context): existing_ids = self.exists(cr, uid, ids, context=context)
for mail in self.browse(cr, uid, existing_ids, context=context):
if not mail.opened: if not mail.opened:
self.write(cr, uid, [mail.id], {'opened': fields.datetime.now()}, context=context) self.write(cr, uid, [mail.id], {'opened': fields.datetime.now()}, context=context)
return True return True
def set_replied(self, cr, uid, ids, context=None): def set_replied(self, cr, uid, ids, context=None):
""" Set as replied """ """ Set as replied """
for mail in self.browse(cr, uid, ids, context=context): existing_ids = self.exists(cr, uid, ids, context=context)
for mail in self.browse(cr, uid, existing_ids, context=context):
if not mail.replied: if not mail.replied:
self.write(cr, uid, [mail.id], {'replied': fields.datetime.now()}, context=context) self.write(cr, uid, [mail.id], {'replied': fields.datetime.now()}, context=context)
return True return True
def set_bounced(self, cr, uid, ids, context=None): def set_bounced(self, cr, uid, ids, context=None):
""" Set as bounced """ """ Set as bounced """
for mail in self.browse(cr, uid, ids, context=context): existing_ids = self.exists(cr, uid, ids, context=context)
for mail in self.browse(cr, uid, existing_ids, context=context):
if not mail.bounced: if not mail.bounced:
self.write(cr, uid, [mail.id], {'bounced': fields.datetime.now()}, context=context) self.write(cr, uid, [mail.id], {'bounced': fields.datetime.now()}, context=context)
return True return True

View File

@ -44,6 +44,7 @@
<group string="Tracking"> <group string="Tracking">
<field name="opened"/> <field name="opened"/>
<field name="replied"/> <field name="replied"/>
<field name="bounced"/>
</group> </group>
</div> </div>
<div> <div>

View File

@ -792,6 +792,7 @@ class mail_thread(osv.AbstractModel):
bounce_match = tools.bounce_re.search(email_to) bounce_match = tools.bounce_re.search(email_to)
if bounce_match: if bounce_match:
bounced_mail_id = bounce_match.group(1) bounced_mail_id = bounce_match.group(1)
self.pool['mail.mail'].set_bounced(cr, uid, [bounced_mail_id], context=context)
if self.pool['mail.mail'].exists(cr, uid, bounced_mail_id): if self.pool['mail.mail'].exists(cr, uid, bounced_mail_id):
mail = self.pool['mail.mail'].browse(cr, uid, bounced_mail_id, context=context) mail = self.pool['mail.mail'].browse(cr, uid, bounced_mail_id, context=context)
bounced_model = mail.model bounced_model = mail.model
@ -1426,7 +1427,8 @@ class mail_thread(osv.AbstractModel):
# update original mail_mail if exists # update original mail_mail if exists
if type == 'email': if type == 'email':
mail_mail_ids = self.pool['mail.mail'].search(cr, SUPERUSER_ID, [('mail_message_id', '=', parent_id)], context=context) mail_mail_ids = self.pool['mail.mail'].search(cr, SUPERUSER_ID, [('mail_message_id', '=', parent_id)], context=context)
self.pool['mail.mail'].set_replied(cr, SUPERUSER_ID, mail_mail_ids, context=context) if mail_mail_ids:
self.pool['mail.mail'].set_replied(cr, SUPERUSER_ID, mail_mail_ids, context=context)
message_ids = mail_message.search(cr, SUPERUSER_ID, [('id', '=', parent_id), ('parent_id', '!=', False)], context=context) message_ids = mail_message.search(cr, SUPERUSER_ID, [('id', '=', parent_id), ('parent_id', '!=', False)], context=context)
# avoid loops when finding ancestors # avoid loops when finding ancestors

View File

@ -14,6 +14,7 @@
<field name="parent_id" invisible="1"/> <field name="parent_id" invisible="1"/>
<field name="mail_server_id" invisible="1"/> <field name="mail_server_id" invisible="1"/>
<field name="use_active_domain" invisible="1"/> <field name="use_active_domain" invisible="1"/>
<field name="active_domain" invisible="1"/>
<!-- visible wizard --> <!-- visible wizard -->
<field name="email_from" <field name="email_from"
attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/> attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/>
@ -32,9 +33,6 @@
context="{'force_email':True, 'show_email':True}"/> context="{'force_email':True, 'show_email':True}"/>
</div> </div>
<!-- mass post / mass mailing --> <!-- mass post / mass mailing -->
<field name="active_domain"
attrs="{'invisible': [('composition_mode', '!=', 'mass_mail')],
'readonly': True}"/>
<field name="post" <field name="post"
attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/> attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/>
<field name="notify" <field name="notify"

View File

@ -36,6 +36,14 @@ class MailMail(osv.Model):
'mass_mailing_segment_id', 'mass_mailing_campaign_id', 'mass_mailing_segment_id', 'mass_mailing_campaign_id',
type='many2one', ondelete='set null', type='many2one', ondelete='set null',
relation='mail.mass_mailing.campaign', relation='mail.mass_mailing.campaign',
string='Mass Mailing Campaign',
store=True, readonly=True,
),
'template_id': fields.related(
'mass_mailing_segment_id', 'template_id',
type='many2one', ondelete='set null',
relation='email.template',
string='Email Template',
store=True, readonly=True, store=True, readonly=True,
), ),
} }

View File

@ -11,6 +11,7 @@
<xpath expr="//field[@name='opened']" position="before"> <xpath expr="//field[@name='opened']" position="before">
<field name="mass_mailing_campaign_id"/> <field name="mass_mailing_campaign_id"/>
<field name="mass_mailing_segment_id"/> <field name="mass_mailing_segment_id"/>
<field name="template_id"/>
</xpath> </xpath>
</field> </field>
</record> </record>

View File

@ -184,7 +184,7 @@ class MassMailingSegment(osv.Model):
'name': fields.char('Name', required=True), 'name': fields.char('Name', required=True),
'mass_mailing_campaign_id': fields.many2one( 'mass_mailing_campaign_id': fields.many2one(
'mail.mass_mailing.campaign', 'Mass Mailing Campaign', 'mail.mass_mailing.campaign', 'Mass Mailing Campaign',
ondelete='cascade', ondelete='cascade', required=True,
), ),
'template_id': fields.many2one( 'template_id': fields.many2one(
'email.template', 'Email Template', 'email.template', 'Email Template',
@ -192,6 +192,10 @@ class MassMailingSegment(osv.Model):
), ),
'domain': fields.char('Domain'), 'domain': fields.char('Domain'),
'date': fields.datetime('Date'), 'date': fields.datetime('Date'),
'color': fields.related(
'mass_mailing_campaign_id', 'color',
type='integer', string='Color Index',
),
# mail_mail data # mail_mail data
'mail_ids': fields.one2many( 'mail_ids': fields.one2many(
'mail.mail', 'mass_mailing_segment_id', 'mail.mail', 'mass_mailing_segment_id',
@ -234,3 +238,7 @@ class MassMailingSegment(osv.Model):
type='char', multi='_get_monthly_statistics', type='char', multi='_get_monthly_statistics',
), ),
} }
_defaults = {
'date': fields.datetime.now(),
}

View File

@ -122,7 +122,7 @@
<field name="name">mail.mass_mailing.segment.form</field> <field name="name">mail.mass_mailing.segment.form</field>
<field name="model">mail.mass_mailing.segment</field> <field name="model">mail.mass_mailing.segment</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Mass Mailing Campaign" version="7.0"> <form string="Mass Mailing Segment" version="7.0">
<sheet> <sheet>
<group> <group>
<group> <group>
@ -140,14 +140,38 @@
</field> </field>
</record> </record>
<record model="ir.ui.view" id="view_mail_mass_mailing_segment_form_readonly">
<field name="name">mail.mass_mailing.segment.form</field>
<field name="model">mail.mass_mailing.segment</field>
<field name="priority">18</field>
<field name="arch" type="xml">
<form string="Mass Mailing Segment" version="7.0">
<sheet>
<group>
<group>
<field name="name"/>
<field name="date" readonly="True"/>
</group>
<group>
<field name="mass_mailing_campaign_id" readonly="True"/>
<field name="template_id" readonly="True"/>
<field name="domain" readonly="True"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_mail_mass_mailing_segment_kanban"> <record model="ir.ui.view" id="view_mail_mass_mailing_segment_kanban">
<field name="name">mail.mass_mailing.segment.kanban</field> <field name="name">mail.mass_mailing.segment.kanban</field>
<field name="model">mail.mass_mailing.segment</field> <field name="model">mail.mass_mailing.segment</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<kanban> <kanban>
<field name='color'/>
<templates> <templates>
<t t-name="kanban-box"> <t t-name="kanban-box">
<div t-attf-class="oe_kanban_card oe_kanban_global_click oe_kanban_mass_mailing oe_kanban_mass_mailing_segment"> <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_kanban_mass_mailing oe_kanban_mass_mailing_segment">
<div class="oe_kanban_content"> <div class="oe_kanban_content">
<div> <div>
<h3> <h3>

View File

@ -14,6 +14,7 @@
border: 1px solid rgba(0, 0, 0, 0.16); border: 1px solid rgba(0, 0, 0, 0.16);
-webkit-border-radius: 2px; -webkit-border-radius: 2px;
border-radius: 2px; border-radius: 2px;
background-color: #FFFFFF;
} }
.openerp .oe_kanban_view .oe_kanban_mass_mailing .oe_mail_result { .openerp .oe_kanban_view .oe_kanban_mass_mailing .oe_mail_result {

View File

@ -28,24 +28,30 @@ class MailComposeMessage(osv.TransientModel):
_inherit = 'mail.compose.message' _inherit = 'mail.compose.message'
_columns = { _columns = {
'mass_mail_campaign_id': fields.many2one( 'use_mass_mailing_campaign': fields.boolean(
'mail.mass_mailing.campaign', 'Mass mailing campaign' 'Use mass mailing campaigns',
),
'mass_mailing_campaign_id': fields.many2one(
'mail.mass_mailing.campaign', 'Mass mailing campaign',
),
'mass_mailing_segment_id': fields.many2one(
'mail.mass_mailing.segment', 'Mass mailing segment',
domain="[('mass_mailing_campaign_id', '=', mass_mailing_campaign_id)]",
), ),
} }
def onchange_mass_mail_campaign_id(self, cr, uid, ids, mass_mail_campaign_id, context=None): _defaults = {
values = {} 'use_mass_mailing_campaign': True,
if mass_mail_campaign_id: }
campaign = self.pool['mail.mass_mailing.campaign'].browse(cr, uid, mass_mail_campaign_id, context=context)
if campaign and campaign.template_id:
values['template_id'] = campaign.template_id.id
return {'value': values}
def render_message(self, cr, uid, wizard, res_id, context=None): def onchange_mass_mail_campaign_id(self, cr, uid, ids, mass_mail_campaign_id, context=None):
return {'value': {'mass_mailing_segment_id': False}}
def render_message_batch(self, cr, uid, wizard, res_ids, context=None):
""" Override method that generated the mail content by adding the mass """ Override method that generated the mail content by adding the mass
mailing campaign, when doing pure email mass mailing. """ mailing campaign, when doing pure email mass mailing. """
res = super(MailComposeMessage, self).render_message(cr, uid, wizard, res_id, context=context) res = super(MailComposeMessage, self).render_message_batch(cr, uid, wizard, res_ids, context=context)
print res, wizard.mass_mail_campaign_id if wizard.composition_mode == 'mass_mail' and wizard.mass_mailing_segment_id: # TODO: which kind of mass mailing ?
if wizard.composition_mode == 'mass_mail' and wizard.mass_mail_campaign_id: # TODO: which kind of mass mailing ? for res_id in res_ids:
res['mass_mailing_campaign_id'] = wizard.mass_mail_campaign_id.id res[res_id]['mass_mailing_segment_id'] = wizard.mass_mailing_segment_id.id
return res return res

View File

@ -8,10 +8,25 @@
<field name="model">mail.compose.message</field> <field name="model">mail.compose.message</field>
<field name="inherit_id" ref="mail.email_compose_message_wizard_form"/> <field name="inherit_id" ref="mail.email_compose_message_wizard_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='subject']" position="after"> <xpath expr="//field[@name='notify']" position="after">
<field name="mass_mail_campaign_id" <field name="use_mass_mailing_campaign"
on_change="onchange_mass_mail_campaign_id(mass_mail_campaign_id)" attrs="{'invisible': [('composition_mode', '!=', 'mass_mail')]}"/>
attrs="{'invisible': [('composition_mode', '!=', 'mass_mail')]}"/> <label for="mass_mailing_campaign_id" string=" "/>
<div>
<group>
<field name="mass_mailing_campaign_id"
on_change="onchange_mass_mail_campaign_id(mass_mailing_campaign_id)"
attrs="{'invisible': ['|', ('composition_mode', '!=', 'mass_mail'), ('use_mass_mailing_campaign', '=', False)],
'required': [('composition_mode', '=', 'mass_mail'), ('use_mass_mailing_campaign', '=', True)]}"/>
<field name="mass_mailing_segment_id"
attrs="{'invisible': ['|', ('composition_mode', '!=', 'mass_mail'), ('use_mass_mailing_campaign', '=', False)],
'required': [('composition_mode', '=', 'mass_mail'), ('use_mass_mailing_campaign', '=', True)]}"
context="{'default_mass_mailing_campaign_id': mass_mailing_campaign_id,
'default_template_id': template_id,
'default_domain': active_domain,
'form_view_ref': 'mass_mailing.view_mail_mass_mailing_segment_form_readonly'}"/>
</group>
</div>
</xpath> </xpath>
</field> </field>
</record> </record>