diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 5b3b6b38b82..4740c0fdcf1 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -116,6 +116,7 @@ class crm_case_section(osv.osv): return [] reads = self.read(cr, uid, ids, ['name', 'parent_id'], context) res = [] + for record in reads: name = record['name'] if record['parent_id']: @@ -178,9 +179,11 @@ class crm_case_resource_type(osv.osv): object_id = context and context.get('object_id', False) or False ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', object_id)]) return ids and ids[0] + _defaults = { 'object_id' : _find_object_id } + crm_case_resource_type() @@ -215,6 +218,7 @@ class crm_case_stage(osv.osv): object_id = context and context.get('object_id', False) or False ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', object_id)]) return ids and ids[0] + _defaults = { 'sequence': lambda *args: 1, 'probability': lambda *args: 0.0, @@ -295,11 +299,14 @@ class crm_case(osv.osv): 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]),\ @@ -495,6 +502,7 @@ class crm_case(osv.osv): 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()]) @@ -519,8 +527,10 @@ class crm_case(osv.osv): value = {} if not name: value['name'] = case.name + if (not partner_id) and case.partner_id: value['partner_id'] = case.partner_id.id + if case.partner_address_id: value['partner_address_id'] = case.partner_address_id.id if case.email_from: @@ -552,6 +562,7 @@ class crm_case(osv.osv): model_obj = self.pool.get('ir.model') + for case in cases: model_ids = model_obj.search(cr, uid, [('model', '=', case._name)]) data = { @@ -562,6 +573,7 @@ class crm_case(osv.osv): 'res_id': case.id, 'section_id': case.section_id.id } + obj = self.pool.get('crm.case.log') if history: obj = self.pool.get('crm.case.history') @@ -636,12 +648,15 @@ class crm_case(osv.osv): if not case.email_from: raise osv.except_osv(_('Error!'), _('You must put a Partner eMail to use this action!')) + if not case.user_id: raise osv.except_osv(_('Error!'), _('You must define a responsible user for this case in order to use this action!')) + if not case.description: raise osv.except_osv(_('Error!'), _('Can not send mail with empty body,you should have description in the body')) + self.__history(cr, uid, cases, _('Send'), history=True, email=False) for case in cases: self.write(cr, uid, [case.id], { @@ -735,6 +750,7 @@ class crm_case(osv.osv): 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: @@ -868,6 +884,7 @@ class crm_case_history(osv.osv): res[hist.id] = (hist.email or '/') + ' (' + str(hist.date) + ')\n' res[hist.id] += (hist.description or '') return res + _columns = { 'description': fields.text('Description'), 'note': fields.function(_note_get, method=True, string="Description", type="text"), @@ -944,6 +961,7 @@ class crm_email_add_cc_wizard(osv.osv_memory): openobject_id = str(case.id), subtype = "html" ) + if flag: model_pool.write(cr, uid, case.id, {'email_cc' : case.email_cc and case.email_cc + ',' + email or email}) else: diff --git a/addons/crm/crm_action_rule.py b/addons/crm/crm_action_rule.py index 1e7c50588db..f2d5a19997d 100644 --- a/addons/crm/crm_action_rule.py +++ b/addons/crm/crm_action_rule.py @@ -27,26 +27,47 @@ import tools import mx.DateTime from tools.translate import _ -from osv import fields -from osv import osv +from osv import fields +from osv import osv from osv import orm from osv.orm import except_orm import crm class case(osv.osv): + """ Case """ + _inherit = 'crm.case' + _description = 'case' + _columns = { 'date_action_last': fields.datetime('Last Action', readonly=1), 'date_action_next': fields.datetime('Next Action', readonly=1), } def remind_partner(self, cr, uid, ids, context={}, attach=False): + + """ + @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 Remind Partner's IDs + @param context: A standard dictionary for contextual values + + """ return self.remind_user(cr, uid, ids, context, attach, destination=False) - def remind_user(self, cr, uid, ids, context={}, attach=False, - destination=True): + def remind_user(self, cr, uid, ids, context={}, attach=False,destination=True): + + """ + @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 Remind user's IDs + @param context: A standard dictionary for contextual values + + """ for case in self.browse(cr, uid, ids): if not case.section_id.reply_to: raise osv.except_osv(_('Error!'), ("Reply To is not specified in Section")) @@ -83,34 +104,40 @@ class case(osv.osv): raise osv.except_osv(_('Email!'),("Email Successfully Sent")) else: raise osv.except_osv(_('Email Fail!'),("Email is not sent successfully")) - return True + return True def _check(self, cr, uid, ids=False, context={}): - ''' + """ Function called by the scheduler to process cases for date actions Only works on not done and cancelled cases - ''' + + @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 + """ 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 []) - cases = self.browse(cr, uid, ids2, context) - return self._action(cr, uid, cases, False, context=context) - def _action(self, cr, uid, cases, state_to, scrit=None, context={}): + ids2 = map(lambda x: x[0], cr.fetchall() or []) + cases = self.browse(cr, uid, ids2, context) + return self._action(cr, uid, cases, False, context=context) + + def _action(self, cr, uid, cases, state_to, scrit=None, context={}): if not context: context = {} - context['state_to'] = state_to + 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)]) + model_ids = model_obj.search(cr, uid, [('model','=',self._name)]) rule_ids = rule_obj.search(cr, uid, [('name','=',model_ids[0])]) return rule_obj._action(cr, uid, rule_ids, cases, scrit=scrit, context=context) - def format_body(self, body): + def format_body(self, body): return self.pool.get('base.action.rule').format_body(body) def format_mail(self, obj, body): @@ -118,12 +145,19 @@ class case(osv.osv): case() class base_action_rule(osv.osv): + """ Base Action Rule """ _inherit = 'base.action.rule' _description = 'Action Rules' - + def do_check(self, cr, uid, action, obj, 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 context: A standard dictionary for contextual values""" + ok = super(base_action_rule, self).do_check(cr, uid, action, obj, context=context) - + if hasattr(obj, 'section_id'): ok = ok and (not action.trg_section_id or action.trg_section_id.id==obj.section_id.id) if hasattr(obj, 'categ_id'): @@ -143,13 +177,19 @@ class base_action_rule(osv.osv): return ok def do_action(self, cr, uid, action, model_obj, obj, context={}): - res = super(base_action_rule, self).do_action(cr, uid, action, model_obj, obj, context=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 context: A standard dictionary for contextual values """ + + res = super(base_action_rule, self).do_action(cr, uid, action, model_obj, obj, context=context) write = {} - + if action.act_section_id: obj.section_id = action.act_section_id - write['section_id'] = action.act_section_id.id - + write['section_id'] = action.act_section_id.id + if hasattr(obj, 'email_cc') and action.act_email_cc: if '@' in (obj.email_cc or ''): emails = obj.email_cc.split(",") @@ -157,9 +197,10 @@ class base_action_rule(osv.osv): write['email_cc'] = obj.email_cc+','+obj.act_email_cc else: write['email_cc'] = obj.act_email_cc - + model_obj.write(cr, uid, [obj.id], write, context) emails = [] + if hasattr(obj, 'email_from') and action.act_mail_to_partner: emails.append(obj.email_from) emails = filter(None, emails) @@ -167,29 +208,44 @@ class base_action_rule(osv.osv): emails = list(set(emails)) self.email_send(cr, uid, obj, emails, action.act_mail_body) return True - - + + base_action_rule() class base_action_rule_line(osv.osv): + """ Base Action Rule Line """ _inherit = 'base.action.rule.line' + _description = 'Base Action Rule Line' def state_get(self, cr, uid, context={}): - res = super(base_action_rule_line, self).state_get(cr, uid, context=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 context: A standard dictionary for contextual values """ + + res = super(base_action_rule_line, self).state_get(cr, uid, context=context) return res + [('escalate','Escalate')] + crm.AVAILABLE_STATES def priority_get(self, cr, uid, context={}): - res = super(base_action_rule_line, self).priority_get(cr, uid, context=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 context: A standard dictionary for contextual values """ + + res = super(base_action_rule_line, self).priority_get(cr, uid, context=context) return res + crm.AVAILABLE_PRIORITIES - - _columns = { + + _columns = { 'trg_section_id': fields.many2one('crm.case.section', 'Section'), 'trg_max_history': fields.integer('Maximum Communication History'), - 'trg_categ_id': fields.many2one('crm.case.categ', 'Category'), + 'trg_categ_id': fields.many2one('crm.case.categ', 'Category'), 'regex_history' : fields.char('Regular Expression on Case History', size=128), - 'act_section_id': fields.many2one('crm.case.section', 'Set section to'), + 'act_section_id': fields.many2one('crm.case.section', 'Set section to'), 'act_categ_id': fields.many2one('crm.case.categ', 'Set Category to'), - 'act_mail_to_partner': fields.boolean('Mail to partner',help="Check this if you want the rule to send an email to the partner."), + 'act_mail_to_partner': fields.boolean('Mail to partner',help="Check this \ + if you want the rule to send an email to the partner."), } base_action_rule_line() diff --git a/addons/crm/crm_claim.py b/addons/crm/crm_claim.py index cbd34af2e52..43ec4fe9895 100755 --- a/addons/crm/crm_claim.py +++ b/addons/crm/crm_claim.py @@ -31,31 +31,43 @@ class crm_claim(osv.osv): _order = "id desc" _inherit = 'crm.case' _columns = { - 'date_closed': fields.datetime('Closed', readonly=True), - 'date': fields.datetime('Date'), - 'ref' : fields.reference('Reference', selection=crm._links_get, size=128), - 'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128), - 'canal_id': fields.many2one('res.partner.canal', 'Channel', help="The channels represent the different communication modes available with the customer." \ - " With each commercial opportunity, you can indicate the canall which is this opportunity source."), - 'planned_revenue': fields.float('Planned Revenue'), - 'planned_cost': fields.float('Planned Costs'), - 'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \ - "the partner mentality in relation to our services.The scale has" \ - "to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."), - 'categ_id': fields.many2one('crm.case.categ', 'Category', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]"), - 'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'), - 'type_id': fields.many2one('crm.case.resource.type', 'Claim Type', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]"), - - 'partner_name': fields.char("Employee's Name", size=64), - 'partner_mobile': fields.char('Mobile', size=32), - 'partner_phone': fields.char('Phone', size=32), - 'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_id','=',section_id),('object_id.model', '=', 'crm.claim')]"), - 'probability': fields.float('Probability (%)'), + 'date_closed': fields.datetime('Closed', readonly=True), + 'date': fields.datetime('Date'), + 'ref' : fields.reference('Reference', selection=crm._links_get, size=128), + 'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128), + 'canal_id': fields.many2one('res.partner.canal', 'Channel',\ + help="The channels represent the different communication\ + modes available with the customer." \ + " With each commercial opportunity, you can indicate the\ + canall which is this opportunity source."), + 'planned_revenue': fields.float('Planned Revenue'), + 'planned_cost': fields.float('Planned Costs'), + 'som': fields.many2one('res.partner.som', 'State of Mind', \ + help="The minds states allow to define a value scale which represents" \ + "the partner mentality in relation to our services.The scale has" \ + "to be created with a factor for each level from 0 (Very dissatisfied) \ + to 10 (Extremely satisfied)."), + 'categ_id': fields.many2one('crm.case.categ', 'Category',\ + domain="[('section_id','=',section_id),\ + ('object_id.model', '=', 'crm.claim')]"), + 'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'), + 'type_id': fields.many2one('crm.case.resource.type', 'Claim Type',\ + domain="[('section_id','=',section_id),\ + ('object_id.model', '=', 'crm.claim')]"), + + 'partner_name': fields.char("Employee's Name", size=64), + 'partner_mobile': fields.char('Mobile', size=32), + 'partner_phone': fields.char('Phone', size=32), + 'stage_id': fields.many2one ('crm.case.stage', 'Stage',\ + domain="[('section_id','=',section_id),\ + ('object_id.model', '=', 'crm.claim')]"), + 'probability': fields.float('Probability (%)'), } - + _defaults = { - 'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0], + 'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0], } - + crm_claim() +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/crm/crm_claims_menu.xml b/addons/crm/crm_claims_menu.xml index 24afc46de58..1eac8e007a3 100755 --- a/addons/crm/crm_claims_menu.xml +++ b/addons/crm/crm_claims_menu.xml @@ -2,48 +2,50 @@ - - + + - + Claims crm.claim form tree,calendar,form,graph - + - + tree - + calendar - + form - + graph - - - + - + + + diff --git a/addons/crm/crm_claims_view.xml b/addons/crm/crm_claims_view.xml index 1af94e62e11..ee2711f2890 100755 --- a/addons/crm/crm_claims_view.xml +++ b/addons/crm/crm_claims_view.xml @@ -1,9 +1,9 @@ - + - + Claim Categories crm.case.categ @@ -12,12 +12,12 @@ [('object_id.model', '=', 'crm.claim')] {'object_id':'crm.claim'} - + - + Claim Stages crm.case.stage @@ -26,7 +26,7 @@ [('object_id.model', '=', 'crm.claim')] {'object_id':'crm.claim'} - + @@ -40,13 +40,13 @@ [('object_id.model', '=', 'crm.claim')] {'object_id':'crm.claim'} - + - + CRM - Claims Tree crm.claim @@ -115,7 +115,7 @@