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
2012-05-22 08:14:13 +00:00
# Copyright (C) 2004-today OpenERP SA (<http://www.openerp.com>)
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-07-06 11:46:25 +00:00
import base64
2012-05-29 14:55:35 +00:00
import time
2012-06-27 10:20:05 +00:00
from lxml import etree
2010-02-16 13:57:41 +00:00
from osv import fields
from osv import osv
2012-05-29 14:55:35 +00:00
import tools
2010-02-16 13:57:41 +00:00
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 ' ) ,
2010-06-10 13:04:07 +00:00
( ' cancel ' , ' Cancelled ' ) ,
2011-09-14 13:11:11 +00:00
( ' open ' , ' In Progress ' ) ,
2010-04-28 07:20:02 +00:00
( ' pending ' , ' Pending ' ) ,
2012-05-01 11:11:34 +00:00
( ' done ' , ' Closed ' )
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 ) :
2012-05-22 08:14:13 +00:00
""" Model for case stages. This models the main stages of a document
2012-10-02 10:29:15 +00:00
management flow . Main CRM objects ( leads , opportunities , project
2012-05-22 08:14:13 +00:00
issues , . . . ) will now use only stages , instead of state and stages .
Stages are for example used to display the kanban view of records .
"""
2011-08-25 04:10:37 +00:00
_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 ) ,
2012-05-22 08:14:13 +00:00
' sequence ' : fields . integer ( ' Sequence ' , help = " Used to order stages. Lower is better. " ) ,
2011-08-25 04:10:37 +00:00
' 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 ' ) ,
2012-05-22 08:14:13 +00:00
' section_ids ' : fields . many2many ( ' crm.case.section ' , ' section_stage_rel ' , ' stage_id ' , ' section_id ' , string = ' Sections ' ,
help = " Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams. " ) ,
2012-09-12 13:35:37 +00:00
' state ' : fields . selection ( AVAILABLE_STATES , ' Related Status ' , required = True ,
help = " The status of your document will automatically change regarding the selected stage. " \
2012-10-12 11:42:58 +00:00
" For example, if a stage is related to the status ' Close ' , when your document reaches this stage, it is automatically closed. " ) ,
2012-05-25 15:19:59 +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. " ) ,
' fold ' : fields . boolean ( ' Hide in Views when Empty ' ,
help = " This stage is not visible, for example in status bar or kanban view, when there are no records in that stage to display. " ) ,
2012-05-24 09:10:24 +00:00
' type ' : fields . selection ( [ ( ' lead ' , ' Lead ' ) ,
( ' opportunity ' , ' Opportunity ' ) ,
( ' both ' , ' Both ' ) ] ,
string = ' Type ' , size = 16 , required = True ,
help = " This field is used to distinguish stages related to Leads from stages related to Opportunities, or to specify stages available for both types. " ) ,
2011-08-25 04:10:37 +00:00
}
_defaults = {
' sequence ' : lambda * args : 1 ,
' probability ' : lambda * args : 0.0 ,
2012-08-28 11:32:41 +00:00
' state ' : ' open ' ,
2012-05-22 14:11:27 +00:00
' fold ' : False ,
2012-05-24 09:10:24 +00:00
' type ' : ' both ' ,
2012-08-28 11:32:41 +00:00
' case_default ' : True ,
2011-08-25 04:10:37 +00:00
}
class crm_case_section ( osv . osv ) :
2012-05-22 08:14:13 +00:00
""" Model for sales teams. """
2011-08-25 04:10:37 +00:00
_name = " crm.case.section "
2012-06-26 11:21:09 +00:00
_inherits = { ' mail.alias ' : ' alias_id ' }
2012-09-24 12:51:39 +00:00
_inherit = " mail.thread "
2011-08-25 04:10:37 +00:00
_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. " ) ,
2012-07-13 10:17:51 +00:00
' change_responsible ' : fields . boolean ( ' Reassign Escalated ' , help = " When escalating to this team override the salesman with the team leader. " ) ,
2011-08-25 04:10:37 +00:00
' 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 ' ) ,
2012-10-02 10:29:15 +00:00
' alias_id ' : fields . many2one ( ' mail.alias ' , ' Alias ' , ondelete = " cascade " , required = True ,
2012-08-01 09:14:39 +00:00
help = " The email address associated with this team. New emails received will automatically "
" create new leads assigned to the team. " ) ,
2011-08-25 04:10:37 +00:00
}
2012-10-02 10:29:15 +00:00
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 = {
2012-08-14 10:51:14 +00:00
' active ' : 1 ,
' stage_ids ' : _get_stage_common ,
' alias_domain ' : False , # always hide alias during creation
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 """
2012-02-23 10:46:41 +00:00
if not isinstance ( ids , list ) :
2011-08-25 04:10:37 +00:00
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
2012-06-26 11:21:09 +00:00
def create ( self , cr , uid , vals , context = None ) :
2012-08-07 14:08:21 +00:00
mail_alias = self . pool . get ( ' mail.alias ' )
2012-06-27 08:35:52 +00:00
if not vals . get ( ' alias_id ' ) :
2012-08-07 14:08:21 +00:00
vals . pop ( ' alias_name ' , None ) # prevent errors during copy()
2012-10-02 10:29:15 +00:00
alias_id = mail_alias . create_unique_alias ( cr , uid ,
2012-08-07 14:08:21 +00:00
{ ' alias_name ' : vals [ ' name ' ] } ,
2012-08-06 00:44:17 +00:00
model_name = " crm.lead " ,
context = context )
vals [ ' alias_id ' ] = alias_id
2012-07-04 08:37:54 +00:00
res = super ( crm_case_section , self ) . create ( cr , uid , vals , context )
2012-08-07 14:08:21 +00:00
mail_alias . write ( cr , uid , [ vals [ ' alias_id ' ] ] , { ' alias_defaults ' : { ' section_id ' : res , ' type ' : ' lead ' } } , context )
2012-07-04 08:37:54 +00:00
return res
2012-10-02 10:29:15 +00:00
2012-07-05 12:54:17 +00:00
def unlink ( self , cr , uid , ids , context = None ) :
2012-07-05 14:17:06 +00:00
# Cascade-delete mail aliases as well, as they should not exist without the sales team.
mail_alias = self . pool . get ( ' mail.alias ' )
alias_ids = [ team . alias_id . id for team in self . browse ( cr , uid , ids , context = context ) if team . alias_id ]
2012-07-05 12:54:17 +00:00
res = super ( crm_case_section , self ) . unlink ( cr , uid , ids , context = context )
2012-07-05 14:17:06 +00:00
mail_alias . unlink ( cr , uid , alias_ids , context = context )
2012-07-05 12:54:17 +00:00
return res
2011-08-25 04:10:37 +00:00
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 """
2012-12-08 13:14:49 +00:00
context = context or { }
object_id = context . get ( ' object_id ' , False )
ids = self . pool . get ( ' ir.model ' ) . search ( cr , uid , [ ' | ' , ( ' id ' , ' = ' , object_id ) , ( ' model ' , ' = ' , context . get ( ' object_name ' , False ) ] )
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 ' ) ,
}
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
2012-08-01 06:44:42 +00:00
class crm_payment_mode ( osv . osv ) :
""" Payment Mode for Fund """
_name = " crm.payment.mode "
_description = " CRM Payment Mode "
2010-01-08 11:05:05 +00:00
_columns = {
2012-08-01 08:50:40 +00:00
' name ' : fields . char ( ' Name ' , size = 64 , required = True ) ,
2012-08-01 06:44:42 +00:00
' 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
2011-11-22 08:51:38 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: