2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2006-12-07 13:41:40 +00:00
##############################################################################
2009-12-01 07:19:53 +00:00
#
2009-02-04 09:46:57 +00:00
# OpenERP, Open Source Management Solution
2010-01-12 09:18:39 +00:00
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2008-06-16 11:00:21 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is free software: you can redistribute it and/or modify
2009-10-14 11:15:34 +00:00
# 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.
2006-12-07 13:41:40 +00:00
#
2008-11-03 19:18:56 +00:00
# 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
2009-10-14 11:15:34 +00:00
# GNU Affero General Public License for more details.
2006-12-07 13:41:40 +00:00
#
2009-10-14 11:15:34 +00:00
# You should have received a copy of the GNU Affero General Public License
2009-12-01 07:19:53 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2006-12-07 13:41:40 +00:00
#
##############################################################################
2010-03-22 13:08:05 +00:00
import time
2010-07-06 11:46:25 +00:00
import base64
2010-03-22 13:08:05 +00:00
import tools
2010-12-10 17:54:55 +00:00
2010-02-16 13:57:41 +00:00
from osv import fields
from osv import osv
from tools . translate import _
2009-09-24 10:46:21 +00:00
2006-12-07 13:41:40 +00:00
MAX_LEVEL = 15
AVAILABLE_STATES = [
2011-09-14 13:11:11 +00:00
( ' draft ' , ' New ' ) ,
( ' open ' , ' In Progress ' ) ,
2010-06-10 13:04:07 +00:00
( ' cancel ' , ' Cancelled ' ) ,
( ' done ' , ' Closed ' ) ,
2010-04-28 07:20:02 +00:00
( ' pending ' , ' Pending ' ) ,
2006-12-07 13:41:40 +00:00
]
AVAILABLE_PRIORITIES = [
2010-04-28 07:20:02 +00:00
( ' 1 ' , ' Highest ' ) ,
2010-06-10 13:04:07 +00:00
( ' 2 ' , ' High ' ) ,
( ' 3 ' , ' Normal ' ) ,
( ' 4 ' , ' Low ' ) ,
( ' 5 ' , ' Lowest ' ) ,
2006-12-07 13:41:40 +00:00
]
2011-08-27 23:31:30 +00:00
class crm_case_channel ( osv . osv ) :
_name = " crm.case.channel "
_description = " Channels "
_order = ' name '
_columns = {
' name ' : fields . char ( ' Channel Name ' , size = 64 , required = True ) ,
' active ' : fields . boolean ( ' Active ' ) ,
}
_defaults = {
' active ' : lambda * a : 1 ,
}
2011-08-25 04:10:37 +00:00
class crm_case_stage ( osv . osv ) :
""" Stage of case """
_name = " crm.case.stage "
_description = " Stage of case "
_rec_name = ' name '
_order = " sequence "
_columns = {
' name ' : fields . char ( ' Stage Name ' , size = 64 , required = True , translate = True ) ,
' sequence ' : fields . integer ( ' Sequence ' , help = " Used to order stages. " ) ,
' probability ' : fields . float ( ' Probability ( % ) ' , required = True , help = " This percentage depicts the default/average probability of the Case for this stage to be a success " ) ,
' on_change ' : fields . boolean ( ' Change Probability Automatically ' , help = " Setting this stage will change the probability automatically on the opportunity. " ) ,
' requirements ' : fields . text ( ' Requirements ' ) ,
' section_ids ' : fields . many2many ( ' crm.case.section ' , ' section_stage_rel ' , ' stage_id ' , ' section_id ' , ' Sections ' ) ,
2011-10-01 21:15:29 +00:00
' case_default ' : fields . boolean ( ' Common to All Teams ' , help = " If you check this field, this stage will be proposed by default on each sales team. It will not assign this stage to existing teams. " ) ,
2011-08-25 04:10:37 +00:00
}
_defaults = {
' sequence ' : lambda * args : 1 ,
' probability ' : lambda * args : 0.0 ,
}
class crm_case_section ( osv . osv ) :
""" Sales Team """
_name = " crm.case.section "
_description = " Sales Teams "
_order = " complete_name "
def get_full_name ( self , cr , uid , ids , field_name , arg , context = None ) :
return dict ( self . name_get ( cr , uid , ids , context = context ) )
_columns = {
' name ' : fields . char ( ' Sales Team ' , size = 64 , required = True , translate = True ) ,
' complete_name ' : fields . function ( get_full_name , type = ' char ' , size = 256 , readonly = True , store = True ) ,
' code ' : fields . char ( ' Code ' , size = 8 ) ,
' active ' : fields . boolean ( ' Active ' , help = " If the active field is set to " \
" true, it will allow you to hide the sales team without removing it. " ) ,
' allow_unlink ' : fields . boolean ( ' Allow Delete ' , help = " Allows to delete non draft cases " ) ,
' change_responsible ' : fields . boolean ( ' Reassign Escalated ' , help = " When escalating to this team override the saleman with the team leader. " ) ,
' user_id ' : fields . many2one ( ' res.users ' , ' Team Leader ' ) ,
' member_ids ' : fields . many2many ( ' res.users ' , ' sale_member_rel ' , ' section_id ' , ' member_id ' , ' Team Members ' ) ,
' reply_to ' : fields . char ( ' Reply-To ' , size = 64 , help = " The email address put in the ' Reply-To ' of all emails sent by OpenERP about cases in this sales team " ) ,
' parent_id ' : fields . many2one ( ' crm.case.section ' , ' Parent Team ' ) ,
' child_ids ' : fields . one2many ( ' crm.case.section ' , ' parent_id ' , ' Child Teams ' ) ,
' resource_calendar_id ' : fields . many2one ( ' resource.calendar ' , " Working Time " , help = " Used to compute open days " ) ,
' note ' : fields . text ( ' Description ' ) ,
' working_hours ' : fields . float ( ' Working Hours ' , digits = ( 16 , 2 ) ) ,
' stage_ids ' : fields . many2many ( ' crm.case.stage ' , ' section_stage_rel ' , ' section_id ' , ' stage_id ' , ' Stages ' ) ,
}
2011-10-01 21:15:29 +00:00
def _get_stage_common ( self , cr , uid , context ) :
ids = self . pool . get ( ' crm.case.stage ' ) . search ( cr , uid , [ ( ' case_default ' , ' = ' , 1 ) ] , context = context )
return ids
2011-08-25 04:10:37 +00:00
_defaults = {
' active ' : lambda * a : 1 ,
' allow_unlink ' : lambda * a : 1 ,
2011-10-01 21:15:29 +00:00
' stage_ids ' : _get_stage_common
2011-08-25 04:10:37 +00:00
}
_sql_constraints = [
( ' code_uniq ' , ' unique (code) ' , ' The code of the sales team must be unique ! ' )
]
_constraints = [
2011-08-27 21:19:48 +00:00
( osv . osv . _check_recursion , ' Error ! You cannot create recursive Sales team. ' , [ ' parent_id ' ] )
2011-08-25 04:10:37 +00:00
]
def name_get ( self , cr , uid , ids , context = None ) :
2011-08-27 21:19:48 +00:00
""" Overrides orm name_get method """
2011-08-25 04:10:37 +00:00
if not isinstance ( ids , list ) :
ids = [ ids ]
res = [ ]
if not ids :
return res
reads = self . read ( cr , uid , ids , [ ' name ' , ' parent_id ' ] , context )
for record in reads :
name = record [ ' name ' ]
if record [ ' parent_id ' ] :
name = record [ ' parent_id ' ] [ 1 ] + ' / ' + name
res . append ( ( record [ ' id ' ] , name ) )
return res
class crm_case_categ ( osv . osv ) :
""" Category of Case """
_name = " crm.case.categ "
_description = " Category of Case "
_columns = {
' name ' : fields . char ( ' Name ' , size = 64 , required = True , translate = True ) ,
' section_id ' : fields . many2one ( ' crm.case.section ' , ' Sales Team ' ) ,
' object_id ' : fields . many2one ( ' ir.model ' , ' Object Name ' ) ,
}
def _find_object_id ( self , cr , uid , context = None ) :
2011-08-27 21:19:48 +00:00
""" Finds id for case object """
2011-08-25 04:10:37 +00:00
object_id = context and context . get ( ' object_id ' , False ) or False
ids = self . pool . get ( ' ir.model ' ) . search ( cr , uid , [ ( ' model ' , ' = ' , object_id ) ] )
2011-11-14 21:33:19 +00:00
return ids and ids [ 0 ] or False
2011-08-25 04:10:37 +00:00
_defaults = {
' object_id ' : _find_object_id
}
class crm_case_resource_type ( osv . osv ) :
""" Resource Type of case """
_name = " crm.case.resource.type "
_description = " Campaign "
_rec_name = " name "
_columns = {
' name ' : fields . char ( ' Campaign Name ' , size = 64 , required = True , translate = True ) ,
' section_id ' : fields . many2one ( ' crm.case.section ' , ' Sales Team ' ) ,
}
2011-05-31 13:32:32 +00:00
class crm_base ( object ) :
2011-08-25 04:10:37 +00:00
""" Base utility mixin class for crm objects,
Object subclassing this should define colums :
date_open
date_closed
user_id
partner_id
partner_address_id
2011-05-31 13:32:32 +00:00
"""
def _get_default_partner_address ( self , cr , uid , context = None ) :
""" Gives id of default address for current user
2011-06-29 11:05:31 +00:00
: param context : if portal in context is false return false anyway
2011-05-31 13:32:32 +00:00
"""
if context is None :
context = { }
2011-06-29 11:05:31 +00:00
if not context . get ( ' portal ' ) :
2011-05-31 13:32:32 +00:00
return False
2011-08-03 10:06:02 +00:00
# was user.address_id.id, but address_id has been removed
2011-08-09 23:44:28 +00:00
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context )
if hasattr ( user , ' partner_address_id ' ) and user . partner_address_id :
return user . partner_address_id
2011-08-03 05:42:15 +00:00
return False
2011-05-31 13:32:32 +00:00
def _get_default_partner ( self , cr , uid , context = None ) :
""" Gives id of partner for current user
2011-06-29 11:05:31 +00:00
: param context : if portal in context is false return false anyway
2011-05-31 13:32:32 +00:00
"""
if context is None :
context = { }
if not context . get ( ' portal ' , False ) :
return False
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context )
2011-08-09 23:44:28 +00:00
if hasattr ( user , ' partner_address_id ' ) and user . partner_address_id :
return user . partner_address_id
2011-08-03 10:06:02 +00:00
return user . company_id . partner_id . id
2011-08-25 04:10:37 +00:00
2011-05-31 13:32:32 +00:00
def _get_default_email ( self , cr , uid , context = None ) :
""" Gives default email address for current user
2011-06-29 11:05:31 +00:00
: param context : if portal in context is false return false anyway
2011-05-31 13:32:32 +00:00
"""
if not context . get ( ' portal ' , False ) :
return False
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context )
2011-07-28 06:11:56 +00:00
return user . user_email
2011-08-25 04:10:37 +00:00
2011-05-31 13:32:32 +00:00
def _get_default_user ( self , cr , uid , context = None ) :
""" Gives current user id
2011-06-29 11:05:31 +00:00
: param context : if portal in context is false return false anyway
2011-05-31 13:32:32 +00:00
"""
if context and context . get ( ' portal ' , False ) :
return False
return uid
def _get_section ( self , cr , uid , context = None ) :
""" Gives section id for current User
"""
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context )
return user . context_section_id . id or False
2011-08-25 04:10:37 +00:00
2011-05-31 13:32:32 +00:00
def onchange_partner_address_id ( self , cr , uid , ids , add , email = False ) :
""" This function returns value of partner email based on Partner Address
2011-08-09 23:44:28 +00:00
: param ids : List of case IDs
: param add : Id of Partner ' s address
: param email : Partner ' s email ID
2011-05-31 13:32:32 +00:00
"""
2011-10-25 09:18:37 +00:00
data = { ' value ' : { ' email_from ' : False , ' phone ' : False } }
if add :
address = self . pool . get ( ' res.partner.address ' ) . browse ( cr , uid , add )
data [ ' value ' ] = { ' email_from ' : address and address . email or False ,
' phone ' : address and address . phone or False }
2011-11-14 21:33:19 +00:00
if ' phone ' not in self . _columns :
del data [ ' value ' ] [ ' phone ' ]
2011-10-25 09:18:37 +00:00
return data
2011-08-25 04:10:37 +00:00
2011-05-31 13:32:32 +00:00
def onchange_partner_id ( self , cr , uid , ids , part , email = False ) :
""" This function returns value of partner address based on partner
2011-08-09 23:44:28 +00:00
: param ids : List of case IDs
: param part : Partner ' s id
: param email : Partner ' s email ID
2011-05-31 13:32:32 +00:00
"""
data = { }
if part :
addr = self . pool . get ( ' res.partner ' ) . address_get ( cr , uid , [ part ] , [ ' contact ' ] )
data = { ' partner_address_id ' : addr [ ' contact ' ] }
data . update ( self . onchange_partner_address_id ( cr , uid , ids , addr [ ' contact ' ] ) [ ' value ' ] )
return { ' value ' : data }
2011-08-25 04:10:37 +00:00
2011-05-31 13:32:32 +00:00
def case_open ( self , cr , uid , ids , * args ) :
""" Opens Case
2011-08-09 23:44:28 +00:00
: param ids : List of case Ids
2011-05-31 13:32:32 +00:00
"""
cases = self . browse ( cr , uid , ids )
for case in cases :
data = { ' state ' : ' open ' , ' active ' : True }
if not case . user_id :
data [ ' user_id ' ] = uid
self . write ( cr , uid , case . id , data )
self . _action ( cr , uid , cases , ' open ' )
return True
def case_close ( self , cr , uid , ids , * args ) :
""" Closes Case
2011-08-09 23:44:28 +00:00
: param ids : List of case Ids
2011-05-31 13:32:32 +00:00
"""
cases = self . browse ( cr , uid , ids )
cases [ 0 ] . state # to fill the browse record cache
2011-08-25 04:10:37 +00:00
self . write ( cr , uid , ids , { ' state ' : ' done ' , ' date_closed ' : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) , } )
2011-05-31 13:32:32 +00:00
# We use the cache of cases to keep the old case state
self . _action ( cr , uid , cases , ' done ' )
return True
def case_cancel ( self , cr , uid , ids , * args ) :
""" Cancels Case
2011-08-09 23:44:28 +00:00
: param ids : List of case Ids
2011-05-31 13:32:32 +00:00
"""
cases = self . browse ( cr , uid , ids )
cases [ 0 ] . state # to fill the browse record cache
2011-08-25 04:10:37 +00:00
self . write ( cr , uid , ids , { ' state ' : ' cancel ' , ' active ' : True } )
# We use the cache of cases to keep the old case state
2011-05-31 13:32:32 +00:00
self . _action ( cr , uid , cases , ' cancel ' )
return True
def case_pending ( self , cr , uid , ids , * args ) :
""" Marks case as pending
2011-08-09 23:44:28 +00:00
: param ids : List of case Ids
2011-05-31 13:32:32 +00:00
"""
cases = self . browse ( cr , uid , ids )
cases [ 0 ] . state # to fill the browse record cache
self . write ( cr , uid , ids , { ' state ' : ' pending ' , ' active ' : True } )
self . _action ( cr , uid , cases , ' pending ' )
return True
def case_reset ( self , cr , uid , ids , * args ) :
""" Resets case as draft
2011-08-09 23:44:28 +00:00
: param ids : List of case Ids
2011-05-31 13:32:32 +00:00
"""
cases = self . browse ( cr , uid , ids )
cases [ 0 ] . state # to fill the browse record cache
self . write ( cr , uid , ids , { ' state ' : ' draft ' , ' active ' : True } )
self . _action ( cr , uid , cases , ' draft ' )
return True
2011-08-09 23:44:28 +00:00
2011-05-31 13:32:32 +00:00
def _action ( self , cr , uid , cases , state_to , scrit = None , context = None ) :
if context is None :
context = { }
context [ ' state_to ' ] = state_to
rule_obj = self . pool . get ( ' base.action.rule ' )
model_obj = self . pool . get ( ' ir.model ' )
model_ids = model_obj . search ( cr , uid , [ ( ' model ' , ' = ' , self . _name ) ] )
rule_ids = rule_obj . search ( cr , uid , [ ( ' model_id ' , ' = ' , model_ids [ 0 ] ) ] )
return rule_obj . _action ( cr , uid , rule_ids , cases , scrit = scrit , context = context )
class crm_case ( crm_base ) :
2011-08-25 04:10:37 +00:00
""" A simple python class to be used for common functions
Object that inherit from this class should inherit from mailgate . thread
And need a stage_id field
And object that inherit ( orm inheritance ) from a class the overwrite copy
2011-05-31 13:32:32 +00:00
"""
2010-05-05 11:55:13 +00:00
2011-08-25 04:10:37 +00:00
def stage_find ( self , cr , uid , section_id , domain = [ ] , order = ' sequence ' ) :
domain = list ( domain )
if section_id :
domain . append ( ( ' section_ids ' , ' = ' , section_id ) )
stage_ids = self . pool . get ( ' crm.case.stage ' ) . search ( cr , uid , domain , order = order )
if stage_ids :
return stage_ids [ 0 ]
2011-09-13 08:52:49 +00:00
return False
2011-08-25 04:10:37 +00:00
def stage_set ( self , cr , uid , ids , stage_id , context = None ) :
value = { }
if hasattr ( self , ' onchange_stage_id ' ) :
value = self . onchange_stage_id ( cr , uid , ids , stage_id ) [ ' value ' ]
2011-08-25 04:54:55 +00:00
value [ ' stage_id ' ] = stage_id
2011-09-13 08:52:49 +00:00
return self . write ( cr , uid , ids , value , context = context )
2011-08-25 04:10:37 +00:00
def stage_change ( self , cr , uid , ids , op , order , context = None ) :
if context is None :
context = { }
for case in self . browse ( cr , uid , ids , context = context ) :
seq = 0
if case . stage_id :
seq = case . stage_id . sequence
section_id = None
if case . section_id :
section_id = case . section_id . id
next_stage_id = self . stage_find ( cr , uid , section_id , [ ( ' sequence ' , op , seq ) ] , order )
if next_stage_id :
2011-09-13 08:52:49 +00:00
return self . stage_set ( cr , uid , [ case . id ] , next_stage_id , context = context )
return False
2010-12-28 08:29:54 +00:00
2011-08-25 04:10:37 +00:00
def stage_next ( self , cr , uid , ids , context = None ) :
""" This function computes next stage for case from its current stage
using available stage for that case type
2010-12-16 10:28:40 +00:00
"""
2011-09-13 08:52:49 +00:00
return self . stage_change ( cr , uid , ids , ' > ' , ' sequence ' , context )
2011-02-18 09:54:19 +00:00
2011-08-25 04:10:37 +00:00
def stage_previous ( self , cr , uid , ids , context = None ) :
""" This function computes previous stage for case from its current
stage using available stage for that case type
2010-12-16 10:28:40 +00:00
"""
2011-09-13 08:52:49 +00:00
return self . stage_change ( cr , uid , ids , ' < ' , ' sequence desc ' , context )
2010-05-05 11:55:13 +00:00
2010-08-17 12:54:00 +00:00
def copy ( self , cr , uid , id , default = None , context = None ) :
2011-07-22 18:23:37 +00:00
""" Overrides orm copy method to avoid copying messages,
as well as date_closed and date_open columns if they
exist . """
2010-08-17 12:54:00 +00:00
if default is None :
default = { }
2011-08-25 04:10:37 +00:00
default . update ( { ' message_ids ' : [ ] , } )
2010-08-17 12:54:00 +00:00
if hasattr ( self , ' _columns ' ) :
if self . _columns . get ( ' date_closed ' ) :
2011-08-25 04:10:37 +00:00
default . update ( { ' date_closed ' : False , } )
2010-08-17 12:54:00 +00:00
if self . _columns . get ( ' date_open ' ) :
2011-08-25 04:10:37 +00:00
default . update ( { ' date_open ' : False } )
2011-08-16 10:32:48 +00:00
return super ( crm_case , self ) . copy ( cr , uid , id , default , context = context )
2011-02-18 09:54:19 +00:00
2010-06-10 13:04:07 +00:00
2010-05-05 11:55:13 +00:00
def case_open ( self , cr , uid , ids , * args ) :
2011-07-22 18:23:37 +00:00
""" Opens Case """
2010-05-05 11:55:13 +00:00
cases = self . browse ( cr , uid , ids )
2011-08-25 12:27:57 +00:00
self . message_append ( cr , uid , cases , _ ( ' Open ' ) )
2010-05-05 11:55:13 +00:00
for case in cases :
2011-08-25 04:10:37 +00:00
data = { ' state ' : ' open ' , ' active ' : True }
2010-05-05 11:55:13 +00:00
if not case . user_id :
data [ ' user_id ' ] = uid
self . write ( cr , uid , case . id , data )
2011-02-18 09:54:19 +00:00
self . _action ( cr , uid , cases , ' open ' )
2010-05-05 11:55:13 +00:00
return True
def case_close ( self , cr , uid , ids , * args ) :
2011-07-22 18:23:37 +00:00
""" Closes Case """
2010-05-05 11:55:13 +00:00
cases = self . browse ( cr , uid , ids )
cases [ 0 ] . state # to fill the browse record cache
2011-08-25 12:27:57 +00:00
self . message_append ( cr , uid , cases , _ ( ' Close ' ) )
2010-05-05 11:55:13 +00:00
self . write ( cr , uid , ids , { ' state ' : ' done ' ,
' date_closed ' : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) ,
} )
#
# We use the cache of cases to keep the old case state
#
self . _action ( cr , uid , cases , ' done ' )
return True
def case_escalate ( self , cr , uid , ids , * args ) :
2011-07-22 18:23:37 +00:00
""" Escalates case to parent level """
2010-05-05 11:55:13 +00:00
cases = self . browse ( cr , uid , ids )
for case in cases :
2010-07-09 10:27:44 +00:00
data = { ' active ' : True }
2010-05-05 11:55:13 +00:00
if case . section_id . parent_id :
data [ ' section_id ' ] = case . section_id . parent_id . id
2010-07-09 10:27:44 +00:00
if case . section_id . parent_id . change_responsible :
if case . section_id . parent_id . user_id :
data [ ' user_id ' ] = case . section_id . parent_id . user_id . id
2010-05-05 11:55:13 +00:00
else :
2010-06-10 13:04:07 +00:00
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You can not escalate, You are already at the top level regarding your sales-team category. ' ) )
2010-05-05 11:55:13 +00:00
self . write ( cr , uid , [ case . id ] , data )
cases = self . browse ( cr , uid , ids )
2011-08-25 12:27:57 +00:00
self . message_append ( cr , uid , cases , _ ( ' Escalate ' ) )
2010-05-05 11:55:13 +00:00
self . _action ( cr , uid , cases , ' escalate ' )
return True
2010-05-12 10:12:56 +00:00
2010-05-05 11:55:13 +00:00
def case_cancel ( self , cr , uid , ids , * args ) :
2011-07-22 18:23:37 +00:00
""" Cancels Case """
2010-05-05 11:55:13 +00:00
cases = self . browse ( cr , uid , ids )
cases [ 0 ] . state # to fill the browse record cache
2011-08-25 12:27:57 +00:00
self . message_append ( cr , uid , cases , _ ( ' Cancel ' ) )
2010-05-05 11:55:13 +00:00
self . write ( cr , uid , ids , { ' state ' : ' cancel ' ,
' active ' : True } )
self . _action ( cr , uid , cases , ' cancel ' )
2010-07-22 11:00:56 +00:00
for case in cases :
2010-10-16 14:02:41 +00:00
message = _ ( " The case ' %s ' has been cancelled. " ) % ( case . name , )
2010-07-22 11:00:56 +00:00
self . log ( cr , uid , case . id , message )
2010-05-05 11:55:13 +00:00
return True
def case_pending ( self , cr , uid , ids , * args ) :
2011-07-22 18:23:37 +00:00
""" Marks case as pending """
2010-05-05 11:55:13 +00:00
cases = self . browse ( cr , uid , ids )
cases [ 0 ] . state # to fill the browse record cache
2011-08-25 12:27:57 +00:00
self . message_append ( cr , uid , cases , _ ( ' Pending ' ) )
2010-05-05 11:55:13 +00:00
self . write ( cr , uid , ids , { ' state ' : ' pending ' , ' active ' : True } )
self . _action ( cr , uid , cases , ' pending ' )
return True
def case_reset ( self , cr , uid , ids , * args ) :
2011-07-22 18:23:37 +00:00
""" Resets case as draft """
2011-08-09 23:44:28 +00:00
state = ' draft '
2011-05-16 06:17:45 +00:00
if ' crm.phonecall ' in args :
2011-08-09 23:44:28 +00:00
state = ' open '
2010-05-05 11:55:13 +00:00
cases = self . browse ( cr , uid , ids )
cases [ 0 ] . state # to fill the browse record cache
2011-08-25 12:27:57 +00:00
self . message_append ( cr , uid , cases , _ ( ' Draft ' ) )
2011-05-16 06:17:45 +00:00
self . write ( cr , uid , ids , { ' state ' : state , ' active ' : True } )
self . _action ( cr , uid , cases , state )
2010-05-05 11:55:13 +00:00
return True
2010-06-10 13:04:07 +00:00
2010-11-19 13:48:01 +00:00
def remind_partner ( self , cr , uid , ids , context = None , attach = False ) :
2010-05-19 13:42:43 +00:00
return self . remind_user ( cr , uid , ids , context , attach ,
destination = False )
2010-11-23 11:31:52 +00:00
def remind_user ( self , cr , uid , ids , context = None , attach = False , destination = True ) :
2011-07-22 18:23:37 +00:00
mail_message = self . pool . get ( ' mail.message ' )
2010-11-19 13:48:01 +00:00
for case in self . browse ( cr , uid , ids , context = context ) :
2011-03-02 12:29:07 +00:00
if not destination and not case . email_from :
2011-04-20 15:29:55 +00:00
return False
2011-03-02 10:28:38 +00:00
if not case . user_id . user_email :
2011-04-20 15:29:55 +00:00
return False
2011-03-04 12:13:36 +00:00
if destination and case . section_id . user_id :
2011-03-02 12:29:07 +00:00
case_email = case . section_id . user_id . user_email
2011-03-02 10:28:38 +00:00
else :
2011-03-02 12:29:07 +00:00
case_email = case . user_id . user_email
2011-03-04 12:13:36 +00:00
src = case_email
2011-10-05 09:05:32 +00:00
dest = case . user_id . user_email or " "
2011-03-04 12:13:36 +00:00
body = case . description or " "
2011-04-22 11:41:11 +00:00
for message in case . message_ids :
2011-11-08 22:53:37 +00:00
if message . email_from :
2011-04-22 11:41:11 +00:00
body = message . description
break
2011-03-04 12:13:36 +00:00
if not destination :
src , dest = dest , case . email_from
if body and case . user_id . signature :
if body :
body + = ' \n \n %s ' % ( case . user_id . signature )
else :
body = ' \n \n %s ' % ( case . user_id . signature )
body = self . format_body ( body )
2011-04-20 09:54:58 +00:00
attach_to_send = { }
2011-03-04 12:13:36 +00:00
if attach :
attach_ids = self . pool . get ( ' ir.attachment ' ) . search ( cr , uid , [ ( ' res_model ' , ' = ' , self . _name ) , ( ' res_id ' , ' = ' , case . id ) ] )
attach_to_send = self . pool . get ( ' ir.attachment ' ) . read ( cr , uid , attach_ids , [ ' datas_fname ' , ' datas ' ] )
2011-04-20 09:54:58 +00:00
attach_to_send = dict ( map ( lambda x : ( x [ ' datas_fname ' ] , base64 . decodestring ( x [ ' datas ' ] ) ) , attach_to_send ) )
2010-05-19 13:42:43 +00:00
2011-04-06 05:45:13 +00:00
# Send an email
2011-03-29 12:27:36 +00:00
subject = " Reminder: [ %s ] %s " % ( str ( case . id ) , case . name , )
2011-07-22 18:23:37 +00:00
mail_message . schedule_with_attach ( cr , uid ,
2011-03-04 12:13:36 +00:00
src ,
[ dest ] ,
subject ,
body ,
2011-03-29 12:27:36 +00:00
model = ' crm.case ' ,
reply_to = case . section_id . reply_to ,
2011-08-22 17:16:59 +00:00
res_id = case . id ,
attachments = attach_to_send ,
context = context
2011-03-04 12:13:36 +00:00
)
2010-06-10 13:04:07 +00:00
return True
2010-05-19 13:42:43 +00:00
2010-11-19 13:48:01 +00:00
def _check ( self , cr , uid , ids = False , context = None ) :
2011-07-22 18:23:37 +00:00
""" Function called by the scheduler to process cases for date actions
Only works on not done and cancelled cases
2010-05-19 13:42:43 +00:00
"""
cr . execute ( ' select * from crm_case \
where ( date_action_last < % s or date_action_last is null ) \
and ( date_action_next < = % s or date_action_next is null ) \
and state not in ( \' cancel \' , \' done \' ) ' ,
( time . strftime ( " % Y- % m- %d % H: % M: % S " ) ,
time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) ) )
ids2 = map ( lambda x : x [ 0 ] , cr . fetchall ( ) or [ ] )
2010-11-19 13:48:01 +00:00
cases = self . browse ( cr , uid , ids2 , context = context )
2010-05-19 13:42:43 +00:00
return self . _action ( cr , uid , cases , False , context = context )
def format_body ( self , body ) :
return self . pool . get ( ' base.action.rule ' ) . format_body ( body )
def format_mail ( self , obj , body ) :
return self . pool . get ( ' base.action.rule ' ) . format_mail ( obj , body )
2010-05-05 11:55:13 +00:00
2011-08-23 17:58:09 +00:00
def message_thread_followers ( self , cr , uid , ids , context = None ) :
2010-08-17 13:00:44 +00:00
res = { }
for case in self . browse ( cr , uid , ids , context = context ) :
l = [ ]
if case . email_cc :
l . append ( case . email_cc )
2010-08-17 19:23:58 +00:00
if case . user_id and case . user_id . user_email :
l . append ( case . user_id . user_email )
2010-08-17 13:00:44 +00:00
res [ case . id ] = l
return res
2010-04-06 10:20:15 +00:00
def _links_get ( self , cr , uid , context = None ) :
2011-07-22 18:23:37 +00:00
""" Gets links value for reference field """
2008-07-22 15:11:28 +00:00
obj = self . pool . get ( ' res.request.link ' )
ids = obj . search ( cr , uid , [ ] )
res = obj . read ( cr , uid , ids , [ ' object ' , ' name ' ] , context )
return [ ( r [ ' object ' ] , r [ ' name ' ] ) for r in res ]
2006-12-07 13:41:40 +00:00
2010-01-11 09:20:00 +00:00
class users ( osv . osv ) :
_inherit = ' res.users '
_description = " Users "
2010-01-08 11:05:05 +00:00
_columns = {
2010-06-10 13:04:07 +00:00
' context_section_id ' : fields . many2one ( ' crm.case.section ' , ' Sales Team ' ) ,
2010-02-01 08:21:18 +00:00
}
2011-02-18 09:54:19 +00:00
def create ( self , cr , uid , vals , context = None ) :
res = super ( users , self ) . create ( cr , uid , vals , context = context )
2011-02-01 11:26:58 +00:00
section_obj = self . pool . get ( ' crm.case.section ' )
2011-07-22 18:23:37 +00:00
if vals . get ( ' context_section_id ' ) :
2011-02-18 09:54:19 +00:00
section_obj . write ( cr , uid , [ vals [ ' context_section_id ' ] ] , { ' member_ids ' : [ ( 4 , res ) ] } , context )
return res
2010-03-05 10:40:27 +00:00
2011-08-25 04:10:37 +00:00
users ( )
2011-11-22 08:51:38 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: