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
2010-01-12 09:18:39 +00:00
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
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
#
##############################################################################
2011-05-31 13:32:32 +00:00
from crm import crm_base
2009-12-30 10:20:44 +00:00
from osv import fields , osv
2010-04-01 11:31:30 +00:00
from tools . translate import _
2010-01-13 13:34:09 +00:00
import crm
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
2011-03-04 14:21:02 +00:00
from datetime import datetime
2010-01-11 13:16:46 +00:00
2011-05-31 13:32:32 +00:00
class crm_phonecall ( crm_base , osv . osv ) :
2010-03-22 10:40:26 +00:00
""" Phonecall Cases """
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-04-03 17:21:08 +00:00
_inherit = [ ' ir.needaction_mixin ' , ' mail.thread ' ]
2010-01-08 11:05:05 +00:00
_columns = {
2010-05-03 12:30:48 +00:00
# From crm.case
2011-10-12 11:11:42 +00:00
' id ' : fields . integer ( ' ID ' , readonly = True ) ,
2011-10-26 11:33:32 +00:00
' name ' : fields . char ( ' Call Summary ' , size = 64 , required = True ) ,
2011-02-07 05:51:57 +00:00
' active ' : fields . boolean ( ' Active ' , required = False ) ,
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 ' ) ,
' partner_id ' : fields . many2one ( ' res.partner ' , ' Partner ' ) ,
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' ) ,
' description ' : fields . text ( ' Description ' ) ,
2010-05-06 13:44:29 +00:00
' state ' : fields . selection ( [
2012-02-29 07:02:40 +00:00
( ' draft ' , ' Draft ' ) ,
( ' open ' , ' Todo ' ) ,
2011-05-17 13:28:30 +00:00
( ' pending ' , ' Not Held ' ) ,
2012-04-27 09:15:00 +00:00
( ' cancel ' , ' Cancelled ' ) ,
2012-04-27 09:51:37 +00:00
( ' done ' , ' Held ' ) ,
2012-05-04 11:57:48 +00:00
] , ' Status ' , size = 16 , readonly = True ,
2011-05-16 06:17:45 +00:00
help = ' The state is set to \' Todo \' , when a case is created. \
2010-05-03 13:41:42 +00:00
\nIf the case is in progress the state is set to \' Open \' . \
2011-08-09 23:44:28 +00:00
\nWhen the call is over , the state is set to \' Held \' . \
\nIf the call needs to be done then the state 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
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 ' ) ,
2011-07-22 18:23:37 +00:00
' message_ids ' : fields . one2many ( ' mail.message ' , ' res_id ' , ' Messages ' , domain = [ ( ' model ' , ' = ' , _name ) ] ) ,
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 = {
2011-02-07 05:51:57 +00:00
' date ' : lambda * a : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) ,
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 ,
2011-02-07 05:51:57 +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 ) :
2010-05-05 11:55:13 +00:00
""" Overrides close for crm_case for setting close date
2010-05-03 13:41:42 +00:00
"""
2011-03-03 10:40:25 +00:00
res = True
2010-07-13 10:05:22 +00:00
for phone in self . browse ( cr , uid , ids ) :
2011-03-04 14:21:02 +00:00
phone_id = phone . id
2010-07-13 10:05:22 +00:00
data = { ' date_closed ' : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) }
if phone . duration < = 0 :
duration = datetime . now ( ) - datetime . strptime ( phone . date , ' % Y- % m- %d % H: % M: % S ' )
data . update ( { ' duration ' : duration . seconds / float ( 60 ) } )
2012-03-06 09:18:55 +00:00
res = super ( crm_phonecall , self ) . case_close ( cr , uid , [ phone_id ] , context )
2011-03-04 14:21:02 +00:00
self . write ( cr , uid , [ phone_id ] , data )
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 )
2011-12-08 09:54:39 +00:00
self . write ( cr , uid , ids , { ' duration ' : 0.0 , ' state ' : ' open ' } )
2010-07-13 10:05:22 +00:00
return res
2012-03-06 09:18:55 +00:00
def case_open ( self , cr , uid , ids , context = None ) :
2010-05-05 11:55:13 +00:00
""" Overrides cancel for crm_case for setting Open Date
2010-05-03 13:41:42 +00:00
"""
2012-03-06 09:18:55 +00:00
res = super ( crm_phonecall , self ) . case_open ( cr , uid , ids , context )
2010-05-05 11:55:13 +00:00
self . write ( cr , uid , ids , { ' date_open ' : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) } )
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 = { }
for call in self . browse ( cr , uid , ids , context = context ) :
if action == ' create ' :
if not partner_id :
partner_id = 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 ) :
"""
This opens Meeting ' s calendar view to schedule meeting on current Phonecall
@return : Dictionary value for created Meeting view
"""
value = { }
2010-11-19 13:48:01 +00:00
for phonecall in self . browse ( cr , uid , ids , context = context ) :
2010-04-01 11:31:30 +00:00
data_obj = self . pool . get ( ' ir.model.data ' )
# Get meeting views
result = data_obj . _get_id ( cr , uid , ' crm ' , ' view_crm_case_meetings_filter ' )
res = data_obj . read ( cr , uid , result , [ ' res_id ' ] )
id1 = data_obj . _get_id ( cr , uid , ' crm ' , ' crm_case_calendar_view_meet ' )
id2 = data_obj . _get_id ( cr , uid , ' crm ' , ' crm_case_form_view_meet ' )
id3 = data_obj . _get_id ( cr , uid , ' crm ' , ' crm_case_tree_view_meet ' )
if id1 :
id1 = data_obj . browse ( cr , uid , id1 , context = context ) . res_id
if id2 :
id2 = data_obj . browse ( cr , uid , id2 , context = context ) . res_id
if id3 :
id3 = data_obj . browse ( cr , uid , id3 , context = context ) . res_id
context = {
2011-02-07 05:51:57 +00:00
' default_phonecall_id ' : phonecall . id ,
' default_partner_id ' : phonecall . partner_id and phonecall . partner_id . id or False ,
' default_email ' : phonecall . email_from ,
2010-04-01 11:31:30 +00:00
' default_name ' : phonecall . name
}
value = {
2011-02-07 05:51:57 +00:00
' name ' : _ ( ' Meetings ' ) ,
' domain ' : " [( ' user_id ' , ' = ' , %s )] " % ( uid ) ,
' context ' : context ,
' view_type ' : ' form ' ,
' view_mode ' : ' calendar,form,tree ' ,
' res_model ' : ' crm.meeting ' ,
' view_id ' : False ,
' views ' : [ ( id1 , ' calendar ' ) , ( id2 , ' form ' ) , ( id3 , ' tree ' ) ] ,
' type ' : ' ir.actions.act_window ' ,
' search_view_id ' : res [ ' res_id ' ] ,
2010-04-01 11:31:30 +00:00
' nodestroy ' : True
}
return value
2012-04-03 07:35:33 +00:00
# ----------------------------------------
# OpenChatter methods and notifications
# ----------------------------------------
def get_needaction_user_ids ( self , cr , uid , ids , context = None ) :
result = dict . fromkeys ( ids )
for obj in self . browse ( cr , uid , ids , context = context ) :
result [ obj . id ] = [ ]
if ( obj . state == ' draft ' and obj . user_id ) :
result [ obj . id ] = [ obj . user_id . id ]
return result
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>. ' )
return self . message_append_note ( cr , uid , ids , body = message , context = context )
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 ) :
phonecall . message_subscribe ( [ phonecall . user_id . id ] , 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>. " )
phonecall . message_append_note ( body = message )
return True
def _call_set_partner_send_note ( self , cr , uid , ids , context = None ) :
return self . message_append_note ( cr , uid , ids , body = _ ( " Partner has been <b>created</b> " ) , context = context )
2010-04-01 11:31:30 +00:00
2009-12-31 12:57:20 +00:00
crm_phonecall ( )
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: