Revert "[IMP] better handling of next activities"

This reverts commit ab303435d3.

Changing a feature one week before freezing a new saas, without review,
without spec, without testing, does not seem to fit the R&D process.
This commit will be set in a branch, tested and reviewed accordingly.
This commit is contained in:
Thibault Delavallée
2015-11-20 10:18:52 +01:00
parent b2afe3f1db
commit ebcc2ea4eb
6 changed files with 107 additions and 218 deletions
+61 -119
View File
@@ -119,16 +119,6 @@ class crm_lead(format_address, osv.osv):
'stage_id': _read_group_stage_ids
}
def _compute_kanban_state(self, cr, uid, ids, fields, args, context=None):
result = {}
today = datetime.now().strftime("%Y-%m-%d")
for lead in self.browse(cr, uid, ids, context=context):
if not lead.date_action:
result[lead.id] = False
else:
result[lead.id] = {1: 'green', -1: 'red'}.get(cmp(lead.date_action, today), 'grey')
return result
def _compute_day(self, cr, uid, ids, fields, args, context=None):
"""
:return dict: difference between current date and log date
@@ -172,8 +162,6 @@ class crm_lead(format_address, osv.osv):
'email_from': fields.char('Email', size=128, help="Email address of the contact", select=1),
'team_id': fields.many2one('crm.team', 'Sales Team', oldname='section_id',
select=True, track_visibility='onchange', help='When sending mails, the default email address is taken from the sales team.'),
'kanban_state': fields.function(_compute_kanban_state, string='Activity State', type="selection",
selection=[('', ''), ('normal', 'Normal'), ('blocked', 'Blocked'), ('done', 'Ready for next stage')]),
'create_date': fields.datetime('Creation Date', readonly=True),
'email_cc': fields.text('Global CC', help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
'description': fields.text('Notes'),
@@ -213,6 +201,9 @@ class crm_lead(format_address, osv.osv):
# CRM Actions
'last_activity_id': fields.many2one("crm.activity", "Last Activity", select=True),
'next_activity_id': fields.many2one("crm.activity", "Next Activity", select=True),
'next_activity_1': fields.related("last_activity_id", "activity_1_id", "name", type="char", string="Next Activity 1"),
'next_activity_2': fields.related("last_activity_id", "activity_2_id", "name", type="char", string="Next Activity 2"),
'next_activity_3': fields.related("last_activity_id", "activity_3_id", "name", type="char", string="Next Activity 3"),
'date_action': fields.date('Next Activity Date', select=True),
'title_action': fields.char('Next Activity Summary'),
@@ -366,9 +357,62 @@ class crm_lead(format_address, osv.osv):
# Backward compatibility
case_mark_won = action_set_won
def log_next_activity_1(self, cr, uid, ids, context=None):
return self.set_next_activity(cr, uid, ids, next_activity_name='activity_1_id', context=context)
def log_next_activity_2(self, cr, uid, ids, context=None):
return self.set_next_activity(cr, uid, ids, next_activity_name='activity_2_id', context=context)
def log_next_activity_3(self, cr, uid, ids, context=None):
return self.set_next_activity(cr, uid, ids, next_activity_name='activity_3_id', context=context)
def set_next_activity(self, cr, uid, ids, next_activity_name, context=None):
for lead in self.browse(cr, uid, ids, context=context):
if not lead.last_activity_id:
continue
next_activity = next_activity_name and getattr(lead.last_activity_id, next_activity_name, False) or False
if next_activity:
date_action = False
if next_activity.days:
date_action = (datetime.now() + timedelta(days=next_activity.days)).strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT),
lead.write({
'next_activity_id': next_activity.id,
'date_action': date_action,
'title_action': next_activity.description,
})
return True
def log_next_activity_done(self, cr, uid, ids, context=None, next_activity_name=False):
to_clear_ids = []
for lead in self.browse(cr, uid, ids, context=context):
if not lead.next_activity_id:
continue
body_html = """<div><b>Activity Done</b>: ${object.next_activity_id.name}</div>
%if object.title_action:
<div>${object.title_action}</div>
%endif"""
body_html = self.pool['mail.template'].render_template(cr, uid, body_html, 'crm.lead', lead.id, context=context)
msg_id = lead.message_post(body_html, subtype_id=lead.next_activity_id.subtype_id.id)
to_clear_ids.append(lead.id)
self.write(cr, uid, [lead.id], {'last_activity_id': lead.next_activity_id.id}, context=context)
if to_clear_ids:
self.cancel_next_activity(cr, uid, to_clear_ids, context=context)
return True
def cancel_next_activity(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {
'next_activity_id': False,
'date_action': False,
'title_action': False,
}, context=context)
def onchange_next_activity_id(self, cr, uid, ids, next_activity_id, context=None):
if not next_activity_id:
return {'value': {
'next_action1': False,
'next_action2': False,
'next_action3': False,
'title_action': False,
'date_action': False,
}}
@@ -377,6 +421,9 @@ class crm_lead(format_address, osv.osv):
if activity.days:
date_action = (datetime.now() + timedelta(days=activity.days)).strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
return {'value': {
'next_activity_1': activity.activity_1_id and activity.activity_1_id.name or False,
'next_activity_2': activity.activity_2_id and activity.activity_2_id.name or False,
'next_activity_3': activity.activity_3_id and activity.activity_3_id.name or False,
'title_action': activity.description,
'date_action': date_action,
'last_activity_id': False,
@@ -1175,121 +1222,16 @@ class crm_lead_tag(osv.Model):
('name_uniq', 'unique (name)', "Tag name already exists !"),
]
class crm_lead_log(osv.osv_memory):
_name = "crm.lead.log"
_description = "Log an Activity"
_columns = {
'next_activity_id': fields.many2one("crm.activity", "Activity"),
'last_activity_id': fields.many2one("crm.activity", "Activity"),
'recommended_activity': fields.many2one("crm.activity", "Recommended Activities"),
'name': fields.char('Summary'),
'mode': fields.selection([('log','Log activity'), ('new','New activity')], 'Summary'),
'lead_id': fields.many2one('crm.lead', 'Lead', required=True),
'note': fields.html('Note'),
'date_deadline': fields.related('lead_id', 'date_deadline', string='Expected Closing', type='date'),
'planned_revenue': fields.float('Expected Revenue'),
'date_action': fields.date('Next Activity Date'),
'team_id': fields.many2one('crm.team', 'Sales Team'),
}
def action_schedule(self, cr, uid, ids, context={}):
for log in self.browse(cr, uid, ids, context):
lead = log.lead_id.write({
'title_action': log.name,
'date_action': log.date_action,
'next_activity_id': log.next_activity_id.id,
})
return True
def action_log_schedule(self, cr, uid, ids, context={}):
lead_id,activity_id = self.action_log(cr, uid, ids, context)
view_id = self.pool.get('ir.model.data').xmlid_to_res_id(cr, uid, 'crm.crm_lead_log_plan_form')
return {
'name': _('Next activity'),
'res_model': 'crm.lead.log',
'context': {'activity_id': activity_id, 'active_id': lead_id, 'active_model': 'crm.lead', 'active_ids': [lead_id], 'default_mode': 'new'},
'type': 'ir.actions.act_window',
'view_id': False,
'views': [(view_id, 'form')],
'view_mode': 'form',
'target': 'new',
'view_type': 'form',
'res_id': False
}
def action_log(self, cr, uid, ids, context={}):
lead_id = False
for log in self.browse(cr, uid, ids, context):
body_html = """<div><b>Activity Done</b>: ${object.next_activity_id.name}</div>
%if object.name:
<p><em>${object.name}</em></p>
%endif"""
activity_id = log.next_activity_id or False
body_html = self.pool['mail.template'].render_template(cr, uid, body_html, 'crm.lead.log', log.id, context=context)
if log.note:
body_html += '<br/>' + log.note
msg_id = log.lead_id.message_post(body_html, subtype_id=log.next_activity_id.subtype_id.id)
log.lead_id.write({
'date_deadline': log.date_deadline,
'planned_revenue': log.planned_revenue,
'title_action': False,
'date_action': False,
'next_activity_id': False,
'last_activity_id': log.next_activity_id.id,
})
lead_id = log.lead_id.id
return (lead_id, activity_id and activity_id.id or False)
def _get_default_lead_id(self, cr, uid, context={}):
return context.get('active_id', False)
def _get_default_name(self, cr, uid, context={}):
log = self.pool.get('crm.lead').browse(cr, uid, ctx['active_id'], ctx)
if log.mode=='log':
return log.title_action
return False
def _get_next_activity(self, cr, uid, field, context=None):
activity = self.pool.get('crm.activity').browse(cr, uid, context.get('activity_id'), context)
data = getattr(activity, field)
if data:
return data.id
return False
def onchange_next_activity_id(self, cr, uid, ids, next_activity_id, context=None):
if not next_activity_id:
return {'value': {
'name': False,
'date_action': False,
}}
activity = self.pool['crm.activity'].browse(cr, uid, next_activity_id, context=context)
date_action = False
if activity.days:
date_action = (datetime.now() + timedelta(days=activity.days)).strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
return {'value': {
'name': activity.description,
'date_action': date_action,
'next_activity_id': next_activity_id
}}
_defaults = {
'lead_id': _get_default_lead_id,
'date_deadline': lambda self, cr,uid,ctx: self.pool.get('crm.lead').browse(cr, uid, ctx.get('active_id'), ctx).date_deadline,
'planned_revenue': lambda self, cr,uid,ctx: self.pool.get('crm.lead').browse(cr, uid, ctx.get('active_id'), ctx).planned_revenue,
'name': lambda self, cr,uid,ctx: self.pool.get('crm.lead').browse(cr, uid, ctx.get('active_id'), ctx).title_action,
'next_activity_id': lambda self, cr,uid,ctx: self.pool.get('crm.lead').browse(cr, uid, ctx.get('active_id'), ctx).next_activity_id.id,
'last_activity_id': lambda self, cr,uid,ctx: ctx.get('activity_id', False),
'team_id': lambda self, cr,uid,ctx: self.pool.get('crm.lead').browse(cr, uid, ctx.get('active_id'), ctx).team_id.id,
'mode': 'log'
}
class crm_lost_reason(osv.Model):
_name = "crm.lost.reason"
_description = 'Reason for loosing leads'
_columns = {
'name': fields.char('Name', required=True),
'active': fields.boolean('Active'),
}
_defaults = {
'active': True,
}
+31 -89
View File
@@ -280,15 +280,12 @@
<field name="color"/>
<field name="priority"/>
<field name="planned_revenue"/>
<field name="kanban_state"/>
<field name="date_action"/>
<field name="user_email"/>
<field name="user_id"/>
<field name="partner_address_email"/>
<field name="message_needaction_counter"/>
<field name="tag_ids"/>
<field name="partner_id"/>
<field name="title_action"/>
<field name="active"/>
<field name="company_currency"/>
<templates>
@@ -316,22 +313,22 @@
<strong><field name="name"/></strong>
</div>
<div class="text-muted">
<t t-if="record.planned_revenue.raw_value"><field name="planned_revenue" widget="monetary" options="{'currency_field': 'company_currency'}"/></t> <span t-if="record.partner_id.value">, <t t-esc="record.partner_id.value"/></span>
<t t-if="record.planned_revenue.raw_value"><field name="planned_revenue" widget="monetary" options="{'currency_field': 'company_currency'}"/></t> <span t-if="record.partner_id.value"> - <t t-esc="record.partner_id.value"/></span>
</div>
<div class="text-muted">
<t t-if="record.date_deadline.raw_value and record.date_deadline.raw_value lt (new Date())" t-set="red">oe_kanban_text_red</t>
<span t-attf-class="#{red || ''}">
<field name="date_action"/>
<t t-if="record.date_action.raw_value"> : </t>
<field name="next_activity_id"/>
</span>
</div>
<div class="o_kanban_footer">
<field name="priority" widget="priority" groups="base.group_user"/>
<t t-if="record.message_needaction_counter.raw_value">
<span class='oe_kanban_mail_new' title='Important Messages'><i class='fa fa-comments'/><t t-raw="record.message_needaction_counter.raw_value"/></span>
</t>
<div>
<a name="%(crm.crm_lead_log_action)d" type="action">
<span
t-if="record.date_action.raw_value" t-att-title="record.date_action.value + ': '+ record.title_action.value"
t-attf-class="oe_kanban_status oe_kanban_status_#{record.kanban_state.raw_value}"/>
</a>
<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 pull-right"/>
</div>
<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 pull-right"/>
</div>
</div>
<div class="oe_clear"></div>
@@ -399,78 +396,6 @@
<!--
OPPORTUNITY
-->
<record model="ir.ui.view" id="crm_lead_log_form">
<field name="name">Log an Activity</field>
<field name="model">crm.lead.log</field>
<field name="priority">20</field>
<field name="arch" type="xml">
<form string="Log an Activity">
<group>
<group>
<field name="team_id" invisible="True"/>
<field name="next_activity_id" required="1"
domain="['|',('team_id','=',False),('team_id','=',team_id)]"
options="{'no_create': True, 'no_open': True}"/>
<field name="name" placeholder="e.g. Discuss proposal"/>
</group>
<group>
<field name="planned_revenue"/>
<field name="date_deadline"/>
</group>
</group>
<field name="note" placeholder="Log a note..."/>
<footer>
<button name="action_log_schedule" string="Log &amp; Schedule Next" type="object" class="btn btn-primary"/>
<button name="action_log" string="Log Only" type="object" class="btn btn-primary"/>
<button string="Cancel" class="btn btn-default" special="cancel"/>
</footer>
</form>
</field>
</record>
<record model="ir.ui.view" id="crm_lead_log_plan_form">
<field name="name">Schedule next Activity</field>
<field name="model">crm.lead.log</field>
<field name="priority">40</field>
<field name="arch" type="xml">
<form string="Schedule Next Activity">
<group class="mt0">
<group>
<field name="team_id" invisible="True"/>
<field name="last_activity_id" invisible="True"/>
<field name="next_activity_id"
domain="['|',('team_id','=',False),('team_id','=',team_id)]"
on_change="onchange_next_activity_id(next_activity_id)"
options="{'no_create': True, 'no_open': True}"/>
<field name="date_action"/>
<field name="name" placeholder="e.g. Discuss proposal"/>
</group>
<group>
<div>
<p><strong>Recommended activities:</strong></p>
<field name="recommended_activity" widget="radio"
on_change="onchange_next_activity_id(recommended_activity)"
domain="[('activity_invert_ids','in',[last_activity_id])]"/>
</div>
</group>
</group>
<footer>
<button name="action_schedule" string="Schedule Activity" type="object" class="btn btn-primary"/>
<button string="No activity" class="btn btn-default" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="crm_lead_log_action" model="ir.actions.act_window">
<field name="name">Log an Activity</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">crm.lead.log</field>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_lead_log_form"/>
<field name="target">new</field>
</record>
<!-- Opportunities Form View -->
<record model="ir.ui.view" id="crm_case_form_view_oppor">
@@ -487,8 +412,6 @@
type="action" class="oe_highlight"
context="{'default_lead_id': active_id}"
attrs="{'invisible': [('active', '=', False)]}"/>
<button name="%(crm.crm_lead_log_action)d" string="Log Activity" type="action" class="btn-link"
attrs="{'invisible': [('active', '=', False)]}"/>
<field name="stage_id" widget="statusbar" clickable="True"
options="{'fold_field': 'fold'}"
domain="['&amp;', ('team_ids', '=', team_id), '|', ('type', '=', type), ('type', '=', 'both')]"
@@ -515,6 +438,8 @@
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1><field name="name" placeholder="e.g. Product Pricing"/></h1>
<h2 class="o_row">
<div>
<label for="planned_revenue" class="oe_edit_only" />
@@ -555,10 +480,27 @@
<span class="oe_form_field"
attrs="{'invisible': ['|', ('next_activity_id', '=', False), ('date_action', '=', False)]}">&#160;on&#160;</span>
<field name="date_action" attrs="{'invisible': [('next_activity_id', '=', False)]}" placeholder="Choose a date..."/>
<div attrs="{'invisible': ['|', ('last_activity_id', '=', False), ('next_activity_id', '!=', False)]}">
<button name="log_next_activity_1" type="object" class="btn-link" attrs="{'invisible': [('next_activity_1','=',False)]}">
<field name="next_activity_1" readonly="1"/>
</button>
<span attrs="{'invisible': [('next_activity_2','=',False)]}">|</span>
<button name="log_next_activity_2" type="object" class="btn-link" attrs="{'invisible': [('next_activity_2','=',False)]}">
<field name="next_activity_2" readonly="1"/>
</button>
<span attrs="{'invisible': [('next_activity_3','=',False)]}">|</span>
<button name="log_next_activity_3" type="object" class="btn-link" attrs="{'invisible': [('next_activity_3','=',False)]}">
<field name="next_activity_3" readonly="1"/>
</button>
</div>
</div>
<div>
<div class="o_row">
<field name="title_action" placeholder="e.g. Discuss proposal"
attrs="{'invisible': [('next_activity_id', '=', False)]}"/>
attrs="{'invisible': [('next_activity_id', '=', False)]}"/>
<div attrs="{'invisible': [('next_activity_id', '=', False)]}">
<button name="log_next_activity_done" string="Done" type="object" class="btn-link"/>
<button name="cancel_next_activity" string="Cancel" type="object" class="btn-link"/>
</div>
</div>
</div>
<field name="date_deadline"/>
+9 -4
View File
@@ -11,23 +11,28 @@
<field name="name">Make Quote</field>
<field name="description">Send a quotation</field>
<field name="days">15</field>
<field name="activity_ids" eval="[(6,0, [ref('crm.crm_activity_demo_followup_quote')])]"/>
<field name="activity_1_id" ref="crm_activity_demo_followup_quote"/>
</record>
<record id="crm_activity_demo_call_demo" model="crm.activity">
<field name="name">Call for Demo</field>
<field name="days">10</field>
<field name="description">Call for a demo</field>
<field name="activity_ids" eval="[(6, 0, [ref('crm.crm_activity_demo_make_quote')])]"/>
<field name="activity_1_id" ref="crm_activity_demo_make_quote"/>
</record>
<record id="crm_activity_data_call" model="crm.activity">
<field name="activity_2_id" ref="crm_activity_demo_call_demo"/>
<field name="days">5</field>
</record>
<record id="crm_activity_data_call" model="crm.activity">
<field name="activity_1_id" ref="crm_activity_data_email"/>
<field name="description">Follow-up call</field>
<field name="activity_ids" eval="[(6, 0, [ref('crm.crm_activity_data_email')])]"/>
</record>
<record id="crm_activity_data_meeting" model="crm.activity">
<field name="activity_ids" eval="[(6, 0, [ref('crm_activity_data_call'), ref('crm_activity_data_email')])]"/>
<field name="activity_1_id" ref="crm_activity_data_call"/>
<field name="activity_2_id" ref="crm_activity_data_email"/>
<field name="days">15</field>
</record>
+3 -3
View File
@@ -29,9 +29,9 @@ class CrmActivity(models.Model):
sequence = fields.Integer('Sequence', default=0)
team_id = fields.Many2one('crm.team', string='Sales Team')
subtype_id = fields.Many2one('mail.message.subtype', string='Message Subtype', required=True, ondelete='cascade')
activity_ids = fields.Many2many('crm.activity', 'crm_activity_rel', 'activity_id', 'recommended_id', string='Recommended Activities')
activity_invert_ids = fields.Many2many('crm.activity', 'crm_activity_rel', 'recommended_id', 'activity_id', string='Preceding Activities')
activity_1_id = fields.Many2one('crm.activity', string="Next Activity 1")
activity_2_id = fields.Many2one('crm.activity', string="Next Activity 2")
activity_3_id = fields.Many2one('crm.activity', string="Next Activity 3")
@api.model
def create(self, values):
+3 -1
View File
@@ -27,7 +27,9 @@
<field name="days"/>
</group>
<group>
<field name="activity_ids" widget="many2many_tags"/>
<field name="activity_1_id"/>
<field name="activity_2_id"/>
<field name="activity_3_id"/>
</group>
</group>
</form>
@@ -554,8 +554,6 @@
height: 12px;
width: 12px;
border-radius: 6px;
margin-top: 6px;
margin-right: 6px;
background-color: @odoo-brand-secondary;