[IMP] framework to import link between objects
[odoo/odoo.git] / addons / import_sugarcrm / import_sugarcrm.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21 from osv import fields, osv
22 from operator import itemgetter
23 import sugar
24 import sugarcrm_fields_mapping
25 from tools.translate import _
26 import pprint
27 pp = pprint.PrettyPrinter(indent=4)
28
29 MODULE_NAME = 'sugarcrm_import'
30 DO_NOT_FIND_DOMAIN = [('id', '=', 0)]
31
32
33 def find_mapped_id(obj, cr, uid, res_model, sugar_id, context):
34     model_obj = obj.pool.get('ir.model.data')
35     return model_obj.search(cr, uid, [('model', '=', res_model), ('module', '=', MODULE_NAME), ('name', '=', sugar_id)], context=context)
36
37 def mapped_id(obj, cr, uid, res_model, sugar_id, id, context):
38     """
39         This function create the mapping between an already existing data and the similar data of sugarcrm
40         @param res_model: model of the mapped object
41         @param sugar_id: external sugar id
42         @param id: id in the database
43         
44         @return : the xml_id or sugar_id 
45     """
46     ir_model_data_obj = obj.pool.get('ir.model.data')
47     id = ir_model_data_obj._update(cr, uid, res_model,
48                      MODULE_NAME, {}, mode='update', xml_id=sugar_id,
49                      noupdate=True, res_id=id, context=context)
50     return sugar_id
51
52
53
54
55 def mapped_id_if_exist(sugar_obj, cr, uid, model, domain, xml_id, context=None):
56     """
57         @param domain : search domain to find existing record, should return a unique record
58         @param xml_id: xml_id give to the mapping
59         
60         @return : the xml_id if the record exist in the db, False otherwise
61     """
62     obj = sugar_obj.pool.get(model)
63     ids = obj.search(cr, uid, domain, context=context)
64     print "ids", ids, "domain", domain
65     if ids:
66         return MODULE_NAME + "." + mapped_id(obj, cr, uid, model, xml_id, ids[0], context=context)
67     return False
68
69 def import_object(sugar_obj, cr, uid, fields, data, model, table, name, domain_search=False,  context=None):
70     """
71         This method will import an object in the openerp, usefull for field that is only a char in sugar and is an object in openerp
72         use import_data that will take care to create/update or do nothing with the data
73         this method return the xml_id
74         @param fields: list of fields needed to create the object without id
75         @param data: the list of the data, in the same order as the field
76             ex : fields = ['firstname', 'lastname'] ; data = ['John', 'Mc donalds']
77         @param model: the openerp's model of the create/update object
78         @param table: the table where data come from in sugarcrm, no need to fit the real name of openerp name, just need to be unique
79         @param unique_name: the name of the object that we want to create/update get the id
80         @param domain_search : the domain that should find the unique existing record
81         
82         @return: the xml_id of the ressources
83     """
84     domain_search = not domain_search and [('name', 'ilike', name)] or domain_search
85     obj = sugar_obj.pool.get(model)
86     xml_id = generate_xml_id(name, table)
87     
88     xml_ref = mapped_id_if_exist(obj, cr, uid, model, domain_search, xml_id, context=context)
89     
90     fields.append('id')
91     data.append(xml_id)
92     
93     obj.import_data(cr, uid, fields, [data], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
94     return xml_ref or MODULE_NAME + "." + xml_id
95
96 def add_m2o_data(data, fields, column, xml_ids):
97     """
98         @param fields: list of fields
99         @param data: the list of the data, in the same order as the field
100             ex : fields = ['firstname', 'lastname'] ; data = ['John', 'Mc donalds']
101         @param column : name of the column that will contains the xml_id of o2m data
102             ex : contact_id/id
103         @param xml_ids : the list of xml id of the data
104         
105         @return fields and data with the last column "column", "xml_id1,xml_id2,xml_id3,.."
106     """
107     fields.append(column)
108     data.append(','.join(xml_ids))    
109     return fields, data
110
111
112 def generate_xml_id(name, table):
113     """
114         @param name: name of the object, has to be unique in for a given table
115         @param table : table where the record we want generate come from
116         @return: a unique xml id for record, the xml_id will be the same given the same table and same name
117                  To be used to avoid duplication of data that don't have ids
118     """
119     sugar_instance = "sugarcrm" #TODO need to be changed we information is known in the wizard
120     name = name.replace('.', '_')
121     return sugar_instance + "_" + table + "_" + name
122
123 def get_all(sugar_obj, cr, uid, model, sugar_val, context=None):
124     models = sugar_obj.pool.get(model)
125     model_code = sugar_val[0:2]
126     all_model_ids = models.search(cr, uid, [('name', '=', sugar_val)]) or models.search(cr, uid, [('code', '=', model_code.upper())]) 
127     output = sorted([(o.id, o.name)
128                      for o in models.browse(cr, uid, all_model_ids, context=context)],
129                     key=itemgetter(1))
130     return output
131
132 def get_all_states(sugar_obj, cr, uid, sugar_val, country_id, context=None):
133     """Get states or create new state unless country_id is False"""
134     
135     state_code = sugar_val[0:3] #take the tree first char
136     fields = ['country_id/id', 'name', 'code']
137     data = [country_id, sugar_val, state_code]
138     if country_id:
139         return import_object(sugar_obj, cr, uid, fields, data, 'res.country.state', 'country_state', sugar_val, context=context) 
140         
141     return False
142
143
144 def get_all_countries(sugar_obj, cr, uid, sugar_country_val, context=None):
145     """Get Country, if no country match do not create anything, to avoid duplicate country code"""
146     xml_id = generate_xml_id(sugar_country_val, 'country')
147     return mapped_id_if_exist(sugar_obj, cr, uid, 'res.country', [('name', 'ilike', sugar_country_val)], xml_id, context=context)
148
149 def import_partner_address(sugar_obj, cr, uid, context=None):
150     if not context:
151         context = {}
152     map_partner_address = {
153              'id': 'id',              
154              'name': ['first_name', 'last_name'],
155             'phone': 'phone_work',
156             'mobile': 'phone_mobile',
157             'fax': 'phone_fax',
158             'function': 'title',
159             'street': 'primary_address_street',
160             'zip': 'primary_address_postalcode',
161             'city': 'primary_address_city',
162             'country_id/id': 'country_id/id',
163             'state_id/id': 'state_id/id'
164             }
165     address_obj = sugar_obj.pool.get('res.partner.address')
166     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
167     sugar_data = sugar.search(PortType, sessionid, 'Contacts')
168     for val in sugar_data:
169         if val.get('primary_address_country'):
170             country_id = get_all_countries(sugar_obj, cr, uid, val.get('primary_address_country'), context)
171             state = get_all_states(sugar_obj,cr, uid, val.get('primary_address_state'), country_id, context)
172             val['country_id/id'] =  country_id
173             val['state_id/id'] =  state        
174         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner_address)
175         address_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
176     return True
177     
178
179
180 def import_users(sugar_obj, cr, uid, context=None):
181     map_user = {
182         'id' : 'id', 
183         'name': ['first_name', 'last_name'],
184         'login': 'user_name',
185         'context_lang' : 'context_lang',
186         'password' : 'password',
187         '.id' : '.id',
188         'context_department_id.id': 'context_department_id.id',
189     } 
190     
191     def get_users_department(sugar_obj, cr, uid, val, context=None):
192         department_id = False       
193         department_obj = sugar_obj.pool.get('hr.department')
194         department_ids = department_obj.search(cr, uid, [('name', '=', val)])
195         if department_ids:
196             department_id = department_ids[0]
197         elif val:
198             department_id = department_obj.create(cr, uid, {'name': val})
199         return department_id 
200     
201     if not context:
202         context = {}
203     department_id = False        
204     
205     user_obj = sugar_obj.pool.get('res.users')
206     PortType,sessionid = sugar.login(context.get('username',''), context.get('password',''), context.get('url',''))
207     sugar_data = sugar.search(PortType,sessionid, 'Users')
208     for val in sugar_data:
209         user_ids = user_obj.search(cr, uid, [('login', '=', val.get('user_name'))])
210         if user_ids: 
211             val['.id'] = str(user_ids[0])
212         else:
213             val['password'] = 'sugarcrm' #default password for all user
214         department_id = get_users_department(sugar_obj, cr, uid, val.get('department'), context=context)
215         val['context_department_id.id'] = department_id     
216         val['context_lang'] = context.get('lang','en_US')
217         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_user)
218         #All data has to be imported separatly because they don't have the same field
219         user_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
220     return True
221
222 def get_lead_status(surgar_obj, cr, uid, sugar_val,context=None):
223     if not context:
224         context = {}
225     stage_id = False
226     stage_dict = {'status': #field in the sugarcrm database
227         { #Mapping of sugarcrm stage : openerp opportunity stage
228             'New' : 'New',
229             'Assigned':'Qualification',
230             'In Progress': 'Proposition',
231             'Recycled': 'Negotiation',
232             'Dead': 'Lost'
233         },}
234     stage = stage_dict['status'].get(sugar_val['status'], '')
235     stage_pool = surgar_obj.pool.get('crm.case.stage')
236     stage_ids = stage_pool.search(cr, uid, [('type', '=', 'lead'), ('name', '=', stage)])
237     for stage in stage_pool.browse(cr, uid, stage_ids, context):
238         stage_id = stage.id
239     return stage_id
240
241 def get_lead_state(surgar_obj, cr, uid, sugar_val,context=None):
242     if not context:
243         context = {}
244     state = False
245     state_dict = {'status': #field in the sugarcrm database
246         { #Mapping of sugarcrm stage : openerp opportunity stage
247             'New' : 'draft',
248             'Assigned':'open',
249             'In Progress': 'open',
250             'Recycled': 'cancel',
251             'Dead': 'done'
252         },}
253     state = state_dict['status'].get(sugar_val['status'], '')
254     return state
255
256
257
258 def get_user_address(sugar_obj, cr, uid, val, context=None):
259     address_obj = sugar_obj.pool.get('res.partner.address')
260     map_user_address = {
261     'name': ['first_name', 'last_name'],
262     'city': 'address_city',
263     'country_id/id': 'country_id/id',
264     'state_id/id': 'state_id/id',
265     'street': 'address_street',
266     'zip': 'address_postalcode',
267     }
268     address_ids = address_obj.search(cr, uid, [('name', 'like', val.get('first_name') +' '+ val.get('last_name'))])
269     if val.get('address_country'):
270         country_id = get_all_countries(sugar_obj, cr, uid, val.get('address_country'), context)
271         state_id = get_all_states(sugar_obj, cr, uid, val.get('address_state'), country_id, context)
272         val['country_id/id'] =  country_id
273         val['state_id/id'] =  state_id
274     fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_user_address)
275     dict_val = dict(zip(fields,datas))
276     if address_ids:
277         address_obj.write(cr, uid, address_ids, dict_val)
278     else:        
279         new_address_id = address_obj.create(cr,uid, dict_val)
280         return new_address_id
281     return True
282
283 def get_address_type(sugar_obj, cr, uid, val, map_partner_address, type, context=None):
284         address_obj = sugar_obj.pool.get('res.partner.address')
285         if type == 'invoice':
286             type_address = 'billing'
287         else:
288             type_address = 'shipping'     
289     
290         map_partner_address.update({
291             'street': type_address + '_address_street',
292             'zip': type_address +'_address_postalcode',
293             'city': type_address +'_address_city',
294              'country_id/id': 'country_id/id',
295              'type': 'type',
296             })
297         val['type'] = type
298         if val.get(type_address +'_address_country'):
299             country_id = get_all_countries(sugar_obj, cr, uid, val.get(type_address +'_address_country'), context)
300             state = get_all_states(sugar_obj, cr, uid, val.get(type_address +'_address_state'), country_id, context)
301             val['country_id/id'] =  country_id
302             val['state_id/id'] =  state
303         
304         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner_address)
305         print 'fields', fields
306         print 'data'
307         pp.pprint(datas)
308         unique_name = val['id'] + '_address_' + type
309         #Convert To list into Dictionary(Key, val). value pair.
310         #dict_val = dict(zip(fields,datas))
311         #pp.pprint(dict_val)
312         return import_object(sugar_obj, cr, uid, fields, datas, 'res.partner.address', 'contact', unique_name, DO_NOT_FIND_DOMAIN, context=context)
313         #new_address_id = address_obj.create(cr,uid, dict_val)
314         #return new_address_id
315     
316 def get_address(sugar_obj, cr, uid, val, context=None):
317     address_id=[]
318     map_partner_address = {
319             'name': 'name',
320             'partner_id/id': 'account_id',
321             'phone': 'phone_office',
322             'mobile': 'phone_mobile',
323             'fax': 'phone_fax',
324             'type': 'type',
325             }
326     if val.get('billing_address_street'):
327         id = get_address_type(sugar_obj, cr, uid, val, map_partner_address, 'invoice', context)
328         print "xml id billing", id
329         address_id.append(id)
330             
331     if val.get('shipping_address_street'):
332         id = get_address_type(sugar_obj, cr, uid, val, map_partner_address, 'delivery', context)
333         print "xml id shipping", id
334         address_id.append(id)
335     return address_id
336
337 def import_partners(sugar_obj, cr, uid, context=None):
338     if not context:
339         context = {}
340     map_partner = {
341                 'id': 'id',
342                 'name': 'name',
343                 'website': 'website',
344                 'user_id/id': 'assigned_user_id',
345                 'ref': 'sic_code',
346                 'comment': ['__prettyprint__', 'description', 'employees', 'ownership', 'annual_revenue', 'rating', 'industry', 'ticker_symbol'],
347                 'customer': 'customer',
348                 'supplier': 'supplier', 
349                 }
350     partner_obj = sugar_obj.pool.get('res.partner')
351     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
352     sugar_data = sugar.search(PortType, sessionid, 'Accounts')
353     for val in sugar_data:
354         add_id = get_address(sugar_obj, cr, uid, val, context)
355         val['customer'] = '1'
356         val['supplier'] = '0'
357         fields, data = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner)
358         fields, data = add_m2o_data(data, fields, 'address/id', add_id)
359         print "fields, data"
360         print fields
361         print data
362         partner_obj.import_data(cr, uid, fields, [data], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
363     return True
364
365 def get_category(sugar_obj, cr, uid, model, name, context=None):
366     categ_id = False
367     categ_obj = sugar_obj.pool.get('crm.case.categ')
368     categ_ids = categ_obj.search(cr, uid, [('object_id.model','=',model), ('name', 'like', name)] )
369     if categ_ids:
370         categ_id = categ_ids[0]
371     else:
372         model_ids = sugar_obj.pool.get('ir.model').search(cr, uid, [('model', '=', model)], context=context)
373         model = model_ids and model_ids[0] or False
374         categ_id = categ_obj.create(cr, uid, {'name': name, 'object_id': model})
375     return categ_id     
376
377 def get_alarm_id(sugar_obj, cr, uid, val, context=None):
378     
379     alarm_dict = {'60': '1 minute before',
380                   '300': '5 minutes before',
381                   '600': '10 minutes before',
382                   '900': '15 minutes before',
383                   '1800':'30 minutes before',
384                   '3600': '1 hour before',
385      }
386     alarm_id = False
387     alarm_obj = sugar_obj.pool.get('res.alarm')
388     if alarm_dict.get(val):
389         alarm_ids = alarm_obj.search(cr, uid, [('name', 'like', alarm_dict.get(val))])
390         for alarm in alarm_obj.browse(cr, uid, alarm_ids, context):
391             alarm_id = alarm.id
392     return alarm_id 
393     
394 def get_meeting_state(sugar_obj, cr, uid, val,context=None):
395     if not context:
396         context = {}
397     state = False
398     state_dict = {'status': #field in the sugarcrm database
399         { #Mapping of sugarcrm stage : openerp meeting stage
400             'Planned' : 'draft',
401             'Held':'open',
402             'Not Held': 'draft',
403         },}
404     state = state_dict['status'].get(val, '')
405     return state    
406
407 def get_task_state(sugar_obj, cr, uid, val, context=None):
408     if not context:
409         context = {}
410     state = False
411     state_dict = {'status': #field in the sugarcrm database
412         { #Mapping of sugarcrm stage : openerp meeting stage
413             'Completed' : 'done',
414             'Not Started':'draft',
415             'In Progress': 'open',
416             'Pending Input': 'draft',
417             'deferred': 'cancel'
418         },}
419     state = state_dict['status'].get(val, '')
420     return state    
421
422 def get_project_state(sugar_obj, cr, uid, val,context=None):
423     if not context:
424         context = {}
425     state = False
426     state_dict = {'status': #field in the sugarcrm database
427         { #Mapping of sugarcrm staus : openerp Projects state
428             'Draft' : 'draft',
429             'In Review': 'open',
430             'Published': 'close',
431         },}
432     state = state_dict['status'].get(val, '')
433     return state    
434
435 def get_project_task_state(sugar_obj, cr, uid, val,context=None):
436     if not context:
437         context = {}
438     state = False
439     state_dict = {'status': #field in the sugarcrm database
440         { #Mapping of sugarcrm status : openerp Porject Tasks state
441              'Not Started': 'draft',
442              'In Progress': 'open',
443              'Completed': 'done',
444             'Pending Input': 'pending',
445             'Deferred': 'cancelled',
446         },}
447     state = state_dict['status'].get(val, '')
448     return state    
449
450 def get_project_task_priority(sugar_obj, cr, uid, val,context=None):
451     if not context:
452         context = {}
453     priority = False
454     priority_dict = {'priority': #field in the sugarcrm database
455         { #Mapping of sugarcrm status : openerp Porject Tasks state
456             'High': '0',
457             'Medium': '2',
458             'Low': '3'
459         },}
460     priority = priority_dict['priority'].get(val, '')
461     return priority    
462
463
464 def get_account(sugar_obj, cr, uid, val, context=None):
465     if not context:
466         context = {}
467     partner_id = False    
468     partner_address_id = False
469     model_obj = sugar_obj.pool.get('ir.model.data')
470     address_obj = sugar_obj.pool.get('res.partner.address')
471     if val.get('parent_type') == 'Accounts':
472         model_ids = model_obj.search(cr, uid, [('name', '=', val.get('parent_id')), ('model', '=', 'res.partner')])
473         if model_ids:
474             model = model_obj.browse(cr, uid, model_ids)[0]
475             partner_id = model.res_id
476             address_ids = address_obj.search(cr, uid, [('partner_id', '=', partner_id)])
477             partner_address_id = address_ids and address_ids[0]
478             
479     if val.get('parent_type') == 'Contacts':
480         model_ids = model_obj.search(cr, uid, [('name', '=', val.get('parent_id')), ('model', '=', 'res.partner.address')])
481         for model in model_obj.browse(cr, uid, model_ids):
482             partner_address_id = model.res_id
483             address_id = address_obj.browse(cr, uid, partner_address_id)
484             partner_id = address_id and address_id.partner_id or False
485     return partner_id, partner_address_id                             
486
487 def import_tasks(sugar_obj, cr, uid, context=None):
488     if not context:
489         context = {}
490     map_task = {'id' : 'id',
491                 'name': 'name',
492                 'date': 'date_start',
493                 'date_deadline' : 'date_due',
494                 'user_id/id': 'assigned_user_id',
495                 'categ_id/.id': 'categ_id/.id',
496                 'partner_id/.id': 'partner_id/.id',
497                 'partner_address_id/.id': 'partner_address_id/.id',
498                 'state': 'state'
499     }
500     meeting_obj = sugar_obj.pool.get('crm.meeting')
501     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
502     categ_id = get_category(sugar_obj, cr, uid, 'crm.meeting', 'Tasks')
503     sugar_data = sugar.search(PortType, sessionid, 'Tasks')
504     for val in sugar_data:
505         partner_xml_id = find_mapped_id(sugar_obj, cr, uid, 'res.partner.address', val.get('contact_id'), context)
506         if not partner_xml_id:
507             raise osv.except_osv(_('Warning !'), _('Reference Contact %s cannot be created, due to Lower Record Limit in SugarCRM Configuration.') % val.get('contact_name'))
508         partner_id, partner_address_id = get_account(sugar_obj, cr, uid, val, context)
509         val['partner_id/.id'] = partner_id
510         val['partner_address_id/.id'] = partner_address_id
511         val['categ_id/.id'] = categ_id
512         val['state'] = get_task_state(sugar_obj, cr, uid, val.get('status'), context=None)
513         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_task)
514         meeting_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
515     return True    
516     
517 def get_attendee_id(sugar_obj, cr, uid, PortType, sessionid, module_name, module_id, context=None):
518     if not context:
519         context = {}
520     model_obj = sugar_obj.pool.get('ir.model.data')
521     att_obj = sugar_obj.pool.get('calendar.attendee')
522     meeting_obj = sugar_obj.pool.get('crm.meeting')
523     user_dict = sugar.user_get_attendee_list(PortType, sessionid, module_name, module_id)
524     for user in user_dict: 
525         user_model_ids = find_mapped_id(sugar_obj, cr, uid, 'res.users', user.get('id'), context)
526         user_resource_id = model_obj.browse(cr, uid, user_model_ids)        
527         if user_resource_id:
528             user_id = user_resource_id[0].res_id 
529             attend_ids = att_obj.search(cr, uid, [('user_id', '=', user_id)])
530             if attend_ids:
531                 attendees = attend_ids[0]
532             else:      
533                 attendees = att_obj.create(cr, uid, {'user_id': user_id, 'email': user.get('email1')})
534             meeting_model_ids = find_mapped_id(sugar_obj, cr, uid, 'crm.meeting', module_id, context)
535             meeting_xml_id = model_obj.browse(cr, uid, meeting_model_ids)
536             if meeting_xml_id:
537                 meeting_obj.write(cr, uid, [meeting_xml_id[0].res_id], {'attendee_ids': [(4, attendees)]})       
538     return True   
539     
540 def import_meetings(sugar_obj, cr, uid, context=None):
541     if not context:
542         context = {}
543     map_meeting = {'id' : 'id',
544                     'name': 'name',
545                     'date': 'date_start',
546                     'duration': ['duration_hours', 'duration_minutes'],
547                     'location': 'location',
548                     'alarm_id/.id': 'alarm_id/.id',
549                     'user_id/id': 'assigned_user_id',
550                     'partner_id/.id':'partner_id/.id',
551                     'partner_address_id/.id':'partner_address_id/.id',
552                     'state': 'state'
553     }
554     meeting_obj = sugar_obj.pool.get('crm.meeting')
555     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
556     sugar_data = sugar.search(PortType, sessionid, 'Meetings')
557     for val in sugar_data:
558         partner_id, partner_address_id = get_account(sugar_obj, cr, uid, val, context)
559         val['partner_id/.id'] = partner_id
560         val['partner_address_id/.id'] = partner_address_id
561         val['state'] = get_meeting_state(sugar_obj, cr, uid, val.get('status'),context)
562         val['alarm_id/.id'] = get_alarm_id(sugar_obj, cr, uid, val.get('reminder_time'), context)
563         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_meeting)
564         meeting_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
565         get_attendee_id(sugar_obj, cr, uid, PortType, sessionid, 'Meetings', val.get('id'), context)
566     return True    
567
568 def get_calls_state(sugar_obj, cr, uid, val,context=None):
569     if not context:
570         context = {}
571     state = False
572     state_dict = {'status': #field in the sugarcrm database
573         { #Mapping of sugarcrm stage : openerp calls stage
574             'Planned' : 'open',
575             'Held':'done',
576             'Not Held': 'pending',
577         },}
578     state = state_dict['status'].get(val, '')
579     return state   
580
581 def import_calls(sugar_obj, cr, uid, context=None):
582     if not context:
583         context = {}
584     map_calls = {'id' : 'id',
585                     'name': 'name',
586                     'date': 'date_start',
587                     'duration': ['duration_hours', 'duration_minutes'],
588                     'user_id/id': 'assigned_user_id',
589                     'partner_id/.id': 'partner_id/.id',
590                     'partner_address_id/.id': 'partner_address_id/.id',
591                     'categ_id/.id': 'categ_id/.id',
592                     'state': 'state',
593     }
594     phonecall_obj = sugar_obj.pool.get('crm.phonecall')
595     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
596     sugar_data = sugar.search(PortType, sessionid, 'Calls')
597     for val in sugar_data:
598         categ_id = get_category(sugar_obj, cr, uid, 'crm.phonecall', val.get('direction'))         
599         val['categ_id/.id'] = categ_id
600         partner_id, partner_address_id = get_account(sugar_obj, cr, uid, val, context)
601         val['partner_id/.id'] = partner_id
602         val['partner_address_id/.id'] = partner_address_id
603         val['state'] =  get_calls_state(sugar_obj, cr, uid, val.get('status'), context)  
604         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_calls)
605         phonecall_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
606     return True
607     
608 def import_resources(sugar_obj, cr, uid, context=None):
609     if not context:
610         context = {}
611     map_resource = {'id' : 'user_hash',
612                     'name': ['first_name', 'last_name'],
613     }
614     resource_obj = sugar_obj.pool.get('resource.resource')
615     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
616     sugar_data = sugar.search(PortType, sessionid, 'Employees')
617     for val in sugar_data:
618         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_resource)
619         resource_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
620     return True    
621
622 def get_bug_priority(sugar_obj, cr, uid, val,context=None):
623     if not context:
624         context = {}
625     priority = False
626     priority_dict = {'priority': #field in the sugarcrm database
627         { #Mapping of sugarcrm priority : openerp bugs priority
628             'Urgent': '1',
629             'High': '2',
630             'Medium': '3',
631             'Low': '4'
632         },}
633     priority = priority_dict['priority'].get(val, '')
634     return priority    
635
636 def get_bug_state(sugar_obj, cr, uid, val,context=None):
637     if not context:
638         context = {}
639     state = False
640     state_dict = {'status': #field in the sugarcrm database
641         { #Mapping of sugarcrm status : openerp Bugs state
642             'New' : 'draft',
643             'Assigned':'open',
644             'Closed': 'done',
645             'Pending': 'pending',
646             'Rejected': 'cancel',
647         },}
648     state = state_dict['status'].get(val, '')
649     return state
650     
651 def get_issue_related_project(sugar_obj,cr,uid, PortType, sessionid, val, context=None):
652     if not context:
653         context={}
654     project_id = False        
655     model_obj = sugar_obj.pool.get('ir.model.data')
656     project_obj = sugar_obj.pool.get('project.project')
657     sugar_bug_project = sugar.relation_search(PortType, sessionid, 'Bugs', module_id=val.get('id'), related_module='Project', query=None, deleted=None)
658     for project_id in sugar_bug_project:
659         model_ids = find_mapped_id(sugar_obj, cr, uid, 'project.project', project_id, context)
660         if model_ids:
661             model_id = model_obj.browse(cr, uid, model_ids)[0].res_id
662             project_id = project_obj.browse(cr, uid, model_id).id
663     return project_id     
664
665 def import_bug(sugar_obj, cr, uid, context=None):
666     if not context:
667         context = {}
668     map_resource = {'id' : 'id',
669                     'name': 'name',
670                     'project_id/.id':'project_id/.id',
671                     'categ_id.id': 'categ_id.id',
672                     'priority':'priority',
673                     'description': 'description',
674                     'state': 'state',
675     }
676     issue_obj = sugar_obj.pool.get('project.issue')
677     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
678     sugar_data = sugar.search(PortType, sessionid, 'Bugs')
679     for val in sugar_data:
680         val['project_id/.id'] = get_issue_related_project(sugar_obj,cr,uid, PortType, sessionid, val, context)
681         val['categ_id.id'] = get_category(sugar_obj, cr, uid, 'project.issue', val.get('type'))
682         val['priority'] = get_bug_priority(sugar_obj, cr, uid, val.get('priority'),context)
683         val['state'] = get_bug_state(sugar_obj, cr, uid, val.get('status'),context)
684         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_resource)
685         issue_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
686     return True    
687
688 def get_job_id(sugar_obj, cr, uid, val, context=None):
689     if not context:
690         context={}
691     job_id = False    
692     job_obj = sugar_obj.pool.get('hr.job')        
693     job_ids = job_obj.search(cr, uid, [('name', '=', val)])
694     if job_ids:
695         job_id = job_ids[0]
696     else:
697         job_id = job_obj.create(cr, uid, {'name': val})
698     return job_id
699     
700 def get_attachment(sugar_obj, cr, uid, val, model, File, context=None):
701     if not context:
702         context = {}
703     attachment_obj = sugar_obj.pool.get('ir.attachment')
704     model_obj = sugar_obj.pool.get('ir.model.data')
705     mailgate_obj = sugar_obj.pool.get('mailgate.message')
706     new_attachment_id = attachment_obj.create(cr, uid, {'name': val.get('name'), 'datas': File, 'res_id': val['res_id'],'res_model': val['model']})
707     message_model_ids = find_mapped_id(sugar_obj, cr, uid, model, val.get('id'), context)
708     message_xml_id = model_obj.browse(cr, uid, message_model_ids)
709     if message_xml_id:
710         mailgate_obj.write(cr, uid, [message_xml_id[0].res_id], {'attachment_ids': [(4, new_attachment_id)]})             
711     return True    
712     
713 def import_history(sugar_obj, cr, uid, context=None):
714     if not context:
715         context = {}
716     map_attachment = {'id' : 'id',
717                       'name':'name',
718                       'date':'date_entered',
719                       'user_id/id': 'assigned_user_id',
720                       'description': ['description', 'description_html'],
721                       'res_id': 'res_id',
722                       'model': 'model',
723                       'partner_id.id' : 'partner_id.id',
724     }
725     mailgate_obj = sugar_obj.pool.get('mailgate.message')
726     model_obj =  sugar_obj.pool.get('ir.model.data')
727     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
728     sugar_data = sugar.search(PortType, sessionid, 'Notes')
729     for val in sugar_data:
730         File = sugar.attachment_search(PortType, sessionid, 'Notes', val.get('id'))
731         model_ids = model_obj.search(cr, uid, [('name', 'like', val.get('parent_id'))])
732         for model in model_obj.browse(cr, uid, model_ids):
733             val['res_id'] = model.res_id
734             val['model'] = model.model
735         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_attachment)   
736         mailgate_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
737         get_attachment(sugar_obj, cr, uid, val, 'mailgate.message', File, context)
738     return True       
739     
740 def import_employees(sugar_obj, cr, uid, context=None):
741     if not context:
742         context = {}
743     map_employee = {'id' : 'user_hash',
744                     'resource_id/.id': 'resource_id/.id',
745                     'name': ['first_name', 'last_name'],
746                     'work_phone': 'phone_work',
747                     'mobile_phone':  'phone_mobile',
748                     'user_id/name': ['first_name', 'last_name'], 
749                     'address_home_id/.id': 'address_home_id/.id',
750                     'notes': 'description',
751                     #TODO: Creation of Employee create problem.
752                  #   'coach_id/id': 'reports_to_id',
753                     'job_id/.id': 'job_id/.id'
754     }
755     employee_obj = sugar_obj.pool.get('hr.employee')
756     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
757     sugar_data = sugar.search(PortType, sessionid, 'Employees')
758     for val in sugar_data:
759         address_id = get_user_address(sugar_obj, cr, uid, val, context)
760         val['address_home_id/.id'] = address_id
761         model_ids = find_mapped_id(sugar_obj, cr, uid, 'resource.resource', val.get('user_hash')+ '_resource_resource', context)
762         resource_id = sugar_obj.pool.get('ir.model.data').browse(cr, uid, model_ids)
763         if resource_id:
764             val['resource_id/.id'] = resource_id[0].res_id
765         val['job_id/.id'] = get_job_id(sugar_obj, cr, uid, val.get('title'), context)
766         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_employee)
767         employee_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
768     return True
769
770 def get_contact_title(sugar_obj, cr, uid, salutation, domain, context=None):
771     fields = ['shortcut', 'name', 'domain']
772     data = [salutation, salutation, domain]
773     return import_object(sugar_obj, cr, uid, fields, data, 'res.partner.title', 'contact_title', salutation, [('shortcut', '=', salutation)], context=context)
774
775
776     
777         
778     
779     
780 def import_emails(sugar_obj, cr, uid, context=None):
781     if not context:
782         context= {}
783     map_emails = {'id': 'id',
784     'name':'name',
785     'date':'date_sent',
786     'email_from': 'from_addr_name',
787     'email_to': 'reply_to_addr',
788     'email_cc': 'cc_addrs_names',
789     'email_bcc': 'bcc_addrs_names',
790     'message_id': 'message_id',
791     'user_id/id': 'assigned_user_id',
792     'description': ['description', 'description_html'],
793     'res_id': 'res_id',
794     'model': 'model',
795     }
796     mailgate_obj = sugar_obj.pool.get('mailgate.message')
797     model_obj = sugar_obj.pool.get('ir.model.data')
798     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
799     sugar_data = sugar.search(PortType, sessionid, 'Emails')
800     for val in sugar_data:
801         model_ids = model_obj.search(cr, uid, [('name', 'like', val.get('parent_id'))])
802         for model in model_obj.browse(cr, uid, model_ids):
803             val['res_id'] = model.res_id
804             val['model'] = model.model
805         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_emails)
806         mailgate_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
807     return True    
808
809
810 #TODO more simplier use xml id please !!!!    
811 def get_project_account(sugar_obj,cr,uid, PortType, sessionid, val, context=None):
812     if not context:
813         context={}
814     partner_id = False
815     partner_invoice_id = False        
816     model_obj = sugar_obj.pool.get('ir.model.data')
817     partner_obj = sugar_obj.pool.get('res.partner')
818     partner_address_obj = sugar_obj.pool.get('res.partner.address')
819     sugar_project_account = sugar.relation_search(PortType, sessionid, 'Project', module_id=val.get('id'), related_module='Accounts', query=None, deleted=None)
820     for account_id in sugar_project_account:
821         model_ids = find_mapped_id(sugar_obj, cr, uid, 'res.partner', account_id, context)
822         if model_ids:
823             model_id = model_obj.browse(cr, uid, model_ids)[0].res_id
824             partner_id = partner_obj.browse(cr, uid, model_id).id
825             address_ids = partner_address_obj.search(cr, uid, [('partner_id', '=', partner_id),('type', '=', 'invoice')])
826             partner_invoice_id = address_ids[0] 
827     return partner_id, partner_invoice_id      
828     
829 def import_projects(sugar_obj, cr, uid, context=None):
830     if not context:
831         context = {}
832     map_project = {'id': 'id',
833         'name': 'name',
834         'date_start': 'estimated_start_date',
835         'date': 'estimated_end_date',
836         'user_id/id': 'assigned_user_id',
837         'partner_id/.id': 'partner_id/.id',
838         'contact_id/.id': 'contact_id/.id', 
839          'state': 'state'   
840     }
841     project_obj = sugar_obj.pool.get('project.project')
842     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
843     sugar_data = sugar.search(PortType, sessionid, 'Project')
844     for val in sugar_data:
845         partner_id, partner_invoice_id = get_project_account(sugar_obj,cr,uid, PortType, sessionid, val, context) 
846         val['partner_id/.id'] = partner_id
847         val['contact_id/.id'] = partner_invoice_id 
848         val['state'] = get_project_state(sugar_obj, cr, uid, val.get('status'),context)
849         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_project)
850         project_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
851     return True 
852
853
854 def import_project_tasks(sugar_obj, cr, uid, context=None):
855     if not context:
856         context = {}
857     map_project_task = {'id': 'id',
858         'name': 'name',
859         'date_start': 'date_start',
860         'date_end': 'date_finish',
861         'progress': 'progress',
862         'project_id/name': 'project_name',
863         'planned_hours': 'planned_hours',
864         'total_hours': 'total_hours',        
865         'priority': 'priority',
866         'description': 'description',
867         'user_id/id': 'assigned_user_id',
868          'state': 'state'   
869     }
870     task_obj = sugar_obj.pool.get('project.task')
871     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
872     sugar_data = sugar.search(PortType, sessionid, 'ProjectTask')
873     for val in sugar_data:
874         val['state'] = get_project_task_state(sugar_obj, cr, uid, val.get('status'),context)
875         val['priority'] = get_project_task_priority(sugar_obj, cr, uid, val.get('priority'),context)
876         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_project_task)
877         task_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
878     return True 
879     
880 def import_leads(sugar_obj, cr, uid, context=None):
881     if not context:
882         context = {}
883     map_lead = {
884             'id' : 'id',
885             'name': ['first_name', 'last_name'],
886             'contact_name': ['first_name', 'last_name'],
887             'description': ['description', 'refered_by', 'lead_source', 'lead_source_description', 'website'],
888             'partner_name': 'account_name',
889             'email_from': 'email1',
890             'phone': 'phone_work',
891             'mobile': 'phone_mobile',
892             'title.id': 'title.id',
893             'function':'title',
894             'street': 'primary_address_street',
895             'street2': 'alt_address_street',
896             'zip': 'primary_address_postalcode',
897             'city':'primary_address_city',
898             'user_id/id' : 'assigned_user_id',
899             'stage_id.id' : 'stage_id.id',
900             'type' : 'type',
901             'state': 'state',
902             }
903         
904     lead_obj = sugar_obj.pool.get('crm.lead')
905     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
906     sugar_data = sugar.search(PortType, sessionid, 'Leads')
907     for val in sugar_data:
908         if val.get('opportunity_id'):
909             continue
910         title_id = get_contact_title(sugar_obj, cr, uid, val.get('salutation'), 'Contact', context)
911         val['title/id'] = title_id
912         val['type'] = 'lead'
913         stage_id = get_lead_status(sugar_obj, cr, uid, val, context)
914         val['stage_id.id'] = stage_id
915         val['state'] = get_lead_state(sugar_obj, cr, uid, val,context)
916         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_lead)
917         lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
918     return True
919
920 def get_opportunity_contact(sugar_obj,cr,uid, PortType, sessionid, val, partner_xml_id, context=None):
921     if not context:
922         context={}
923     partner_contact_name = False        
924     model_obj = sugar_obj.pool.get('ir.model.data')
925     partner_address_obj = sugar_obj.pool.get('res.partner.address')
926     model_account_ids = model_obj.search(cr, uid, [('res_id', '=', partner_xml_id[0]), ('model', '=', 'res.partner'), ('module', '=', MODULE_NAME)])
927     model_xml_id = model_obj.browse(cr, uid, model_account_ids)[0].name 
928     sugar_account_contact = set(sugar.relation_search(PortType, sessionid, 'Accounts', module_id=model_xml_id, related_module='Contacts', query=None, deleted=None))
929     sugar_opportunities_contact = set(sugar.relation_search(PortType, sessionid, 'Opportunities', module_id=val.get('id'), related_module='Contacts', query=None, deleted=None))
930     sugar_contact = list(sugar_account_contact.intersection(sugar_opportunities_contact))
931     if sugar_contact: 
932         for contact in sugar_contact:
933             model_ids = find_mapped_id(sugar_obj, cr, uid, 'res.partner.address', contact, context)
934             if model_ids:
935                 model_id = model_obj.browse(cr, uid, model_ids)[0].res_id
936                 address_id = partner_address_obj.browse(cr, uid, model_id)
937                 partner_address_obj.write(cr, uid, [address_id.id], {'partner_id': partner_xml_id[0]})
938                 partner_contact_name = address_id.name
939             else:
940                 partner_contact_name = val.get('account_name')    
941     return partner_contact_name 
942
943 def import_opportunities(sugar_obj, cr, uid, context=None):
944     if not context:
945         context = {}
946     map_opportunity = {'id' : 'id',
947         'name': 'name',
948         'probability': 'probability',
949         'partner_id/name': 'account_name',
950         'title_action': 'next_step',
951         'partner_address_id/name': 'partner_address_id/name',
952         'planned_revenue': 'amount',
953         'date_deadline':'date_closed',
954         'user_id/id' : 'assigned_user_id',
955         'stage_id/id' : 'stage_id/id',
956         'type' : 'type',
957         'categ_id.id': 'categ_id.id'
958     }
959     lead_obj = sugar_obj.pool.get('crm.lead')
960     partner_obj = sugar_obj.pool.get('res.partner')
961     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
962     sugar_data = sugar.search(PortType, sessionid, 'Opportunities')
963     for val in sugar_data:
964         partner_xml_id = partner_obj.search(cr, uid, [('name', 'like', val.get('account_name'))])
965         if not partner_xml_id:
966             raise osv.except_osv(_('Warning !'), _('Reference Partner %s cannot be created, due to Lower Record Limit in SugarCRM Configuration.') % val.get('account_name'))
967         partner_contact_name = get_opportunity_contact(sugar_obj,cr,uid, PortType, sessionid, val, partner_xml_id, context)
968         val['partner_address_id/name'] = partner_contact_name
969         val['categ_id.id'] = get_category(sugar_obj, cr, uid, 'crm.lead', val.get('opportunity_type'))                    
970         val['type'] = 'opportunity'
971         val['stage_id/id'] = get_opportunity_status(sugar_obj, cr, uid, val, context)
972         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_opportunity)
973         lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
974     return True
975
976 def get_opportunity_status(sugar_obj, cr, uid, sugar_val,context=None):
977     if not context:
978         context = {}
979     fields = ['name', 'type']
980     name = 'Opportunity_' + sugar_val['sales_stage']
981     data = [sugar_val['sales_stage'], 'Opportunity']
982     return import_object(sugar_obj, cr, uid, fields, data, 'crm.case.stage', 'crm_stage', name, [('type', '=', 'opportunity'), ('name', 'ilike', sugar_val['sales_stage'])], context)
983
984 MAP_FIELDS = {'Opportunities':  #Object Mapping name
985                     {'dependencies' : ['Users', 'Accounts', 'Contacts', 'Leads'],  #Object to import before this table
986                      'process' : import_opportunities,
987                      },
988               'Leads':
989                     {'dependencies' : ['Users', 'Accounts', 'Contacts'],  #Object to import before this table
990                      'process' : import_leads,
991                     },
992               'Contacts':
993                     {'dependencies' : [],  #Object to import before this table
994                      'process' : import_partner_address,
995                     },
996               'Accounts':
997                     {'dependencies' : ['Users', 'Contacts'],  #Object to import before this table
998                      'process' : import_partners,
999                     },
1000               'Users': 
1001                     {'dependencies' : [],
1002                      'process' : import_users,
1003                     },
1004               'Meetings': 
1005                     {'dependencies' : ['Accounts', 'Contacts', 'Users'],
1006                      'process' : import_meetings,
1007                     },        
1008               'Tasks': 
1009                     {'dependencies' : ['Accounts', 'Contacts', 'Users'],
1010                      'process' : import_tasks,
1011                     },  
1012               'Calls': 
1013                     {'dependencies' : ['Accounts', 'Contacts', 'Users', 'Opportunities'],
1014                      'process' : import_calls,
1015                     },  
1016               'Projects': 
1017                     {'dependencies' : ['Users', 'Accounts', 'Contacts'],
1018                      'process' : import_projects,
1019                     },                        
1020               'Project Tasks': 
1021                     {'dependencies' : ['Users', 'Projects'],
1022                      'process' : import_project_tasks,
1023                     },
1024               'Bugs': 
1025                     {'dependencies' : ['Users', 'Projects', 'Project Tasks'],
1026                      'process' : import_bug,
1027                     },                         
1028               
1029               'Emails': 
1030                     {'dependencies' : ['Users'],
1031                      'process' : import_emails,
1032                     },    
1033               
1034               'Notes': 
1035                     {'dependencies' : ['Users', 'Projects', 'Project Tasks', 'Accounts', 'Contacts', 'Leads', 'Opportunities', 'Meetings', 'Calls'],
1036                      'process' : import_history,
1037                     },  
1038               'Employees': 
1039                     {'dependencies' : ['Resources', 'Users'],
1040                      'process' : import_employees,
1041                     },                  
1042               'Resources': 
1043                     {'dependencies' : ['Users'],
1044                      'process' : import_resources,
1045                     },                                      
1046           }
1047
1048 class import_sugarcrm(osv.osv):
1049     """Import SugarCRM DATA"""
1050     
1051     _name = "import.sugarcrm"
1052     _description = __doc__
1053     _columns = {
1054         'opportunity': fields.boolean('Leads and Opportunities', help="If Opportunities are checked, SugarCRM opportunities data imported in OpenERP crm-Opportunity form"),
1055         'user': fields.boolean('Users', help="If Users  are checked, SugarCRM Users data imported in OpenERP Users form"),
1056         'contact': fields.boolean('Contacts', help="If Contacts are checked, SugarCRM Contacts data imported in OpenERP partner address form"),
1057         'account': fields.boolean('Accounts', help="If Accounts are checked, SugarCRM  Accounts data imported in OpenERP partners form"),
1058         'employee': fields.boolean('Employee', help="If Employees is checked, SugarCRM Employees data imported in OpenERP employees form"),
1059         'meeting': fields.boolean('Meetings', help="If Meetings is checked, SugarCRM Meetings data imported in OpenERP meetings form"),
1060         'call': fields.boolean('Calls', help="If Calls is checked, SugarCRM Calls data imported in OpenERP phonecalls form"),
1061         'email': fields.boolean('Emails', help="If Emails is checked, SugarCRM Emails data imported in OpenERP Emails form"),
1062         'project': fields.boolean('Projects', help="If Projects is checked, SugarCRM Projects data imported in OpenERP Projects form"),
1063         'project_task': fields.boolean('Project Tasks', help="If Project Tasks is checked, SugarCRM Project Tasks data imported in OpenERP Project Tasks form"),
1064         'bug': fields.boolean('Bugs', help="If Bugs is checked, SugarCRM Bugs data imported in OpenERP Project Issues form"),
1065         'attachment': fields.boolean('Attachments', help="If Attachments is checked, SugarCRM Notes data imported in OpenERP's Related module's History with attachment"),
1066         'username': fields.char('User Name', size=64),
1067         'password': fields.char('Password', size=24),
1068     }
1069     _defaults = { #to be set to true, but easier for debugging
1070        'opportunity': False,
1071        'user' : False,
1072        'contact' : False,
1073        'account' : False,
1074         'employee' : False,
1075         'meeting' : False,
1076         'call' : False,    
1077         'email' : False, 
1078         'project' : False,   
1079         'project_task': False,     
1080         'bug': False,
1081     }
1082     
1083     def get_key(self, cr, uid, ids, context=None):
1084         """Select Key as For which Module data we want import data."""
1085         if not context:
1086             context = {}
1087         key_list = []
1088         for current in self.browse(cr, uid, ids, context):
1089             if current.opportunity:
1090                 key_list.append('Opportunities')
1091             if current.user:
1092                 key_list.append('Users')
1093             if current.contact:
1094                 key_list.append('Contacts')
1095             if current.account:
1096                 key_list.append('Accounts') 
1097             if current.employee:
1098                 key_list.append('Employees')  
1099             if current.meeting:
1100                 key_list.append('Meetings')
1101             if current.call:
1102                 key_list.append('Calls')
1103             if current.email:
1104                 key_list.append('Emails') 
1105             if current.project:
1106                 key_list.append('Projects')
1107             if current.project_task:
1108                 key_list.append('Project Tasks')
1109             if current.bug:
1110                 key_list.append('Bugs')
1111             if current.attachment:
1112                 key_list.append('Notes')                                    
1113         return key_list
1114
1115     def import_all(self, cr, uid, ids, context=None):
1116         """Import all sugarcrm data into openerp module"""
1117         if not context:
1118             context = {}
1119         keys = self.get_key(cr, uid, ids, context)
1120         imported = set() #to invoid importing 2 times the sames modules
1121         for key in keys:
1122             if not key in imported:
1123                 self.resolve_dependencies(cr, uid, MAP_FIELDS, MAP_FIELDS[key]['dependencies'], imported, context=context)
1124                 MAP_FIELDS[key]['process'](self, cr, uid, context)
1125                 imported.add(key)
1126
1127         obj_model = self.pool.get('ir.model.data')
1128         model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','import.message.form')])
1129         resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])
1130         return {
1131                 'view_type': 'form',
1132                 'view_mode': 'form',
1133                 'res_model': 'import.message',
1134                 'views': [(resource_id,'form')],
1135                 'type': 'ir.actions.act_window',
1136                 'target': 'new',
1137             }
1138
1139     def resolve_dependencies(self, cr, uid, dict, dep, imported, context=None):
1140         for dependency in dep:
1141             if not dependency in imported:
1142                 self.resolve_dependencies(cr, uid, dict, dict[dependency]['dependencies'], imported, context=context)
1143                 dict[dependency]['process'](self, cr, uid, context)
1144                 imported.add(dependency)
1145         return True        
1146
1147 import_sugarcrm()