res = obj.read(cr, uid, ids, ['object', 'name'], context)
return [(r['object'], r['name']) for r in res]
-class crm_case(osv.osv):
- """ CRM Case """
-
- _name = "crm.case"
- _description = "Case"
-
- def _email_last(self, cursor, user, ids, name, arg, context=None):
- """Return last email from History
- @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 case’s IDs
- @param context: A standard dictionary for contextual values
- """
- res = {}
- for case in self.browse(cursor, user, ids):
- if case.history_line:
- res[case.id] = case.history_line[0].description
- else:
- res[case.id] = False
- return res
-
- def copy(self, cr, uid, id, default=None, context=None):
- """Overrides orm copy method
- @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 case’s IDs
- @param context: A standard dictionary for contextual values
- """
- if not context:
- context = {}
- if not default:
- default = {}
- default.update({'state': 'draft', 'id': False})
- return super(crm_case, self).copy(cr, uid, id, default, context)
-
- def _get_log_ids(self, cr, uid, ids, field_names, arg, context=None):
- """Gets id for case log from history of particular case
- @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 Case IDs
- @param context: A standard dictionary for contextual values
- @return:Dictionary of History Ids
- """
- if not context:
- context = {}
-
- result = {}
- history_obj = False
- model_obj = self.pool.get('ir.model')
-
- if 'history_line' in field_names:
- history_obj = self.pool.get('crm.case.history')
- name = 'history_line'
-
- if 'log_ids' in field_names:
- history_obj = self.pool.get('crm.case.log')
- name = 'log_ids'
-
- if not history_obj:
- return result
-
- for case in self.browse(cr, uid, ids, context):
- model_ids = model_obj.search(cr, uid, [('model', '=', case._name)])
- history_ids = history_obj.search(cr, uid, [('model_id', '=', model_ids[0]), \
- ('res_id', '=', case.id)])
- if history_ids:
- result[case.id] = {name: history_ids}
- else:
- result[case.id] = {name: []}
-
- return result
-
- _columns = {
- 'id': fields.integer('ID', readonly=True),
- 'name': fields.char('Description', size=1024, required=True),
- 'active': fields.boolean('Active', help="If the active field is set to\
- true, it will allow you to hide the case without removing it."),
- 'description': fields.text('Description'),
- 'section_id': fields.many2one('crm.case.section', 'Sales Team', \
- select=True, help='Sales team to which Case belongs to.\
- Define Responsible user and Email account for mail gateway.'),
- 'email_from': fields.char('Email', size=128, help="These people will receive email."),
- 'email_cc': fields.text('Watchers Emails', size=252 , help="These people\
- will receive a copy of the future" \
- " communication between partner and users by email"),
- 'probability': fields.float('Probability'),
- 'email_last': fields.function(_email_last, method=True,
- string='Latest E-Mail', type='text'),
- 'partner_id': fields.many2one('res.partner', 'Partner'),
- 'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
- domain="[('partner_id','=',partner_id)]"),
- 'create_date': fields.datetime('Creation Date' , readonly=True),
- 'write_date': fields.datetime('Update Date' , readonly=True),
- 'date_deadline': fields.date('Deadline'),
- 'user_id': fields.many2one('res.users', 'Responsible'),
- 'history_line': fields.function(_get_log_ids, method=True, type='one2many', \
- multi="history_line", relation="crm.case.history", string="Communication"),
- 'log_ids': fields.function(_get_log_ids, method=True, type='one2many', \
- multi="log_ids", relation="crm.case.log", string="Logs History"),
- 'stage_id': fields.many2one ('crm.case.stage', 'Stage', \
- domain="[('section_id','=',section_id),\
- ('object_id.model', '=', 'crm.lead')]"),
- 'state': fields.selection(AVAILABLE_STATES, 'State', size=16, readonly=True,
- help='The state is set to \'Draft\', when a case is created.\
- \nIf the case is in progress the state is set to \'Open\'.\
- \nWhen the case is over, the state is set to \'Done\'.\
- \nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
- 'company_id': fields.many2one('res.company', 'Company'),
- }
- def _get_default_partner_address(self, cr, uid, context):
- """Gives id of default address for current user
- @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 context: A standard dictionary for contextual values
- """
- if not context.get('portal', False):
- return False
- return self.pool.get('res.users').browse(cr, uid, uid, context).address_id.id
-
- def _get_default_partner(self, cr, uid, context):
- """Gives id of partner for current user
- @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 context: A standard dictionary for contextual values
- """
- if not context.get('portal', False):
- return False
- user = self.pool.get('res.users').browse(cr, uid, uid, context)
- if not user.address_id:
- return False
- return user.address_id.partner_id.id
-
- def _get_default_email(self, cr, uid, context):
- """Gives default email address for current user
- @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 context: A standard dictionary for contextual values
- """
- if not context.get('portal', False):
- return False
- user = self.pool.get('res.users').browse(cr, uid, uid, context)
- if not user.address_id:
- return False
- return user.address_id.email
-
- def _get_default_user(self, cr, uid, context):
- """Gives current user id
- @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 context: A standard dictionary for contextual values
- """
- if context.get('portal', False):
- return False
- return uid
-
- def _get_section(self, cr, uid, context):
- """Gives section id for current User
- @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 context: A standard dictionary for contextual values
- """
- user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
- return user.context_section_id.id or False
-
- _defaults = {
- 'active': lambda *a: 1,
- 'user_id': _get_default_user,
- 'partner_id': _get_default_partner,
- 'partner_address_id': _get_default_partner_address,
- 'email_from': _get_default_email,
- 'state': lambda *a: 'draft',
- 'section_id': _get_section,
- 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
- }
-
- _order = 'date_deadline desc, create_date desc,id desc'
-
- def unlink(self, cr, uid, ids, context=None):
- """Overrides orm unlink method
- @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 case IDs
- @param context: A standard dictionary for contextual values
- """
- if not context:
- context = {}
-
- hist_obj = self.pool.get('crm.case.history')
- log_obj = self.pool.get('crm.case.log')
-
- for case in self.browse(cr, uid, ids, context):
- if (not case.section_id.allow_unlink) and (case.state <> 'draft'):
- raise osv.except_osv(_('Warning !'),
- _('You can not delete this case. You should better cancel it.'))
-
- # Also removing history and logs
- history_ids = map(lambda x: x.id, case.history_line)
- log_ids = map(lambda x: x.id, case.log_ids)
- hist_obj.unlink(cr, uid, history_ids, context=context)
- log_obj.unlink(cr, uid, log_ids, context=context)
- return super(crm_case, self).unlink(cr, uid, ids, context)
-
- 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
- @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 case IDs
- @param context: A standard dictionary for contextual values"""
- if not context:
- context = {}
-
- s = self.get_stage_dict(cr, uid, ids, context=context)
- for case in self.browse(cr, uid, ids, context):
- section = (case.section_id.id or False)
- if section in s:
- st = case.stage_id.id or False
- if st in s[section]:
- self.write(cr, uid, [case.id], {'stage_id': s[section][st]})
- return True
-
- def get_stage_dict(self, cr, uid, ids, context=None):
- """This function gives dictionary for stage according to stage levels
- @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 case IDs
- @param context: A standard dictionary for contextual values"""
- if not context:
- context = {}
-
- sid = self.pool.get('crm.case.stage').search(cr, uid, \
- [('object_id.model', '=', self._name)], context=context)
- s = {}
- previous = {}
- for stage in self.pool.get('crm.case.stage').browse(cr, uid, sid, context=context):
- section = stage.section_id.id or False
- s.setdefault(section, {})
- s[section][previous.get(section, False)] = stage.id
- previous[section] = stage.id
- return s
-
- 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
- @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 case IDs
- @param context: A standard dictionary for contextual values"""
- if not context:
- context = {}
-
- s = self.get_stage_dict(cr, uid, ids, context=context)
- for case in self.browse(cr, uid, ids, context):
- section = (case.section_id.id or False)
-
- if section in s:
- st = case.stage_id.id or False
- s[section] = dict([(v, k) for (k, v) in s[section].iteritems()])
- if st in s[section]:
- self.write(cr, uid, [case.id], {'stage_id': s[section][st]})
- return True
-
- def __history(self, cr, uid, cases, keyword, history=False, email=False, details=None, email_from=False, message_id=False, context={}):
- """
- @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 cases: a browse record list
- @param keyword: Case action keyword e.g.: If case is closed "Close" keyword is used
- @param history: Value True/False, If True it makes entry in case History otherwise in Case Log
- @param email: Email address if any
- @param details: Details of case history if any
- @param context: A standard dictionary for contextual values"""
- if not context:
- context = {}
-
- # The mailgate sends the ids of the cases and not the object list
- if all(isinstance(case_id, (int, long)) for case_id in cases) and context.get('model'):
- cases = self.pool.get(context['model']).browse(cr, uid, cases, context=context)
-
- model_obj = self.pool.get('ir.model')
- obj = self.pool.get('crm.case.log')
- for case in cases:
- model_ids = model_obj.search(cr, uid, [('model', '=', case._name)])
- data = {
- 'name': keyword,
- 'user_id': uid,
- 'date': time.strftime('%Y-%m-%d %H:%M:%S'),
- 'model_id' : model_ids and model_ids[0] or False,
- 'res_id': case.id,
- 'section_id': case.section_id.id,
- 'message_id':message_id
- }
-
- if history:
- obj = self.pool.get('crm.case.history')
- data['description'] = details or case.description
- data['email_to'] = email or \
- (case.section_id and case.section_id.reply_to) or \
- (case.user_id and case.user_id.address_id and \
- case.user_id.address_id.email) or tools.config.get('email_from', False)
- data['email_from'] = email_from or \
- (case.section_id and case.section_id.reply_to) or \
- (case.user_id and case.user_id.address_id and \
- case.user_id.address_id.email) or tools.config.get('email_from', False)
- res = obj.create(cr, uid, data, context)
- return True
-
- _history = __history
- history = __history
-
- def create(self, cr, uid, *args, **argv):
- """Overrides orm create method
- @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 *args: Tuple Value for additional Params
- @param **argv: Dictionay of Keyword Params
- """
- res = super(crm_case, self).create(cr, uid, *args, **argv)
- cases = self.browse(cr, uid, [res])
- cases[0].state # to fill the browse record cache
- self._action(cr, uid, cases, 'draft')
- return res
-
- def add_reply(self, cursor, user, ids, context=None):
- """This function finds last email and gives its description value for reply mail
- @param self: The object pointer
- @param cursor: the current row, from the database cursor,
- @param user: the current user’s ID for security checks
- @param ids: List of case IDs
- @param context: A standard dictionary for contextual values
- """
- for case in self.browse(cursor, user, ids, context=context):
- if case.email_last:
- description = case.email_last
- self.write(cursor, user, case.id, {
- 'description': '> ' + description.replace('\n', '\n> '),
- }, context=context)
- return True
-
- def onchange_partner_id(self, cr, uid, ids, part, email=False):
- """This function returns value of partner address based on partner
- @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 case IDs
- @param part: Partner's id
- @email: Partner's email ID
- """
- if not part:
- return {'value': {'partner_address_id': False,
- 'email_from': False,
- }}
- 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}
-
- def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
- """This function returns value of partner email based on Partner Address
- @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 case IDs
- @param add: Id of Partner's address
- @email: Partner's email ID
- """
- if not add:
- return {'value': {'email_from': False}}
- address = self.pool.get('res.partner.address').browse(cr, uid, add)
- return {'value': {'email_from': address.email}}
-
- def case_close(self, cr, uid, ids, *args):
- """Closes Case
- @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 case Ids
- @param *args: Tuple Value for additional Params
- """
- cases = self.browse(cr, uid, ids)
- cases[0].state # to fill the browse record cache
- self.__history(cr, uid, cases, _('Close'))
- self.write(cr, uid, ids, {'state': 'done',
- 'date_closed': time.strftime('%Y-%m-%d %H:%M:%S'),
- 'probability' : 100.0})
- #
- # 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):
- """Escalates case to top level
- @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 case Ids
- @param *args: Tuple Value for additional Params
- """
- cases = self.browse(cr, uid, ids)
- for case in cases:
- data = {'active': True, 'user_id': False}
-
- if case.section_id.parent_id:
- data['section_id'] = case.section_id.parent_id.id
- if case.section_id.parent_id.user_id:
- data['user_id'] = case.section_id.parent_id.user_id.id
- else:
- raise osv.except_osv(_('Error !'), _('You can not escalate this case.\nYou are already at the top level.'))
- self.write(cr, uid, [case.id], data)
- cases = self.browse(cr, uid, ids)
- self.__history(cr, uid, cases, _('Escalate'))
- self._action(cr, uid, cases, 'escalate')
- return True
-
- def case_open(self, cr, uid, ids, *args):
- """Opens Case
- @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 case Ids
- @param *args: Tuple Value for additional Params
- """
- cases = self.browse(cr, uid, ids)
- self.__history(cr, uid, cases, _('Open'))
-
- 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_cancel(self, cr, uid, ids, *args):
- """Cancels Case
- @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 case Ids
- @param *args: Tuple Value for additional Params
- """
- cases = self.browse(cr, uid, ids)
- cases[0].state # to fill the browse record cache
- self.__history(cr, uid, cases, _('Cancel'))
- self.write(cr, uid, ids, {'state': 'cancel',
- 'active': True,
- 'probability' : 0.0})
- self._action(cr, uid, cases, 'cancel')
- return True
-
- def case_pending(self, cr, uid, ids, *args):
- """Marks case as pending
- @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 case Ids
- @param *args: Tuple Value for additional Params
- """
- cases = self.browse(cr, uid, ids)
- cases[0].state # to fill the browse record cache
- self.__history(cr, uid, cases, _('Pending'))
- 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
- @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 case Ids
- @param *args: Tuple Value for additional Params
- """
- cases = self.browse(cr, uid, ids)
- cases[0].state # to fill the browse record cache
- self.__history(cr, uid, cases, _('Draft'))
- self.write(cr, uid, ids, {'state': 'draft', 'active': True})
- self._action(cr, uid, cases, 'draft')
- return True
-
-crm_case()
-
class crm_case_log(osv.osv):
""" Case Communication History """