#
##############################################################################
-from openerp.osv import fields, osv
from openerp.tools.translate import _
'phone': address and address.phone or False,
'mobile': address and address.mobile or False,
'fax': address and address.fax or False,
+ 'function': address and address.function or False,
'street': address and address.street or False,
'street2': address and address.street2 or False,
'city': address and address.city or False,
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_stage_graph"/>
- <field name="domain">[('probability', 'not in', (0, 100)),('stage_id.sequence','!=',1),('type', '=', 'opportunity')]</field>
- <field name="context">{'search_default_Stage':1}</field>
+ <field name="domain">['|',
+ '!', '&', ('probability', '=', 100), ('stage_id.on_change', '=', 1),
+ '!', '&', ('probability', '=', 0), ('stage_id.sequence', '!=', 1),
+ ('type', '=', 'opportunity')]</field>
+ <field name="context">{'search_default_Stage': 1}</field>
</record>
<!--Planned Revenue By User line graph-->
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
<field name="view_id" ref="view_crm_opportunity_user_stage_graph"/>
- <field name="domain">[('probability', '=', '0'), ('stage_id.sequence', '!=', 1),('opening_date','>',context_today().strftime("%Y-%m-%d"))]</field>
- <field name="context">{'search_default_Stage':1}</field>
+ <field name="domain">['!', '&', ('probability', '=', 0), ('stage_id.sequence', '!=', 1)]</field>
+ <field name="context">{'search_default_user': 1, 'search_default_Stage': 1}</field>
</record>
<record model="ir.ui.view" id="board_crm_statistical_form">
from openerp.osv import fields
from openerp.osv import osv
-AVAILABLE_STATES = [
- ('draft', 'New'),
- ('cancel', 'Cancelled'),
- ('open', 'In Progress'),
- ('pending', 'Pending'),
- ('done', 'Closed')
-]
-
AVAILABLE_PRIORITIES = [
('1', 'Highest'),
('2', 'High'),
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-today OpenERP SA (<http://www.openerp.com>)
+# Copyright (C) 2004-Today OpenERP SA (<http://www.openerp.com>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
#
##############################################################################
-from openerp.addons.base_status.base_stage import base_stage
-import crm
from datetime import datetime
from operator import itemgetter
-from openerp.osv import fields, osv, orm
import time
+
from openerp import SUPERUSER_ID
from openerp import tools
-from openerp.tools.translate import _
-from openerp.tools import html2plaintext
-
+from openerp.addons.crm import crm
+from openerp.addons.base_status.base_stage import base_stage
from openerp.addons.base.res.res_partner import format_address
+from openerp.osv import fields, osv, orm
+from openerp.tools import html2plaintext
+from openerp.tools.translate import _
CRM_LEAD_FIELDS_TO_MERGE = ['name',
'partner_id',
_track = {
'stage_id': {
'crm.mt_lead_create': lambda self, cr, uid, obj, ctx=None: obj.probability == 0 and obj.stage_id and obj.stage_id.sequence == 1,
- 'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: obj.probability > 0 and obj.probability < 100,
- 'crm.mt_lead_won': lambda self, cr, uid, obj, ctx=None: obj.probability == 100,
+ 'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: (obj.stage_id and obj.stage_id.sequence != 1) and obj.probability < 100,
+ 'crm.mt_lead_won': lambda self, cr, uid, obj, ctx=None: obj.probability == 100 and obj.stage_id and obj.stage_id.on_change,
'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj.probability == 0 and obj.stage_id and obj.stage_id.sequence != 1,
}
}
return {'value': {}}
return {'value': {'probability': stage.probability}}
- def on_change_partner(self, cr, uid, ids, partner_id, context=None):
- result = {}
- values = {}
- if partner_id:
- partner = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
- values = {
- 'partner_name' : partner.name,
- 'street' : partner.street,
- 'street2' : partner.street2,
- 'city' : partner.city,
- 'state_id' : partner.state_id and partner.state_id.id or False,
- 'country_id' : partner.country_id and partner.country_id.id or False,
- 'email_from' : partner.email,
- 'phone' : partner.phone,
- 'mobile' : partner.mobile,
- 'fax' : partner.fax,
- }
- return {'value' : values}
-
def on_change_user(self, cr, uid, ids, user_id, context=None):
""" When changing the user, also set a section_id or restrict section id
to the ones user_id is member of. """
def _check(self, cr, uid, ids=False, context=None):
""" Override of the base.stage method.
Function called by the scheduler to process cases for date actions
- Only works on not won and lost cases.
+ Avoid won cases
"""
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 probability not in (0,100)',
+ and probability not in (100)',
(time.strftime("%Y-%m-%d %H:%M:%S"),
time.strftime('%Y-%m-%d %H:%M:%S')))
if stage_id:
self.case_set(cr, uid, [lead.id], new_stage_id=stage_id, context=context)
else:
- raise osv.except_osv(_('Warning!'), _('To relieve your sales pipe and group all Lost opportunities, configure one of your sales stage as follow:\n'
- 'probability = 0 %, select "Change Probability Automatically".\n'
- 'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
+ raise osv.except_osv(_('Warning!'),
+ _('To relieve your sales pipe and group all Lost opportunities, configure one of your sales stage as follow:\n'
+ 'probability = 0 %, select "Change Probability Automatically".\n'
+ 'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
return True
def case_mark_won(self, cr, uid, ids, context=None):
if stage_id:
self.case_set(cr, uid, [lead.id], new_stage_id=stage_id, context=context)
else:
- raise osv.except_osv(_('Warning!'), _('To relieve your sales pipe and group all Won opportunities, configure one of your sales stage as follow:\n'
- 'probability = 100 % and select "Change Probability Automatically".\n'
- 'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
+ raise osv.except_osv(_('Warning!'),
+ _('To relieve your sales pipe and group all Won opportunities, configure one of your sales stage as follow:\n'
+ 'probability = 100 % and select "Change Probability Automatically".\n'
+ 'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
return True
- def set_priority(self, cr, uid, ids, priority):
+ def set_priority(self, cr, uid, ids, priority, context=None):
""" Set lead priority
"""
- return self.write(cr, uid, ids, {'priority': priority})
+ return self.write(cr, uid, ids, {'priority': priority}, context=context)
def set_high_priority(self, cr, uid, ids, context=None):
""" Set lead priority to high
"""
- return self.set_priority(cr, uid, ids, '1')
+ return self.set_priority(cr, uid, ids, '1', context=context)
def set_normal_priority(self, cr, uid, ids, context=None):
""" Set lead priority to normal
"""
- return self.set_priority(cr, uid, ids, '3')
+ return self.set_priority(cr, uid, ids, '3', context=context)
def _merge_get_result_type(self, cr, uid, opps, context=None):
"""
sequenced_opps = []
for opportunity in opportunities:
sequence = -1
- if opportunity.stage_id and (opportunity.probability == 0 and opportunity.stage_id and opportunity.stage_id.sequence != 1):
+ if opportunity.probability == 0 and opportunity.stage_id and opportunity.stage_id.sequence != 1:
sequence = opportunity.stage_id.sequence
sequenced_opps.append(((int(sequence != -1 and opportunity.type == 'opportunity'), sequence, -opportunity.id), opportunity))
res_partner = self.pool.get('res.partner')
if partner_id:
res_partner.write(cr, uid, partner_id, {'section_id': lead.section_id and 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)
- message = _("<b>Partner</b> set to <em>%s</em>." % (lead.partner_id.name))
- self.message_post(cr, uid, [lead.id], body=message, context=context)
return res
def handle_partner_assignation(self, cr, uid, ids, action='create', partner_id=False, context=None):
res['context'] = {
'default_opportunity_id': opportunity.id,
'default_partner_id': opportunity.partner_id and opportunity.partner_id.id or False,
- 'default_partner_ids' : opportunity.partner_id and [opportunity.partner_id.id] or False,
+ 'default_partner_ids': opportunity.partner_id and [opportunity.partner_id.id] or False,
'default_user_id': uid,
'default_section_id': opportunity.section_id and opportunity.section_id.id or False,
'default_email_from': opportunity.email_from,
return res
def write(self, cr, uid, ids, vals, context=None):
- stage_pool=self.pool.get('crm.case.stage')
if vals.get('stage_id') and not vals.get('probability'):
# change probability of lead(s) if required by stage
- stage = stage_pool.browse(cr, uid, vals['stage_id'], context=context)
+ stage = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
if stage.on_change:
vals['probability'] = stage.probability
- if vals.get('probability') == 100:
- vals['stage_id'] = stage_pool.search(cr, uid, [('probability','=',100.0)],order='sequence')[0]
return super(crm_lead, self).write(cr, uid, ids, vals, context=context)
def new_mail_send(self, cr, uid, ids, context=None):
<?xml version="1.0"?>
<openerp>
- <!-- <data noupdate="1"> -->
- <data>
+ <data noupdate="1">
+
<!-- Crm stages -->
<record model="crm.case.stage" id="stage_lead1">
<field name="name">New</field>
<field name="partner_name" string="Company Name"/>
<!-- Preload all the partner's information -->
<field name="partner_id" string="Customer"
- on_change="on_change_partner(partner_id)"
+ on_change="onchange_partner_id(partner_id)"
options='{"create_name_field": "name"}'
context="{'default_name': contact_name, 'default_street': street, 'default_city': city, 'default_state_id': state_id, 'default_zip': zip, 'default_country_id': country_id, 'default_function': function, 'default_phone': phone, 'default_mobile': mobile, 'default_fax': fax, 'default_email': email_from, 'default_user_id': user_id, 'default_section_id': section_id}"/>
<label for="street" string="Address"/>
<field name="description"/>
</page>
<page string="Extra Info">
- <group>
- <group string="Categorization" groups="base.group_multi_company,base.group_no_one" name="categorization">
- <field name="company_id"
- groups="base.group_multi_company"
- widget="selection" colspan="2"/>
- </group>
- <group string="Mailings">
- <field name="opt_out"/>
- </group>
- <group string="Misc">
+ <group string="Categorization" groups="base.group_multi_company,base.group_no_one" name="categorization">
+ <field name="company_id"
+ groups="base.group_multi_company"
+ widget="selection" colspan="2"/>
+ </group>
+ <group string="Mailings">
+ <field name="opt_out"/>
+ </group>
+ <group string="Misc">
+ <group>
<field name="probability" groups="base.group_no_one"/>
<field name="active"/>
<field name="referred"/>
</group>
+ <group>
+ <field name="date_open" groups="base.group_no_one"/>
+ <field name="date_closed" groups="base.group_no_one"/>
+ </group>
</group>
</page>
</notebook>
<field name="create_date"/>
<field name="country_id" context="{'invisible_country': False}"/>
<separator/>
- <filter string="Open" name="open" domain="[('user_id', '!=', 'False'), ('probability', '!=', 100)]" help="Open and Assigned Leads"/>
- <filter string="Dead" name="dead" domain="[('probability', '=', '0'), ('stage_id.sequence', '!=', 1)]"/>
- <filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
+ <filter string="Unassigned" name="unassigned"
+ domain="[('user_id','=', False)]"
+ help="No salesperson"/>
<filter string="Assigned to Me"
domain="[('user_id','=',uid)]" context="{'invisible_section': False}"
help="Leads that are assigned to me"/>
- <filter string="Assigned to My Team(s)"
+ <filter string="Assigned to My Team(s)" groups="base.group_multi_salesteams"
domain="[('section_id.member_ids', 'in', [uid])]" context="{'invisible_section': False}"
- help="Leads that are assigned to any sales teams I am member of" groups="base.group_multi_salesteams"/>
+ help="Leads that are assigned to any sales teams I am member of"/>
+ <filter string="Dead" name="dead"
+ domain="[('probability', '=', '0'), ('stage_id.sequence', '!=', 1)]"/>
+ <separator />
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/>
<separator />
<filter string="Available for mass mailing"
<field name="stage_id"/>
<field name="probability"/>
<separator/>
- <filter string="New" name="new" domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]" help="New Opportunities"/>
- <filter string="Won" name="won" domain="[('probability', '=', 100)]"/>
- <filter string="Lost" name="lost" domain="[('probability', '=',0), ('stage_id.sequence, '!=', 1')]"/>
- <filter string="Unassigned" name="unassigned" domain="[('user_id','=', False)]" help="No salesperson"/>
- <filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]" help="Unread messages"/>
+ <filter string="New" name="new"
+ domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
+ <filter string="Won" name="won"
+ domain="[('probability', '=', 100), ('stage_id.on_change', '=', 1)]"/>
+ <filter string="Lost" name="lost"
+ domain="[('probability', '=', 0), ('stage_id.sequence', '!=', 1)]"/>
+ <filter string="Unassigned" name="unassigned"
+ domain="[('user_id','=', False)]" help="No salesperson"/>
<filter string="My Opportunities" name="assigned_to_me"
- domain="[('user_id','=',uid)]" context="{'invisible_section': False}"
+ domain="[('user_id', '=', uid)]" context="{'invisible_section': False}"
help="Opportunities that are assigned to me"/>
<filter string="Assigned to My Team(s)"
domain="[('section_id.member_ids', 'in', [uid])]" context="{'invisible_section': False}"
help="Opportunities that are assigned to any sales teams I am member of"/>
<separator/>
+ <filter string="Unread Messages" name="message_unread"
+ domain="[('message_unread', '=', True)]" help="Unread messages"/>
+ <separator/>
<group expand="0" string="Group By..." colspan="16">
<filter string="Salesperson" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Team" domain="[]" context="{'group_by':'section_id'}"/>
if context.get('active_model') == 'crm.lead' and context.get('active_ids'):
self.case_mark_lost(cr, uid, context['active_ids'], context=context)
</field>
- <field name="groups_id" eval="[(4,ref('base.group_sale_salesman'))]"/>
</record>
<record id="ir_mark_as_lost" model="ir.values">
#
##############################################################################
-from openerp.osv import fields,osv
+from openerp.osv import fields, osv
from openerp import tools
-from .. import crm
+from openerp.addons.crm import crm
MONTHS = [
('01', 'January'),
'section_id':fields.many2one('crm.case.section', 'Sales Team', readonly=True),
'channel_id':fields.many2one('crm.case.channel', 'Channel', readonly=True),
'type_id':fields.many2one('crm.case.resource.type', 'Campaign', readonly=True),
- # 'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'probability': fields.float('Probability',digits=(16,2),readonly=True, group_operator="avg"),
'planned_revenue': fields.float('Planned Revenue',digits=(16,2),readonly=True),
('opportunity','Opportunity'),
],'Type', help="Type is used to separate Leads and Opportunities"),
}
-
-
-
-
+
def init(self, cr):
"""
c.planned_revenue*(c.probability/100) as probable_revenue,
1 as nbr,
date_trunc('day',c.create_date) as create_date,
- extract('epoch' from (c.write_date-c.create_date))/(3600*24) as delay_close,
+ extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
abs(extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24)) as delay_expected,
extract('epoch' from (c.date_open-c.create_date))/(3600*24) as delay_open
FROM
<field name="creation_month" invisible="1"/>
<field name="creation_day" invisible="1"/>
<field name="deadline_month" invisible="1"/>
- <!-- <field name="state" invisible="1"/> -->
<field name="stage_id" invisible="1"/>
<field name="type_id" invisible="1"/>
<field name="channel_id" invisible="1"/>
<filter icon="terp-personal" name="lead" string="Lead" domain="[('type','=', 'lead')]" help="Show only lead"/>
<filter icon="terp-personal+" string="Opportunity" name="opportunity" domain="[('type','=','opportunity')]" help="Show only opportunity"/>
<separator/>
- <!-- <filter icon="terp-check" string="New" domain="[('state','=','draft')]" help="Leads/Opportunities which are in New state"/> -->
- <!-- <filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Leads/Opportunities which are in open state"/> -->
- <!-- <filter icon="gtk-media-pause" string="Pending" domain="[('state','=','pending')]" help="Leads/Opportunities which are in pending state"/> -->
- <!-- <filter icon="terp-dialog-close" string="Closed" domain="[('state','=','done')]" help="Leads/Opportunities which are in done state"/> -->
+ <filter string="New" name="new"
+ domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
+ <filter string="Won" name="won"
+ domain="[('probability', '=', 100), ('stage_id.on_change', '=', 1)]"/>
+ <filter string="Lost" name="lost"
+ domain="[('probability', '=', 0), ('stage_id.sequence', '!=', 1)]"/>
<separator/>
<filter string="My Sales Team(s)" icon="terp-personal+" context="{'invisible_section': False}" domain="[('section_id.user_id','=',uid)]"
help="Leads/Opportunities that are assigned to one of the sale teams I manage" groups="base.group_multi_salesteams"/>
<field name="name">crm.lead.report.tree</field>
<field name="model">crm.lead.report</field>
<field name="arch" type="xml">
- <!-- <tree colors="blue:state == 'draft';black:state in ('open','pending','done');gray:state == 'cancel' " create="false" string="Opportunities Analysis"> -->
<tree create="false" string="Opportunities Analysis">
<field name="creation_year" invisible="1"/>
<field name="creation_month" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="country_id" invisible="1"/>
- <!-- <field name="state" invisible="1"/> -->
<field name="stage_id" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="type_id" invisible="1"/>
#
##############################################################################
-from openerp.osv import fields,osv
from openerp import tools
-from .. import crm
+from openerp.addons.crm import crm
+from openerp.osv import fields, osv
+AVAILABLE_STATES = [
+ ('draft', 'Draft'),
+ ('open', 'Todo'),
+ ('cancel', 'Cancelled'),
+ ('done', 'Held'),
+ ('pending', 'Pending')
+]
class crm_phonecall_report(osv.osv):
""" Phone calls by user and section """
_name = "crm.phonecall.report"
_description = "Phone calls by user and section"
_auto = False
-
+
_columns = {
'name': fields.char('Year', size=64, required=False, readonly=True),
'user_id':fields.many2one('res.users', 'User', readonly=True),
'section_id':fields.many2one('crm.case.section', 'Section', readonly=True),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
'nbr': fields.integer('# of Cases', readonly=True),
+ 'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True),
'month':fields.selection([('01', 'January'), ('02', 'February'), \
('03', 'March'), ('04', 'April'),\
('05', 'May'), ('06', 'June'), \
<field name="user_id" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
- <!-- <field name="state" invisible="1"/> -->
+ <field name="state" invisible="1"/>
<field name="categ_id" invisible="1"/>
<field name="day" invisible="1"/>
<field name="nbr" string="#Phone calls" sum="#Phone calls"/>
<field name="model">crm.phonecall.report</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Phone calls" type="bar">
- <!-- <field name="state"/> -->
+ <field name="state"/>
<field name="nbr" operator="+"/>
<field group="True" name="user_id"/>
</graph>
<field name="model">crm.phonecall.report</field>
<field name="arch" type="xml">
<search string="Search">
-<!-- <filter icon="terp-gtk-go-back-rtl" string="Todo" domain="[('state','in',('draft','open'))]"
+ <filter icon="terp-gtk-go-back-rtl" string="Todo" domain="[('state','in',('draft','open'))]"
help="Phone calls which are in draft and open state"/>
<filter icon="terp-camera_test" string="Held" domain="[('state','=','done')]"
help="Phone calls which are in closed state"/>
<filter icon="gtk-media-pause" string="Not Held" domain="[('state','=','pending')]"
- help="Phone calls which are in pending state"/> -->
+ help="Phone calls which are in pending state"/>
<separator/>
<filter string="My Sales Team(s)" icon="terp-personal+" context="{'invisible_section': False}" domain="[('section_id.user_id','=',uid)]"
help="Phone calls that are assigned to one of the sale teams I manage" groups="base.group_multi_salesteams"/>
<filter string="Partner" icon="terp-partner" context="{'group_by':'partner_id'}" />
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
<filter string="Category" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'categ_id'}" />
- <!-- <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}" /> -->
+ <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}" />
<filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<filter string="Day" icon="terp-go-today" domain="[]" context="{'group_by':'day'}" help="Date of call"/>
<filter string="Month" icon="terp-go-month" domain="[]" context="{'group_by':'month'}" help="Month of call"/>
from openerp.tools.translate import _
from openerp.tools import html2plaintext
-CRM_HELPDESK_STATES = (
- crm.AVAILABLE_STATES[2][0], # Cancelled
- crm.AVAILABLE_STATES[3][0], # Done
- crm.AVAILABLE_STATES[4][0], # Pending
-)
+AVAILABLE_STATES = [
+ ('draft', 'New'),
+ ('cancel', 'Cancelled'),
+ ('open', 'In Progress'),
+ ('pending', 'Pending'),
+ ('done', 'Closed')
+]
+
class crm_helpdesk(base_state, base_stage, osv.osv):
""" Helpdesk Cases """
domain="['|',('section_id','=',False),('section_id','=',section_id),\
('object_id.model', '=', 'crm.helpdesk')]"),
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
- 'state': fields.selection(crm.AVAILABLE_STATES, 'Status', size=16, readonly=True,
+ 'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True,
help='The status is set to \'Draft\', when a case is created.\
\nIf the case is in progress the status is set to \'Open\'.\
\nWhen the case is over, the status is set to \'Done\'.\