2009-12-30 10:20:44 +00:00
# -*- coding: utf-8 -*-
##############################################################################
2010-01-08 11:05:05 +00:00
#
2009-12-30 10:20:44 +00:00
# OpenERP, Open Source Management Solution
2012-05-22 07:41:49 +00:00
# Copyright (C) 2004-today OpenERP SA (<http://www.openerp.com>)
2009-12-30 10:20:44 +00:00
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
2010-01-08 11:05:05 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2009-12-30 10:20:44 +00:00
#
##############################################################################
2012-05-29 14:03:14 +00:00
from base_status . base_state import base_state
2010-01-13 13:34:09 +00:00
import crm
2012-05-22 07:41:49 +00:00
from datetime import datetime
2009-12-30 10:20:44 +00:00
from osv import fields , osv
2010-02-28 20:36:51 +00:00
import time
2012-04-18 13:41:43 +00:00
from tools import DEFAULT_SERVER_DATE_FORMAT , DEFAULT_SERVER_DATETIME_FORMAT , DATETIME_FORMATS_MAP
2012-05-22 07:41:49 +00:00
from tools . translate import _
2010-03-22 10:40:26 +00:00
2012-05-29 14:03:14 +00:00
class crm_phonecall ( base_state , osv . osv ) :
2012-05-23 15:06:25 +00:00
""" Model for CRM phonecalls """
2009-12-30 10:20:44 +00:00
_name = " crm.phonecall "
2010-05-19 18:32:32 +00:00
_description = " Phonecall "
2009-12-30 10:20:44 +00:00
_order = " id desc "
2012-08-15 10:29:19 +00:00
_inherit = [ ' mail.thread ' ]
2010-01-08 11:05:05 +00:00
_columns = {
2012-05-23 15:06:25 +00:00
# base_state required fields
2010-05-26 12:13:46 +00:00
' date_action_last ' : fields . datetime ( ' Last Action ' , readonly = 1 ) ,
2011-02-07 05:51:57 +00:00
' date_action_next ' : fields . datetime ( ' Next Action ' , readonly = 1 ) ,
2010-05-26 12:13:46 +00:00
' create_date ' : fields . datetime ( ' Creation Date ' , readonly = True ) ,
2010-05-03 12:30:48 +00:00
' section_id ' : fields . many2one ( ' crm.case.section ' , ' Sales Team ' , \
2011-02-07 05:51:57 +00:00
select = True , help = ' Sales team to which Case belongs to. ' ) ,
' user_id ' : fields . many2one ( ' res.users ' , ' Responsible ' ) ,
2012-07-03 13:02:06 +00:00
' partner_id ' : fields . many2one ( ' res.partner ' , ' Contact ' ) ,
2011-02-07 05:51:57 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' ) ,
' description ' : fields . text ( ' Description ' ) ,
2012-05-23 15:06:25 +00:00
' state ' : fields . selection ( [ ( ' draft ' , ' Draft ' ) ,
( ' open ' , ' Confirmed ' ) ,
2011-05-17 13:28:30 +00:00
( ' pending ' , ' Not Held ' ) ,
2012-02-29 07:02:40 +00:00
( ' cancel ' , ' Cancelled ' ) ,
2012-05-23 15:06:25 +00:00
( ' done ' , ' Held ' ) , ] ,
string = ' Status ' , size = 16 , readonly = True ,
2012-10-12 12:45:13 +00:00
help = ' The status is set to \' Todo \' , when a case is created. \
If the case is in progress the status is set to \' Open \' . \
When the call is over , the status is set to \' Held \' . \
If the call needs to be done then the status is set to \' Not Held \' . ' ) ,
2011-02-07 05:51:57 +00:00
' email_from ' : fields . char ( ' Email ' , size = 128 , help = " These people will receive email. " ) ,
2010-05-06 10:27:00 +00:00
' date_open ' : fields . datetime ( ' Opened ' , readonly = True ) ,
2010-05-03 12:30:48 +00:00
# phonecall fields
2012-05-23 15:06:25 +00:00
' name ' : fields . char ( ' Call Summary ' , size = 64 , required = True ) ,
' active ' : fields . boolean ( ' Active ' , required = False ) ,
2011-02-07 05:51:57 +00:00
' duration ' : fields . float ( ' Duration ' , help = " Duration in Minutes " ) ,
2010-03-22 10:40:26 +00:00
' categ_id ' : fields . many2one ( ' crm.case.categ ' , ' Category ' , \
2010-09-28 22:03:25 +00:00
domain = " [ ' | ' ,( ' section_id ' , ' = ' ,section_id),( ' section_id ' , ' = ' ,False), \
2011-02-07 05:51:57 +00:00
( ' object_id.model ' , ' = ' , ' crm.phonecall ' ) ] " ),
' partner_phone ' : fields . char ( ' Phone ' , size = 32 ) ,
' partner_mobile ' : fields . char ( ' Mobile ' , size = 32 ) ,
' priority ' : fields . selection ( crm . AVAILABLE_PRIORITIES , ' Priority ' ) ,
2012-02-28 13:38:04 +00:00
' date_closed ' : fields . datetime ( ' Closed ' , readonly = True ) ,
' date ' : fields . datetime ( ' Date ' ) ,
' opportunity_id ' : fields . many2one ( ' crm.lead ' , ' Lead/Opportunity ' ) ,
2009-12-30 10:20:44 +00:00
}
2010-03-22 10:40:26 +00:00
2011-04-14 11:57:33 +00:00
def _get_default_state ( self , cr , uid , context = None ) :
if context and context . get ( ' default_state ' , False ) :
return context . get ( ' default_state ' )
return ' open '
2010-02-28 13:21:56 +00:00
_defaults = {
2012-05-23 15:06:25 +00:00
' date ' : fields . datetime . now ,
2012-02-29 07:02:40 +00:00
' priority ' : crm . AVAILABLE_PRIORITIES [ 2 ] [ 0 ] ,
' state ' : _get_default_state ,
2010-05-31 17:09:19 +00:00
' user_id ' : lambda self , cr , uid , ctx : uid ,
2012-08-06 05:52:13 +00:00
' active ' : 1
2010-02-28 13:21:56 +00:00
}
2011-02-07 05:51:57 +00:00
2012-03-13 10:55:28 +00:00
def create ( self , cr , uid , vals , context = None ) :
obj_id = super ( crm_phonecall , self ) . create ( cr , uid , vals , context )
for phonecall in self . browse ( cr , uid , [ obj_id ] , context = context ) :
if not phonecall . opportunity_id :
self . case_open_send_note ( cr , uid , [ obj_id ] , context = context )
return obj_id
2012-03-06 09:18:55 +00:00
def case_close ( self , cr , uid , ids , context = None ) :
2012-05-29 14:56:55 +00:00
""" Overrides close for crm_case for setting duration """
2011-03-03 10:40:25 +00:00
res = True
2012-05-29 14:56:55 +00:00
for phone in self . browse ( cr , uid , ids , context = context ) :
2011-03-04 14:21:02 +00:00
phone_id = phone . id
2012-05-29 14:56:55 +00:00
data = { }
2010-07-13 10:05:22 +00:00
if phone . duration < = 0 :
2012-05-29 14:56:55 +00:00
duration = datetime . now ( ) - datetime . strptime ( phone . date , DEFAULT_SERVER_DATETIME_FORMAT )
2012-05-29 15:02:16 +00:00
data [ ' duration ' ] = duration . seconds / float ( 60 )
2012-05-29 14:56:55 +00:00
res = super ( crm_phonecall , self ) . case_close ( cr , uid , [ phone_id ] , context = context )
self . write ( cr , uid , [ phone_id ] , data , context = context )
2010-05-05 11:55:13 +00:00
return res
2010-05-03 13:41:42 +00:00
2012-03-06 09:18:55 +00:00
def case_reset ( self , cr , uid , ids , context = None ) :
2011-05-16 06:17:45 +00:00
""" Resets case as Todo
2010-07-13 10:05:22 +00:00
"""
2012-03-06 09:18:55 +00:00
res = super ( crm_phonecall , self ) . case_reset ( cr , uid , ids , context )
2012-05-29 14:56:55 +00:00
self . write ( cr , uid , ids , { ' duration ' : 0.0 , ' state ' : ' open ' } , context = context )
2010-05-05 11:55:13 +00:00
return res
2010-03-22 10:40:26 +00:00
2011-10-24 13:30:10 +00:00
def schedule_another_phonecall ( self , cr , uid , ids , schedule_time , call_summary , \
user_id = False , section_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 :
res_id = model_data . _get_id ( cr , uid , ' crm ' , ' categ_phone2 ' )
if res_id :
categ_id = model_data . browse ( cr , uid , res_id , context = context ) . res_id
for call in self . browse ( cr , uid , ids , context = context ) :
if not section_id :
section_id = call . section_id and call . section_id . id or False
if not user_id :
user_id = call . user_id and call . user_id . id or False
vals = {
' name ' : call_summary ,
' user_id ' : user_id or False ,
2011-11-02 05:30:58 +00:00
' categ_id ' : categ_id or False ,
2011-10-24 13:30:10 +00:00
' description ' : call . description or False ,
' date ' : schedule_time ,
' section_id ' : section_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 ,
}
new_id = self . create ( cr , uid , vals , context = context )
if action == ' log ' :
self . case_close ( cr , uid , [ new_id ] )
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
2011-10-26 16:30:04 +00:00
def _call_set_partner ( self , cr , uid , ids , partner_id , context = None ) :
2012-03-20 13:24:56 +00:00
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
2011-10-24 13:30:10 +00:00
def _call_create_partner_address ( self , cr , uid , phonecall , partner_id , context = None ) :
2012-02-29 12:41:42 +00:00
address = self . pool . get ( ' res.partner ' )
2011-10-24 13:30:10 +00:00
return address . create ( cr , uid , {
2012-03-05 11:03:46 +00:00
' parent_id ' : partner_id ,
2011-10-24 13:30:10 +00:00
' name ' : phonecall . name ,
' phone ' : phonecall . partner_phone ,
} )
2011-10-26 16:30:04 +00:00
def convert_partner ( self , cr , uid , ids , action = ' create ' , partner_id = False , context = None ) :
2011-10-24 13:30:10 +00:00
"""
This function convert partner based on action .
if action is ' create ' , create new partner with contact and assign lead to new partner_id .
otherwise assign lead to specified partner_id
"""
if context is None :
context = { }
partner_ids = { }
2012-08-23 20:06:29 +00:00
force_partner_id = partner_id
2011-10-24 13:30:10 +00:00
for call in self . browse ( cr , uid , ids , context = context ) :
if action == ' create ' :
2012-08-23 20:06:29 +00:00
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 )
2011-10-26 16:30:04 +00:00
self . _call_set_partner ( cr , uid , [ call . id ] , partner_id , context = context )
2011-10-24 13:30:10 +00:00
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
2011-11-03 06:14:32 +00:00
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 ' )
2011-10-24 13:30:10 +00:00
value = {
' name ' : _ ( ' Phone Call ' ) ,
' view_type ' : ' form ' ,
' view_mode ' : ' tree,form ' ,
' res_model ' : ' crm.phonecall ' ,
' res_id ' : int ( phonecall_id ) ,
2011-11-03 06:14:32 +00:00
' views ' : [ ( form_view and form_view [ 1 ] or False , ' form ' ) , ( tree_view and tree_view [ 1 ] or False , ' tree ' ) , ( False , ' calendar ' ) ] ,
2011-10-24 13:30:10 +00:00
' type ' : ' ir.actions.act_window ' ,
2011-11-03 06:14:32 +00:00
' search_view_id ' : search_view and search_view [ 1 ] or False ,
2011-10-24 13:30:10 +00:00
}
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 = { }
2011-11-01 13:14:21 +00:00
default_contact = False
2011-10-24 13:30:10 +00:00
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 :
2012-02-29 12:41:42 +00:00
default_contact = partner . browse ( cr , uid , address_id , context = context )
2011-10-24 13:30:10 +00:00
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 ,
' section_id ' : call . section_id and call . section_id . id or False ,
' description ' : call . description or False ,
' priority ' : call . priority ,
2012-02-29 07:02:40 +00:00
' type ' : ' opportunity ' ,
2011-10-24 13:30:10 +00:00
' phone ' : call . partner_phone or False ,
2012-01-11 12:01:22 +00:00
' email_from ' : default_contact and default_contact . email ,
2011-10-24 13:30:10 +00:00
} )
vals = {
' partner_id ' : partner_id ,
' opportunity_id ' : opportunity_id ,
}
self . write ( cr , uid , [ call . id ] , vals )
self . case_close ( cr , uid , [ call . id ] )
opportunity . case_open ( cr , uid , [ opportunity_id ] )
opportunity_dict [ call . id ] = opportunity_id
2012-02-29 07:02:40 +00:00
return opportunity_dict
2011-10-24 13:30:10 +00:00
2010-04-01 11:31:30 +00:00
def action_make_meeting ( self , cr , uid , ids , context = None ) :
2012-07-06 12:29:59 +00:00
""" This opens Meeting ' s calendar view to schedule meeting on current Phonecall
@return : Dictionary value for created Meeting view
2010-04-01 11:31:30 +00:00
"""
2012-07-06 12:29:59 +00:00
phonecall = self . browse ( cr , uid , ids [ 0 ] , context )
res = self . pool . get ( ' ir.actions.act_window ' ) . for_xml_id ( cr , uid , ' base_calendar ' , ' action_crm_meeting ' , 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
2012-04-03 07:35:33 +00:00
# ----------------------------------------
2012-05-23 15:06:25 +00:00
# OpenChatter
2012-04-03 07:35:33 +00:00
# ----------------------------------------
def case_get_note_msg_prefix ( self , cr , uid , id , context = None ) :
return ' Phonecall '
def case_reset_send_note ( self , cr , uid , ids , context = None ) :
message = _ ( ' Phonecall has been <b>reset and set as open</b>. ' )
2012-08-17 10:03:02 +00:00
return self . message_post ( cr , uid , ids , body = message , context = context )
2012-04-03 07:35:33 +00:00
def case_open_send_note ( self , cr , uid , ids , context = None ) :
lead_obj = self . pool . get ( ' crm.lead ' )
for phonecall in self . browse ( cr , uid , ids , context = context ) :
if phonecall . opportunity_id :
lead = phonecall . opportunity_id
2012-04-18 12:31:50 +00:00
# convert datetime field to a datetime, using server format, then
# convert it to the user TZ and re-render it with %Z to add the timezone
2012-04-18 13:41:43 +00:00
phonecall_datetime = fields . DT . datetime . strptime ( phonecall . date , DEFAULT_SERVER_DATETIME_FORMAT )
phonecall_date_str = fields . datetime . context_timestamp ( cr , uid , phonecall_datetime , context = context ) . strftime ( DATETIME_FORMATS_MAP [ ' % + ' ] + " ( % Z) " )
2012-04-18 12:31:50 +00:00
message = _ ( " Phonecall linked to the opportunity <em> %s </em> has been <b>created</b> and <b>scheduled</b> on <em> %s </em>. " ) % ( lead . name , phonecall_date_str )
2012-04-03 07:35:33 +00:00
else :
message = _ ( " Phonecall has been <b>created and opened</b>. " )
2012-08-17 10:03:02 +00:00
phonecall . message_post ( body = message )
2012-04-03 07:35:33 +00:00
return True
def _call_set_partner_send_note ( self , cr , uid , ids , context = None ) :
2012-08-17 10:03:02 +00:00
return self . message_post ( cr , uid , ids , body = _ ( " Partner has been <b>created</b>. " ) , context = context )
2009-12-31 12:57:20 +00:00
2010-05-13 14:15:36 +00:00
2010-04-07 07:03:45 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: