[MERGE] Merged with bth CRM branch.

bzr revid: tde@openerp.com-20120403080740-hig2sxkeeb62xw93
This commit is contained in:
Thibault Delavallée 2012-04-03 10:07:40 +02:00
commit 746c5c2119
11 changed files with 302 additions and 179 deletions

View File

@ -127,7 +127,7 @@ class crm_case_section(osv.osv):
def name_get(self, cr, uid, ids, context=None):
"""Overrides orm name_get method"""
if not isinstance(ids, list) :
if not isinstance(ids, list) :
ids = [ids]
res = []
if not ids:
@ -256,7 +256,40 @@ class crm_base(object):
data.update(self.onchange_partner_address_id(cr, uid, ids, addr['contact'])['value'])
return {'value': data}
def case_open(self, cr, uid, ids, *args):
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
return ''
def case_open_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = '%s has been <b>opened</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
self.message_append_note(cr, uid, [id], body=msg, context=context)
return True
def case_close_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = '%s has been <b>closed</b>.'% (self.case_get_note_msg_prefix(cr, uid, id, context=context))
self.message_append_note(cr, uid, [id], body=msg, context=context)
return True
def case_cancel_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = '%s has been <b>canceled</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
self.message_append_note(cr, uid, [id], body=msg, context=context)
return True
def case_pending_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = '%s is now <b>pending</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
self.message_append_note(cr, uid, [id], body=msg, context=context)
return True
def case_reset_send_note(self, cr, uid, ids, context=None):
for id in ids:
msg = '%s has been <b>renewed</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
self.message_append_note(cr, uid, [id], body=msg, context=context)
return True
def case_open(self, cr, uid, ids, context=None):
"""Opens Case
:param ids: List of case Ids
"""
@ -266,11 +299,12 @@ class crm_base(object):
if not case.user_id:
data['user_id'] = uid
self.write(cr, uid, [case.id], data)
self.case_open_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, 'open')
return True
def case_close(self, cr, uid, ids, *args):
def case_close(self, cr, uid, ids, context=None):
"""Closes Case
:param ids: List of case Ids
"""
@ -278,10 +312,11 @@ class crm_base(object):
cases[0].state # to fill the browse record cache
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.case_close_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, 'done')
return True
def case_cancel(self, cr, uid, ids, *args):
def case_cancel(self, cr, uid, ids, context=None):
"""Cancels Case
:param ids: List of case Ids
"""
@ -289,26 +324,29 @@ class crm_base(object):
cases[0].state # to fill the browse record cache
self.write(cr, uid, ids, {'state': 'cancel', 'active': True})
# We use the cache of cases to keep the old case state
self.case_cancel_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, 'cancel')
return True
def case_pending(self, cr, uid, ids, *args):
def case_pending(self, cr, uid, ids, context=None):
"""Marks case as pending
:param ids: List of case Ids
"""
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.case_pending_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, 'pending')
return True
def case_reset(self, cr, uid, ids, *args):
def case_reset(self, cr, uid, ids, context=None):
"""Resets case as draft
:param ids: List of case Ids
"""
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.case_reset_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, 'draft')
return True
@ -323,12 +361,12 @@ class crm_base(object):
return rule_obj._action(cr, uid, rule_ids, cases, scrit=scrit, context=context)
class crm_case(crm_base):
""" A simple python class to be used for common functions
""" 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
And object that inherit (orm inheritance) from a class the overwrite copy
"""
def stage_find(self, cr, uid, section_id, domain=[], order='sequence'):
domain = list(domain)
if section_id:
@ -387,8 +425,16 @@ class crm_case(crm_base):
default.update({ 'date_open': False })
return super(crm_case, self).copy(cr, uid, id, default, context=context)
def case_escalate_send_note(self, cr, uid, ids, new_section=None, context=None):
for id in ids:
if new_section:
msg = '%s has been <b>escalated</b> to <b>%s</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context), new_section.name)
else:
msg = '%s has been <b>escalated</b>.' % (self.case_get_note_msg_prefix(cr, uid, id, context=context))
self.message_append_note(cr, uid, [id], 'System Notification', msg, context=context)
return True
def case_open(self, cr, uid, ids, *args):
def case_open(self, cr, uid, ids, context=None):
"""Opens Case"""
cases = self.browse(cr, uid, ids)
for case in cases:
@ -396,10 +442,11 @@ class crm_case(crm_base):
if not case.user_id:
data['user_id'] = uid
self.write(cr, uid, [case.id], data)
self.case_open_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, 'open')
return True
def case_close(self, cr, uid, ids, *args):
def case_close(self, cr, uid, ids, context=None):
"""Closes Case"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
@ -409,10 +456,11 @@ class crm_case(crm_base):
#
# We use the cache of cases to keep the old case state
#
self.case_close_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, 'done')
return True
def case_escalate(self, cr, uid, ids, *args):
def case_escalate(self, cr, uid, ids, context=None):
"""Escalates case to parent level"""
cases = self.browse(cr, uid, ids)
for case in cases:
@ -425,38 +473,37 @@ class crm_case(crm_base):
else:
raise osv.except_osv(_('Error !'), _('You can not escalate, you are already at the top level regarding your sales-team category.'))
self.write(cr, uid, [case.id], data)
case.case_escalate_send_note(case.section_id.parent_id)
cases = self.browse(cr, uid, ids)
self._action(cr, uid, cases, 'escalate')
return True
def case_cancel(self, cr, uid, ids, *args):
def case_cancel(self, cr, uid, ids, context=None):
"""Cancels Case"""
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
self.write(cr, uid, ids, {'state': 'cancel',
'active': True})
self.case_cancel_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, 'cancel')
for case in cases:
message = _("The case '%s' has been cancelled.") % (case.name,)
self.log(cr, uid, case.id, message)
return True
def case_pending(self, cr, uid, ids, *args):
def case_pending(self, cr, uid, ids, context=None):
"""Marks case as pending"""
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.case_pending_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, 'pending')
return True
def case_reset(self, cr, uid, ids, *args):
def case_reset(self, cr, uid, ids, context=None):
"""Resets case as draft"""
state = 'draft'
if 'crm.phonecall' in args:
state = 'open'
cases = self.browse(cr, uid, ids)
cases[0].state # to fill the browse record cache
self.write(cr, uid, ids, {'state': state, 'active': True})
self.case_reset_send_note(cr, uid, ids, context=context)
self._action(cr, uid, cases, state)
return True

View File

@ -40,7 +40,7 @@ class crm_lead(crm_case, osv.osv):
_name = "crm.lead"
_description = "Lead/Opportunity"
_order = "priority,date_action,id desc"
_inherit = ['mail.thread','res.partner']
_inherit = ['ir.needaction', 'mail.thread','res.partner']
def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None):
access_rights_uid = access_rights_uid or uid
@ -183,7 +183,6 @@ class crm_lead(crm_case, osv.osv):
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', type='char', size=64),
# Only used for type opportunity
'probability': fields.float('Probability (%)',group_operator="avg"),
'planned_revenue': fields.float('Expected Revenue'),
@ -215,6 +214,19 @@ class crm_lead(crm_case, osv.osv):
'color': 0,
}
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):
# salesman must perform an action when in draft mode
if obj.state == 'draft' and obj.user_id:
result[obj.id] = [obj.user_id.id]
return result
def create(self, cr, uid, vals, context=None):
obj_id = super(crm_lead, self).create(cr, uid, vals, context)
self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id
def on_change_optin(self, cr, uid, ids, optin):
return {'value':{'optin':optin,'optout':False}}
@ -248,75 +260,58 @@ class crm_lead(crm_case, osv.osv):
def stage_find_won(self, cr, uid, section_id):
return self.stage_find_percent(cr, uid, 100.0, section_id)
def case_open(self, cr, uid, ids, *args):
for l in self.browse(cr, uid, ids):
# When coming from draft override date and stage otherwise just set state
if l.state == 'draft':
if l.type == 'lead':
message = _("The lead '%s' has been opened.") % l.name
elif l.type == 'opportunity':
message = _("The opportunity '%s' has been opened.") % l.name
else:
message = _("The case '%s' has been opened.") % l.name
self.log(cr, uid, l.id, message)
def case_open(self, cr, uid, ids, context=None):
for lead in self.browse(cr, uid, ids, context=context):
if lead.state == 'draft':
value = {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')}
self.write(cr, uid, [l.id], value)
if l.type == 'opportunity' and not l.stage_id:
stage_id = self.stage_find(cr, uid, l.section_id.id or False, [('sequence','>',0)])
self.write(cr, uid, [lead.id], value)
if lead.type == 'opportunity' and not lead.stage_id:
stage_id = self.stage_find(cr, uid, lead.section_id.id or False, [('sequence','>',0)])
if stage_id:
self.stage_set(cr, uid, [l.id], stage_id)
res = super(crm_lead, self).case_open(cr, uid, ids, *args)
self.stage_set(cr, uid, [lead.id], stage_id)
res = super(crm_lead, self).case_open(cr, uid, ids, context)
return res
def case_close(self, cr, uid, ids, *args):
res = super(crm_lead, self).case_close(cr, uid, ids, *args)
def case_close(self, cr, uid, ids, context=None):
res = super(crm_lead, self).case_close(cr, uid, ids, context)
self.write(cr, uid, ids, {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
for case in self.browse(cr, uid, ids):
if case.type == 'lead':
message = _("The lead '%s' has been closed.") % case.name
else:
message = _("The case '%s' has been closed.") % case.name
self.log(cr, uid, case.id, message)
return res
def case_cancel(self, cr, uid, ids, *args):
def case_cancel(self, cr, uid, ids, context=None):
"""Overrides cancel for crm_case for setting probability
"""
res = super(crm_lead, self).case_cancel(cr, uid, ids, args)
res = super(crm_lead, self).case_cancel(cr, uid, ids, context)
self.write(cr, uid, ids, {'probability' : 0.0})
return res
def case_reset(self, cr, uid, ids, *args):
def case_reset(self, cr, uid, ids, context=None):
"""Overrides reset as draft in order to set the stage field as empty
"""
res = super(crm_lead, self).case_reset(cr, uid, ids, *args)
res = super(crm_lead, self).case_reset(cr, uid, ids, context)
self.write(cr, uid, ids, {'stage_id': False, 'probability': 0.0})
return res
def case_mark_lost(self, cr, uid, ids, *args):
def case_mark_lost(self, cr, uid, ids, context=None):
"""Mark the case as lost: state = done and probability = 0%
"""
res = super(crm_lead, self).case_close(cr, uid, ids, *args)
res = super(crm_lead, self).case_close(cr, uid, ids, context)
self.write(cr, uid, ids, {'probability' : 0.0})
for l in self.browse(cr, uid, ids):
stage_id = self.stage_find_lost(cr, uid, l.section_id.id or False)
for lead in self.browse(cr, uid, ids):
stage_id = self.stage_find_lost(cr, uid, lead.section_id.id or False)
if stage_id:
self.stage_set(cr, uid, [l.id], stage_id)
message = _("The opportunity '%s' has been marked as lost.") % l.name
self.log(cr, uid, l.id, message)
self.stage_set(cr, uid, [lead.id], stage_id)
return res
def case_mark_won(self, cr, uid, ids, *args):
def case_mark_won(self, cr, uid, ids, context=None):
"""Mark the case as lost: state = done and probability = 0%
"""
res = super(crm_lead, self).case_close(cr, uid, ids, *args)
res = super(crm_lead, self).case_close(cr, uid, ids, context=None)
self.write(cr, uid, ids, {'probability' : 100.0})
for l in self.browse(cr, uid, ids):
stage_id = self.stage_find_won(cr, uid, l.section_id.id or False)
for lead in self.browse(cr, uid, ids):
stage_id = self.stage_find_won(cr, uid, lead.section_id.id or False)
if stage_id:
self.stage_set(cr, uid, [l.id], stage_id)
message = _("The opportunity '%s' has been been won.") % l.name
self.log(cr, uid, l.id, message)
self.stage_set(cr, uid, [lead.id], stage_id)
self.case_mark_won_send_note(cr, uid, [lead.id], context=context)
return res
def set_priority(self, cr, uid, ids, priority):
@ -324,12 +319,12 @@ class crm_lead(crm_case, osv.osv):
"""
return self.write(cr, uid, ids, {'priority' : priority})
def set_high_priority(self, cr, uid, ids, *args):
def set_high_priority(self, cr, uid, ids, context=None):
"""Set lead priority to high
"""
return self.set_priority(cr, uid, ids, '1')
def set_normal_priority(self, cr, uid, ids, *args):
def set_normal_priority(self, cr, uid, ids, context=None):
"""Set lead priority to normal
"""
return self.set_priority(cr, uid, ids, '3')
@ -422,7 +417,7 @@ class crm_lead(crm_case, osv.osv):
subject = subject[0] + ", ".join(subject[1:])
details = "\n\n".join(details)
return self.message_append(cr, uid, [opportunity_id], subject, body_text=details, context=context)
return self.message_append_note(cr, uid, [opportunity_id], subject=subject, body=details)
def _merge_opportunity_history(self, cr, uid, opportunity_id, opportunities, context=None):
message = self.pool.get('mail.message')
@ -529,13 +524,6 @@ class crm_lead(crm_case, osv.osv):
'date_open': time.strftime('%Y-%m-%d %H:%M:%S'),
}
def _convert_opportunity_notification(self, cr, uid, lead, context=None):
success_message = _("Lead '%s' has been converted to an opportunity.") % lead.name
self.message_append(cr, uid, [lead.id], success_message, body_text=success_message, context=context)
self.log(cr, uid, lead.id, success_message)
self._send_mail_to_salesman(cr, uid, lead, context=context)
return True
def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, section_id=False, context=None):
partner = self.pool.get('res.partner')
mail_message = self.pool.get('mail.message')
@ -551,7 +539,7 @@ class crm_lead(crm_case, osv.osv):
vals = self._convert_opportunity_data(cr, uid, lead, customer, section_id, context=context)
self.write(cr, uid, [lead.id], vals, context=context)
self._convert_opportunity_notification(cr, uid, lead, context=context)
self.convert_opportunity_send_note(cr, uid, lead, context=context)
#TOCHECK: why need to change partner details in all messages of lead ?
if lead.partner_id:
msg_ids = [ x.id for x in lead.message_ids]
@ -605,6 +593,7 @@ class crm_lead(crm_case, osv.osv):
res_partner.write(cr, uid, partner_id, {'section_id': lead.section_id.id or False})
contact_id = res_partner.address_get(cr, uid, [partner_id])['default']
res = lead.write({'partner_id' : partner_id, }, context=context)
self._lead_set_partner_send_note(cr, uid, [lead.id], context)
return res
def convert_partner(self, cr, uid, ids, action='create', partner_id=False, context=None):
@ -684,12 +673,12 @@ class crm_lead(crm_case, osv.osv):
'partner_mobile' : lead.partner_id and lead.partner_id.mobile or False,
'priority': lead.priority,
}
new_id = phonecall.create(cr, uid, vals, context=context)
phonecall.case_open(cr, uid, [new_id])
phonecall.case_open(cr, uid, [new_id], context=context)
if action == 'log':
phonecall.case_close(cr, uid, [new_id])
phonecall.case_close(cr, uid, [new_id], context=context)
phonecall_dict[lead.id] = new_id
self.schedule_phonecall_send_note(cr, uid, [lead.id], new_id, action, context=context)
return phonecall_dict
@ -767,7 +756,7 @@ class crm_lead(crm_case, osv.osv):
#re-open
values.update(state=crm.AVAILABLE_STATES[1][0])
if not case.date_open:
values['date_open'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
values['date_open'] = time.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
res = self.write(cr, uid, [case.id], values, context=context)
return res
@ -831,17 +820,59 @@ class crm_lead(crm_case, osv.osv):
# change probability of lead(s) if required by stage
if not vals.get('probability') and stage.on_change:
vals['probability'] = stage.probability
text = _("Changed Stage to: %s") % stage.name
self.message_append(cr, uid, ids, text, body_text=text, context=context)
for case in self.browse(cr, uid, ids, context=context):
if case.type == 'lead' or context.get('stage_type') == 'lead':
message = _("The stage of lead '%s' has been changed to '%s'.") % (case.name, stage.name)
self.log(cr, uid, case.id, message)
elif case.type == 'opportunity':
message = _("The stage of opportunity '%s' has been changed to '%s'.") % (case.name, stage.name)
self.log(cr, uid, case.id, message)
message = _("Stage changed to <b>%s</b>.") % (stage.name)
case.message_append_note(body=message)
return super(crm_lead,self).write(cr, uid, ids, vals, context)
# ----------------------------------------
# OpenChatter methods and notifications
# ----------------------------------------
def message_get_subscribers(self, cr, uid, ids, context=None):
sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context)
# add salesman to the subscribers
for obj in self.browse(cr, uid, ids, context=context):
if obj.user_id:
sub_ids.append(obj.user_id.id)
return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
def case_get_note_msg_prefix(self, cr, uid, lead, context=None):
if isinstance(lead, (int, long)):
lead = self.browse(cr, uid, [lead], context=context)[0]
return ('Opportunity' if lead.type == 'opportunity' else 'Lead')
def create_send_note(self, cr, uid, ids, context=None):
for id in ids:
message = _("%s has been <b>created</b>.")% (self.case_get_note_msg_prefix(cr, uid, id, context=context))
self.message_append_note(cr, uid, [id], body=message, context=context)
return True
def case_mark_lost_send_note(self, cr, uid, ids, context=None):
message = _("Opportunity has been <b>lost</b>.")
return self.message_append_note(cr, uid, ids, body=message, context=context)
def case_mark_won_send_note(self, cr, uid, ids, context=None):
message = _("Opportunity has been <b>won</b>.")
return self.message_append_note(cr, uid, ids, body=message, context=context)
def schedule_phonecall_send_note(self, cr, uid, ids, phonecall_id, action, context=None):
phonecall = self.pool.get('crm.phonecall').browse(cr, uid, [phonecall_id], context=context)[0]
if action == 'log': prefix = 'Logged'
else: prefix = 'Scheduled'
message = _("<b>%s a call</b> for the <em>%s</em>.") % (prefix, phonecall.date)
return self. message_append_note(cr, uid, ids, body=message, context=context)
def _lead_set_partner_send_note(self, cr, uid, ids, context=None):
for lead in self.browse(cr, uid, ids, context=context):
message = _("%s <b>partner</b> is now set to <em>%s</em>." % (self.case_get_note_msg_prefix(cr, uid, lead, context=context), lead.partner_id.name))
lead.message_append_note(body=message)
return True
def convert_opportunity_send_note(self, cr, uid, lead, context=None):
message = _("Lead has been <b>converted to an opportunity</b>.")
lead.message_append_note(body=message)
return True
crm_lead()

View File

@ -143,29 +143,6 @@
type="object" icon="gtk-convert" />
</group>
</page>
<page string="Communication &amp; History" groups="base.group_extended">
<group colspan="4">
<field colspan="4" name="email_cc" widget="char" size="512"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree" readonly="1">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="email_from" invisible="1"/>
<button
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
icon="terp-mail-replied" type="action" />
</tree>
</field>
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
<button string="Send New Email"
name="%(mail.action_email_compose_message_wizard)d"
icon="terp-mail-message-new" type="action"/>
</page>
<page string="Extra Info" groups="base.group_extended">
<group colspan="2" col="2">
<separator string="Categorization" colspan="2" col="2"/>
@ -176,13 +153,6 @@
<field name="channel_id" select="1" widget="selection"/>
<field name="referred"/>
</group>
<group colspan="2" col="2" groups="base.group_no_one">
<separator string="Dates" colspan="2" col="2"/>
<field name="create_date"/>
<field name="write_date"/>
<field name="date_open"/>
<field name="date_closed"/>
</group>
<group colspan="2" col="2">
<separator string="Mailings" colspan="2" col="2"/>
<field name="optin" on_change="on_change_optin(optin)"/>
@ -195,6 +165,7 @@
</group>
</page>
</notebook>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>
@ -545,37 +516,7 @@
<field name="optout" on_change="on_change_optout(optout)"/>
</group>
</page>
<page string="Communication &amp; History" groups="base.group_extended">
<group colspan="4">
<field colspan="4" name="email_cc" widget="char" size="512"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree" readonly="1">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="email_from" invisible="1"/>
<button
string="Reply" attrs="{'invisible': [('email_from', '=', False)]}"
name="%(mail.action_email_compose_message_wizard)d"
context="{'mail.compose.message.mode':'reply', 'message_id':active_id}"
icon="terp-mail-replied" type="action" />
</tree>
</field>
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
<button string="Send New Email"
name="%(mail.action_email_compose_message_wizard)d"
icon="terp-mail-message-new" type="action"/>
</page>
<page string="Extra Info" groups="base.group_extended">
<group col="2" colspan="2" groups="base.group_no_one">
<separator string="Dates" colspan="2"/>
<field name="create_date"/>
<field name="write_date"/>
<field name="date_closed"/>
<field name="date_open"/>
</group>
<group col="2" colspan="2">
<separator string="Misc" colspan="2"/>
<field name="active"/>
@ -588,6 +529,7 @@
<field name="ref2"/>
</page>
</notebook>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>

View File

@ -42,7 +42,7 @@ class crm_meeting(crm_base, osv.osv):
_name = 'crm.meeting'
_description = "Meeting"
_order = "id desc"
_inherit = "calendar.event"
_inherit = ["calendar.event", 'ir.needaction', "mail.thread"]
_columns = {
# From crm.case
'name': fields.char('Summary', size=124, required=True, states={'done': [('readonly', True)]}),
@ -78,7 +78,55 @@ class crm_meeting(crm_base, osv.osv):
'user_id': lambda self, cr, uid, ctx: uid,
}
def case_open(self, cr, uid, ids, *args):
def create(self, cr, uid, vals, context=None):
obj_id = super(crm_meeting, self).create(cr, uid, vals, context=context)
self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id
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):
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 'Meeting'
def create_send_note(self, cr, uid, ids, context=None):
if context is None:
context = {}
# update context: if come from phonecall, default state values can make the message_append_note crash
context.pop('default_state', False)
for meeting in self.browse(cr, uid, ids, context=context):
message = _("A meeting has been <b>scheduled</b> on <em>%s</em>.") % (meeting.date)
if meeting.opportunity_id: # meeting can be create from phonecalls or opportunities, therefore checking for the parent
lead = meeting.opportunity_id
parent_message = _("Meeting linked to the opportunity <em>%s</em> has been <b>created</b> and <b>cscheduled</b> on <em>%s</em>.") % (lead.name, meeting.date)
lead.message_append_note(_('System Notification'), message)
elif meeting.phonecall_id:
phonecall = meeting.phonecall_id
parent_message = _("Meeting linked to the phonecall <em>%s</em> has been <b>created</b> and <b>cscheduled</b> on <em>%s</em>.") % (phonecall.name, meeting.date)
phonecall.message_append_note(body=message)
else:
parent_message = message
if parent_message:
meeting.message_append_note(body=parent_message)
return True
def case_close_send_note(self, cr, uid, ids, context=None):
message = _("Meeting has been <b>done</b>.")
return self.message_append_note(cr, uid, ids, body=message, context=context)
def case_open_send_note(self, cr, uid, ids, context=None):
for meeting in self.browse(cr, uid, ids, context=context):
if meeting.state != 'draft':
return False
message = _("Meeting has been <b>confirmed</b>.")
meeting.message_append_note(body=message)
return True
def case_open(self, cr, uid, ids, context=None):
"""Confirms meeting
@param self: The object pointer
@param cr: the current row, from the database cursor,
@ -86,11 +134,9 @@ class crm_meeting(crm_base, osv.osv):
@param ids: List of Meeting Ids
@param *args: Tuple Value for additional Params
"""
res = super(crm_meeting, self).case_open(cr, uid, ids, args)
res = super(crm_meeting, self).case_open(cr, uid, ids, context)
for (id, name) in self.name_get(cr, uid, ids):
message = _("The meeting '%s' has been confirmed.") % name
id=base_calendar.base_calendar_id2real_id(id)
self.log(cr, uid, id, message)
return res
crm_meeting()

View File

@ -212,6 +212,7 @@
</page>
</notebook>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>

View File

@ -32,6 +32,7 @@ class crm_phonecall(crm_base, osv.osv):
_name = "crm.phonecall"
_description = "Phonecall"
_order = "id desc"
_inherit = ['ir.needaction', 'mail.thread']
_columns = {
# From crm.case
'id': fields.integer('ID', readonly=True),
@ -47,12 +48,12 @@ class crm_phonecall(crm_base, osv.osv):
'company_id': fields.many2one('res.company', 'Company'),
'description': fields.text('Description'),
'state': fields.selection([
('draft', 'Draft'),
('open', 'Todo'),
('cancel', 'Cancelled'),
('done', 'Held'),
('draft', 'Draft'),
('open', 'Todo'),
('cancel', 'Cancelled'),
('done', 'Held'),
('pending', 'Not Held'),
], 'State', size=16, readonly=True,
], 'State', size=16, readonly=True,
help='The state is set to \'Todo\', when a case is created.\
\nIf the case is in progress the state is set to \'Open\'.\
\nWhen the call is over, the state is set to \'Held\'.\
@ -67,9 +68,9 @@ class crm_phonecall(crm_base, osv.osv):
'partner_phone': fields.char('Phone', size=32),
'partner_mobile': fields.char('Mobile', size=32),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
'date_closed': fields.datetime('Closed', readonly=True),
'date': fields.datetime('Date'),
'opportunity_id': fields.many2one ('crm.lead', 'Lead/Opportunity'),
'date_closed': fields.datetime('Closed', readonly=True),
'date': fields.datetime('Date'),
'opportunity_id': fields.many2one ('crm.lead', 'Lead/Opportunity'),
'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
}
@ -80,13 +81,30 @@ class crm_phonecall(crm_base, osv.osv):
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'priority': crm.AVAILABLE_PRIORITIES[2][0],
'state': _get_default_state,
'priority': crm.AVAILABLE_PRIORITIES[2][0],
'state': _get_default_state,
'user_id': lambda self,cr,uid,ctx: uid,
'active': 1,
}
def case_close(self, cr, uid, ids, *args):
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
# From crm.case
def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
res = super(crm_phonecall, self).onchange_partner_address_id(cr, uid, ids, add, email)
res.setdefault('value', {})
if add:
address = self.pool.get('res.partner.address').browse(cr, uid, add)
res['value']['partner_phone'] = address.phone
res['value']['partner_mobile'] = address.mobile
return res
def case_close(self, cr, uid, ids, context=None):
"""Overrides close for crm_case for setting close date
"""
res = True
@ -96,22 +114,22 @@ class crm_phonecall(crm_base, osv.osv):
if phone.duration <=0:
duration = datetime.now() - datetime.strptime(phone.date, '%Y-%m-%d %H:%M:%S')
data.update({'duration': duration.seconds/float(60)})
res = super(crm_phonecall, self).case_close(cr, uid, [phone_id], args)
res = super(crm_phonecall, self).case_close(cr, uid, [phone_id], context)
self.write(cr, uid, [phone_id], data)
return res
def case_reset(self, cr, uid, ids, *args):
def case_reset(self, cr, uid, ids, context=None):
"""Resets case as Todo
"""
res = super(crm_phonecall, self).case_reset(cr, uid, ids, args, 'crm.phonecall')
res = super(crm_phonecall, self).case_reset(cr, uid, ids, context)
self.write(cr, uid, ids, {'duration': 0.0, 'state':'open'})
return res
def case_open(self, cr, uid, ids, *args):
def case_open(self, cr, uid, ids, context=None):
"""Overrides cancel for crm_case for setting Open Date
"""
res = super(crm_phonecall, self).case_open(cr, uid, ids, *args)
res = super(crm_phonecall, self).case_open(cr, uid, ids, context)
self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')})
return res
@ -143,9 +161,7 @@ class crm_phonecall(crm_base, osv.osv):
'partner_mobile' : call.partner_mobile,
'priority': call.priority,
}
new_id = self.create(cr, uid, vals, context=context)
self.case_open(cr, uid, [new_id])
if action == 'log':
self.case_close(cr, uid, [new_id])
phonecall_dict[call.id] = new_id
@ -162,7 +178,9 @@ class crm_phonecall(crm_base, osv.osv):
return partner_id
def _call_set_partner(self, cr, uid, ids, partner_id, context=None):
return self.write(cr, uid, ids, {'partner_id' : partner_id}, context=context)
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
def _call_create_partner_address(self, cr, uid, phonecall, partner_id, context=None):
address = self.pool.get('res.partner')
@ -231,7 +249,7 @@ class crm_phonecall(crm_base, osv.osv):
'section_id': call.section_id and call.section_id.id or False,
'description': call.description or False,
'priority': call.priority,
'type': 'opportunity',
'type': 'opportunity',
'phone': call.partner_phone or False,
'email_from': default_contact and default_contact.email,
})
@ -243,7 +261,7 @@ class crm_phonecall(crm_base, osv.osv):
self.case_close(cr, uid, [call.id])
opportunity.case_open(cr, uid, [opportunity_id])
opportunity_dict[call.id] = opportunity_id
return opportunity_dict
return opportunity_dict
def action_make_meeting(self, cr, uid, ids, context=None):
"""
@ -289,6 +307,41 @@ class crm_phonecall(crm_base, osv.osv):
}
return value
# ----------------------------------------
# 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
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)
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)
crm_phonecall()

View File

@ -120,6 +120,7 @@
states="cancel" type="object"
icon="gtk-convert" />
</group>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>

View File

@ -95,6 +95,9 @@ class crm_claim(crm.crm_case, osv.osv):
'active': lambda *a: 1
}
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
return 'Claim'
def onchange_partner_id(self, cr, uid, ids, part, email=False):
"""This function returns value of partner address based on partner
:param part: Partner's id

View File

@ -304,6 +304,7 @@ class mail_message(osv.osv):
'headers': headers, # serialize the dict on the fly
'mail_server_id': mail_server_id,
'state': 'outgoing',
'type': 'email',
'auto_delete': auto_delete
}
email_msg_id = self.create(cr, uid, msg_vals, context)

View File

@ -23,6 +23,5 @@
<field name="action" ref="action_mail_my_feeds"/>
<field name="parent_id" ref="mail_feeds"/>
</record>
</data>
</openerp>

View File

@ -105,9 +105,8 @@ class crm_make_sale(osv.osv_memory):
sale_order = sale_obj.browse(cr, uid, new_id, context=context)
case_obj.write(cr, uid, [case.id], {'ref': 'sale.order,%s' % new_id})
new_ids.append(new_id)
message = _("Opportunity '%s' is converted to Quotation.") % (case.name)
self.log(cr, uid, case.id, message)
case_obj.message_append(cr, uid, [case], _("Converted to Sales Quotation(%s).") % (sale_order.name), context=context)
message = _("Opportunity has been <b>converted</b> to the quotation <em>%s</em>.") % (sale_order.name)
case.message_append_note(body=message)
if make.close:
case_obj.case_close(cr, uid, data)