Merge lp:~openerp-dev/openobject-addons/trunk-import_sugarcrm-import_opportunities-atp into lp:~openerp-dev/openobject-addons/trunk-import_sugarcrm

Proposed by Atul Patel(OpenERP)
Status: Merged
Merged at revision: 4432
Proposed branch: lp:~openerp-dev/openobject-addons/trunk-import_sugarcrm-import_opportunities-atp
Merge into: lp:~openerp-dev/openobject-addons/trunk-import_sugarcrm
Diff against target: 559 lines (+272/-226)
5 files modified
sugarcrm_syncro/__init__.py (+1/-0)
sugarcrm_syncro/import_sugarcrm.py (+220/-212)
sugarcrm_syncro/import_sugarcrm_view.xml (+2/-1)
sugarcrm_syncro/sugarcrm_fields_mapping.py (+32/-0)
sugarcrm_syncro/wizard/sugarcrm_login.py (+17/-13)
To merge this branch: bzr merge lp:~openerp-dev/openobject-addons/trunk-import_sugarcrm-import_opportunities-atp
Reviewer Review Type Date Requested Status
Bhumika Shrimali Pending
Review via email: mp+52805@code.launchpad.net

Description of the change

Hello,
1) Backlogs -2 Import CRM:
   -----------------------
          i) Import sugarcrm Leads into lead
          ii) Import sugarcrm opportunity into lead

Thanks

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'sugarcrm_syncro/__init__.py'
2--- sugarcrm_syncro/__init__.py 2011-02-17 11:07:49 +0000
3+++ sugarcrm_syncro/__init__.py 2011-03-16 10:57:00 +0000
4@@ -22,3 +22,4 @@
5 import import_sugarcrm
6 import sugar
7 import wizard
8+import sugarcrm_fields_mapping
9
10=== modified file 'sugarcrm_syncro/import_sugarcrm.py'
11--- sugarcrm_syncro/import_sugarcrm.py 2011-03-03 13:52:35 +0000
12+++ sugarcrm_syncro/import_sugarcrm.py 2011-03-16 10:57:00 +0000
13@@ -18,223 +18,231 @@
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
16 ##############################################################################
17-from operator import itemgetter
18 from osv import fields, osv
19 import sugar
20-from tools.translate import _
21+import sugarcrm_fields_mapping
22+import pprint
23+pp = pprint.PrettyPrinter(indent=4)
24+
25+def create_mapping(obj, cr, uid, res_model, open_id, sugar_id, context):
26+ model_data = {
27+ 'name': sugar_id,
28+ 'model': res_model,
29+ 'module': 'sugarcrm_import',
30+ 'res_id': open_id
31+ }
32+ model_obj = obj.pool.get('ir.model.data')
33+ model_obj.create(cr, uid, model_data, context=context)
34+
35+def find_mapped_id(obj, cr, uid, res_model, sugar_id, context):
36+ model_obj = obj.pool.get('ir.model.data')
37+ return model_obj.search(cr, uid, [('model', '=', res_model), ('module', '=', 'sugarcrm_import'), ('name', '=', sugar_id)], context=context)
38+
39+
40+def import_users(sugar_obj, cr, uid, context=None):
41+ if not context:
42+ context = {}
43+ map_user = {'id' : 'id',
44+ 'name': ['first_name', 'last_name'],
45+ 'login': 'user_name',
46+
47+
48+ 'context_lang' : 'context_lang',
49+ 'password' : 'password',
50+ '.id' : '.id',
51+ }
52+ user_obj = sugar_obj.pool.get('res.users')
53+ PortType,sessionid = sugar.login(context.get('username',''), context.get('password',''))
54+ sugar_data = sugar.search(PortType,sessionid, 'Users')
55+ for val in sugar_data:
56+ user_ids = user_obj.search(cr, uid, [('login', '=', val.get('user_name'))])
57+ if user_ids:
58+ val['.id'] = str(user_ids[0])
59+ else:
60+ val['password'] = 'sugarcrm' #default password for all user
61+
62+ val['context_lang'] = context.get('lang','en_US')
63+ fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_user)
64+ #All data has to be imported separatly because they don't have the same field
65+ user_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', context=context)
66+
67+def get_lead_status(surgar_obj, cr, uid, sugar_val,context=None):
68+ if not context:
69+ context = {}
70+ stage_id = ''
71+ stage_dict = {'status': #field in the sugarcrm database
72+ { #Mapping of sugarcrm stage : openerp opportunity stage
73+ 'New' : 'New',
74+ 'Assigned':'Qualification',
75+ 'In Progress': 'Proposition',
76+ 'Recycled': 'Negotiation',
77+ 'Dead': 'Lost'
78+ },}
79+ stage = stage_dict['status'].get(sugar_val['status'], '')
80+ stage_pool = surgar_obj.pool.get('crm.case.stage')
81+ stage_ids = stage_pool.search(cr, uid, [('type', '=', 'lead'), ('name', '=', stage)])
82+ for stage in stage_pool.browse(cr, uid, stage_ids, context):
83+ stage_id = stage.id
84+ return stage_id
85+
86+def get_opportunity_status(surgar_obj, cr, uid, sugar_val,context=None):
87+ if not context:
88+ context = {}
89+ stage_id = ''
90+ stage_dict = { 'sales_stage':
91+ {#Mapping of sugarcrm stage : openerp opportunity stage Mapping
92+ 'Need Analysis': 'New',
93+ 'Closed Lost': 'Lost',
94+ 'Closed Won': 'Won',
95+ 'Value Proposition': 'Proposition',
96+ 'Negotiation/Review': 'Negotiation'
97+ },
98+ }
99+ stage = stage_dict['sales_stage'].get(sugar_val['sales_stage'], '')
100+ stage_pool = surgar_obj.pool.get('crm.case.stage')
101+ stage_ids = stage_pool.search(cr, uid, [('type', '=', 'opportunity'), ('name', '=', stage)])
102+ for stage in stage_pool.browse(cr, uid, stage_ids, context):
103+ stage_id = stage.id
104+ return stage_id
105+
106+def import_leads(sugar_obj, cr, uid, context=None):
107+ if not context:
108+ context = {}
109+ map_lead = {
110+ 'id' : 'id',
111+ 'name': ['first_name', 'last_name'],
112+ 'contact_name': ['first_name', 'last_name'],
113+ 'description': 'description',
114+ 'partner_name': ['first_name', 'last_name'],
115+ 'email_from': 'email1',
116+ 'phone': 'phone_work',
117+ 'mobile': 'phone_mobile',
118+ 'function':'title',
119+ 'street': 'primary_address_street',
120+ 'zip': 'primary_address_postalcode',
121+ 'city':'primary_address_city',
122+ 'user_id/id' : 'assigned_user_id',
123+
124+
125+ 'stage_id.id' : 'stage_id.id',
126+ 'type' : 'type',
127+
128+ }
129+
130+ lead_obj = sugar_obj.pool.get('crm.lead')
131+ PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''))
132+ sugar_data = sugar.search(PortType, sessionid, 'Leads')
133+ for val in sugar_data:
134+ val['type'] = 'lead'
135+ stage_id = get_lead_status(sugar_obj, cr, uid, val, context)
136+ val['stage_id.id'] = stage_id
137+ fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_lead)
138+ lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', context=context)
139+
140+def import_opportunities(sugar_obj, cr, uid, context=None):
141+ if not context:
142+ context = {}
143+ map_opportunity = {'id' : 'id',
144+ 'name': 'name',
145+ 'probability': 'probability',
146+ 'planned_revenue': 'amount_usdollar',
147+ 'date_deadline':'date_closed',
148+ 'user_id/id' : 'assigned_user_id',
149+ 'stage_id.id' : 'stage_id.id',
150+ 'type' : 'type',
151+ }
152+ lead_obj = sugar_obj.pool.get('crm.lead')
153+ PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''))
154+ sugar_data = sugar.search(PortType, sessionid, 'Opportunities')
155+ for val in sugar_data:
156+ val['type'] = 'opportunity'
157+ stage_id = get_opportunity_status(sugar_obj, cr, uid, val, context)
158+ val['stage_id.id'] = stage_id
159+ fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_opportunity)
160+ lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', context=context)
161+
162+
163+
164+MAP_FIELDS = {'Opportunities': #Object Mapping name
165+ { 'dependencies' : ['Users'], #Object to import before this table
166+ 'process' : import_opportunities,
167+ },
168+ 'Users' : {'dependencies' : [],
169+ 'process' : import_users,
170+ },
171+ 'Leads':
172+ { 'dependencies' : ['Users'], #Object to import before this table
173+ 'process' : import_leads,
174+ },
175+ }
176
177 class import_sugarcrm(osv.osv):
178- """Import SugarCRM DATA"""
179-
180- _name = "import.sugarcrm"
181- _description = __doc__
182- _columns = {
183+ """Import SugarCRM DATA"""
184+
185+
186+ _name = "import.sugarcrm"
187+ _description = __doc__
188+ _columns = {
189 'lead': fields.boolean('Leads', help="If Leads is checked, SugarCRM Leads data imported in openerp crm-Lead form"),
190 'opportunity': fields.boolean('Opportunities', help="If Leads is checked, SugarCRM Leads data imported in openerp crm-Opportunity form"),
191- 'username': fields.char('User Name', size=64),
192- 'password': fields.char('Password', size=24),
193- }
194- _defaults = {
195- 'lead': lambda *a: True,
196- 'opportunity': lambda *a: True,
197- }
198-
199- def _get_all(self, cr, uid, model, sugar_val, context=None):
200- if not context:
201- context = {}
202- models = self.pool.get(model)
203- all_model_ids = models.search(cr, uid, [('name', '=', sugar_val)])
204- output = [(False, '')]
205- output = sorted([(o.id, o.name)
206- for o in models.browse(cr, uid, all_model_ids,
207- context=context)],
208- key=itemgetter(1))
209- return output
210-
211- def _get_all_states(self, cr, uid, sugar_val, context=None):
212- if not context:
213- context = {}
214- return self._get_all(
215- cr, uid, 'res.country.state', sugar_val, context=context)
216-
217- def _get_all_countries(self, cr, uid, sugar_val, context=None):
218- if not context:
219- context = {}
220- return self._get_all(
221- cr, uid, 'res.country', sugar_val, context=context)
222-
223- def _get_lead_status(self, cr, uid, sugar_val, context=None):
224- if not context:
225- context = {}
226- sugar_stage = ''
227- if sugar_val.get('status','') == 'New':
228- sugar_stage = 'New'
229- elif sugar_val.get('status','') == 'Assigned':
230- sugar_stage = 'Qualification'
231- elif sugar_val.get('status','') == 'In Progress':
232- sugar_stage = 'Proposition'
233- elif sugar_val.get('status','') == 'Recycled':
234- sugar_stage = 'Negotiation'
235- elif sugar_val.get('status','') == 'Dead':
236- sugar_stage = 'Lost'
237- else:
238- sugar_stage = ''
239- return sugar_stage
240-
241- def _get_opportunity_status(self, cr, uid, sugar_val, context=None):
242- if not context:
243- context = {}
244- sugar_stage = ''
245- if sugar_val.get('sales_stage','') == 'Need Analysis':
246- sugar_stage = 'New'
247- elif sugar_val.get('sales_stage','') == 'Closed Lost':
248- sugar_stage = 'Lost'
249- elif sugar_val.get('sales_stage','') == 'Closed Won':
250- sugar_stage = 'Won'
251- elif sugar_val.get('sales_stage','') == 'Value Proposition':
252- sugar_stage = 'Proposition'
253- elif sugar_val.get('sales_stage','') == 'Negotiation/Review':
254- sugar_stage = 'Negotiation'
255- else:
256- sugar_stage = ''
257- return sugar_stage
258-
259- def create_lead(self, cr, uid, sugar_val, country, state, context=None):
260- if not context:
261- context = {}
262-
263- lead_pool = self.pool.get("crm.lead")
264- stage_id = ''
265- stage = self._get_lead_status(cr, uid, sugar_val, context=None)
266- stage_pool = self.pool.get('crm.case.stage')
267-
268- stage_ids = stage_pool.search(cr, uid, [("type", '=', 'lead'), ('name', '=', stage)])
269-
270- for stage in stage_pool.browse(cr, uid, stage_ids):
271- stage_id = stage.id
272- vals = {'name': sugar_val.get('first_name','')+' '+ sugar_val.get('last_name',''),
273- 'contact_name': sugar_val.get('first_name','')+' '+ sugar_val.get('last_name',''),
274- 'user_id':sugar_val.get('created_by',''),
275- 'description': sugar_val.get('description',''),
276- 'partner_name': sugar_val.get('first_name','')+' '+ sugar_val.get('last_name',''),
277- 'email_from': sugar_val.get('email1',''),
278- 'stage_id': stage_id or '',
279- 'phone': sugar_val.get('phone_work',''),
280- 'mobile': sugar_val.get('phone_mobile',''),
281- 'write_date':sugar_val.get('date_modified',''),
282- 'function':sugar_val.get('title',''),
283- 'street': sugar_val.get('primary_address_street',''),
284- 'zip': sugar_val.get('primary_address_postalcode',''),
285- 'city':sugar_val.get('primary_address_city',''),
286- 'country_id': country and country[0][0] or False,
287- 'state_id': state and state[0][0] or False
288- }
289- new_lead_id = lead_pool.create(cr, uid, vals)
290- return new_lead_id
291-
292- def create_opportunity(self, cr, uid, sugar_val, country, state, context=None):
293- if not context:
294- context = {}
295- lead_pool = self.pool.get("crm.lead")
296- stage_id = ''
297- stage_pool = self.pool.get('crm.case.stage')
298- stage = self._get_opportunity_status(cr, uid, sugar_val, context)
299-
300- stage_ids = stage_pool.search(cr, uid, [("type", '=', 'opportunity'), ('name', '=', stage)])
301- for stage in stage_pool.browse(cr, uid, stage_ids):
302- stage_id = stage.id
303- vals = {'name': sugar_val.get('name',''),
304- 'probability': sugar_val.get('probability',''),
305- 'user_id': sugar_val.get('created_by', ''),
306- 'stage_id': stage_id or '',
307- 'type': 'opportunity',
308- 'user_id': sugar_val.get('created_by',''),
309- 'planned_revenue': sugar_val.get('amount_usdollar'),
310- 'write_date':sugar_val.get('date_modified',''),
311- }
312- new_opportunity_id = lead_pool.create(cr, uid, vals)
313- return new_opportunity_id
314-
315- def _get_sugar_module_name(self, cr, uid, ids, context=None):
316-
317- if not context:
318- context = {}
319-
320- sugar_name = []
321-
322- for current in self.read(cr, uid, ids):
323- if current.get('lead'):
324- sugar_name.append('Leads')
325- if current.get('opportunity'):
326- sugar_name.append('Opportunities')
327-
328- return sugar_name
329-
330-
331- def _get_module_name(self, cr, uid, ids, context=None):
332-
333- if not context:
334- context = {}
335- module_name = []
336-
337- for current in self.read(cr, uid, ids, ['lead', 'opportunity']):
338- if not current.get('lead') and not current.get('opportunity'):
339- raise osv.except_osv(_('Error !'), _('Please Select Module'))
340-
341- if current.get('lead'):
342- module_name.append('crm')
343- if current.get('opportunity'):
344- module_name.append('crm')
345-
346- ids = self.pool.get("ir.module.module").search(cr, uid, [('name', 'in', module_name),('state', '=', 'installed')])
347- if not ids:
348- for module in module_name:
349- raise osv.except_osv(_('Error !'), _('Please Install %s Module') % ((module)))
350-
351- def get_create_method(self, cr, uid, sugar_name, sugar_val, country, state, context=None):
352- if not context:
353- context = {}
354-
355- if sugar_name == "Leads":
356- self.create_lead(cr, uid, sugar_val, country, state, context)
357-
358- elif sugar_name == "Opportunities":
359- self.create_opportunity(cr, uid, sugar_val, country, state,context)
360- return {}
361-
362- def import_data(self, cr, uid, ids,context=None):
363- if not context:
364- context={}
365- sugar_val = []
366-
367- self._get_module_name(cr, uid, ids, context)
368- sugar_module = self._get_sugar_module_name(cr, uid, ids, context=None)
369-
370- PortType,sessionid = sugar.login(context.get('username',''), context.get('password',''))
371- for sugar_name in sugar_module:
372- sugar_data = sugar.search(PortType,sessionid,sugar_name)
373-
374- for val in sugar_data:
375- country = self._get_all_countries(cr, uid, val.get('primary_address_country'), context)
376- state = self._get_all_states(cr, uid, val.get('primary_address_state'), context)
377- self.get_create_method(cr, uid, sugar_name, val, country, state, context)
378-
379-
380- obj_model = self.pool.get('ir.model.data')
381- model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','import.message.form')])
382- resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])
383- return {
384- 'view_type': 'form',
385- 'view_mode': 'form',
386- 'res_model': 'import.message',
387- 'views': [(resource_id,'form')],
388- 'type': 'ir.actions.act_window',
389- 'target': 'new',
390- }
391+ 'user': fields.boolean('User', help="If Users is checked, SugarCRM Users data imported in openerp crm-Opportunity form"),
392+ 'username': fields.char('User Name', size=64),
393+ 'password': fields.char('Password', size=24),
394+ }
395+ _defaults = {
396+ 'lead': True,
397+ 'opportunity': True,
398+ 'user' : True,
399+ }
400+ def get_key(self, cr, uid, ids, context=None):
401+ """Select Key as For which Module data we want import data."""
402+ if not context:
403+ context = {}
404+ key_list = []
405+ for current in self.browse(cr, uid, ids, context):
406+ if current.lead:
407+ key_list.append('Leads')
408+ if current.opportunity:
409+ key_list.append('Opportunities')
410+ if current.user:
411+ key_list.append('Users')
412+
413+ return key_list
414+
415+ def import_all(self, cr, uid, ids, context=None):
416+ """Import all sugarcrm data into openerp module"""
417+ if not context:
418+ context = {}
419+ keys = self.get_key(cr, uid, ids, context)
420+ imported = set() #to invoid importing 2 times the sames modules
421+ for key in keys:
422+ if not key in imported:
423+ self.resolve_dependencies(cr, uid, MAP_FIELDS, MAP_FIELDS[key]['dependencies'], imported, context=context)
424+ MAP_FIELDS[key]['process'](self, cr, uid, context)
425+ imported.add(key)
426+
427+
428+ obj_model = self.pool.get('ir.model.data')
429+ model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','import.message.form')])
430+ resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])
431+ return {
432+ 'view_type': 'form',
433+ 'view_mode': 'form',
434+ 'res_model': 'import.message',
435+ 'views': [(resource_id,'form')],
436+ 'type': 'ir.actions.act_window',
437+ 'target': 'new',
438+ }
439+
440+ def resolve_dependencies(self, cr, uid, dict, dep, imported, context=None):
441+ for dependency in dep:
442+ if not dependency in imported:
443+ self.resolve_dependencies(cr, uid, dict, dict[dependency]['dependencies'], imported, context=context)
444+ dict[dependency]['process'](self, cr, uid, context)
445+ imported.add(dependency)
446+
447+
448+
449+
450
451 import_sugarcrm()
452-
453-
454-
455-
456-
457
458=== modified file 'sugarcrm_syncro/import_sugarcrm_view.xml'
459--- sugarcrm_syncro/import_sugarcrm_view.xml 2011-03-01 05:47:06 +0000
460+++ sugarcrm_syncro/import_sugarcrm_view.xml 2011-03-16 10:57:00 +0000
461@@ -13,6 +13,7 @@
462 <separator string="Select SugarCRM Module Name" colspan="4"/>
463 <field name="lead" />
464 <field name="opportunity" />
465+ <field name="user" />
466 <field name="username" invisible="1"/>
467 <field name="password" invisible="1"/>
468 </group>
469@@ -20,7 +21,7 @@
470 <group colspan="4" >
471 <label string="" colspan="2"/>
472 <button icon="gtk-cancel" special="cancel" string="_Cancel"/>
473- <button name="import_data" string="Import"
474+ <button name="import_all" string="Import"
475 type="object" icon="gtk-ok"/>
476 </group>
477 </form>
478
479=== added file 'sugarcrm_syncro/sugarcrm_fields_mapping.py'
480--- sugarcrm_syncro/sugarcrm_fields_mapping.py 1970-01-01 00:00:00 +0000
481+++ sugarcrm_syncro/sugarcrm_fields_mapping.py 2011-03-16 10:57:00 +0000
482@@ -0,0 +1,32 @@
483+# -*- coding: utf-8 -*-
484+##############################################################################
485+#
486+# OpenERP, Open Source Management Solution
487+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
488+#
489+# This program is free software: you can redistribute it and/or modify
490+# it under the terms of the GNU Affero General Public License as
491+# published by the Free Software Foundation, either version 3 of the
492+# License, or (at your option) any later version.
493+#
494+# This program is distributed in the hope that it will be useful,
495+# but WITHOUT ANY WARRANTY; without even the implied warranty of
496+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
497+# GNU Affero General Public License for more details.
498+#
499+# You should have received a copy of the GNU Affero General Public License
500+# along with this program. If not, see <http://www.gnu.org/licenses/>.
501+#
502+##############################################################################
503+
504+def sugarcrm_fields_mapp(dict_sugar, openerp_dict):
505+ fields=[]
506+ data_lst = []
507+ for key,val in openerp_dict.items():
508+ if key not in fields and dict_sugar.get(isinstance(val, list) and val[0] or val):
509+ fields.append(key)
510+ if isinstance(val, list):
511+ data_lst.append(' '.join(map(lambda x : dict_sugar[x], val)))
512+ else:
513+ data_lst.append(dict_sugar.get(val,''))
514+ return fields,data_lst
515
516=== modified file 'sugarcrm_syncro/wizard/sugarcrm_login.py'
517--- sugarcrm_syncro/wizard/sugarcrm_login.py 2011-03-03 10:58:21 +0000
518+++ sugarcrm_syncro/wizard/sugarcrm_login.py 2011-03-16 10:57:00 +0000
519@@ -23,17 +23,21 @@
520 from sugarcrm_syncro import sugar
521
522 class sugarcrm_login(osv.osv):
523- """SugarCRM Login"""
524-
525- _name = "sugarcrm.login"
526- _description = __doc__
527- _columns = {
528- 'username': fields.char('User Name', size=64, required=True),
529- 'password': fields.char('Password', size=24,required=True),
530- }
531-
532- def open_import(self, cr, uid, ids, context=None):
533-
534+ """SugarCRM Login"""
535+
536+ _name = "sugarcrm.login"
537+ _description = __doc__
538+ _columns = {
539+ 'username': fields.char('User Name', size=64, required=True),
540+ 'password': fields.char('Password', size=24,required=True),
541+ }
542+ _defaults = {
543+ 'username' : 'admin',
544+ 'password' : 'admin',
545+ }
546+
547+ def open_import(self, cr, uid, ids, context=None):
548+
549 for current in self.browse(cr, uid, ids, context):
550 PortType,sessionid = sugar.login(current.username, current.password)
551 if sessionid == '-1':
552@@ -52,5 +56,5 @@
553 'target': 'new',
554 'context': context
555 }
556-
557-sugarcrm_login()
558+
559+sugarcrm_login()

Subscribers

People subscribed via source and target branches

to all changes: