[IMP][ADD] crm: add the concept of activities, allowing

to define custom light workflows on opportunities.

Activities are linked to mail.message.subtype through inheritance.
This means that the follow mechanism works for activities. When
an activity is done, a message with the matching subtype is posted
on the opportunity.

Activities are internal by default. They are only visible by
employees.

A shortcut in the 'log a note' chatter option allows to post a
note linked to an activity (subtype).
This commit is contained in:
Jay Patel
2015-07-08 17:15:22 +02:00
committed by Thibault Delavallée
parent 03592e1c73
commit ff2b14d4c3
44 changed files with 450 additions and 1349 deletions
+1 -1
View File
@@ -4,8 +4,8 @@
import crm
import crm_lead
import sales_team
import models
import calendar_event
import crm_phonecall
import report
import wizard
import res_partner
+6 -13
View File
@@ -7,12 +7,12 @@
'version': '1.0',
'category': 'Customer Relationship Management',
'sequence': 2,
'summary': 'Leads, Opportunities, Phone Calls',
'summary': 'Leads, Opportunities, Activities',
'description': """
The generic OpenERP Customer Relationship Management
====================================================
This application enables a group of people to intelligently and efficiently manage leads, opportunities, meetings and phone calls.
This application enables a group of people to intelligently and efficiently manage leads, opportunities, meetings and activities.
It manages key tasks such as communication, identification, prioritization, assignment, resolution and notification.
@@ -44,33 +44,27 @@ Dashboard for CRM will include:
'web_planner',
],
'data': [
'data/crm_action_data.xml',
'crm_data.xml',
'crm_lead_data.xml',
'crm_phonecall_data.xml',
'crm_tip_data.xml',
'security/crm_security.xml',
'security/ir.model.access.csv',
'wizard/crm_lead_to_opportunity_view.xml',
'wizard/crm_phonecall_to_phonecall_view.xml',
'wizard/crm_merge_opportunities_view.xml',
'crm_view.xml',
'crm_phonecall_view.xml',
'crm_phonecall_menu.xml',
'crm_lead_view.xml',
'crm_lead_menu.xml',
'views/crm_action_views.xml',
'calendar_event_menu.xml',
'report/crm_lead_report_view.xml',
'report/crm_activity_report_view.xml',
'report/crm_opportunity_report_view.xml',
'report/crm_phonecall_report_view.xml',
'res_partner_view.xml',
@@ -85,7 +79,7 @@ Dashboard for CRM will include:
'demo': [
'crm_demo.xml',
'crm_lead_demo.xml',
'crm_phonecall_demo.xml',
'data/crm_action_demo.xml',
'crm_action_rule_demo.xml',
],
'test': [
@@ -95,7 +89,6 @@ Dashboard for CRM will include:
'test/lead2opportunity_assign_salesmen.yml',
'test/crm_lead_merge.yml',
'test/crm_lead_cancel.yml',
'test/phonecalls.yml',
'test/crm_lead_onchange.yml',
'test/crm_lead_copy.yml',
'test/crm_lead_unlink.yml',
-1
View File
@@ -10,7 +10,6 @@ class calendar_event(osv.Model):
""" Model for Calendar Event """
_inherit = 'calendar.event'
_columns = {
'phonecall_id': fields.many2one('crm.phonecall', 'Phonecall'),
'opportunity_id': fields.many2one('crm.lead', 'Opportunity', domain="[('type', '=', 'opportunity')]"),
}
+1 -1
View File
@@ -33,7 +33,7 @@
<field name="message_type">notification</field>
<field name="subtype_id" ref="mail.mt_comment"/>
<field name="subject">CRM application installed!</field>
<field name="body"><![CDATA[<p>From the top Sales menu you can track leads and opportunities, get accurate forecast on your sales pipeline, plan meetings and phonecalls, get realtime statistics and efficiently organize the communication with your prospects.</p>
<field name="body"><![CDATA[<p>From the top Sales menu you can track leads and opportunities, get accurate forecast on your sales pipeline, plan meetings, get realtime statistics and efficiently organize the communication with your prospects.</p>
<p>To manage quotations and sale orders, install the "Sales Management" application.</p>]]></field>
</record>
+78 -77
View File
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import crm
from datetime import datetime
from datetime import datetime, timedelta
import logging
from operator import itemgetter
import crm
import openerp
from openerp import SUPERUSER_ID
from openerp import tools, api
@@ -14,6 +15,7 @@ from openerp.tools.translate import _
from openerp.tools import email_re, email_split
from openerp.exceptions import UserError, AccessError
_logger = logging.getLogger(__name__)
CRM_LEAD_FIELDS_TO_MERGE = ['name',
'partner_id',
@@ -155,14 +157,6 @@ class crm_lead(format_address, osv.osv):
for opp_id in ids
}
def _calls_count(self, cr, uid, ids, field_name, args, context=None):
res = dict.fromkeys(ids, 0)
phonecall_data = self.pool['crm.phonecall'].read_group(
cr, uid, [('opportunity_id', 'in', ids)], ['opportunity_id'], ['opportunity_id'], context=context)
for data in phonecall_data:
res[data['opportunity_id'][0]] = data['opportunity_id_count']
return res
_columns = {
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', track_visibility='onchange',
select=True, help="Linked partner (optional). Usually created when converting the lead."),
@@ -211,8 +205,14 @@ class crm_lead(format_address, osv.osv):
'ref2': fields.reference('Reference 2', selection=openerp.addons.base.res.res_request.referencable_models),
'phone': fields.char("Phone", size=64),
'date_deadline': fields.date('Expected Closing', help="Estimate of the date on which the opportunity will be won."),
# CRM Actions
'next_activity_id': fields.many2one("crm.activity", "Next Activity", select=True),
'next_activity_1': fields.related("next_activity_id", "activity_1_id", "name", type="char", string="Next Activity 1"),
'next_activity_2': fields.related("next_activity_id", "activity_2_id", "name", type="char", string="Next Activity 2"),
'next_activity_3': fields.related("next_activity_id", "activity_3_id", "name", type="char", string="Next Activity 3"),
'date_action': fields.date('Next Action Date', select=True),
'title_action': fields.char('Next Action'),
'title_action': fields.char('Next Action Summary'),
'color': fields.integer('Color Index'),
'partner_address_name': fields.related('partner_id', 'name', type='char', string='Partner Contact Name', readonly=True),
'partner_address_email': fields.related('partner_id', 'email', type='char', string='Partner Contact Email', readonly=True),
@@ -236,7 +236,6 @@ class crm_lead(format_address, osv.osv):
'planned_cost': fields.float('Planned Costs'),
'meeting_count': fields.function(_meeting_count, string='# Meetings', type='integer'),
'lost_reason': fields.many2one('crm.lost.reason', 'Lost Reason', select=True, track_visibility='onchange'),
'calls_count': fields.function(_calls_count, string='# Phonecalls', type='integer'),
}
_defaults = {
@@ -381,6 +380,73 @@ class crm_lead(format_address, osv.osv):
self.write(cr, uid, lead_ids, {'stage_id': stage_id}, context=context)
return True
def log_next_activity_1(self, cr, uid, ids, context=None):
return self.log_next_activity_done(cr, uid, ids, next_activity_name='activity_1_id', context=context)
def log_next_activity_2(self, cr, uid, ids, context=None):
return self.log_next_activity_done(cr, uid, ids, next_activity_name='activity_2_id', context=context)
def log_next_activity_3(self, cr, uid, ids, context=None):
return self.log_next_activity_done(cr, uid, ids, next_activity_name='activity_3_id', context=context)
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>${object.next_activity_id.name}</b></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)
# update subtype after posting NOT SURE
next_activity = next_activity_name and getattr(lead.next_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,
})
else:
to_clear_ids.append(lead.id)
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,
}}
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': {
'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,
}}
def _merge_get_result_type(self, cr, uid, opps, context=None):
"""
Define the type of the result of the merge. If at least one of the
@@ -534,13 +600,6 @@ class crm_lead(format_address, osv.osv):
attachment.write(values)
return True
def _merge_opportunity_phonecalls(self, cr, uid, opportunity_id, opportunities, context=None):
phonecall_obj = self.pool['crm.phonecall']
for opportunity in opportunities:
for phonecall_id in phonecall_obj.search(cr, uid, [('opportunity_id', '=', opportunity.id)], context=context):
phonecall_obj.write(cr, uid, phonecall_id, {'opportunity_id': opportunity_id}, context=context)
return True
def get_duplicated_leads(self, cr, uid, ids, partner_id, include_lost=False, context=None):
"""
Search for opportunities that have the same partner and that arent done or cancelled
@@ -571,7 +630,6 @@ class crm_lead(format_address, osv.osv):
self._merge_notify(cr, uid, highest, opportunities, context=context)
self._merge_opportunity_history(cr, uid, highest, opportunities, context=context)
self._merge_opportunity_attachments(cr, uid, highest, opportunities, context=context)
self._merge_opportunity_phonecalls(cr, uid, highest, opportunities, context=context)
def merge_opportunity(self, cr, uid, ids, user_id=False, team_id=False, context=None):
"""
@@ -647,7 +705,6 @@ class crm_lead(format_address, osv.osv):
'name': lead.name,
'partner_id': customer and customer.id or False,
'type': 'opportunity',
'date_action': fields.datetime.now(),
'date_open': fields.datetime.now(),
'email_from': customer and customer.email or lead.email_from,
'phone': customer and customer.phone or lead.phone,
@@ -726,7 +783,6 @@ class crm_lead(format_address, osv.osv):
:param int partner_id: partner to assign if any
:return dict: dictionary organized as followed: {lead_id: partner_assigned_id}
"""
#TODO this is a duplication of the handle_partner_assignation method of crm_phonecall
partner_ids = {}
for lead in self.browse(cr, uid, ids, context=context):
# If the action is set to 'create' and no partner_id is set, create a new one
@@ -767,45 +823,6 @@ class crm_lead(format_address, osv.osv):
self.write(cr, uid, [lead_id], value, context=context)
return True
def schedule_phonecall(self, cr, uid, ids, schedule_time, call_summary, desc, phone, contact_name, user_id=False, team_id=False, categ_id=False, action='schedule', context=None):
"""
:param string action: ('schedule','Schedule a call'), ('log','Log a call')
"""
phonecall = self.pool.get('crm.phonecall')
model_data = self.pool.get('ir.model.data')
phonecall_dict = {}
if not categ_id:
try:
res_id = model_data._get_id(cr, uid, 'crm', 'categ_phone2')
categ_id = model_data.browse(cr, uid, res_id, context=context).res_id
except ValueError:
pass
for lead in self.browse(cr, uid, ids, context=context):
if not team_id:
team_id = lead.team_id and lead.team_id.id or False
if not user_id:
user_id = lead.user_id and lead.user_id.id or False
vals = {
'name': call_summary,
'opportunity_id': lead.id,
'user_id': user_id or False,
'categ_id': categ_id or False,
'description': desc or '',
'date': schedule_time,
'team_id': team_id or False,
'partner_id': lead.partner_id and lead.partner_id.id or False,
'partner_phone': phone or lead.phone or (lead.partner_id and lead.partner_id.phone or False),
'partner_mobile': lead.partner_id and lead.partner_id.mobile or False,
'priority': lead.priority,
}
new_id = phonecall.create(cr, uid, vals, context=context)
phonecall.write(cr, uid, [new_id], {'state': 'open'}, context=context)
if action == 'log':
phonecall.write(cr, uid, [new_id], {'state': 'done'}, context=context)
phonecall_dict[lead.id] = new_id
self.schedule_phonecall_send_note(cr, uid, [lead.id], new_id, action, context=context)
return phonecall_dict
def redirect_opportunity_view(self, cr, uid, opportunity_id, context=None):
models_data = self.pool.get('ir.model.data')
@@ -1006,22 +1023,6 @@ class crm_lead(format_address, osv.osv):
return super(crm_lead, self).message_update(cr, uid, ids, msg, update_vals=update_vals, context=context)
# ----------------------------------------
# OpenChatter methods and notifications
# ----------------------------------------
def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None):
phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0]
if action == 'log':
message = _('Logged a call for %(date)s. %(description)s')
else:
message = _('Scheduled a call for %(date)s. %(description)s')
phonecall_date = datetime.strptime(phonecall.date, tools.DEFAULT_SERVER_DATETIME_FORMAT)
phonecall_usertime = fields.datetime.context_timestamp(cr, uid, phonecall_date, context=context).strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
html_time = "<time datetime='%s+00:00'>%s</time>" % (phonecall.date, phonecall_usertime)
message = message % dict(date=html_time, description=phonecall.description)
return self.message_post(cr, uid, ids, body=message, context=context)
def log_meeting(self, cr, uid, ids, meeting_subject, meeting_date, duration, context=None):
if not duration:
duration = _('unknown')
+16 -1
View File
@@ -319,6 +319,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor1])]"/>
<field name="priority">1</field>
<field eval="time.strftime('%Y-%m-25')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_meeting"/>
<field eval="time.strftime('%Y-%m-12')" name="date_action"/>
<field name="title_action">Meeting for pricing information.</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
@@ -345,6 +346,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor2])]"/>
<field name="priority">2</field>
<field eval="time.strftime('%Y-%m-23')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_email"/>
<field eval="time.strftime('%Y-%m-10')" name="date_action"/>
<field name="title_action">Send Catalogue by Email</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
@@ -368,6 +370,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor1])]"/>
<field name="priority">1</field>
<field eval="time.strftime('%Y-%m-12')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_call"/>
<field eval="time.strftime('%Y-%m-10')" name="date_action"/>
<field name="title_action">Call to ask system requirement</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
@@ -396,6 +399,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor5])]"/>
<field name="priority">2</field>
<field eval="time.strftime('%Y-%m-28')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_meeting"/>
<field eval="time.strftime('%Y-%m-1')" name="date_action"/>
<field name="title_action">Convert to quote</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
@@ -421,6 +425,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor3,categ_oppor4])]"/>
<field name="priority">1</field>
<field eval="time.strftime('%Y-%m-8')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_email"/>
<field eval="time.strftime('%Y-%m-3')" name="date_action"/>
<field name="title_action">Send price list regarding our interventions</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
@@ -450,6 +455,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor4,categ_oppor6])]"/>
<field name="priority">1</field>
<field eval="time.strftime('%Y-%m-13')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_call"/>
<field eval="time.strftime('%Y-%m-4')" name="date_action"/>
<field name="title_action">Call to define real needs about training</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
@@ -478,6 +484,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor1])]"/>
<field name="priority">1</field>
<field eval="time.strftime('%Y-%m-10')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_call"/>
<field eval="time.strftime('%Y-%m-5')" name="date_action"/>
<field name="title_action">Ask for the good receprion of the proposition</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
@@ -498,6 +505,7 @@ Andrew</field>
<field name="partner_id" ref="base.res_partner_5"/>
<field name="tag_ids" eval="[(6, 0, [categ_oppor4,categ_oppor8])]"/>
<field name="priority">2</field>
<field name="next_activity_id" ref="crm_activity_data_call"/>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead4"/>
@@ -512,6 +520,7 @@ Andrew</field>
<field name="partner_id" ref="base.res_partner_7"/>
<field name="tag_ids" eval="[(6, 0, [categ_oppor7])]"/>
<field name="priority">2</field>
<field name="next_activity_id" ref="crm_activity_data_meeting"/>
<field name="team_id" ref="sales_team.crm_team_2"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead4"/>
@@ -531,6 +540,7 @@ Andrew</field>
<field name="partner_id" ref="base.res_partner_17"/>
<field name="tag_ids" eval="[(6, 0, [categ_oppor3])]"/>
<field name="priority">1</field>
<field name="next_activity_id" ref="crm_activity_data_email"/>
<field name="team_id" ref="sales_team.crm_team_2"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead5"/>
@@ -547,6 +557,7 @@ Andrew</field>
<field name="partner_id" ref="base.res_partner_18"/>
<field name="tag_ids" eval="[(6, 0, [categ_oppor3])]"/>
<field name="priority">0</field>
<field name="next_activity_id" ref="crm_activity_data_email"/>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead5"/>
@@ -567,6 +578,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor7])]"/>
<field name="priority">0</field>
<field eval="time.strftime('%Y-%m-6')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_email"/>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead5"/>
@@ -591,6 +603,7 @@ Andrew</field>
<field name="zip">B7313</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor4])]"/>
<field name="priority">2</field>
<field name="next_activity_id" ref="crm_activity_data_call"/>
<field name="title_action">Conf call with technical service</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_root"/>
@@ -614,6 +627,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor2])]"/>
<field name="priority">2</field>
<field eval="time.strftime('%Y-%m-23')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_email"/>
<field eval="time.strftime('%Y-%m-10')" name="date_action"/>
<field name="title_action">Send Catalogue by Email</field>
<field name="team_id" ref="sales_team.crm_team_2"/>
@@ -640,6 +654,7 @@ Andrew</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor2])]"/>
<field name="priority">2</field>
<field eval="time.strftime('%Y-%m-23')" name="date_deadline"/>
<field name="next_activity_id" ref="crm_activity_data_email"/>
<field eval="time.strftime('%Y-%m-10')" name="date_action"/>
<field name="title_action">Send Catalogue by Email</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
@@ -703,7 +718,7 @@ Andrew</field>
<field name="model">crm.lead</field>
<field name="res_id" ref="crm_case_15"/>
<field name="body"><![CDATA[<p>Hello</p>
<p>After our phonecall and discussion with our technical experts, here is the offer of YourCompany. We believe it will meet every requirement you had in mind. Please feel free to contact me for any detail or technical detail that is not clear enough for you.</p>
<p>After our discussion with our technical experts, here is the offer of YourCompany. We believe it will meet every requirement you had in mind. Please feel free to contact me for any detail or technical detail that is not clear enough for you.</p>
<p>Notice that as agreed on phone, we offer you a <b>10% discount on the hardware</b>!</p>
<p>Best regards,</p>]]></field>
<field name="message_type">email</field>
+29 -27
View File
@@ -88,15 +88,6 @@
<!--
LEADS
-->
<act_window
id="act_crm_opportunity_crm_phonecall_new"
name="Phone calls"
groups="base.group_sale_salesman"
res_model="crm.phonecall"
view_mode="tree,calendar,form"
context="{'default_duration': 1.0 ,'default_opportunity_id': active_id}"
view_type="form"/>
<act_window
id="act_crm_opportunity_calendar_event_new"
name="Meetings"
@@ -121,13 +112,7 @@
on_change="onchange_stage_id(stage_id)"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="action"
context="{'default_opportunity_id': active_id, 'search_default_opportunity_id': active_id, 'default_partner_id': partner_id, 'default_duration': 1.0}"
name="%(crm.crm_phonecall_category_phone_incoming0)d" icon="fa-phone">
<field string="Calls" name="calls_count" widget="statinfo"/>
</button>
</div>
<div class="oe_button_box" name="button_box"/>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1><field name="name" placeholder="Describe the lead..."/></h1>
@@ -309,7 +294,6 @@
<t t-if="widget.editable"><li><a type="edit">Edit Opportunity</a></li></t>
<t t-if="widget.deletable"><li><a type="delete">Delete</a></li></t>
<li><a name="%(mail.action_email_compose_message_wizard)d" type="action" >Send Email</a></li>
<li><a type="action" name="%(crm.crm_phonecall_category_phone_incoming0)d">Calls</a></li>
<li><a name="action_schedule_meeting" type="object">Schedule Meeting</a></li>
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
</ul>
@@ -402,11 +386,6 @@
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="action"
name="%(crm.crm_phonecall_category_phone_incoming0)d" icon="fa-phone"
context="{'default_opportunity_id': active_id, 'search_default_opportunity_id': active_id, 'default_partner_id': partner_id, 'default_duration': 1.0}">
<field string="Calls" name="calls_count" widget="statinfo"/>
</button>
<button class="oe_stat_button" type="object"
context="{'partner_id': partner_id}"
name="action_schedule_meeting" icon="fa-calendar">
@@ -439,11 +418,34 @@
</group>
<group>
<label for="title_action"/>
<div class="o_row">
<field name="date_action" nolabel="1"/>
<span attrs="{'invisible': ['|', ('date_action', '=', False), ('title_action', '=', False)]}" class="oe_read_only"> - </span>
<field name="title_action" nolabel="1" placeholder="e.g. Call for proposal"/>
<label for="next_activity_id"/>
<div>
<field name="next_activity_id"
class="oe_inline" options="{'no_create': True, 'no_open': True}"
domain="['|',('team_id','=',False),('team_id','=',team_id)]"
on_change="onchange_next_activity_id(next_activity_id)"/>
<span class="oe_form_field oe_read_only oe_inline"
attrs="{'invisible': ['|', ('next_activity_id', '=', False), ('date_action', '=', False)]}">&#160;on&#160;</span>
<field name="date_action" nolabel="1" attrs="{'invisible': [('next_activity_id', '=', False)]}"/>
<field name="title_action" nolabel="1" placeholder="e.g. Discuss proposal"
attrs="{'invisible': [('next_activity_id', '=', False)]}"/>
<div attrs="{'invisible': [('next_activity_id', '=', False)]}">
<button name="log_next_activity_done" string="Done" type="object" class="oe_link"/>
<button name="log_next_activity_1" type="object" class="oe_link" attrs="{'invisible': [('next_activity_1','=',False)]}">
<span>&#160;|&#160;</span>
<field name="next_activity_1" class="oe_inline" readonly="1"/>
</button>
<button name="log_next_activity_2" type="object" class="oe_link" attrs="{'invisible': [('next_activity_2','=',False)]}">
<span>&#160;|&#160;</span>
<field name="next_activity_2" class="oe_inline" readonly="1"/>
</button>
<button name="log_next_activity_3" type="object" class="oe_link" attrs="{'invisible': [('next_activity_3','=',False)]}">
<span>&#160;|&#160;</span>
<field name="next_activity_3" class="oe_inline" readonly="1"/>
</button>
<span>&#160;|&#160;</span>
<button name="cancel_next_activity" string="Cancel" type="object" class="oe_link"/>
</div>
</div>
<field name="date_deadline"/>
<field name="priority" widget="priority"/>
-292
View File
@@ -1,292 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import crm
from datetime import datetime
from openerp.osv import fields, osv
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
from openerp.tools.translate import _
from openerp.exceptions import UserError
class crm_phonecall(osv.osv):
""" Model for CRM phonecalls """
_name = "crm.phonecall"
_description = "Phonecall"
_order = "id desc"
_inherit = ['mail.thread']
_columns = {
'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1),
'create_date': fields.datetime('Creation Date' , readonly=True),
'team_id': fields.many2one('crm.team', 'Sales Team', oldname='section_id',\
select=True, help='Sales team to which Case belongs to.'),
'user_id': fields.many2one('res.users', 'Responsible'),
'partner_id': fields.many2one('res.partner', 'Contact'),
'company_id': fields.many2one('res.company', 'Company'),
'description': fields.text('Description'),
'state': fields.selection(
[('open', 'Confirmed'),
('cancel', 'Cancelled'),
('pending', 'Pending'),
('done', 'Held')
], string='Status', readonly=True, track_visibility='onchange',
help='The status is set to Confirmed, when a case is created.\n'
'When the call is over, the status is set to Held.\n'
'If the callis not applicable anymore, the status can be set to Cancelled.'),
'email_from': fields.char('Email', size=128, help="These people will receive email."),
'date_open': fields.datetime('Opened', readonly=True),
# phonecall fields
'name': fields.char('Call Summary', required=True),
'active': fields.boolean('Active', required=False),
'duration': fields.float('Duration', help='Duration in minutes and seconds.'),
'categ_id': fields.many2one('crm.phonecall.category', 'Category'),
'partner_phone': fields.char('Phone'),
'partner_mobile': fields.char('Mobile'),
'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'),
'date_closed': fields.datetime('Closed', readonly=True),
'date': fields.datetime('Date'),
'opportunity_id': fields.many2one ('crm.lead', 'Lead/Opportunity'),
}
def _get_default_state(self, cr, uid, context=None):
if context and context.get('default_state'):
return context.get('default_state')
return 'open'
_defaults = {
'date': fields.datetime.now,
'priority': '1',
'state': _get_default_state,
'user_id': lambda self, cr, uid, ctx: uid,
'team_id': lambda s, cr, uid, c: s.pool['crm.team']._get_default_team_id(cr, uid, context=c),
'active': 1
}
def on_change_partner_id(self, cr, uid, ids, partner_id, context=None):
values = {}
if partner_id:
partner = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
values = {
'partner_phone': partner.phone,
'partner_mobile': partner.mobile,
}
return {'value': values}
def write(self, cr, uid, ids, values, context=None):
""" Override to add case management: open/close dates """
if values.get('state'):
if values.get('state') == 'done':
values['date_closed'] = fields.datetime.now()
self.compute_duration(cr, uid, ids, context=context)
elif values.get('state') == 'open':
values['date_open'] = fields.datetime.now()
values['duration'] = 0.0
return super(crm_phonecall, self).write(cr, uid, ids, values, context=context)
def compute_duration(self, cr, uid, ids, context=None):
for phonecall in self.browse(cr, uid, ids, context=context):
if phonecall.duration <= 0:
duration = datetime.now() - datetime.strptime(phonecall.date, DEFAULT_SERVER_DATETIME_FORMAT)
values = {'duration': duration.seconds/float(60)}
self.write(cr, uid, [phonecall.id], values, context=context)
return True
def schedule_another_phonecall(self, cr, uid, ids, schedule_time, call_summary, \
user_id=False, team_id=False, categ_id=False, action='schedule', context=None):
"""
action :('schedule','Schedule a call'), ('log','Log a call')
"""
model_data = self.pool.get('ir.model.data')
phonecall_dict = {}
if not categ_id:
try:
res_id = model_data._get_id(cr, uid, 'crm', 'categ_phone2')
categ_id = model_data.browse(cr, uid, res_id, context=context).res_id
except ValueError:
pass
for call in self.browse(cr, uid, ids, context=context):
if not team_id:
team_id = call.team_id and call.team_id.id or False
if not user_id:
user_id = call.user_id and call.user_id.id or False
if not schedule_time:
schedule_time = call.date
vals = {
'name' : call_summary,
'user_id' : user_id or False,
'categ_id' : categ_id or False,
'description' : call.description or False,
'date' : schedule_time,
'team_id' : team_id or False,
'partner_id': call.partner_id and call.partner_id.id or False,
'partner_phone' : call.partner_phone,
'partner_mobile' : call.partner_mobile,
'priority': call.priority,
'opportunity_id': call.opportunity_id and call.opportunity_id.id or False,
}
new_id = self.create(cr, uid, vals, context=context)
if action == 'log':
self.write(cr, uid, [new_id], {'state': 'done'}, context=context)
phonecall_dict[call.id] = new_id
return phonecall_dict
def _call_create_partner(self, cr, uid, phonecall, context=None):
partner = self.pool.get('res.partner')
partner_id = partner.create(cr, uid, {
'name': phonecall.name,
'user_id': phonecall.user_id.id,
'comment': phonecall.description,
'address': []
})
return partner_id
def on_change_opportunity(self, cr, uid, ids, opportunity_id, context=None):
values = {}
if opportunity_id:
opportunity = self.pool.get('crm.lead').browse(cr, uid, opportunity_id, context=context)
values = {
'team_id' : opportunity.team_id and opportunity.team_id.id or False,
'partner_phone' : opportunity.phone,
'partner_mobile' : opportunity.mobile,
'partner_id' : opportunity.partner_id and opportunity.partner_id.id or False,
}
return {'value' : values}
def _call_set_partner(self, cr, uid, ids, partner_id, context=None):
write_res = self.write(cr, uid, ids, {'partner_id' : partner_id}, context=context)
self._call_set_partner_send_note(cr, uid, ids, context)
return write_res
def _call_create_partner_address(self, cr, uid, phonecall, partner_id, context=None):
address = self.pool.get('res.partner')
return address.create(cr, uid, {
'parent_id': partner_id,
'name': phonecall.name,
'phone': phonecall.partner_phone,
})
def handle_partner_assignation(self, cr, uid, ids, action='create', partner_id=False, context=None):
"""
Handle partner assignation during a lead conversion.
if action is 'create', create new partner with contact and assign lead to new partner_id.
otherwise assign lead to specified partner_id
:param list ids: phonecalls ids to process
:param string action: what has to be done regarding partners (create it, assign an existing one, or nothing)
:param int partner_id: partner to assign if any
:return dict: dictionary organized as followed: {lead_id: partner_assigned_id}
"""
#TODO this is a duplication of the handle_partner_assignation method of crm_lead
partner_ids = {}
# If a partner_id is given, force this partner for all elements
force_partner_id = partner_id
for call in self.browse(cr, uid, ids, context=context):
# If the action is set to 'create' and no partner_id is set, create a new one
if action == 'create':
partner_id = force_partner_id or self._call_create_partner(cr, uid, call, context=context)
self._call_create_partner_address(cr, uid, call, partner_id, context=context)
self._call_set_partner(cr, uid, [call.id], partner_id, context=context)
partner_ids[call.id] = partner_id
return partner_ids
def redirect_phonecall_view(self, cr, uid, phonecall_id, context=None):
model_data = self.pool.get('ir.model.data')
# Select the view
tree_view = model_data.get_object_reference(cr, uid, 'crm', 'crm_case_phone_tree_view')
form_view = model_data.get_object_reference(cr, uid, 'crm', 'crm_case_phone_form_view')
search_view = model_data.get_object_reference(cr, uid, 'crm', 'view_crm_case_phonecalls_filter')
value = {
'name': _('Phone Call'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'crm.phonecall',
'res_id' : int(phonecall_id),
'views': [(form_view and form_view[1] or False, 'form'), (tree_view and tree_view[1] or False, 'tree'), (False, 'calendar')],
'type': 'ir.actions.act_window',
'search_view_id': search_view and search_view[1] or False,
}
return value
def convert_opportunity(self, cr, uid, ids, opportunity_summary=False, partner_id=False, planned_revenue=0.0, probability=0.0, context=None):
partner = self.pool.get('res.partner')
opportunity = self.pool.get('crm.lead')
opportunity_dict = {}
default_contact = False
for call in self.browse(cr, uid, ids, context=context):
if not partner_id:
partner_id = call.partner_id and call.partner_id.id or False
if partner_id:
address_id = partner.address_get(cr, uid, [partner_id])['default']
if address_id:
default_contact = partner.browse(cr, uid, address_id, context=context)
opportunity_id = opportunity.create(cr, uid, {
'name': opportunity_summary or call.name,
'planned_revenue': planned_revenue,
'probability': probability,
'partner_id': partner_id or False,
'mobile': default_contact and default_contact.mobile,
'team_id': call.team_id and call.team_id.id or False,
'description': call.description or False,
'priority': call.priority,
'type': 'opportunity',
'phone': call.partner_phone or False,
'email_from': default_contact and default_contact.email,
})
vals = {
'partner_id': partner_id,
'opportunity_id': opportunity_id,
'state': 'done',
}
self.write(cr, uid, [call.id], vals, context=context)
opportunity_dict[call.id] = opportunity_id
return opportunity_dict
def action_make_meeting(self, cr, uid, ids, context=None):
"""
Open meeting's calendar view to schedule a meeting on current phonecall.
:return dict: dictionary value for created meeting view
"""
partner_ids = []
phonecall = self.browse(cr, uid, ids[0], context)
if phonecall.partner_id and phonecall.partner_id.email:
partner_ids.append(phonecall.partner_id.id)
res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid, 'calendar', 'action_calendar_event', context)
res['context'] = {
'default_phonecall_id': phonecall.id,
'default_partner_ids': partner_ids,
'default_user_id': uid,
'default_email_from': phonecall.email_from,
'default_name': phonecall.name,
'default_opportunity_id': phonecall.opportunity_id.id,
}
return res
def action_button_convert2opportunity(self, cr, uid, ids, context=None):
"""
Convert a phonecall into an opp and then redirect to the opp view.
:param list ids: list of calls ids to convert (typically contains a single id)
:return dict: containing view information
"""
if len(ids) != 1:
raise UserError(_('It\'s only possible to convert one phonecall at a time.'))
opportunity_dict = self.convert_opportunity(cr, uid, ids, context=context)
return self.pool.get('crm.lead').redirect_opportunity_view(cr, uid, opportunity_dict[ids[0]], context)
# ----------------------------------------
# OpenChatter
# ----------------------------------------
def _call_set_partner_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Partner has been <b>created</b>."), context=context)
class crm_phonecall_category(osv.Model):
_name = "crm.phonecall.category"
_description = "Category of phonecall"
_columns = {
'name': fields.char('Name', required=True, translate=True),
'team_id': fields.many2one('crm.team', 'Sales Team'),
}
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<!--
Phonecall Categories
-->
<record model="crm.phonecall.category" id="categ_phone1">
<field name="name">Inbound</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
</record>
<record model="crm.phonecall.category" id="categ_phone2">
<field name="name">Outbound</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
</record>
</data>
</openerp>
-84
View File
@@ -1,84 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<!-- Demo Cases -->
<record id="crm_phonecall_1" model="crm.phonecall">
<field eval="time.strftime('%Y-%m-04 10:45:36')" name="date"/>
<field name="partner_id" ref="base.res_partner_11"/>
<field eval="'1'" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field name="name">Left the message</field>
<field name="state">done</field>
<field name="partner_phone">+34 934 340 230</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field eval="1" name="active"/>
<field name="categ_id" ref="crm.categ_phone1"/>
<field eval="2.3" name="duration"/>
</record>
<record id="crm_phonecall_2" model="crm.phonecall">
<field eval="time.strftime('%Y-%m-11 11:19:25')" name="date"/>
<field name="partner_id" ref="base.res_partner_7"/>
<field eval="'0'" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field name="name">Need more information on the proposed deal</field>
<field name="state">done</field>
<field name="partner_phone">+44 121 690 4596</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field eval="1" name="active"/>
<field name="categ_id" ref="crm.categ_phone1"/>
<field eval="1.5" name="duration"/>
</record>
<record id="crm_phonecall_3" model="crm.phonecall">
<field eval="time.strftime('%Y-%m-15 17:44:12')" name="date"/>
<field name="partner_id" ref="base.res_partner_10"/>
<field eval="'2'" name="priority"/>
<field name="user_id" ref="base.user_demo"/>
<field name="name">Ask for convenient time of meeting</field>
<field name="state">open</field>
<field name="partner_phone">+1 786 525 0724</field>
<field name="team_id" ref="sales_team.crm_team_2"/>
<field eval="1" name="active"/>
<field name="categ_id" ref="crm.categ_phone2"/>
<field eval="5.0" name="duration"/>
</record>
<record id="crm_phonecall_4" model="crm.phonecall">
<field eval="time.strftime('%Y-%m-21 14:10:23')" name="date"/>
<field eval="'1'" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field name="name">Wanted information about pricing of laptops</field>
<field name="state">done</field>
<field name="partner_phone">(077) 582-4035</field>
<field name="partner_mobile">(077) 341-3591</field>
<field name="team_id" ref="sales_team.crm_team_2"/>
<field eval="1" name="active"/>
<field name="categ_id" ref="crm.categ_phone1"/>
<field eval="5.45" name="duration"/>
</record>
<record id="crm_phonecall_5" model="crm.phonecall">
<field eval="time.strftime('%Y-%m-28 16:20:43')" name="date"/>
<field name="partner_id" ref="base.res_partner_5"/>
<field eval="'1'" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field name="name">More information on the proposed deal</field>
<field name="state">pending</field>
<field name="partner_phone">+1 312 349 2324</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field eval="1" name="active"/>
<field name="categ_id" ref="crm.categ_phone1"/>
<field eval="2.08" name="duration"/>
</record>
<record id="crm_phonecall_6" model="crm.phonecall">
<field eval="'1'" name="priority"/>
<field name="user_id" ref="base.user_root"/>
<field name="name">Proposal for discount offer</field>
<field name="state">open</field>
<field name="partner_phone">+34 230 953 485</field>
<field name="team_id" ref="sales_team.crm_team_2"/>
<field eval="time.strftime('%Y-%m-28 14:15:30')" name="date"/>
<field name="categ_id" ref="crm.categ_phone2"/>
<field eval="8.56" name="duration"/>
</record>
</data>
</openerp>
-97
View File
@@ -1,97 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- TO CONFIRM: This is fine -->
<!-- act_window
id="act_crm_phonecall_calendar_event_new"
name="Meetings"
res_model="calendar.event"
src_model="crm.phonecall"
view_mode="tree,form,calendar"
context="{'default_duration': 4.0, 'default_phonecall_id': active_id}"
domain="[('phonecall_id', '=', active_id)]"
view_type="form"/-->
<!-- PHONE CALLS (menu) -->
<record model="ir.actions.act_window" id="crm_phonecall_category_phone0">
<field name="name">Phone Calls</field>
<field name="res_model">crm.phonecall</field>
<field name="view_type">form</field>
<field name="view_mode">tree,calendar</field>
<field name="view_id" ref="crm_case_phone_tree_view"/>
<field name="context">{"search_default_user_id":uid}</field>
<field name="search_view_id" ref="crm.view_crm_case_phonecalls_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_phone0">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="crm_case_phone_tree_view"/>
<field name="act_window_id" ref="crm_phonecall_category_phone0"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_calendar_phone0">
<field name="sequence" eval="2"/>
<field name="view_mode">calendar</field>
<field name="view_id" ref="crm_case_phone_calendar_view"/>
<field name="act_window_id" ref="crm_phonecall_category_phone0"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_form_phone0">
<field name="sequence" eval="3"/>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_case_phone_form_view"/>
<field name="act_window_id" ref="crm_phonecall_category_phone0"/>
</record>
<record model="ir.actions.act_window" id="crm_phonecall_category_phone_incoming0">
<field name="name">Logged Calls</field>
<field name="res_model">crm.phonecall</field>
<field name="view_type">form</field>
<field name="view_mode">tree,calendar</field>
<field name="view_id" ref="crm_case_inbound_phone_tree_view"/>
<field name="search_view_id" ref="crm.view_crm_case_phonecalls_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to log the summary of a phone call.
</p><p>
Odoo allows you to log inbound calls on the fly to track the
history of the communication with a customer or to inform another
team member.
</p><p>
In order to follow up on the call, you can trigger a request for
another call, a meeting or an opportunity.
</p>
</field>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_phone_incoming0">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="crm_case_inbound_phone_tree_view"/>
<field name="act_window_id" ref="crm_phonecall_category_phone_incoming0"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_calendar_phone_incoming0">
<field name="sequence" eval="2"/>
<field name="view_mode">calendar</field>
<field name="view_id" ref="crm_case_phone_calendar_view"/>
<field name="act_window_id" ref="crm_phonecall_category_phone_incoming0"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_form_phone_incoming0">
<field name="sequence" eval="3"/>
<field name="view_mode">form</field>
<field name="view_id" ref="crm_case_phone_form_view"/>
<field name="act_window_id" ref="crm_phonecall_category_phone_incoming0"/>
</record>
<menuitem name="Calls" id="menu_crm_case_phone" sequence="4"
parent="base.menu_sales"
action="crm_phonecall_category_phone_incoming0" />
</data>
</openerp>
-232
View File
@@ -1,232 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- Phonecall Categories -->
<record id="crm_phonecall_category_form" model="ir.ui.view">
<field name="name">crm.phonecall.category.form</field>
<field name="model">crm.phonecall.category</field>
<field name="arch" type="xml">
<form string="Phonecall Categories">
<group>
<field name="name"/>
<field name="team_id" groups="base.group_multi_salesteams"/>
</group>
</form>
</field>
</record>
<record id="crm_phonecall_category_tree" model="ir.ui.view">
<field name="name">crm.phonecall.category.tree</field>
<field name="model">crm.phonecall.category</field>
<field name="arch" type="xml">
<tree string="Phonecall Categories">
<field name="name"/>
<field name="team_id" groups="base.group_multi_salesteams"/>
</tree>
</field>
</record>
<record id="crm_phonecall_category_action" model="ir.actions.act_window">
<field name="name">Phonecall Categories</field>
<field name="res_model">crm.phonecall.category</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_phonecall_category_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a new category.
</p><p>
Create specific phone call categories to better define the type of
calls tracked in the system.
</p>
</field>
</record>
<menuitem action="crm_phonecall_category_action" name="Categories"
id="menu_crm_case_phonecall-act" parent="menu_crm_config_phonecall" groups="base.group_no_one"/>
<!-- Phonecalls Tree View -->
<record model="ir.ui.view" id="crm_case_phone_tree_view">
<field name="name">CRM - Phone Calls Tree</field>
<field name="model">crm.phonecall</field>
<field name="arch" type="xml">
<tree decoration-muted="state in ('cancel','done')" decoration-info="state in ('pending',)" string="Phone Calls">
<field name="date"/>
<field name="name"/>
<field name="partner_id"/>
<button string="Meeting"
states="open,pending"
name="action_make_meeting"
icon="fa-share"
type="object"/>
<button string="Create an Opportunity"
type="object"
name="action_button_convert2opportunity"
states="open,pending"
icon="fa-check-square-o"
attrs="{'invisible':[('opportunity_id','!=',False)]}"/>
<field name="partner_phone"/>
<field name="user_id"/>
<field name="categ_id" invisible="1"/>
<field name="create_date" invisible="1"/>
<field name="opportunity_id" invisible="1"/>
<field name="state"/>
</tree>
</field>
</record>
<!-- Phonecalls Form View -->
<record model="ir.ui.view" id="crm_case_phone_form_view">
<field name="name">CRM - Phone Call Form</field>
<field name="model">crm.phonecall</field>
<field name="arch" type="xml">
<form string="Phone Call">
<header>
<field name="state" nolabel="1" widget="statusbar" clickable="True"/>
</header>
<sheet string="Phone Call">
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="object" name="action_button_convert2opportunity"
icon="fa-star" attrs="{'invisible':[ '|', ('opportunity_id','!=',False), ('state', 'not in', ('open', 'done'))]}"
help="Convert To Opportunity">
<div class="o_form_field o_stat_info">
<span class="o_stat_text">Convert To</span>
<span class="o_stat_text">Opportunity</span>
</div>
</button>
<button class="oe_stat_button" type="action"
name="%(phonecall_to_phonecall_act)d" icon="fa-phone">
<div class="o_form_field o_stat_info">
<span class="o_stat_text">Schedule</span>
<span class="o_stat_text">Other Call</span>
</div>
</button>
<button class="oe_stat_button" name="action_make_meeting" type="object" icon="fa-calendar fa-fw">
<div class="o_form_field o_stat_info">
<span class="o_stat_text">Schedule</span>
<span class="o_stat_text">A Meeting</span>
</div>
</button>
</div>
<div class="oe_title">
<div class="oe_edit_only">
<label for="name"/>
</div>
<h1><field name="name" required="1"/></h1>
<div class="oe_edit_only">
<label for="partner_phone" string="Phone"/>
</div>
<h2><field name="partner_phone"/></h2>
</div>
<group col="4">
<field name="date"/>
<field name="user_id" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_salesman_all_leads']}"/>
<label for="duration"/>
<div>
<field name="duration" widget="float_time" class="oe_inline" style="vertical-align:baseline"/> <b> min(s)</b>
</div>
<field name="team_id" colspan="1" widget="selection"
groups="base.group_multi_salesteams"/>
<field name="partner_id" on_change="on_change_partner_id(partner_id)"/>
<field name="categ_id" widget="selection"/>
<field name="partner_mobile"/>
<field name="priority" widget="priority"/>
<field name="opportunity_id" on_change="on_change_opportunity(opportunity_id)" context="{'opportunity_id': opportunity_id}"/>
</group>
<field name="description" placeholder="Description..."/>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!--Logged Phonecalls Tree View -->
<record model="ir.ui.view" id="crm_case_inbound_phone_tree_view">
<field name="name">CRM - Logged Phone Calls Tree</field>
<field name="model">crm.phonecall</field>
<field name="arch" type="xml">
<tree string="Phone Calls" editable="top">
<field name="date"/>
<field name="name"/>
<field name="partner_id"
on_change="on_change_partner_id(partner_id)"/>
<field name="partner_phone"
invisible="1"/>
<field name="partner_mobile"
invisible="1"/>
<field name="user_id" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_salesman_all_leads']}"/>
<field name="categ_id" widget="selection"
invisible="1"/>
<field name="state" invisible="1"/>
<field name="create_date" invisible="1"/>
<field name="opportunity_id" invisible="1" on_change="on_change_opportunity(opportunity_id)"/>
<button string="Schedule Other Call"
icon="fa-phone"
name="%(phonecall_to_phonecall_act)d"
type="action"/>
<button string="Meeting"
icon="fa-share"
name="action_make_meeting" type="object"/>
<button string="Create an Opportunity"
name="action_button_convert2opportunity"
states="open,pending"
icon="fa-check-square-o"
type="object" attrs="{'invisible':[('opportunity_id','!=',False)]}"/>
</tree>
</field>
</record>
<!-- Phonecalls Calendar View -->
<record model="ir.ui.view" id="crm_case_phone_calendar_view">
<field name="name">CRM - Phone Calls Calendar</field>
<field name="model">crm.phonecall</field>
<field name="priority" eval="2"/>
<field name="arch" type="xml">
<calendar string="Phone Calls" date_start="date" color="user_id" date_delay="duration">
<field name="name"/>
<field name="partner_id"/>
</calendar>
</field>
</record>
<!-- Phonecalls Search View -->
<record id="view_crm_case_phonecalls_filter" model="ir.ui.view">
<field name="name">CRM - Phone Calls Search</field>
<field name="model">crm.phonecall</field>
<field name="arch" type="xml">
<search string="Search Phonecalls">
<field name="name" string="Phonecalls"/>
<field name="date"/>
<field name="state"/>
<filter string="My Phonecalls" domain="[('user_id', '=', uid)]"/>
<filter string="My Team" domain="[('team_id.user_id', '=', uid)]"/>
<filter string="Unassigned" domain="[('user_id','=',False)]"/>
<separator/>
<filter string="To Do" name="current" domain="[('state','in',('open','pending'))]"/>
<separator/>
<filter string="New Mail" name="message_unread" domain="[('message_unread','=',True)]"/>
<separator/>
<field name="partner_id" operator="child_of"/>
<field name="user_id"/>
<field name="opportunity_id"/>
<field name="team_id" string="Sales Team"
groups="base.group_multi_salesteams"/>
<group expand="0" string="Group By">
<filter string="Partner" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Responsible" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Creation" help="Creation Date" domain="[]" context="{'group_by':'create_date'}"/>
<filter string="Month" domain="[]" context="{'group_by':'date'}" help="Calls Date by Month"/>
</group>
</search>
</field>
</record>
</data>
</openerp>
-3
View File
@@ -22,9 +22,6 @@
<menuitem id="base.menu_sale_config_sales" name="Sales"
parent="base.menu_sale_config" sequence="0" groups="base.group_sale_manager"/>
<menuitem id="menu_crm_config_phonecall" name="Phone Calls"
parent="base.menu_sale_config" sequence="45" groups="base.group_sale_salesman"/>
<!-- CRM.LOST.REASON VIEWS -->
<record id="crm_lost_reason_view_form" model="ir.ui.view">
<field name="name">crm.lost.reason.form</field>
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record id="crm_activity_data_email" model="crm.activity">
<field name="name">Email</field>
</record>
<record id="crm_activity_data_call" model="crm.activity">
<field name="name">Call</field>
<field name="activity_1_id" ref="crm_activity_data_email"/>
</record>
<record id="crm_activity_data_meeting" model="crm.activity">
<field name="name">Task</field>
<field name="days">3</field>
<field name="activity_1_id" ref="crm_activity_data_call"/>
<field name="activity_2_id" ref="crm_activity_data_email"/>
</record>
</data>
</odoo>
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="crm_activity_demo_followup_quote" model="crm.activity">
<field name="name">Follow-up Quote</field>
</record>
<record id="crm_activity_demo_make_quote" model="crm.activity">
<field name="name">Make Quote</field>
<field name="description">Send a quotation</field>
<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">15</field>
<field name="description">Call for a demo</field>
<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"/>
</record>
</data>
</odoo>
+1 -2
View File
@@ -8,11 +8,10 @@ Changelog
- Stage/state update
- ``crm.phonecall``: removed inheritance towards ``base_state``.
- ``crm.lead``: removed ``state`` field. Added ``date_last_stage_update`` field
holding last stage_id modification. Updated reports.
- ``crm.case.stage``: removed ``state`` field.
- ``crm``, ``crm_claim``: removed inheritance from ``base_stage`` class. Missing
methods have been added into ``crm`` and ``crm_claim``. Also removed inheritance
in ``crm_helpdesk`` because it uses states, not stages.
in ``crm_helpdesk`` because it uses states, not stages.
+3
View File
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
import crm_activity
+47
View File
@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp import api, fields, models
class CrmActivity(models.Model):
''' CrmActivity is a model introduced in Odoo v9 that models activities
performed in CRM, like phonecalls, sending emails, making demonstrations,
... Users are able to configure their custom activities.
Each activity has up to three next activities. This allows to model light
custom workflows. This way sales manager can configure their crm workflow
that salepersons will use in their daily job.
CrmActivity inherits from mail.message.subtype. This allows users to follow
some activities through subtypes. Each activity will generate messages with
the matching subtypes, allowing reporting and statistics computation based
on mail.message.subtype model. '''
_name = 'crm.activity'
_description = 'CRM Activity'
_inherits = {'mail.message.subtype': 'subtype_id'}
_rec_name = 'name'
_order = "sequence"
days = fields.Integer('Number of days', default=0,
help='Number of days before doing fulfilling the action, allowing to plan the action date.')
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_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):
''' Override to set the res_model of inherited subtype to crm.lead.
This cannot be achieved using a default on res_model field because
of the inherits. Indeed a new field would be created. However the
field on the subtype would still exist. Being void, the subtype
will be present for every model in Odoo. That's quite an issue. '''
if not values.get('res_model') and 'default_res_model' not in self._context:
values['res_model'] = 'crm.lead'
if 'internal' not in values and 'default_internal' not in self._context:
values['internal'] = True
return super(CrmActivity, self).create(values)
+1 -1
View File
@@ -2,5 +2,5 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import crm_lead_report
import crm_activity_report
import crm_opportunity_report
import crm_phonecall_report
+53
View File
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp import fields, models
from openerp import tools
class crm_activity_report(models.Model):
""" CRM Lead Analysis """
_name = "crm.activity.report"
_auto = False
_description = "CRM Activity Analysis"
_rec_name = 'id'
date = fields.Datetime('Date', readonly=True)
author_id = fields.Many2one('res.partner', 'Author', readonly=True)
user_id = fields.Many2one('res.users', 'Responsible', readonly=True)
team_id = fields.Many2one('crm.team', 'Sales Team', readonly=True)
subtype_id = fields.Many2one('mail.message.subtype', 'Action', readonly=True)
country_id = fields.Many2one('res.country', 'Country', readonly=True)
company_id = fields.Many2one('res.company', 'Company', readonly=True)
stage_id = fields.Many2one('crm.stage', 'Stage', readonly=True)
partner_id = fields.Many2one('res.partner', 'Partner/Customer', readonly=True)
lead_type = fields.Char(
string='Type',
selection=[('lead', 'Lead'), ('opportunity', 'Opportunity')],
help="Type is used to separate Leads and Opportunities")
def init(self, cr):
tools.drop_view_if_exists(cr, 'crm_activity_report')
cr.execute("""
CREATE OR REPLACE VIEW crm_activity_report AS (
select
m.id,
m.subtype_id,
m.author_id,
m.date,
l.user_id,
l.team_id,
l.country_id,
l.company_id,
l.stage_id,
l.partner_id,
l.type as lead_type
from
"mail_message" m
left join
"crm_lead" l
on
(m.res_id = l.id)
WHERE
(m.model = 'crm.lead')
)""")
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="crm_activity_report_view_graph" model="ir.ui.view">
<field name="name">crm.activity.report.graph</field>
<field name="model">crm.activity.report</field>
<field name="arch" type="xml">
<graph string="Activities Analysis" type="pivot" stacked="True">
<field name="subtype_id" type="col"/>
<field name="date" interval="month" type="row"/>
</graph>
</field>
</record>
<record id="crm_activity_report_view_pivot" model="ir.ui.view">
<field name="name">crm.activity.report.pivot</field>
<field name="model">crm.activity.report</field>
<field name="arch" type="xml">
<pivot string="Activities Analysis" disable_linking="True">
<field name="subtype_id" type="col"/>
<field name="date" interval="month" type="row"/>
</pivot>
</field>
</record>
<record id="crm_activity_report_view_search" model="ir.ui.view">
<field name="name">crm.activity.report.search</field>
<field name="model">crm.activity.report</field>
<field name="arch" type="xml">
<search string="Activities Analysis">
<filter name="lead" string="Leads" domain="[('lead_type','=', 'lead')]" help="Show only lead"/>
<filter name="opportunity" string="Opportunities" domain="[('lead_type','=','opportunity')]" help="Show only opportunity"/>
<separator/>
<filter string="Won" name="won"
domain="['&amp;', ('stage_id.probability', '=', 100), ('stage_id.on_change', '=', 1)]"/>
<filter string="Lost" name="lost"
domain="['&amp;', ('stage_id.probability', '=', 0), ('stage_id.sequence', '!=', 1)]"/>
<field name="team_id" context="{'invisible_team': False}"
groups="base.group_multi_salesteams"/>
<field name="author_id" string="Salesperson"/>
<group expand="1" string="Group By">
<filter string="Salesperson" context="{'group_by':'author_id'}" />
<filter string="Sales Team" context="{'group_by':'team_id'}" groups="base.group_multi_salesteams"/>
<filter string="Country" context="{'group_by':'country_id'}" />
<filter string="Company" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<filter string="Stage" context="{'group_by':'stage_id'}"/>
<filter string="Month" context="{'group_by':'date:month'}" name="month"/>
</group>
</search>
</field>
</record>
<record id="crm_activity_report_action" model="ir.actions.act_window">
<field name="name">Activities Analysis</field>
<field name="res_model">crm.activity.report</field>
<field name="view_type">form</field>
<field name="view_mode">pivot,graph</field>
<field name="context">{}</field>
<field name="domain">[]</field>
</record>
<menuitem name="Activities" id="crm_activity_report_menu"
groups="base.group_sale_manager"
parent="base.menu_sale_report" action="crm_activity_report_action" sequence="6"/>
</data>
</openerp>
+13 -4
View File
@@ -29,6 +29,7 @@ class crm_opportunity_report(osv.Model):
'user_id':fields.many2one('res.users', 'User', readonly=True),
'team_id':fields.many2one('crm.team', 'Sales Team', oldname='section_id', readonly=True),
'nbr_activities': fields.integer('# of Activities', readonly=True),
'country_id':fields.many2one('res.country', 'Country', readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'probability': fields.float('Probability',digits=(16,2),readonly=True, group_operator="avg"),
@@ -51,9 +52,9 @@ class crm_opportunity_report(osv.Model):
cr.execute("""
CREATE OR REPLACE VIEW crm_opportunity_report AS (
SELECT
id,
c.id,
c.date_deadline,
count(id) as nbr_cases,
count(c.id) as nbr_cases,
c.date_open as opening_date,
c.date_closed as date_closed,
@@ -67,6 +68,7 @@ class crm_opportunity_report(osv.Model):
c.company_id,
c.priority,
c.team_id,
activity.nbr_activities,
c.campaign_id,
c.source_id,
c.medium_id,
@@ -81,7 +83,14 @@ class crm_opportunity_report(osv.Model):
c.lost_reason,
c.date_conversion as date_conversion
FROM
crm_lead c
"crm_lead" c
LEFT JOIN (
SELECT m.res_id, COUNT(*) nbr_activities
FROM "mail_message" m
WHERE m.model = 'crm.lead'
GROUP BY m.res_id ) activity
ON
(activity.res_id = c.id)
WHERE c.active = 'true'
GROUP BY c.id
GROUP BY c.id, activity.nbr_activities
)""")
@@ -63,6 +63,12 @@
<field name="user_id" eval="False"/>
<field name="context">{'group_by': ['create_date:month', 'country_id']}</field>
</record>
<record id="ir_filters_crm_opportunity_report_next_action" model="ir.filters">
<field name="name">Team Activities</field>
<field name="model_id">crm.opportunity.report</field>
<field name="user_id" eval="False"/>
<field name="context">{'group_by': ['team_id'], 'measures': ['nbr_activities']}</field>
</record>
<!-- Opportunities by user and team Search View -->
<record id="view_report_crm_opportunity_filter" model="ir.ui.view">
-67
View File
@@ -1,67 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp import tools
from openerp.addons.crm import crm
from openerp.osv import fields, osv
AVAILABLE_STATES = [
('draft', 'Draft'),
('open', 'Todo'),
('cancel', 'Cancelled'),
('done', 'Held'),
('pending', 'Pending')
]
class crm_phonecall_report(osv.osv):
""" Phone calls by user and team """
_name = "crm.phonecall.report"
_description = "Phone calls by user and team"
_auto = False
_columns = {
'user_id':fields.many2one('res.users', 'User', readonly=True),
'team_id':fields.many2one('crm.team', 'Sales Team', oldname='section_id', readonly=True),
'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'),
'nbr': fields.integer('# of Cases', readonly=True), # TDE FIXME master: rename into nbr_cases
'state': fields.selection(AVAILABLE_STATES, 'Status', readonly=True),
'create_date': fields.datetime('Create Date', readonly=True, select=True),
'delay_close': fields.float('Delay to close', digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
'duration': fields.float('Duration', digits=(16,2),readonly=True, group_operator="avg"),
'delay_open': fields.float('Delay to open',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to open the case"),
'categ_id': fields.many2one('crm.phonecall.category', 'Category'),
'partner_id': fields.many2one('res.partner', 'Partner' , readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'opening_date': fields.datetime('Opening Date', readonly=True, select=True),
'date_closed': fields.datetime('Close Date', readonly=True, select=True),
}
def init(self, cr):
""" Phone Calls By User And Team
@param cr: the current row, from the database cursor,
"""
tools.drop_view_if_exists(cr, 'crm_phonecall_report')
cr.execute("""
create or replace view crm_phonecall_report as (
select
id,
c.date_open as opening_date,
c.date_closed as date_closed,
c.state,
c.user_id,
c.team_id,
c.categ_id,
c.partner_id,
c.duration,
c.company_id,
c.priority,
1 as nbr,
c.create_date as create_date,
extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
extract('epoch' from (c.date_open-c.create_date))/(3600*24) as delay_open
from
crm_phonecall c
)""")
@@ -1,126 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Phone calls by user and team Pivot View -->
<record id="view_report_crm_phonecall_pivot" model="ir.ui.view">
<field name="name">crm.phonecall.report.pivot</field>
<field name="model">crm.phonecall.report</field>
<field name="arch" type="xml">
<pivot string="Phone calls" disable_linking="True">
<field name="team_id" type="row"/>
<field name="create_date" interval="month" type="col"/>
<field name="nbr" type="measure"/>
<field name="duration" type="measure"/>
</pivot>
</field>
</record>
<!-- Phone calls by user and team Graph View -->
<record id="view_report_crm_phonecall_graph" model="ir.ui.view">
<field name="name">crm.phonecall.report.graph</field>
<field name="model">crm.phonecall.report</field>
<field name="arch" type="xml">
<graph string="Phone calls">
<field name="create_date" interval="month"/>
<field name="team_id"/>
<field name="nbr" type="measure"/>
</graph>
</field>
</record>
<!-- Custom reports (aka filters) -->
<record id="filter_crm_phonecall_sales_team" model="ir.filters">
<field name="name">By Sales Team</field>
<field name="model_id">crm.phonecall.report</field>
<field name="domain">[('state','=','done')]</field>
<field name="user_id" eval="False"/>
<field name="context">{'group_by': ['team_id'], 'col_group_by': ['categ_id'], 'measures': ['nbr', 'duration']}</field>
</record>
<record id="filter_crm_phonecall_delay_to_close" model="ir.filters">
<field name="name">Delay To Close</field>
<field name="model_id">crm.phonecall.report</field>
<field name="domain">[('state','=','done')]</field>
<field name="user_id" eval="False"/>
<field name="context">{'group_by': ['team_id'], 'col_group_by': ['categ_id'], 'measures': ['delay_close']}</field>
</record>
<record id="filter_crm_phonecall_phone_call_to_do" model="ir.filters">
<field name="name">Phone Calls To Do</field>
<field name="model_id">crm.phonecall.report</field>
<field name="domain">[('state','in',('draft','open'))]</field>
<field name="user_id" eval="False"/>
<field name="context">{'group_by': ['team_id'], 'measures': ['nbr']}</field>
</record>
<!-- Phone calls by user and team Search View -->
<record id="view_report_crm_phonecall_filter" model="ir.ui.view">
<field name="name">crm.phonecall.report.select</field>
<field name="model">crm.phonecall.report</field>
<field name="arch" type="xml">
<search string="Search">
<filter string="Held" name="held" domain="[('state','=','done')]"
help="Phone calls which are in closed state"/>
<filter string="Not Held" domain="[('state','=','pending')]"
help="Phone calls which are in pending state"/>
<separator/>
<filter string="My Sales Team(s)" context="{'invisible_team': False}" domain="[('team_id.user_id','=',uid)]"
help="Phone calls that are assigned to one of the sale teams I manage" groups="base.group_multi_salesteams"/>
<separator/>
<field name="team_id" string="Sales Team" context="{'invisible_team': False}"
groups="base.group_multi_salesteams"/>
<field name="user_id" string="Salesperson"/>
<group expand="0" string="Extended Filters...">
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="opening_date"/>
<field name="date_closed"/>
</group>
<group expand="1" string="Group By">
<filter string="Salesperson" name="Salesperson" context="{'group_by':'user_id'}" />
<filter string="Sales Team" context="{'group_by':'team_id'}" groups="base.group_multi_salesteams"/>
<filter string="Customer" context="{'group_by':'partner_id'}" />
<filter string="Status" context="{'group_by':'state'}" />
<separator/>
<filter string="Creation Month" context="{'group_by':'create_date:month'}" help="Month of call"/>
</group>
</search>
</field>
</record>
<!-- Phone calls by user and team Action -->
<record id="action_report_crm_phonecall" model="ir.actions.act_window">
<field name="name">Phone Calls Analysis</field>
<field name="res_model">crm.phonecall.report</field>
<field name="view_type">form</field>
<field name="view_mode">pivot,graph</field>
<field name="context">{}</field>
<field name="search_view_id" ref="view_report_crm_phonecall_filter"/>
<field name="view_id"></field> <!-- force empty -->
<field name="help">From this report, you can analyse the performance of your sales team, based on their phone calls. You can group or filter the information according to several criteria and drill down the information, by adding more groups in the report.</field>
</record>
<record model="ir.actions.act_window.view" id="action_report_crm_phonecall_graph">
<field name="sequence" eval="2"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_crm_phonecall_graph"/>
<field name="act_window_id" ref="action_report_crm_phonecall"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_crm_phonecall_pivot">
<field name="sequence" eval="1"/>
<field name="view_mode">pivot</field>
<field name="view_id" ref="view_report_crm_phonecall_pivot"/>
<field name="act_window_id" ref="action_report_crm_phonecall"/>
</record>
<menuitem name="Phone Calls"
groups="base.group_sale_salesman"
action="action_report_crm_phonecall"
id="menu_report_crm_phonecalls_tree" parent="base.menu_sale_report" sequence="15"/>
</data>
</openerp>
+1 -4
View File
@@ -20,10 +20,7 @@ class crm_configuration(osv.TransientModel):
help='Allows you to communicate with Customer, process Customer query, and provide better help and support.\n'
'-This installs the module crm_helpdesk.'),
'alias_prefix': fields.char('Default Alias Name for Leads'),
'alias_domain' : fields.char('Alias Domain'),
'group_scheduled_calls': fields.boolean("Schedule calls to manage call center",
implied_group='crm.group_scheduled_calls',
help="""This adds the menu 'Scheduled Calls' under 'Sales / Phone Calls'""")
'alias_domain' : fields.char('Alias Domain')
}
_defaults = {
-9
View File
@@ -9,15 +9,6 @@
<data>
<div name="config_sale" position="inside">
<separator string="Sale Services"/>
<group>
<label for="id" string="Pre-Sale Services"/>
<div>
<div>
<field name="group_scheduled_calls" class="oe_inline"/>
<label for="group_scheduled_calls"/>
</div>
</div>
</group>
<group>
<label for="id" string="After-Sale Services"/>
<div>
+3 -8
View File
@@ -7,7 +7,7 @@ class res_partner(osv.osv):
""" Inherits partner and adds CRM information in the partner form """
_inherit = 'res.partner'
def _opportunity_meeting_phonecall_count(self, cr, uid, ids, field_name, arg, context=None):
def _opportunity_meeting_count(self, cr, uid, ids, field_name, arg, context=None):
res = dict(map(lambda x: (x,{'opportunity_count': 0, 'meeting_count': 0}), ids))
# the user may not have access rights for opportunities or meetings
try:
@@ -23,8 +23,6 @@ class res_partner(osv.osv):
}
except:
pass
for partner in self.browse(cr, uid, ids, context):
res[partner.id]['phonecall_count'] = len(partner.phonecall_ids)
return res
_columns = {
@@ -33,11 +31,8 @@ class res_partner(osv.osv):
'Opportunities', domain=[('type', '=', 'opportunity')]),
'meeting_ids': fields.many2many('calendar.event', 'calendar_event_res_partner_rel','res_partner_id', 'calendar_event_id',
'Meetings'),
'phonecall_ids': fields.one2many('crm.phonecall', 'partner_id',\
'Phonecalls'),
'opportunity_count': fields.function(_opportunity_meeting_phonecall_count, string="Opportunity", type='integer', multi='opp_meet'),
'meeting_count': fields.function(_opportunity_meeting_phonecall_count, string="# Meetings", type='integer', multi='opp_meet'),
'phonecall_count': fields.function(_opportunity_meeting_phonecall_count, string="Phonecalls", type="integer", multi='opp_meet'),
'opportunity_count': fields.function(_opportunity_meeting_count, string="Opportunity", type='integer', multi='opp_meet'),
'meeting_count': fields.function(_opportunity_meeting_count, string="# Meetings", type='integer', multi='opp_meet'),
}
def redirect_partner_form(self, cr, uid, partner_id, context=None):
+1 -7
View File
@@ -31,7 +31,7 @@
Use opportunities to keep track of your sales pipeline, follow
up potential sales and better forecast your future revenues.
</p><p>
You will be able to plan meetings and phone calls from
You will be able to plan meetings and log activities from
opportunities, convert them into quotations, attach related
documents, track all discussions, and much more.
</p>
@@ -99,12 +99,6 @@
context="{'partner_id': active_id}">
<field string="Meetings" name="meeting_count" widget="statinfo"/>
</button>
<button class="oe_stat_button" type="action"
name="%(crm.crm_phonecall_category_phone_incoming0)d"
icon="fa-phone"
context="{'search_default_partner_id': active_id, 'default_duration': 1.0}">
<field string="Calls" name="phonecall_count" widget="statinfo"/>
</button>
</div>
</data>
</field>
+1 -1
View File
@@ -53,7 +53,7 @@
Odoo helps you keep track of your sales pipeline to follow
up potential sales and better forecast your future revenues.
</p><p>
You will be able to plan meetings and phone calls from
You will be able to plan meetings and log activities from
opportunities, convert them into quotations, attach related
documents, track all discussions, and much more.
</p>
-18
View File
@@ -29,11 +29,6 @@
<field name="category_id" ref="base.module_category_hidden"/>
</record>
<record id="group_scheduled_calls" model="res.groups">
<field name="name">Show Scheduled Calls Menu</field>
<field name="category_id" ref="base.module_category_hidden"/>
</record>
<record model="res.users" id="base.user_root">
<field eval="[(4,ref('base.group_partner_manager'))]" name="groups_id"/>
</record>
@@ -70,19 +65,6 @@
<field name="domain_force">['|',('user_id','=',user.id),('show_as','=','busy')]</field>
</record>
<record id="crm_rule_personal_phonecall" model="ir.rule">
<field name="name">Personal Phone Calls</field>
<field ref="model_crm_phonecall" name="model_id"/>
<field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field>
<field name="groups" eval="[(4, ref('base.group_sale_salesman'))]"/>
</record>
<record id="crm_rule_all_phones" model="ir.rule">
<field name="name">All Phones</field>
<field ref="model_crm_phonecall" name="model_id"/>
<field name="domain_force">[(1,'=',1)]</field>
<field name="groups" eval="[(4, ref('base.group_sale_salesman_all_leads'))]"/>
</record>
<record id="crm_rule_personal_lead_report" model="ir.rule">
<field name="name">Personal Leads Analysis</field>
<field ref="model_crm_lead_report" name="model_id"/>
+4 -8
View File
@@ -1,12 +1,8 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_crm_lead_manager,crm.lead.manager,model_crm_lead,base.group_sale_manager,1,1,1,1
access_crm_phonecall_manager,crm.phonecall.manager,model_crm_phonecall,base.group_sale_manager,1,1,1,1
access_crm_lead,crm.lead,model_crm_lead,base.group_sale_salesman,1,1,1,0
access_crm_phonecall,crm.phonecall,model_crm_phonecall,base.group_sale_salesman,1,1,1,0
access_crm_stage,crm.stage,model_crm_stage,,1,0,0,0
access_crm_stage_manager,crm.stage,model_crm_stage,base.group_sale_manager,1,1,1,1
access_crm_phonecall_report_user,crm.phonecall.report.user,model_crm_phonecall_report,base.group_sale_salesman,1,0,0,0
access_crm_phonecall_report_manager,crm.phonecall.report,model_crm_phonecall_report,base.group_sale_manager,1,1,1,1
access_crm_opportunity_report_user,crm.opportunity.report,model_crm_opportunity_report,base.group_sale_salesman,1,0,0,0
access_crm_opportunity_report_manager,crm.opportunity.report,model_crm_opportunity_report,base.group_sale_manager,1,1,1,1
access_res_partner_manager,res.partner.crm.manager,base.model_res_partner,base.group_sale_manager,1,0,0,0
@@ -18,13 +14,13 @@ access_base_action_rule_manager,base.action.rule manager,base_action_rule.model_
access_crm_lead_report_user,crm.lead.report user,model_crm_lead_report,base.group_sale_salesman,1,1,1,1
access_res_partner_bank_type_crm_user,res.partner.bank.type.crm.user,base.model_res_partner_bank_type,base.group_sale_salesman,1,0,0,0
access_crm_lead_partner_manager,crm.lead.partner.manager,model_crm_lead,base.group_partner_manager,1,0,0,0
access_crm_phonecall_partner_manager,crm.phonecall.partner.manager,model_crm_phonecall,base.group_partner_manager,1,1,1,1
access_crm_lead_tag,crm_lead_tag,model_crm_lead_tag,base.group_user,1,0,0,0
access_crm_lead_tag_salesman,crm_lead_tag salesman,model_crm_lead_tag,base.group_sale_salesman,1,1,1,0
access_crm_lead_tag_manager,crm_lead_tag manager,model_crm_lead_tag,base.group_sale_manager,1,1,1,1
access_crm_phonecall_category,crm_phonecall_category,model_crm_phonecall_category,base.group_user,1,0,0,0
access_crm_phonecall_category_salesman,crm_phonecall_category salesman,model_crm_phonecall_category,base.group_sale_salesman,1,1,1,0
access_crm_phonecall_category_manager,crm_phonecall_category manager,model_crm_phonecall_category,base.group_sale_manager,1,1,1,1
access_crm_lost_reason_manager,crm.lost.reason.manager,model_crm_lost_reason,base.group_sale_manager,1,1,1,1
access_crm_lost_reason_salesman,crm.lost.reason.salesman,model_crm_lost_reason,base.group_sale_salesman,1,1,1,0
access_crm_lost_reason_user,crm.lost.reason.user,model_crm_lost_reason,base.group_user,1,0,0,0
access_crm_activity_user,crm.activity.user,model_crm_activity,base.group_user,1,1,1,0
access_crm_activity_manager,crm.activity.manager,model_crm_activity,base.group_sale_manager,1,1,1,1
access_crm_activity_salesman,crm.activity.salesman,model_crm_activity,base.group_sale_salesman,1,1,1,0
access_crm_activity_report_user,crm.activity.report.user,model_crm_activity_report,base.group_user,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_crm_lead_manager crm.lead.manager model_crm_lead base.group_sale_manager 1 1 1 1
access_crm_phonecall_manager crm.phonecall.manager model_crm_phonecall base.group_sale_manager 1 1 1 1
3 access_crm_lead crm.lead model_crm_lead base.group_sale_salesman 1 1 1 0
access_crm_phonecall crm.phonecall model_crm_phonecall base.group_sale_salesman 1 1 1 0
4 access_crm_stage crm.stage model_crm_stage 1 0 0 0
5 access_crm_stage_manager crm.stage model_crm_stage base.group_sale_manager 1 1 1 1
access_crm_phonecall_report_user crm.phonecall.report.user model_crm_phonecall_report base.group_sale_salesman 1 0 0 0
access_crm_phonecall_report_manager crm.phonecall.report model_crm_phonecall_report base.group_sale_manager 1 1 1 1
6 access_crm_opportunity_report_user crm.opportunity.report model_crm_opportunity_report base.group_sale_salesman 1 0 0 0
7 access_crm_opportunity_report_manager crm.opportunity.report model_crm_opportunity_report base.group_sale_manager 1 1 1 1
8 access_res_partner_manager res.partner.crm.manager base.model_res_partner base.group_sale_manager 1 0 0 0
14 access_crm_lead_report_user crm.lead.report user model_crm_lead_report base.group_sale_salesman 1 1 1 1
15 access_res_partner_bank_type_crm_user res.partner.bank.type.crm.user base.model_res_partner_bank_type base.group_sale_salesman 1 0 0 0
16 access_crm_lead_partner_manager crm.lead.partner.manager model_crm_lead base.group_partner_manager 1 0 0 0
access_crm_phonecall_partner_manager crm.phonecall.partner.manager model_crm_phonecall base.group_partner_manager 1 1 1 1
17 access_crm_lead_tag crm_lead_tag model_crm_lead_tag base.group_user 1 0 0 0
18 access_crm_lead_tag_salesman crm_lead_tag salesman model_crm_lead_tag base.group_sale_salesman 1 1 1 0
19 access_crm_lead_tag_manager crm_lead_tag manager model_crm_lead_tag base.group_sale_manager 1 1 1 1
access_crm_phonecall_category crm_phonecall_category model_crm_phonecall_category base.group_user 1 0 0 0
access_crm_phonecall_category_salesman crm_phonecall_category salesman model_crm_phonecall_category base.group_sale_salesman 1 1 1 0
access_crm_phonecall_category_manager crm_phonecall_category manager model_crm_phonecall_category base.group_sale_manager 1 1 1 1
20 access_crm_lost_reason_manager crm.lost.reason.manager model_crm_lost_reason base.group_sale_manager 1 1 1 1
21 access_crm_lost_reason_salesman crm.lost.reason.salesman model_crm_lost_reason base.group_sale_salesman 1 1 1 0
22 access_crm_lost_reason_user crm.lost.reason.user model_crm_lost_reason base.group_user 1 0 0 0
23 access_crm_activity_user crm.activity.user model_crm_activity base.group_user 1 1 1 0
24 access_crm_activity_manager crm.activity.manager model_crm_activity base.group_sale_manager 1 1 1 1
25 access_crm_activity_salesman crm.activity.salesman model_crm_activity base.group_sale_salesman 1 1 1 0
26 access_crm_activity_report_user crm.activity.report.user model_crm_activity_report base.group_user 1 0 0 0
+3 -3
View File
@@ -14,7 +14,7 @@
</div>
<div class="oe_span6">
<p class="oe_mt32">
Manage your sales funnel with no effort. Attract leads, follow-up on phone calls and meetings. Analyse the quality of your leads to make informed decisions and save time by integrating emails directly into the application.
Manage your sales funnel with no effort. Attract leads, follow-up on activities and meetings. Analyse the quality of your leads to make informed decisions and save time by integrating emails directly into the application.
</p>
<div class="oe_centeralign oe_websiteonly">
<a href="http://www.openerp.com/start?app=crm" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
@@ -69,7 +69,7 @@ Find duplicates, merge leads and assign them to the right salesperson in one ope
</div>
<div class="oe_span6">
<p class="oe_mt32">
Get your opportunities organized to stay focused on the best deals. Manage all your customer interactions from the opportunity like emails, phone calls, internal notes, meetings and quotations.
Get your opportunities organized to stay focused on the best deals. Manage all your customer interactions from the opportunity like emails, internal notes, meetings and quotations.
</p><p>
Follow opportunities that interest you to get notified upon specific events: deal won or lost, stage changed, new customer demand, etc.
</p>
@@ -105,7 +105,7 @@ Route, sort and filter incoming emails automatically. Odoo CRM handles incoming
</div>
<div class="oe_span6">
<p class="oe_mt32">
Schedule your meetings and phone calls using the integrated calendar. You can see your agenda and your colleagues' in one view. As a manager, it's easy to see what your team is busy with.
Schedule your meetings using the integrated calendar. You can see your agenda and your colleagues' in one view. As a manager, it's easy to see what your team is busy with.
</p>
</div>
</div>
-6
View File
@@ -17,9 +17,3 @@
type: opportunity
stage_id: crm.stage_lead1
opt_out: True
-
Sales manager create a phonecall record to call a partner onchange method.
-
!record {model: crm.phonecall, id: crm_phonecall_5}:
name: 'Bad time'
partner_id: base.res_partner_5
-9
View File
@@ -28,15 +28,6 @@
assert lead.type == 'opportunity', 'Lead is not converted to opportunity!'
assert lead.partner_id.id == ref("base.res_partner_2"), 'Partner mismatch!'
assert lead.stage_id.id == ref("stage_lead1"), 'Stage of opportunity is incorrect!'
-
Now I begin communication and schedule a phone call with the customer.
-
!python {model: crm.phonecall2phonecall}: |
import time
context.update({'active_model': 'crm.lead', 'active_ids': [ref('crm_case_3')],'active_id': ref('crm_case_3')})
call_id = self.create(cr, uid, {'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'name': "Bonjour M. Jean, Comment allez-vous? J'ai bien reçu votre demande, pourrions-nous en parler quelques minutes?"}, context=context)
self.action_schedule(cr, uid, [call_id], context=context)
-
Now I schedule meeting with customer.
-
-17
View File
@@ -1,17 +0,0 @@
-
Salesman check the phone calls data so test with the access rights of salesman.
-
!context
uid: 'crm_res_users_salesman'
-
I schedule a phone call with a customer.
-
!python {model: crm.phonecall2phonecall}: |
context.update({'active_model': 'crm.phonecall', 'active_ids': [ref("crm.crm_phonecall_6")], 'active_id': ref("crm.crm_phonecall_6")})
res_id = self.create(cr, uid, {'name': "Proposition de réduction"}, context=context)
self.action_schedule(cr, uid, [res_id], context=context)
-
I schedule a meeting based on this phone call.
-
!python {model: crm.phonecall}: |
self.action_make_meeting(cr, uid, [ref("crm.crm_phonecall_6")])
+67
View File
@@ -0,0 +1,67 @@
<?xml version="1.0"?>
<odoo>
<record id="crm_activity_view_search" model="ir.ui.view">
<field name="name">crm.activity.view.search</field>
<field name="model">crm.activity</field>
<field name="arch" type="xml">
<search string="Action Search">
<field name="name"/>
<field name="team_id"/>
</search>
</field>
</record>
<record id="crm_activity_view_form" model="ir.ui.view">
<field name="name">crm.activity.view.form</field>
<field name="model">crm.activity</field>
<field name="arch" type="xml">
<form string="Activities">
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name"/>
</h1>
<group>
<group>
<field name="team_id" groups="base.group_multi_salesteams"/>
<field name="description"/>
<field name="days"/>
</group><group>
<field name="activity_1_id"/>
<field name="activity_2_id"/>
<field name="activity_3_id"/>
</group>
</group>
</form>
</field>
</record>
<record id="crm_activity_view_tree" model="ir.ui.view">
<field name="name">crm.activity.view.tree</field>
<field name="model">crm.activity</field>
<field name="arch" type="xml">
<tree string="Activities">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="days"/>
<field name="team_id" groups="base.group_multi_salesteams"/>
</tree>
</field>
</record>
<record id="crm_activity_action" model="ir.actions.act_window">
<field name="name">Activities</field>
<field name="res_model">crm.activity</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new activity.
</p>
</field>
</record>
<menuitem id="crm_activity_menu" action="crm_activity_action"
name="Activities" parent="base.menu_crm_config_lead"/>
</odoo>
-1
View File
@@ -2,6 +2,5 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import crm_partner_binding
import crm_phonecall_to_phonecall
import crm_lead_to_opportunity
import crm_merge_opportunities
+1 -3
View File
@@ -36,11 +36,9 @@ class crm_partner_binding(osv.osv_memory):
partner_id = False
partner_obj = self.pool.get('res.partner')
# The active model has to be a lead or a phonecall
# The active model has to be a lead
if (context.get('active_model') == 'crm.lead') and context.get('active_id'):
active_model = self.pool.get('crm.lead').browse(cr, uid, context.get('active_id'), context=context)
elif (context.get('active_model') == 'crm.phonecall') and context.get('active_id'):
active_model = self.pool.get('crm.phonecall').browse(cr, uid, context.get('active_id'), context=context)
# Find the best matching partner for the active model
if (active_model):
@@ -1,42 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp.osv import osv
from openerp.tools.translate import _
class crm_phonecall2meeting(osv.osv_memory):
""" Phonecall to Meeting """
_name = 'crm.phonecall2meeting'
_description = 'Phonecall To Meeting'
def action_cancel(self, cr, uid, ids, context=None):
"""
Closes Phonecall to Meeting form
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param ids: List of Phonecall to Meeting IDs
@param context: A standard dictionary for contextual values
"""
return {'type':'ir.actions.act_window_close'}
def action_make_meeting(self, cr, uid, ids, context=None):
""" This opens Meeting's calendar view to schedule meeting on current Phonecall
@return : Dictionary value for created Meeting view
"""
res = {}
phonecall_id = context and context.get('active_id', False) or False
if phonecall_id:
phonecall = self.pool.get('crm.phonecall').browse(cr, uid, phonecall_id, context)
res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid, 'calendar', 'action_calendar_event', context)
res['context'] = {
'default_phonecall_id': phonecall.id,
'default_partner_id': phonecall.partner_id and phonecall.partner_id.id or False,
'default_user_id': uid,
'default_email_from': phonecall.email_from,
'default_state': 'open',
'default_name': phonecall.name,
}
return res
@@ -1,36 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- Phonecall to meeting view -->
<record model="ir.ui.view" id="phonecall2phonecall2meeting_view">
<field name="name">crm.phonecall2meeting.form</field>
<field name="model">crm.phonecall2meeting</field>
<field name="arch" type="xml">
<form string="Convert To Meeting">
<label string="Are you sure to schedule a Meeting for this Phonecall?"/>
<footer>
<button name="action_make_meeting" type="object"
string="_Schedule" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<!-- Phonecall to meeting action -->
<record model="ir.actions.act_window" id="phonecall2meeting_act">
<field name="name">Convert To Meeting</field>
<field name="res_model">crm.phonecall2meeting</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="phonecall2phonecall2meeting_view"/>
<field name="target">new</field>
</record>
</data>
</openerp>
@@ -1,79 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp.osv import fields, osv
from openerp.tools.translate import _
import time
class crm_phonecall2phonecall(osv.osv_memory):
_name = 'crm.phonecall2phonecall'
_description = 'Phonecall To Phonecall'
_columns = {
'name' : fields.char('Call summary', required=True, select=1),
'user_id' : fields.many2one('res.users',"Assign To"),
'contact_name':fields.char('Contact'),
'phone':fields.char('Phone'),
'categ_id': fields.many2one('crm.phonecall.category', 'Category'),
'date': fields.datetime('Date'),
'team_id':fields.many2one('crm.team','Sales Team', oldname='section_id'),
'action': fields.selection([('schedule','Schedule a call'), ('log','Log a call')], 'Action', required=True),
'partner_id' : fields.many2one('res.partner', "Partner"),
'note':fields.text('Note')
}
def action_cancel(self, cr, uid, ids, context=None):
"""
Closes Phonecall to Phonecall form
"""
return {'type':'ir.actions.act_window_close'}
def action_schedule(self, cr, uid, ids, context=None):
value = {}
if context is None:
context = {}
phonecall = self.pool.get('crm.phonecall')
phonecall_ids = context and context.get('active_ids') or []
for this in self.browse(cr, uid, ids, context=context):
phocall_ids = phonecall.schedule_another_phonecall(cr, uid, phonecall_ids, this.date, this.name, \
this.user_id and this.user_id.id or False, \
this.team_id and this.team_id.id or False, \
this.categ_id and this.categ_id.id or False, \
action=this.action, context=context)
return phonecall.redirect_phonecall_view(cr, uid, phocall_ids[phonecall_ids[0]], context=context)
def default_get(self, cr, uid, fields, context=None):
"""
This function gets default values
"""
res = super(crm_phonecall2phonecall, self).default_get(cr, uid, fields, context=context)
record_id = context and context.get('active_id', False) or False
res.update({'action': 'schedule', 'date': time.strftime('%Y-%m-%d %H:%M:%S')})
if record_id:
phonecall = self.pool.get('crm.phonecall').browse(cr, uid, record_id, context=context)
categ_id = False
data_obj = self.pool.get('ir.model.data')
try:
res_id = data_obj._get_id(cr, uid, 'crm', 'categ_phone2')
categ_id = data_obj.browse(cr, uid, res_id, context=context).res_id
except ValueError:
pass
if 'name' in fields:
res.update({'name': phonecall.name})
if 'user_id' in fields:
res.update({'user_id': phonecall.user_id and phonecall.user_id.id or False})
if 'date' in fields:
res.update({'date': False})
if 'team_id' in fields:
res.update({'team_id': phonecall.team_id and phonecall.team_id.id or False})
if 'categ_id' in fields:
res.update({'categ_id': categ_id})
if 'partner_id' in fields:
res.update({'partner_id': phonecall.partner_id and phonecall.partner_id.id or False})
return res
@@ -1,42 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- Phonecall to Phonecall view -->
<record model="ir.ui.view" id="phonecall_to_phonecall_view">
<field name="name">crm.phonecall2phonecall.form</field>
<field name="model">crm.phonecall2phonecall</field>
<field name="arch" type="xml">
<form string="Schedule/Log a Call">
<group col="4">
<field name="action"/>
<field name="name"/>
<field name="date" string="Planned Date" attrs="{'invisible': [('action','=','log')]}"/>
<field name="partner_id" readonly="True"/>
<field name="user_id" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_salesman_all_leads']}"/>
<field name="team_id" groups="base.group_multi_salesteams"/>
</group>
<footer>
<button name="action_schedule" type="object" string="Log Call" attrs="{'invisible' : [('action', '!=', 'log')]}" class="oe_highlight"/>
<button name="action_schedule" type="object" string="Schedule Call" attrs="{'invisible' : [('action', '!=', 'schedule')]}" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<!-- Phonecall to Phonecall action -->
<record model="ir.actions.act_window" id="phonecall_to_phonecall_act">
<field name="name">Schedule Other Call</field>
<field name="res_model">crm.phonecall2phonecall</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="phonecall_to_phonecall_view"/>
<field name="target">new</field>
</record>
</data>
</openerp>
@@ -50,16 +50,6 @@
</record>
<record model="gamification.goal.definition" id="definition_crm_nbr_call">
<field name="name">Logged Calls</field>
<field name="description">Log a certain number of calls to reach this goal</field>
<field name="computation_mode">count</field>
<field name="suffix">calls</field>
<field name="model_id" eval="ref('crm.model_crm_phonecall')" />
<field name="field_date_id" eval="ref('crm.field_crm_phonecall_date')" />
<field name="domain">[('user_id','=',user.id),('state','=','done')]</field>
</record>
<record model="gamification.goal.definition" id="definition_crm_nbr_new_opportunities">
<field name="name">New Opportunities</field>
<field name="description">Based on the opening date</field>