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