diff --git a/addons/base_report_designer/plugin/openerp_report_designer.zip b/addons/base_report_designer/plugin/openerp_report_designer.zip index 22c0b7768f2..3ee0260060f 100644 Binary files a/addons/base_report_designer/plugin/openerp_report_designer.zip and b/addons/base_report_designer/plugin/openerp_report_designer.zip differ diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py index 730ce8efefb..d4359a466ca 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py @@ -54,11 +54,11 @@ class Change: def __init__(self, aVal= None, sURL=""): self.win=DBModalDialog(60, 50, 120, 90, "Connect to Open ERP Server") - self.win.addFixedText("lblVariable", 38, 12, 60, 15, "Server") + self.win.addFixedText("lblVariable", 38, 12, 25, 15, "Server ") self.win.addEdit("txtHost",-2,9,60,15,sURL[sURL.find("/")+2:sURL.rfind(":")]) - self.win.addFixedText("lblReportName",45 , 31, 60, 15, "Port") + self.win.addFixedText("lblReportName",45 , 31, 15, 15, "Port ") self.win.addEdit("txtPort",-2,28,60,15,sURL[sURL.rfind(":")+1:]) self.win.addFixedText("lblLoginName", 2, 51, 60, 15, "Protocol Connection") @@ -92,6 +92,8 @@ class Change: global url url = self.protocol[self.win.getListBoxSelectedItem("lstProtocol")]+self.win.getEditText("txtHost")+":"+self.win.getEditText("txtPort") self.sock=RPCSession(url) + desktop=getDesktop() + doc = desktop.getCurrentComponent() docinfo=doc.getDocumentInfo() docinfo.setUserFieldValue(0,url) res=self.sock.listdb() diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py index de67ea0abda..123be9b9bc2 100644 --- a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py +++ b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py @@ -192,6 +192,10 @@ class ServerParameter( unohelper.Base, XJobExecutor ): Change(aVal,url) if aVal[1]== -1: self.win.getEditText("lstDatabase") + self.win.removeListBoxItems("lstDatabase", 0, self.win.getListBoxItemCount("lstDatabase")) + self.win.setEditText("txtHost",aVal[0]) + for i in range(len(aVal[1])): + self.lstDatabase.addItem(aVal[1][i],i) elif aVal[1]==0: ErrorDialog(aVal[0],"") else: diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 9798fd09a4e..5336bdd23fb 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -22,6 +22,7 @@ import time import base64 import tools + from osv import fields from osv import osv from tools.translate import _ @@ -135,6 +136,52 @@ class crm_case(object): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) return user.context_section_id.id or False + def _find_next_stage(self, cr, uid, stage_list, index, current_seq, stage_pool, context=None): + if index + 1 == len(stage_list): + return False + next_stage_id = stage_list[index + 1] + next_stage = stage_pool.browse(cr, uid, next_stage_id, context=context) + if not next_stage: + return False + + next_seq = next_stage.sequence + if (abs(next_seq - current_seq)) >= 1: + return next_stage + else : + return self._find_next_stage(cr, uid, stage_list, index + 1, current_seq, stage_pool) + + def stage_change(self, cr, uid, ids, context=None, order='sequence'): + if not context: + context = {} + stage_pool = self.pool.get('crm.case.stage') + stage_type = context and context.get('stage_type','') + current_seq = False + next_stage_id = False + for case in self.browse(cr, uid, ids, context): + next_stage = False + data = {} + + domain = [('type', '=', stage_type),('section_ids', '=', case.section_id.id)] + if case.section_id and case.section_id.stage_ids: + domain.append(('id', 'in', map(lambda x: x.id, case.section_id.stage_ids))) + + stages = stage_pool.search(cr, uid, domain, order=order) + current_seq = case.stage_id.sequence + index = -1 + if case.stage_id and case.stage_id.id in stages: + index = stages.index(case.stage_id.id) + + next_stage = self._find_next_stage(cr, uid, stages, index, current_seq, stage_pool, context=context) + if next_stage: + next_stage_id = next_stage.id + data = {'stage_id': next_stage.id} + if next_stage.on_change: + data.update({'probability': next_stage.probability}) + self.write(cr, uid, [case.id], data, context=context) + + return next_stage_id + + 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 @@ -143,32 +190,10 @@ class crm_case(object): @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 = {} - stage_pool = self.pool.get('crm.case.stage') - model = self._name - for case in self.browse(cr, uid, ids, context): - next_stage = False - data = {} - domain = [('object_id.model', '=', model),('section_ids', '=', case.section_id.id)] - if case.section_id and case.section_id.stage_ids: - domain.append(('id', 'in', map(lambda x: x.id, case.section_id.stage_ids))) - stages = stage_pool.search(cr, uid, domain, order='sequence') - index = -1 - if case.stage_id and case.stage_id.id in stages: - index = stages.index(case.stage_id.id) - if index + 1 == len(stages): - return False - else: - next_stage = stages[index + 1] - if next_stage: - data = {'stage_id': next_stage} - stage = stage_pool.browse(cr, uid, next_stage, context=context) - if stage.on_change: - data.update({'probability': stage.probability}) - self.write(cr, uid, [case.id], data, context=context) - return next_stage - + + + return self.stage_change(cr, uid, ids, context=context, order='sequence') + 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 @@ -177,31 +202,7 @@ class crm_case(object): @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 = {} - stage_pool = self.pool.get('crm.case.stage') - model = self._name - for case in self.browse(cr, uid, ids, context): - prev_stage = False - data = {} - domain = [('object_id.model', '=', model),('section_ids', '=', case.section_id.id)] - if case.section_id and case.section_id.stage_ids: - domain.append(('id', 'in', map(lambda x: x.id, case.section_id.stage_ids))) - stages = stage_pool.search(cr, uid, domain, order='sequence') - index = 0 - if case.stage_id and case.stage_id.id in stages: - index = stages.index(case.stage_id.id) - if index == 0: - return False - else: - prev_stage = stages[index - 1] - if prev_stage: - data = {'stage_id': prev_stage} - stage = stage_pool.browse(cr, uid, prev_stage, context=context) - if stage.on_change: - data.update({'probability': stage.probability}) - self.write(cr, uid, [case.id], data, context=context) - return prev_stage + return self.stage_change(cr, uid, ids, context=context, order='sequence desc') def onchange_partner_id(self, cr, uid, ids, part, email=False): """This function returns value of partner address based on partner @@ -482,27 +483,27 @@ class crm_case_stage(osv.osv): _columns = { 'name': fields.char('Stage Name', size=64, required=True, translate=True), 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."), - 'object_id': fields.many2one('ir.model', 'Object Name'), 'probability': fields.float('Probability (%)', required=True, help="This percentage depicts the default/average probability of the Case for this stage to be a success"), 'on_change': fields.boolean('Change Probability Automatically', \ help="Change Probability on next and previous stages."), - 'requirements': fields.text('Requirements') + 'requirements': fields.text('Requirements'), + 'type': fields.selection([('lead','Lead'),('opportunity','Opportunity'),('claim','Claim'), ('fundraising','Fundraising')], 'Type'), } - def _find_object_id(self, cr, uid, context=None): - """Finds id for case object + + def _find_stage_type(self, cr, uid, context=None): + """Finds type of stage according to object. @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 """ - 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] + type = context and context.get('type', '') or '' + return type _defaults = { 'sequence': lambda *args: 1, 'probability': lambda *args: 0.0, - 'object_id' : _find_object_id + 'type': _find_stage_type, } crm_case_stage() @@ -629,6 +630,7 @@ class crm_case_stage(osv.osv): _columns = { 'section_ids':fields.many2many('crm.case.section', 'section_stage_rel', 'stage_id', 'section_id', 'Sections'), } + crm_case_stage() diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index e0bed8934f2..8cc45c75e57 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -135,7 +135,7 @@ class crm_lead(crm_case, osv.osv): ],'Type', help="Type is used to separate Leads and Opportunities"), 'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'), 'date_closed': fields.datetime('Closed', readonly=True), - 'stage_id': fields.many2one('crm.case.stage', 'Stage'), + 'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[('type','=','lead')]"), 'user_id': fields.many2one('res.users', 'Salesman',help='By Default Salesman is Administrator when create New User'), 'referred': fields.char('Referred By', size=64), 'date_open': fields.datetime('Opened', readonly=True), @@ -150,6 +150,19 @@ class crm_lead(crm_case, osv.osv): \nIf the case needs to be reviewed then the state is set to \'Pending\'.'), 'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]), } + + def _get_stage_id(self, cr, uid, context=None): + """Finds type of stage according to object. + @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 is None: + context = {} + type = context and context.get('stage_type', '') + stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('type','=',type),('sequence','>=',1)]) + return stage_ids and stage_ids[0] or False _defaults = { 'active': lambda *a: 1, @@ -160,6 +173,7 @@ class crm_lead(crm_case, osv.osv): 'section_id': crm_case._get_section, 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.lead', context=c), 'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0], + 'stage_id': _get_stage_id, } def onchange_partner_address_id(self, cr, uid, ids, add, email=False): @@ -297,7 +311,7 @@ class crm_lead(crm_case, osv.osv): return super(crm_lead,self).write(cr, uid, ids, vals, context) def stage_next(self, cr, uid, ids, context=None): - stage = super(crm_lead, self).stage_next(cr, uid, ids, context) + stage = super(crm_lead, self).stage_next(cr, uid, ids, context=context) if stage: stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, stage, context=context) if stage_obj.on_change: diff --git a/addons/crm/crm_lead_data.xml b/addons/crm/crm_lead_data.xml index 2a49e43e683..3cb34c49299 100644 --- a/addons/crm/crm_lead_data.xml +++ b/addons/crm/crm_lead_data.xml @@ -2,34 +2,39 @@ - + + Lost + + + lead + New - + lead Qualification - + lead Proposition - + lead Negotiation - + lead @@ -37,15 +42,10 @@ - + lead - - Lost - - - - + Sales Department diff --git a/addons/crm/crm_lead_menu.xml b/addons/crm/crm_lead_menu.xml index 6c74dccac15..2fff1b57d3c 100644 --- a/addons/crm/crm_lead_menu.xml +++ b/addons/crm/crm_lead_menu.xml @@ -9,7 +9,7 @@ ['|', ('type','=','lead'), ('type','=',False)] - {'search_default_current':1, 'default_type': 'lead', 'search_default_section_id': section_id} + {'search_default_current':1, 'default_type': 'lead', 'search_default_section_id': section_id, 'stage_type': 'lead'} 'Leads' allows you to manage and keep track of all first potential interests of a partner in one of your products or services. A lead is a first, unqualified, contact with a prospect or customer. After being qualified, a lead can be converted into a business opportunity with the creation of the related partner for further detailed tracking of any linked activities. You can use leads when you import a database of prospects or to integrate your website's contact form with OpenERP. diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index cda3c4fcc1f..979ab26cfd1 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -9,8 +9,8 @@ crm.case.stage form - [('object_id.model', '=', 'crm.lead')] - {'object_id':'crm.lead'} + [('type', '=', 'lead')] + {'type':'lead'} Create specific stages that will help your sales better organise their sales pipeline by maintaining them to their leads and sales opportunities. It will allow them to easily track how is positioned a specific lead or opportunity in the sales cycle. @@ -57,14 +57,14 @@ - +