[ADD]: Invite Multiple Attendee for One Meetings
[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 def create_mapping(obj, cr, uid, res_model, open_id, sugar_id, context):
30     model_data = {
31         'name':  sugar_id,
32         'model': res_model,
33         'module': 'sugarcrm_import',
34         'res_id': open_id
35     }
36     model_obj = obj.pool.get('ir.model.data')
37     model_obj.create(cr, uid, model_data, context=context)
38     return True
39
40 def find_mapped_id(obj, cr, uid, res_model, sugar_id, context):
41     model_obj = obj.pool.get('ir.model.data')
42     return model_obj.search(cr, uid, [('model', '=', res_model), ('module', '=', 'sugarcrm_import'), ('name', '=', sugar_id)], context=context)
43
44 def get_all(sugar_obj, cr, uid, model, sugar_val, context=None):
45        models = sugar_obj.pool.get(model)
46        model_code = sugar_val[0:2]
47        all_model_ids = models.search(cr, uid, [('name', '=', sugar_val)]) or models.search(cr, uid, [('code', '=', model_code.upper())]) 
48        output = sorted([(o.id, o.name)
49                 for o in models.browse(cr, uid, all_model_ids,
50                                        context=context)],
51                key=itemgetter(1))
52        return output
53
54 def get_all_states(sugar_obj, cr, uid, sugar_val, country_id, context=None):
55     """Get states or create new state"""
56     state_id = False
57     res_country_state_obj = sugar_obj.pool.get('res.country.state')
58     
59     state = get_all(sugar_obj,
60         cr, uid, 'res.country.state', sugar_val, context=context)
61     if state:
62         state_id = state and state[0][0]
63     else:
64        state_id = res_country_state_obj.create(cr, uid, {'name': sugar_val, 'code': sugar_val, 'country_id': country_id})
65     return state_id   
66
67 def get_all_countries(sugar_obj, cr, uid, sugar_country_val, context=None):
68     """Get Country or Create new country"""
69     res_country_obj = sugar_obj.pool.get('res.country')
70     country_id = False
71     country_code = sugar_country_val[0:2]
72     country = get_all(sugar_obj,
73         cr, uid, 'res.country', sugar_country_val, context=context)
74     if country:
75         country_id = country and country[0][0] 
76     else:
77         country_id = res_country_obj.create(cr, uid, {'name': sugar_country_val, 'code': country_code})  
78     return country_id
79
80 def import_partner_address(sugar_obj, cr, uid, context=None):
81     if not context:
82         context = {}
83     map_partner_address = {
84              'id': 'id',              
85              'name': ['first_name', 'last_name'],
86             'phone': 'phone_work',
87             'mobile': 'phone_mobile',
88             'fax': 'phone_fax',
89             'function': 'title',
90             'street': 'primary_address_street',
91             'zip': 'primary_address_postalcode',
92             'city': 'primary_address_city',
93             'country_id/.id': 'country_id/.id',
94             'state_id/.id': 'state_id/id'
95             }
96     address_obj = sugar_obj.pool.get('res.partner.address')
97     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
98     sugar_data = sugar.search(PortType, sessionid, 'Contacts')
99     for val in sugar_data:
100         country_id = get_all_countries(sugar_obj, cr, uid, val.get('primary_address_country'), context)
101         state = get_all_states(sugar_obj,cr, uid, val.get('primary_address_state'), country_id, context)
102         val['country_id/.id'] =  country_id
103         val['state_id/.id'] =  state        
104         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner_address)
105         address_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
106     return True
107     
108 def get_users_department(sugar_obj, cr, uid, val, context=None):
109     if not context:
110        context={}
111     department_id = False       
112     department_obj = sugar_obj.pool.get('hr.department')
113     department_ids = department_obj.search(cr, uid, [('name', '=', val)])
114     if department_ids:
115         department_id = department_ids[0]
116     elif val:
117         department_id = department_obj.create(cr, uid, {'name': val})
118     return department_id 
119
120 def import_users(sugar_obj, cr, uid, context=None):
121     if not context:
122         context = {}
123     department_id = False        
124     map_user = {'id' : 'id', 
125              'name': ['first_name', 'last_name'],
126             'login': 'user_name',
127             
128             'context_lang' : 'context_lang',
129             'password' : 'password',
130             '.id' : '.id',
131             'context_department_id.id': 'context_department_id.id',
132             } 
133     user_obj = sugar_obj.pool.get('res.users')
134     PortType,sessionid = sugar.login(context.get('username',''), context.get('password',''), context.get('url',''))
135     sugar_data = sugar.search(PortType,sessionid, 'Users')
136     for val in sugar_data:
137         user_ids = user_obj.search(cr, uid, [('login', '=', val.get('user_name'))])
138         if user_ids: 
139             val['.id'] = str(user_ids[0])
140         else:
141             val['password'] = 'sugarcrm' #default password for all user
142         department_id = get_users_department(sugar_obj, cr, uid, val.get('department'), context=context)
143         val['context_department_id.id'] = department_id     
144         val['context_lang'] = context.get('lang','en_US')
145         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_user)
146         #All data has to be imported separatly because they don't have the same field
147         user_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
148     return True
149
150 def get_lead_status(surgar_obj, cr, uid, sugar_val,context=None):
151     if not context:
152         context = {}
153     stage_id = False
154     stage_dict = {'status': #field in the sugarcrm database
155         { #Mapping of sugarcrm stage : openerp opportunity stage
156             'New' : 'New',
157             'Assigned':'Qualification',
158             'In Progress': 'Proposition',
159             'Recycled': 'Negotiation',
160             'Dead': 'Lost'
161         },}
162     stage = stage_dict['status'].get(sugar_val['status'], '')
163     stage_pool = surgar_obj.pool.get('crm.case.stage')
164     stage_ids = stage_pool.search(cr, uid, [('type', '=', 'lead'), ('name', '=', stage)])
165     for stage in stage_pool.browse(cr, uid, stage_ids, context):
166         stage_id = stage.id
167     return stage_id
168
169 def get_lead_state(surgar_obj, cr, uid, sugar_val,context=None):
170     if not context:
171         context = {}
172     state = False
173     state_dict = {'status': #field in the sugarcrm database
174         { #Mapping of sugarcrm stage : openerp opportunity stage
175             'New' : 'draft',
176             'Assigned':'open',
177             'In Progress': 'open',
178             'Recycled': 'cancel',
179             'Dead': 'done'
180         },}
181     state = state_dict['status'].get(sugar_val['status'], '')
182     return state
183
184 def get_opportunity_status(surgar_obj, cr, uid, sugar_val,context=None):
185     if not context:
186         context = {}
187     stage_id = False
188     stage_dict = { 'sales_stage':
189             {#Mapping of sugarcrm stage : openerp opportunity stage Mapping
190                'Need Analysis': 'New',
191                'Closed Lost': 'Lost',
192                'Closed Won': 'Won',
193                'Value Proposition': 'Proposition',
194                 'Negotiation/Review': 'Negotiation'
195             },
196     }
197     stage = stage_dict['sales_stage'].get(sugar_val['sales_stage'], '')
198     stage_pool = surgar_obj.pool.get('crm.case.stage')
199     stage_ids = stage_pool.search(cr, uid, [('type', '=', 'opportunity'), ('name', '=', stage)])
200     for stage in stage_pool.browse(cr, uid, stage_ids, context):
201         stage_id = stage.id
202     return stage_id
203
204 def get_user_address(sugar_obj, cr, uid, val, context=None):
205     address_obj = sugar_obj.pool.get('res.partner.address')
206     map_user_address = {
207     'name': ['first_name', 'last_name'],
208     'city': 'address_city',
209     'country_id': 'country_id',
210     'state_id': 'state_id',
211     'street': 'address_street',
212     'zip': 'address_postalcode',
213     }
214     address_ids = address_obj.search(cr, uid, [('name', '=',val.get('first_name') +''+ val.get('last_name'))])
215     country_id = get_all_countries(sugar_obj, cr, uid, val.get('address_country'), context)
216     state_id = get_all_states(sugar_obj, cr, uid, val.get('address_state'), country_id, context)
217     val['country_id'] =  country_id
218     val['state_id'] =  state_id
219     fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_user_address)
220     dict_val = dict(zip(fields,datas))
221     if address_ids:
222         address_obj.write(cr, uid, address_ids, dict_val)
223     else:        
224         new_address_id = address_obj.create(cr,uid, dict_val)
225         return new_address_id
226     return True
227
228 def get_address_type(sugar_obj, cr, uid, val, map_partner_address, type, context=None):
229         address_obj = sugar_obj.pool.get('res.partner.address')
230         new_address_id = False
231         if type == 'invoice':
232             type_address = 'billing'
233         else:
234             type_address = 'shipping'     
235     
236         map_partner_address.update({
237             'street': type_address + '_address_street',
238             'zip': type_address +'_address_postalcode',
239             'city': type_address +'_address_city',
240              'country_id': 'country_id',
241              'type': 'type',
242             })
243         val['type'] = type
244         country_id = get_all_countries(sugar_obj, cr, uid, val.get(type_address +'_address_country'), context)
245         state = get_all_states(sugar_obj, cr, uid, val.get(type_address +'_address_state'), country_id, context)
246         val['country_id'] =  country_id
247         val['state_id'] =  state
248         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner_address)
249         #Convert To list into Dictionary(Key, val). value pair.
250         dict_val = dict(zip(fields,datas))
251         new_address_id = address_obj.create(cr,uid, dict_val)
252         return new_address_id
253     
254 def get_address(sugar_obj, cr, uid, val, context=None):
255     map_partner_address={}
256     address_id=[]
257     address_obj = sugar_obj.pool.get('res.partner.address')
258     address_ids = address_obj.search(cr, uid, [('name', '=',val.get('name')), ('type', 'in', ('invoice', 'delivery')), ('street', '=', val.get('billing_address_street'))])
259     if address_ids:
260         return address_ids 
261     else:
262         map_partner_address = {
263             'id': 'id',                    
264             'name': 'name',
265             'partner_id/id': 'account_id',
266             'phone': 'phone_office',
267             'mobile': 'phone_mobile',
268             'fax': 'phone_fax',
269             'type': 'type',
270             }
271         if val.get('billing_address_street'):
272             address_id.append(get_address_type(sugar_obj, cr, uid, val, map_partner_address, 'invoice', context))
273             
274         if val.get('shipping_address_street'):
275             address_id.append(get_address_type(sugar_obj, cr, uid, val, map_partner_address, 'delivery', context))
276         return address_id
277     return True
278
279 def import_partners(sugar_obj, cr, uid, context=None):
280     if not context:
281         context = {}
282     map_partner = {
283                 'id': 'id',
284                 'name': 'name',
285                 'website': 'website',
286                 'user_id/id': 'assigned_user_id',
287                 'ref': 'sic_code',
288                 'comment': ['description', 'employees', 'ownership', 'annual_revenue', 'rating', 'industry', 'ticker_symbol'],
289                 'customer': 'customer',
290                 'supplier': 'supplier', 
291                 }
292     partner_obj = sugar_obj.pool.get('res.partner')
293     address_obj = sugar_obj.pool.get('res.partner.address')
294     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
295     sugar_data = sugar.search(PortType, sessionid, 'Accounts')
296     for val in sugar_data:
297         add_id = get_address(sugar_obj, cr, uid, val, context)
298         if val.get('account_type') in  ('Customer', 'Prospect', 'Other'):
299             val['customer'] = '1'
300         else:
301             val['supplier'] = '1'
302         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_partner)
303         partner_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
304         for address in  address_obj.browse(cr,uid,add_id):
305             data_id = partner_obj.search(cr,uid,[('name','like',address.name),('website','like',val.get('website'))])
306             if data_id:
307                 address_obj.write(cr,uid,address.id,{'partner_id':data_id[0]})                
308     return True
309
310 def get_category(sugar_obj, cr, uid, model, name, context=None):
311     categ_id = False
312     categ_obj = sugar_obj.pool.get('crm.case.categ')
313     categ_ids = categ_obj.search(cr, uid, [('object_id.model','=',model), ('name', 'like', name)] )
314     if categ_ids:
315          categ_id = categ_ids[0]
316     else:
317          categ_id = categ_obj.create(cr, uid, {'name': name, 'object_id.model': model})
318     return categ_id     
319
320 def get_alarm_id(sugar_obj, cr, uid, val, context=None):
321     
322     alarm_dict = {'60': '1 minute before',
323                   '300': '5 minutes before',
324                   '600': '10 minutes before',
325                   '900': '15 minutes before',
326                   '1800':'30 minutes before',
327                   '3600': '1 hour before',
328      }
329     alarm_id = False
330     alarm_obj = sugar_obj.pool.get('res.alarm')
331     if alarm_dict.get(val):
332         alarm_ids = alarm_obj.search(cr, uid, [('name', 'like', alarm_dict.get(val))])
333         for alarm in alarm_obj.browse(cr, uid, alarm_ids, context):
334             alarm_id = alarm.id
335     return alarm_id 
336     
337 def get_meeting_state(sugar_obj, cr, uid, val,context=None):
338     if not context:
339         context = {}
340     state = False
341     state_dict = {'status': #field in the sugarcrm database
342         { #Mapping of sugarcrm stage : openerp meeting stage
343             'Planned' : 'draft',
344             'Held':'open',
345             'Not Held': 'draft',
346         },}
347     state = state_dict['status'].get(val, '')
348     return state    
349
350 def get_task_state(sugar_obj, cr, uid, val, context=None):
351     if not context:
352         context = {}
353     state = False
354     state_dict = {'status': #field in the sugarcrm database
355         { #Mapping of sugarcrm stage : openerp meeting stage
356             'Completed' : 'done',
357             'Not Started':'draft',
358             'In Progress': 'open',
359             'Pending Input': 'draft',
360             'deferred': 'cancel'
361         },}
362     state = state_dict['status'].get(val, '')
363     return state    
364
365 def get_project_state(sugar_obj, cr, uid, val,context=None):
366     if not context:
367         context = {}
368     state = False
369     state_dict = {'status': #field in the sugarcrm database
370         { #Mapping of sugarcrm staus : openerp Projects state
371             'Draft' : 'draft',
372             'In Review': 'open',
373             'Published': 'close',
374         },}
375     state = state_dict['status'].get(val, '')
376     return state    
377
378 def get_project_task_state(sugar_obj, cr, uid, val,context=None):
379     if not context:
380         context = {}
381     state = False
382     state_dict = {'status': #field in the sugarcrm database
383         { #Mapping of sugarcrm status : openerp Porject Tasks state
384              'Not Started': 'draft',
385              'In Progress': 'open',
386              'Completed': 'done',
387             'Pending Input': 'pending',
388             'Deferred': 'cancelled',
389         },}
390     state = state_dict['status'].get(val, '')
391     return state    
392
393 def get_project_task_priority(sugar_obj, cr, uid, val,context=None):
394     if not context:
395         context = {}
396     priority = False
397     priority_dict = {'priority': #field in the sugarcrm database
398         { #Mapping of sugarcrm status : openerp Porject Tasks state
399             'High': '0',
400             'Medium': '2',
401             'Low': '3'
402         },}
403     priority = priority_dict['priority'].get(val, '')
404     return priority    
405
406
407 def get_account(sugar_obj, cr, uid, val, context=None):
408     if not context:
409         context = {}
410     partner_id = False    
411     partner_address_id = False
412     model_obj = sugar_obj.pool.get('ir.model.data')
413     address_obj = sugar_obj.pool.get('res.partner.address')
414     if val.get('parent_type') == 'Accounts':
415         model_ids = model_obj.search(cr, uid, [('name', '=', val.get('parent_id')), ('model', '=', 'res.partner')])
416         if model_ids:
417             model = model_obj.browse(cr, uid, model_ids)[0]
418             partner_id = model.res_id
419             address_ids = address_obj.search(cr, uid, [('partner_id', '=', partner_id)])
420             partner_address_id = address_ids and address_ids[0]
421             
422     if val.get('parent_type') == 'Contacts':
423         model_ids = model_obj.search(cr, uid, [('name', '=', val.get('parent_id')), ('model', '=', 'res.partner.address')])
424         for model in model_obj.browse(cr, uid, model_ids):
425             partner_address_id = model.res_id
426             address_id = address_obj.browse(cr, uid, partner_address_id)
427             partner_id = address_id and address_id.partner_id or False
428     return partner_id, partner_address_id                             
429
430 def import_tasks(sugar_obj, cr, uid, context=None):
431     if not context:
432         context = {}
433     partner_id = False
434     partner_address_id = False        
435     map_task = {'id' : 'id',
436                 'name': 'name',
437                 'date': 'date_entered',
438                 'user_id/id': 'assigned_user_id',
439                 'categ_id/.id': 'categ_id/.id',
440                 'partner_id/.id': 'partner_id/.id',
441                 'partner_address_id/.id': 'partner_address_id/.id',
442                 'state': 'state'
443     }
444     meeting_obj = sugar_obj.pool.get('crm.meeting')
445     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
446     categ_id = get_category(sugar_obj, cr, uid, 'crm.meeting', 'Tasks')
447     sugar_data = sugar.search(PortType, sessionid, 'Tasks')
448     for val in sugar_data:
449         partner_xml_id = find_mapped_id(sugar_obj, cr, uid, 'res.partner.address', val.get('contact_id'), context)
450         if not partner_xml_id:
451             raise osv.except_osv(_('Warning !'), _('Reference Contact %s cannot be created, due to Lower Record Limit in SugarCRM Configuration.') % val.get('contact_name'))
452         partner_id, partner_address_id = get_account(sugar_obj, cr, uid, val, context)
453         val['partner_id/.id'] = partner_id
454         val['partner_address_id/.id'] = partner_address_id
455         val['categ_id/.id'] = categ_id
456         val['state'] = get_task_state(sugar_obj, cr, uid, val.get('status'), context=None)
457         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_task)
458         meeting_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
459     return True    
460     
461 def get_attendee_id(sugar_obj, cr, uid, PortType, sessionid, module_name, module_id, context=None):
462     if not context:
463         context = {}
464     model_obj = sugar_obj.pool.get('ir.model.data')
465     att_obj = sugar_obj.pool.get('calendar.attendee')
466     meeting_obj = sugar_obj.pool.get('crm.meeting')
467     user_xml_ids, user_email_ids = sugar.user_get_attendee_list(PortType, sessionid, module_name, module_id)
468     for user_xml_id in user_xml_ids: 
469         user_model_ids = find_mapped_id(sugar_obj, cr, uid, 'res.users', user_xml_id, context)
470         user_resource_id = model_obj.browse(cr, uid, user_model_ids)        
471         if user_resource_id:
472             user_id = user_resource_id[0].res_id 
473             attend_ids = att_obj.search(cr, uid, [('user_id', '=', user_id)])
474             if attend_ids:
475                  attendees = attend_ids[0]
476             else:      
477                 attendees = att_obj.create(cr, uid, {'user_id': user_id, 'email': user_email_ids[0]})
478             meeting_model_ids = find_mapped_id(sugar_obj, cr, uid, 'crm.meeting', module_id, context)
479             meeting_xml_id = model_obj.browse(cr, uid, meeting_model_ids)
480             if meeting_xml_id:
481                 meeting_obj.write(cr, uid, [meeting_xml_id[0].res_id], {'attendee_ids': [(4, attendees)]})       
482     return True   
483     
484 def import_meetings(sugar_obj, cr, uid, context=None):
485     if not context:
486         context = {}
487     partner_id = False
488     partner_address_id = False    
489     map_meeting = {'id' : 'id',
490                     'name': 'name',
491                     'date': 'date_start',
492                     'duration': ['duration_hours', 'duration_minutes'],
493                     'location': 'location',
494                     'alarm_id/.id': 'alarm_id/.id',
495                     'user_id/id': 'assigned_user_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     sugar_data = sugar.search(PortType, sessionid, 'Meetings')
503     for val in sugar_data:
504         partner_id, partner_address_id = get_account(sugar_obj, cr, uid, val, context)
505         val['partner_id/.id'] = partner_id
506         val['partner_address_id/.id'] = partner_address_id
507         val['state'] = get_meeting_state(sugar_obj, cr, uid, val.get('status'),context)
508         val['alarm_id/.id'] = get_alarm_id(sugar_obj, cr, uid, val.get('reminder_time'), context)
509         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_meeting)
510         meeting_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
511         get_attendee_id(sugar_obj, cr, uid, PortType, sessionid, 'Meetings', val.get('id'), context)
512     return True    
513
514 def get_calls_state(sugar_obj, cr, uid, val,context=None):
515     if not context:
516         context = {}
517     state = False
518     state_dict = {'status': #field in the sugarcrm database
519         { #Mapping of sugarcrm stage : openerp calls stage
520             'Planned' : 'open',
521             'Held':'done',
522             'Not Held': 'pending',
523         },}
524     state = state_dict['status'].get(val, '')
525     return state   
526
527 def import_calls(sugar_obj, cr, uid, context=None):
528     if not context:
529         context = {}
530     partner_id = False
531     partner_address_id = False        
532     map_calls = {'id' : 'id',
533                     'name': 'name',
534                     'date': 'date_start',
535                     'duration': ['duration_hours', 'duration_minutes'],
536                     'user_id/id': 'assigned_user_id',
537                     'partner_id/.id': 'partner_id/.id',
538                     'partner_address_id/.id': 'partner_address_id/.id',
539                     'categ_id/.id': 'categ_id/.id',
540                    'state': 'state',
541     }
542     phonecall_obj = sugar_obj.pool.get('crm.phonecall')
543     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
544     sugar_data = sugar.search(PortType, sessionid, 'Calls')
545     for val in sugar_data:
546         categ_id = get_category(sugar_obj, cr, uid, 'crm.phonecall', val.get('direction'))         
547         val['categ_id/.id'] = categ_id
548         partner_id, partner_address_id = get_account(sugar_obj, cr, uid, val, context)
549         val['partner_id/.id'] = partner_id
550         val['partner_address_id/.id'] = partner_address_id
551         val['state'] =  get_calls_state(sugar_obj, cr, uid, val.get('status'), context)  
552         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_calls)
553         phonecall_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
554     return True
555     
556 def import_resources(sugar_obj, cr, uid, context=None):
557     if not context:
558         context = {}
559     map_resource = {'id' : 'user_hash',
560                     'name': ['first_name', 'last_name'],
561     }
562     resource_obj = sugar_obj.pool.get('resource.resource')
563     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
564     sugar_data = sugar.search(PortType, sessionid, 'Employees')
565     for val in sugar_data:
566         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_resource)
567         resource_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
568     return True    
569
570 def get_job_id(sugar_obj, cr, uid, val, context=None):
571     if not context:
572         context={}
573     job_id = False    
574     job_obj = sugar_obj.pool.get('hr.job')        
575     job_ids = job_obj.search(cr, uid, [('name', '=', val)])
576     if job_ids:
577         job_id = job_ids[0]
578     else:
579         job_id = job_obj.create(cr, uid, {'name': val})
580     return job_id
581     
582 def import_employees(sugar_obj, cr, uid, context=None):
583     if not context:
584         context = {}
585     map_employee = {'id' : 'user_hash',
586                     'resource_id/.id': 'resource_id/.id',
587                     'name': ['first_name', 'last_name'],
588                     'work_phone': 'phone_work',
589                     'mobile_phone':  'phone_mobile',
590                     'user_id/name': ['first_name', 'last_name'], 
591                     'address_home_id/.id': 'address_home_id/.id',
592                     'notes': 'description',
593                     #TODO: Creation of Employee create problem.
594                  #   'coach_id/id': 'reports_to_id',
595                     'job_id/.id': 'job_id/.id'
596     }
597     employee_obj = sugar_obj.pool.get('hr.employee')
598     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
599     sugar_data = sugar.search(PortType, sessionid, 'Employees')
600     for val in sugar_data:
601         address_id = get_user_address(sugar_obj, cr, uid, val, context)
602         val['address_home_id/.id'] = address_id
603         model_ids = find_mapped_id(sugar_obj, cr, uid, 'resource.resource', val.get('user_hash')+ '_resource_resource', context)
604         resource_id = sugar_obj.pool.get('ir.model.data').browse(cr, uid, model_ids)
605         if resource_id:
606             val['resource_id/.id'] = resource_id[0].res_id
607         val['job_id/.id'] = get_job_id(sugar_obj, cr, uid, val.get('title'), context)
608         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_employee)
609         employee_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
610     return True
611
612 def get_contact_title(sugar_obj, cr, uid, salutation, domain, context=None):
613     if not context:
614         context = {}
615     contact_title_obj = sugar_obj.pool.get('res.partner.title')
616     title_id = False            
617     title_ids = contact_title_obj.search(cr, uid, [('shortcut', '=', salutation), ('domain', '=', domain)])
618     if title_ids:
619          title_id = title_ids[0]
620     elif salutation:
621          title_id = contact_title_obj.create(cr, uid, {'name': salutation, 'shortcut': salutation, 'domain': domain})
622     return title_id
623     
624 def import_emails(sugar_obj, cr, uid, context=None):
625     if not context:
626         context=None
627          
628     map_emails = {'id': 'id',
629     'name':'name',
630     'date':'date_sent',
631     'email_from': 'from_addr_name',
632     'email_to': 'reply_to_addr',
633     'email_cc': 'cc_addrs_names',
634     'email_bcc': 'bcc_addrs_names',
635     'message_id': 'message_id',
636     'user_id/id': 'assigned_user_id',
637     'description': 'description_html',
638     'res_id': 'res_id',
639     'model': 'model',
640     }
641     mailgate_obj = sugar_obj.pool.get('mailgate.message')
642     model_obj = sugar_obj.pool.get('ir.model.data')
643     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
644     sugar_data = sugar.search(PortType, sessionid, 'Emails')
645     for val in sugar_data:
646         model_ids = model_obj.search(cr, uid, [('name', 'like', val.get('parent_id'))])
647         for model in model_obj.browse(cr, uid, model_ids):
648             val['res_id'] = model.res_id
649             val['model'] = model.model
650         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_emails)
651         mailgate_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
652     return True    
653     
654 def import_projects(sugar_obj, cr, uid, context=None):
655     if not context:
656         context = {}
657     map_project = {'id': 'id',
658         'name': 'name',
659         'date_start': 'estimated_start_date',
660         'date': 'estimated_end_date',
661         'user_id/id': 'assigned_user_id',
662          'state': 'state'   
663     }
664     project_obj = sugar_obj.pool.get('project.project')
665     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
666     sugar_data = sugar.search(PortType, sessionid, 'Project')
667     for val in sugar_data:
668         val['state'] = get_project_state(sugar_obj, cr, uid, val.get('status'),context)
669         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_project)
670         project_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
671     return True 
672
673
674 def import_project_tasks(sugar_obj, cr, uid, context=None):
675     if not context:
676         context = {}
677     map_project_task = {'id': 'id',
678         'name': 'name',
679         'date_start': 'date_start',
680         'date_end': 'date_finish',
681         'progress': 'progress',
682         'project_id/name': 'project_name',
683         'planned_hours': 'planned_hours',
684         'total_hours': 'total_hours',        
685         'priority': 'priority',
686         'description': 'description',
687         'user_id/id': 'assigned_user_id',
688          'state': 'state'   
689     }
690     task_obj = sugar_obj.pool.get('project.task')
691     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
692     sugar_data = sugar.search(PortType, sessionid, 'ProjectTask')
693     for val in sugar_data:
694         val['state'] = get_project_task_state(sugar_obj, cr, uid, val.get('status'),context)
695         val['priority'] = get_project_task_priority(sugar_obj, cr, uid, val.get('priority'),context)
696         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_project_task)
697         task_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
698     return True 
699     
700 def import_leads(sugar_obj, cr, uid, context=None):
701     if not context:
702         context = {}
703     title_id = False   
704     map_lead = {
705             'id' : 'id',
706             'name': ['first_name', 'last_name'],
707             'contact_name': ['first_name', 'last_name'],
708             'description': ['description', 'refered_by', 'lead_source', 'lead_source_description', 'website'],
709             'partner_name': 'account_name',
710             'email_from': 'email1',
711             'phone': 'phone_work',
712             'mobile': 'phone_mobile',
713             'title.id': 'title.id',
714             'function':'title',
715             'street': 'primary_address_street',
716             'street2': 'alt_address_street',
717             'zip': 'primary_address_postalcode',
718             'city':'primary_address_city',
719             'user_id/id' : 'assigned_user_id',
720             'stage_id.id' : 'stage_id.id',
721             'type' : 'type',
722             'state': 'state',
723             }
724         
725     lead_obj = sugar_obj.pool.get('crm.lead')
726     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
727     sugar_data = sugar.search(PortType, sessionid, 'Leads')
728     for val in sugar_data:
729         if val.get('opportunity_id'):
730             continue
731         title_id = get_contact_title(sugar_obj, cr, uid, val.get('salutation'), 'contact', context)
732         val['title.id'] = title_id
733         val['type'] = 'lead'
734         stage_id = get_lead_status(sugar_obj, cr, uid, val, context)
735         val['stage_id.id'] = stage_id
736         val['state'] = get_lead_state(sugar_obj, cr, uid, val,context)
737         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_lead)
738         lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
739     return True
740
741 def get_opportunity_contact(sugar_obj,cr,uid, PortType, sessionid, val, partner_xml_id, context=None):
742     if not context:
743         context={}
744     partner_contact_name = False        
745     model_obj = sugar_obj.pool.get('ir.model.data')
746     partner_address_obj = sugar_obj.pool.get('res.partner.address')
747     sugar_opportunity_contact = sugar.relation_search(PortType, sessionid, 'Opportunities', module_id=val.get('id'), related_module='Contacts', query=None, deleted=None)
748     for contact in sugar_opportunity_contact:
749         model_ids = find_mapped_id(sugar_obj, cr, uid, 'res.partner.address', contact, context)
750         if model_ids:
751             model_id = model_obj.browse(cr, uid, model_ids)[0].res_id
752             address_id = partner_address_obj.browse(cr, uid, model_id)
753             partner_address_obj.write(cr, uid, [address_id.id], {'partner_id': partner_xml_id[0]})
754             partner_contact_name = address_id.name
755         else:
756             partner_contact_name = val.get('account_name')    
757     return partner_contact_name 
758
759 def import_opportunities(sugar_obj, cr, uid, context=None):
760     if not context:
761         context = {}
762     partner_contact_name = False
763     map_opportunity = {'id' : 'id',
764         'name': 'name',
765         'probability': 'probability',
766         'partner_id/name': 'account_name',
767         'title_action': 'next_step',
768         'partner_address_id/name': 'partner_address_id/name',
769         'planned_revenue': 'amount',
770         'date_deadline':'date_closed',
771         'user_id/id' : 'assigned_user_id',
772         'stage_id.id' : 'stage_id.id',
773         'type' : 'type',
774         'categ_id.id': 'categ_id.id'
775     }
776     lead_obj = sugar_obj.pool.get('crm.lead')
777     partner_obj = sugar_obj.pool.get('res.partner')
778     PortType, sessionid = sugar.login(context.get('username', ''), context.get('password', ''), context.get('url',''))
779     sugar_data = sugar.search(PortType, sessionid, 'Opportunities')
780     for val in sugar_data:
781         partner_xml_id = partner_obj.search(cr, uid, [('name', 'like', val.get('account_name'))])
782         if not partner_xml_id:
783             raise osv.except_osv(_('Warning !'), _('Reference Partner %s cannot be created, due to Lower Record Limit in SugarCRM Configuration.') % val.get('account_name'))
784         partner_contact_name = get_opportunity_contact(sugar_obj,cr,uid, PortType, sessionid, val, partner_xml_id, context)
785         val['partner_address_id/name'] = partner_contact_name
786         val['categ_id.id'] = get_category(sugar_obj, cr, uid, 'crm.lead', val.get('opportunity_type'))                    
787         val['type'] = 'opportunity'
788         stage_id = get_opportunity_status(sugar_obj, cr, uid, val, context)
789         val['stage_id.id'] = stage_id
790         fields, datas = sugarcrm_fields_mapping.sugarcrm_fields_mapp(val, map_opportunity)
791         lead_obj.import_data(cr, uid, fields, [datas], mode='update', current_module='sugarcrm_import', noupdate=True, context=context)
792     return True
793
794 MAP_FIELDS = {'Opportunities':  #Object Mapping name
795                     {'dependencies' : ['Users', 'Accounts'],  #Object to import before this table
796                      'process' : import_opportunities,
797                      },
798               'Leads':
799                     {'dependencies' : ['Users', 'Accounts', 'Contacts'],  #Object to import before this table
800                      'process' : import_leads,
801                     },
802               'Contacts':
803                     {'dependencies' : ['Users'],  #Object to import before this table
804                      'process' : import_partner_address,
805                     },
806               'Accounts':
807                     {'dependencies' : ['Users'],  #Object to import before this table
808                      'process' : import_partners,
809                     },
810               'Users': 
811                     {'dependencies' : [],
812                      'process' : import_users,
813                     },
814               'Meetings': 
815                     {'dependencies' : ['Users', 'Tasks'],
816                      'process' : import_meetings,
817                     },        
818               'Tasks': 
819                     {'dependencies' : ['Users', 'Accounts', 'Contacts'],
820                      'process' : import_tasks,
821                     },  
822               'Calls': 
823                     {'dependencies' : ['Users', 'Accounts', 'Contacts'],
824                      'process' : import_calls,
825                     },                        
826               'Employees': 
827                     {'dependencies' : ['Resources'],
828                      'process' : import_employees,
829                     },
830               'Emails': 
831                     {'dependencies' : ['Users'],
832                      'process' : import_emails,
833                     },    
834               'Projects': 
835                     {'dependencies' : ['Users'],
836                      'process' : import_projects,
837                     },                        
838               'Project Tasks': 
839                     {'dependencies' : ['Users', 'Projects'],
840                      'process' : import_project_tasks,
841                     },                          
842               'Resources': 
843                     {'dependencies' : ['Users'],
844                      'process' : import_resources,
845                     },                                      
846           }
847
848 class import_sugarcrm(osv.osv):
849     """Import SugarCRM DATA"""
850     
851     _name = "import.sugarcrm"
852     _description = __doc__
853     _columns = {
854         'lead': fields.boolean('Leads', help="If Leads are checked, SugarCRM Leads data imported in openERP crm-Lead form"),
855         'opportunity': fields.boolean('Opportunities', help="If Opportunities are checked, SugarCRM opportunities data imported in openERP crm-Opportunity form"),
856         'user': fields.boolean('User', help="If Users  are checked, SugarCRM Users data imported in openERP Users form"),
857         'contact': fields.boolean('Contacts', help="If Contacts are checked, SugarCRM Contacts data imported in openERP partner address form"),
858         'account': fields.boolean('Accounts', help="If Accounts are checked, SugarCRM  Accounts data imported in openERP partners form"),
859         'employee': fields.boolean('Employee', help="If Employees is checked, SugarCRM Employees data imported in openERP employees form"),
860         'meeting': fields.boolean('Meetings', help="If Meetings is checked, SugarCRM Meetings data imported in openERP meetings form"),
861         'call': fields.boolean('Calls', help="If Calls is checked, SugarCRM Calls data imported in openERP phonecalls form"),
862         'email': fields.boolean('Emails', help="If Emails is checked, SugarCRM Emails data imported in openERP Emails form"),
863         'project': fields.boolean('Projects', help="If Projects is checked, SugarCRM Projects data imported in openERP Projects form"),
864         'project_task': fields.boolean('Project Tasks', help="If Project Tasks is checked, SugarCRM Project Tasks data imported in openERP Project Tasks form"),
865         'username': fields.char('User Name', size=64),
866         'password': fields.char('Password', size=24),
867     }
868     _defaults = {
869        'lead': True,
870        'opportunity': True,
871        'user' : True,
872        'contact' : True,
873        'account' : True,
874         'employee' : True,
875         'meeting' : True,
876         'call' : True,    
877         'email' : True, 
878         'project' : True,   
879         'project_task': True     
880     }
881     
882     def get_key(self, cr, uid, ids, context=None):
883         """Select Key as For which Module data we want import data."""
884         if not context:
885             context = {}
886         key_list = []
887         for current in self.browse(cr, uid, ids, context):
888             if current.lead:
889                 key_list.append('Leads')
890             if current.opportunity:
891                 key_list.append('Opportunities')
892             if current.user:
893                 key_list.append('Users')
894             if current.contact:
895                 key_list.append('Contacts')
896             if current.account:
897                 key_list.append('Accounts') 
898             if current.employee:
899                 key_list.append('Employees')  
900             if current.meeting:
901                 key_list.append('Meetings')
902             if current.call:
903                 key_list.append('Calls')
904             if current.email:
905                 key_list.append('Emails') 
906             if current.project:
907                 key_list.append('Projects')
908             if current.project_task:
909                 key_list.append('Project Tasks')                                                                                              
910         return key_list
911
912     def import_all(self, cr, uid, ids, context=None):
913         """Import all sugarcrm data into openerp module"""
914         if not context:
915             context = {}
916         keys = self.get_key(cr, uid, ids, context)
917         imported = set() #to invoid importing 2 times the sames modules
918         for key in keys:
919             if not key in imported:
920                 self.resolve_dependencies(cr, uid, MAP_FIELDS, MAP_FIELDS[key]['dependencies'], imported, context=context)
921                 MAP_FIELDS[key]['process'](self, cr, uid, context)
922                 imported.add(key)
923
924         obj_model = self.pool.get('ir.model.data')
925         model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','import.message.form')])
926         resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])
927         return {
928                 'view_type': 'form',
929                 'view_mode': 'form',
930                 'res_model': 'import.message',
931                 'views': [(resource_id,'form')],
932                 'type': 'ir.actions.act_window',
933                 'target': 'new',
934             }
935
936     def resolve_dependencies(self, cr, uid, dict, dep, imported, context=None):
937         for dependency in dep:
938             if not dependency in imported:
939                 self.resolve_dependencies(cr, uid, dict, dict[dependency]['dependencies'], imported, context=context)
940                 dict[dependency]['process'](self, cr, uid, context)
941                 imported.add(dependency)
942         return True        
943
944 import_sugarcrm()