[IMP]: Intregate history to import_base module
[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 import sugar
23 from tools.translate import _
24 from import_base.import_framework import *
25 from import_base.mapper import *
26 from datetime import datetime
27 import base64
28 import pprint
29 pp = pprint.PrettyPrinter(indent=4)
30
31 #copy old import here
32 class related_ref(dbmapper):
33     def __init__(self, type):
34         self.type = type
35         
36     def __call__(self, external_val):
37         if external_val.get('parent_type') in self.type and external_val.get('parent_id'):
38             return self.parent.xml_id_exist(external_val['parent_type'], external_val['parent_id'])
39         return ''
40
41
42 class sugar_import(import_framework):
43     TABLE_CONTACT = 'Contacts'
44     TABLE_ACCOUNT = 'Accounts'
45     TABLE_USER = 'Users'
46     TABLE_EMPLOYEE = 'Employees'
47     TABLE_RESSOURCE = "resource"
48     TABLE_OPPORTUNITY = 'Opportunities'
49     TABLE_LEAD = 'Leads'
50     TABLE_STAGE = 'crm_stage'
51     TABLE_CALL = 'Calls'
52     TABLE_MEETING = 'Meetings'
53     TABLE_TASK = 'Tasks'
54     TABLE_PROJECT = 'Project'
55     TABLE_PROJECT_TASK = 'ProjectTask'
56     TABLE_BUG = 'Bugs'
57     TABLE_CASE = 'Cases'
58     TABLE_NOTE = 'Notes'
59     
60     
61     def initialize(self):
62         #login
63         PortType,sessionid = sugar.login(self.context.get('username',''), self.context.get('password',''), self.context.get('url',''))
64         self.context['port'] = PortType
65         self.context['session_id'] = sessionid
66         
67     def get_data(self, table):
68         return sugar.search(self.context.get('port'), self.context.get('session_id'), table)
69     """
70         Common import method
71     """
72     def get_category(self, val, model, name):
73         fields = ['name', 'object_id']
74         data = [name, model]
75         return self.import_object(fields, data, 'crm.case.categ', 'crm_categ', name, [('object_id.model','=',model), ('name', 'ilike', name)])
76
77     def get_job_title(self, dict, salutation):
78         fields = ['shortcut', 'name', 'domain']
79         if salutation:
80             data = [salutation, salutation, 'Contact']
81             return self.import_object(fields, data, 'res.partner.title', 'contact_title', salutation, [('shortcut', '=', salutation)])
82
83     def get_campaign_id(self, dict, val):
84         fields = ['name']
85         data = [val]
86         return self.import_object(fields, data, 'crm.case.resource.type', 'crm_campaign', val)
87     
88     def get_all_states(self, external_val, country_id):
89         """Get states or create new state unless country_id is False"""
90         state_code = external_val[0:3] #take the tree first char
91         fields = ['country_id/id', 'name', 'code']
92         data = [country_id, external_val, state_code]
93         if country_id:
94             return self.import_object(fields, data, 'res.country.state', 'country_state', external_val) 
95         return False
96
97     def get_all_countries(self, val):
98         """Get Country, if no country match do not create anything, to avoid duplicate country code"""
99         return self.mapped_id_if_exist('res.country', [('name', 'ilike', val)], 'country', val)
100     
101     def get_float_time(self, dict, hour, min):
102         min = int(min) * 100 / 60
103         return "%s.%i" % (hour, min)
104
105     """
106     import History(Notes)
107     """
108 def get_attachment(sugar_obj, cr, uid, val, model, File, context=None):
109     if not context:
110         context = {}
111     attachment_obj = sugar_obj.pool.get('ir.attachment')
112     model_obj = sugar_obj.pool.get('ir.model.data')
113     mailgate_obj = sugar_obj.pool.get('mailgate.message')
114     new_attachment_id = attachment_obj.create(cr, uid, {'name': val.get('name'), 'datas': File, 'res_id': val.get('res_id',False),'res_model': val.get('model',False)})
115     message_model_ids = find_mapped_id(sugar_obj, cr, uid, model, context.get('instance_name')+'_note_'+val.get('id'), context)
116     message_xml_id = model_obj.browse(cr, uid, message_model_ids)
117     if message_xml_id:
118         mailgate_obj.write(cr, uid, [message_xml_id[0].res_id], {'attachment_ids': [(4, new_attachment_id)]})             
119
120     return True    
121
122     def import_history(self, val):
123         model_obj =  self.obj.pool.get('ir.model.data')
124         xml_id = self.xml_id_exist(val.get('parent_type'), val.get('parent_type'))
125         model_ids = model_obj.search(self.cr, self.uid, [('name', 'like', xml_id)])
126         if model_ids:
127               model = model_obj.browse(self.cr, self.uid, model_ids)[0]
128               if model.model == 'res.partner':
129                     val['partner_id/.id'] = model.res_id
130               else:    
131                     val['res_id'] = model.res_id
132                     val['model'] = model.model
133         return val    
134     
135     def get_history_mapping(self): 
136         return { 
137                 'model' : 'mailgate.message',
138                 'dependencies' : [],
139                 'hook' : self.import_history,
140                 'map' : {
141                       'name':'name',
142                       'date': 'date_entered',
143                       'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'),
144                       'description': ppconcat('__prettyprint__','description', 'description_html'),
145                       'res_id': 'res_id',
146                       'model': 'model',
147                       'partner_id/.id' : 'partner_id/.id',
148                 }
149             }     
150     
151     """
152     import Claims(Cases)
153     """
154     def get_claim_priority(self, val):
155         priority_dict = {            
156                 'High': '2',
157                 'Medium': '3',
158                 'Low': '4'
159         }
160         return priority_dict.get(val.get('priority'), '')
161         
162     def get_contact_info_from_account(self, val):
163         partner_id = self.get_mapped_id(self.TABLE_ACCOUNT, val.get('account_id'))
164         partner_address_id = False
165         partner_phone = False
166         partner_email = False
167         partner = self.obj.pool.get('res.partner').browse(self.cr, self.uid, [partner_id])[0]
168         if partner.address and partner.address[0]:
169             address = partner.address[0]
170             partner_address_id = address.id
171             partner_phone = address.phone
172             partner_email = address.email
173         return partner_address_id, partner_phone,partner_email
174     
175     def import_crm_claim(self, val):
176         partner_address_id, partner_phone,partner_email =  self.get_contact_info_from_account(val)
177         val['partner_address_id/.id'] = partner_address_id
178         val['partner_address_id/.id'] = partner_address_id
179         val['partner_phone'] = partner_phone
180         val['email_from'] = partner_email
181         return val
182     
183     def get_crm_claim_mapping(self): 
184         return { 
185                 'model' : 'crm.claim',
186                 'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD],
187                 'hook' : self.import_crm_claim,
188                 'map' : {
189                     'name': 'name',
190                     'date': 'date_entered',
191                     'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'),
192                     'description': 'description',
193                     'partner_id/id': ref(self.TABLE_ACCOUNT, 'account_id'),
194                     'partner_address_id/.id': 'partner_address_id/.id',
195                     'partner_phone': 'partner_phone',
196                     'email_from': 'email_from',                                        
197                     'priority': self.get_claim_priority,
198                     'state': map_val('status', self.project_issue_state)
199                 }
200             }    
201     """
202     Import Project Issue(Bugs)
203     """
204     project_issue_state = {
205             'New' : 'draft',
206             'Assigned':'open',
207             'Closed': 'done',
208             'Pending': 'pending',
209             'Rejected': 'cancel',
210     }
211      
212     def get_project_issue_priority(self, val):
213         priority_dict = {
214                 'Urgent': '1',
215                 'High': '2',
216                 'Medium': '3',
217                 'Low': '4'
218          }
219         return priority_dict.get(val.get('priority'), '')     
220       
221     def get_bug_project_id(self, dict, val):
222         fields = ['name']
223         data = [val]
224         return self.import_object(fields, data, 'project.project', 'project_issue', val)    
225     
226     def get_project_issue_mapping(self):
227         return { 
228                 'model' : 'project.issue',
229                 'dependencies' : [self.TABLE_USER, self.TABLE_PROJECT, self.TABLE_PROJECT_TASK],
230                 'map' : {
231                     'name': 'name',
232                     'project_id/id': call(self.get_bug_project_id, 'sugarcrm_bugs'),
233                     'categ_id/id': call(self.get_category, 'project.issue', value('type')),
234                     'description': ppconcat('__prettyprint__','description', 'bug_number', 'fixed_in_release_name', 'source', 'fixed_in_release', 'work_log', 'found_in_release', 'release_name', 'resolution'),
235                     'priority': self.get_project_issue_priority,
236                     'state': map_val('status', self.project_issue_state)
237                 }
238             }
239     
240     """
241     import Project Tasks
242     """
243     project_task_state = {
244             'Not Started': 'draft',
245             'In Progress': 'open',
246             'Completed': 'done',
247             'Pending Input': 'pending',
248             'Deferred': 'cancelled',
249      }
250     
251     def get_project_task_priority(self, val):
252       priority_dict = {
253             'High': '0',
254             'Medium': '2',
255             'Low': '3'
256         }
257       return priority_dict.get(val.get('priority'), '')
258
259     def get_project_task_mapping(self):
260         return { 
261                 'model' : 'project.task',
262                 'dependencies' : [self.TABLE_USER, self.TABLE_PROJECT],
263                 'map' : {
264                     'name': 'name',
265                     'date_start': 'date_start',
266                     'date_end': 'date_finish',
267                     'progress': 'progress',
268                     'project_id/id': ref(self.TABLE_PROJECT, 'project_id'),
269                     'planned_hours': 'planned_hours',
270                     'total_hours': 'total_hours',        
271                     'priority': self.get_project_task_priority,
272                     'description': 'description',
273                     'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'),
274                     'partner_id/id': 'partner_id/id',
275                     'contact_id/id': 'contact_id/id',
276                     'state': map_val('status', self.project_task_state)
277                 }
278             }
279
280     """
281     import Projects
282     """
283     project_state = {
284             'Draft' : 'draft',
285             'In Review': 'open',
286             'Published': 'close'
287      }
288     def import_project_account(self, val):
289         partner_id = False
290         partner_invoice_id = False        
291         model_obj = self.obj.pool.get('ir.model.data')
292         partner_obj = self.obj.pool.get('res.partner')
293         partner_address_obj = self.obj.pool.get('res.partner.address')
294         sugar_project_account = sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Project', module_id=val.get('id'), related_module=self.TABLE_ACCOUNT, query=None, deleted=None)
295         sugar_project_contact = sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Project', module_id=val.get('id'), related_module=self.TABLE_CONTACT, query=None, deleted=None)
296         for contact_id in sugar_project_contact:
297             partner_invoice_id = self.get_mapped_id(self.TABLE_CONTACT, contact_id)
298         for account_id in sugar_project_account:
299             partner_id = self.get_mapped_id(self.TABLE_ACCOUNT, account_id)
300         return partner_id, partner_invoice_id      
301            
302     def import_project(self, val):
303         partner_id, partner_invoice_id  = self.import_project_account(val)    
304         val['partner_id/.id'] = partner_id
305         val['contact_id/.id'] = partner_invoice_id
306         return val
307     
308     def get_project_mapping(self):
309         return { 
310                 'model' : 'project.project',
311                 'dependencies' : [self.TABLE_CONTACT, self.TABLE_ACCOUNT, self.TABLE_USER],
312                 'hook' : self.import_project,
313                 'map' : {
314                     'name': 'name',
315                     'date_start': 'estimated_start_date',
316                     'date': 'estimated_end_date',
317                     'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'),
318                     'partner_id/.id': 'partner_id/.id',
319                     'contact_id/.id': 'contact_id/.id',
320                     'state': map_val('status', self.project_state)
321                 }
322             }
323     
324     """
325     import Tasks
326     """
327     task_state = {
328             'Completed' : 'done',
329             'Not Started':'draft',
330             'In Progress': 'open',
331             'Pending Input': 'draft',
332             'deferred': 'cancel'
333         }
334
335     def import_task(self, val):
336         val['date'] = val.get('date_start') or datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
337         val['date_deadline'] = val.get('date_due') or datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
338         return val
339
340     def get_task_mapping(self):
341         return { 
342                 'model' : 'crm.meeting',
343                 'dependencies' : [self.TABLE_CONTACT, self.TABLE_ACCOUNT, self.TABLE_USER],
344                 'hook' : self.import_task,
345                 'map' : {
346                     'name': 'name',
347                     'date': 'date',
348                     'date_deadline': 'date_deadline',
349                     'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'),
350                     'categ_id/id': call(self.get_category, 'crm.meeting', const('Tasks')),
351                     'partner_id/id': related_ref(self.TABLE_ACCOUNT),
352                     'partner_address_id/id': ref(self.TABLE_CONTACT,'contact_id'),
353                     'state': map_val('status', self.task_state)
354                 }
355             }
356        
357     """
358     import Calls
359     """     
360     call_state = {   
361             'Planned' : 'open',
362             'Held':'done',
363             'Not Held': 'pending',
364         }
365
366     def get_calls_mapping(self):
367         return { 
368                 'model' : 'crm.phonecall',
369                 'dependencies' : [self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_OPPORTUNITY, self.TABLE_LEAD],
370                 'map' : {
371                     'name': 'name',
372                     'date': 'date_start',
373                     'duration': call(self.get_float_time, value('duration_hours'), value('duration_minutes')),
374                     'user_id/id':  ref(self.TABLE_USER, 'assigned_user_id'),
375                     'partner_id/id': related_ref(self.TABLE_ACCOUNT),
376                     'partner_address_id/id': related_ref(self.TABLE_CONTACT),
377                     'categ_id/id': call(self.get_category, 'crm.phonecall', value('direction')),
378                     'opportunity_id/id': related_ref(self.TABLE_OPPORTUNITY),
379                     'description': 'description',   
380                     'state': map_val('status', self.call_state)                      
381                 }
382             }        
383         
384     """
385         import meeting
386     """
387     meeting_state = {
388             'Planned' : 'draft',
389             'Held': 'open',
390             'Not Held': 'draft', 
391         }
392     
393     def get_alarm_id(self, dict_val, val):
394         alarm_dict = {
395             '60': '1 minute before',
396             '300': '5 minutes before',
397             '600': '10 minutes before',
398             '900': '15 minutes before',
399             '1800':'30 minutes before',
400             '3600': '1 hour before',
401         }
402         return self.mapped_id_if_exist('res.alarm', [('name', 'like', alarm_dict.get(val))], 'alarm', val)
403     
404     #TODO attendees
405     def get_meeting_mapping(self):
406         return { 
407                 'model' : 'crm.meeting',
408                 'dependencies' : [self.TABLE_CONTACT, self.TABLE_OPPORTUNITY, self.TABLE_LEAD],
409                 'map' : {
410                     'name': 'name',
411                     'date': 'date_start',
412                     'duration': call(self.get_float_time, value('duration_hours'), value('duration_minutes')),
413                     'location': 'location',
414                     'alarm_id/id': call(self.get_alarm_id, value('reminder_time')),
415                     'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'),
416                     'partner_id/id': related_ref(self.TABLE_ACCOUNT),
417                     'partner_address_id/id': related_ref(self.TABLE_CONTACT),
418                     'state': map_val('status', self.meeting_state)
419                 }
420             }
421     
422     """
423         import Opportunity
424     """
425     def get_opportunity_status(self, sugar_val):
426         fields = ['name', 'type']
427         name = 'Opportunity_' + sugar_val['sales_stage']
428         data = [sugar_val['sales_stage'], 'Opportunity']
429         return self.import_object(fields, data, 'crm.case.stage', self.TABLE_STAGE, name, [('type', '=', 'opportunity'), ('name', 'ilike', sugar_val['sales_stage'])])
430     
431     def import_opportunity_contact(self, val):
432         sugar_opportunities_contact = set(sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Opportunities', module_id=val.get('id'), related_module='Contacts', query=None, deleted=None))
433             
434         partner_contact_id = False 
435         partner_contact_email = False       
436         partner_address_obj = self.obj.pool.get('res.partner.address')
437         partner_xml_id = self.name_exist(self.TABLE_ACCOUNT, val['account_name'], 'res.partner')
438         
439         for contact in sugar_opportunities_contact:
440             address_id = self.get_mapped_id(self.TABLE_CONTACT, contact)
441             if address_id:                    
442                 address = partner_address_obj.browse(self.cr, self.uid, address_id)
443                 partner_name = address.partner_id and address.partner_id.name or False
444                 if not partner_name: #link with partner id 
445                     fields = ['partner_id/id']
446                     data = [partner_xml_id]
447                     self.import_object(fields, data, 'res.partner.address', self.TABLE_CONTACT, contact, self.DO_NOT_FIND_DOMAIN)
448                 if not partner_name or partner_name == val.get('account_name'):
449                     partner_contact_id = self.xml_id_exist(self.TABLE_CONTACT, contact)
450                     partner_contact_email = address.email
451         return partner_contact_id, partner_contact_email
452
453     def import_opp(self, val):    
454         partner_contact_name, partner_contact_email = self.import_opportunity_contact(val)
455         val['partner_address_id/id'] = partner_contact_name
456         val['email_from'] = partner_contact_email
457         return val
458     
459     def get_opp_mapping(self):
460         return {
461             'model' : 'crm.lead',
462             'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT],
463             'hook' : self.import_opp,
464             'map' :  {
465                 'name': 'name',
466                 'probability': 'probability',
467                 'partner_id/id': refbyname(self.TABLE_ACCOUNT, 'account_name', 'res.partner'),
468                 'title_action': 'next_step',
469                 'partner_address_id/id': 'partner_address_id/id',
470                 'planned_revenue': 'amount',
471                 'date_deadline': 'date_closed',
472                 'user_id/id' : ref(self.TABLE_USER, 'assigned_user_id'),
473                 'stage_id/id' : self.get_opportunity_status,
474                 'type' : const('opportunity'),
475                 'categ_id/id': call(self.get_category, 'crm.lead', value('opportunity_type')),
476                 'email_from': 'email_from',
477                 'state' : const('open'), #TODO
478             }
479         }
480     
481     """
482         import lead
483     """
484     def get_lead_status(self, sugar_val):
485         fields = ['name', 'type']
486         name = 'lead_' + sugar_val.get('status', '')
487         data = [sugar_val.get('status', ''), 'lead']
488         return self.import_object(fields, data, 'crm.case.stage', self.TABLE_STAGE, name, [('type', '=', 'lead'), ('name', 'ilike', sugar_val.get('status', ''))])
489
490     lead_state = {
491         'New' : 'draft',
492         'Assigned':'open',
493         'In Progress': 'open',
494         'Recycled': 'cancel',
495         'Dead': 'done',
496         'Converted': 'done',
497     }
498
499     
500     def import_lead(self, val):
501         if val.get('opportunity_id'): #if lead is converted into opp, don't import as lead
502             return False
503         if val.get('primary_address_country'):
504             country_id = self.get_all_countries(val.get('primary_address_country'))
505             val['country_id/id'] =  country_id
506             val['state_id/id'] =  self.get_all_states(val.get('primary_address_state'), country_id)
507         return val
508     
509     def get_lead_mapping(self):
510         return {
511             'model' : 'crm.lead',
512             'hook' : self.import_lead,
513             'map' : {
514                 'name': concat('first_name', 'last_name'),
515                 'contact_name': concat('first_name', 'last_name'),
516                 'description': ppconcat('description', 'refered_by', 'lead_source', 'lead_source_description', 'website', 'email2', 'status_description', 'lead_source_description', 'do_not_call'),
517                 'partner_name': 'account_name',
518                 'email_from': 'email1',
519                 'phone': 'phone_work',
520                 'mobile': 'phone_mobile',
521                 'title/id': call(self.get_job_title, value('salutation')),
522                 'function':'title',
523                 'street': 'primary_address_street',
524                 'street2': 'alt_address_street',
525                 'zip': 'primary_address_postalcode',
526                 'city':'primary_address_city',
527                 'user_id/id' : ref(self.TABLE_USER, 'assigned_user_id'),
528                 'stage_id/id' : self.get_lead_status,
529                 'type' : const('lead'),
530                 'state': map_val('status', self.lead_state) ,
531                 'fax': 'phone_fax',
532                 'referred': 'refered_by',
533                 'optout': 'do_not_call',
534                 'type_id/id': call(self.get_campaign_id, value('lead_source')),
535                 'country_id/id': 'country_id/id',
536                 'state_id/id': 'state_id/id'
537                 } 
538         }
539     
540     """
541         import contact
542     """
543     def get_email(self, val):
544         return val.get('email1') + ','+ val.get('email2')
545     
546     def import_contact(self, val):
547         if val.get('primary_address_country'):
548             country_id = self.get_all_countries(val.get('primary_address_country'))
549             state = self.get_all_states(val.get('primary_address_state'), country_id)
550             val['country_id/id'] =  country_id
551             val['state_id/id'] =  state  
552         return val    
553         
554     def get_contact_mapping(self):
555         return { 
556             'model' : 'res.partner.address',
557             'dependencies' : [self.TABLE_ACCOUNT],
558             'hook' : self.import_contact,
559             'map' :  {
560                 'name': concat('first_name', 'last_name'),
561                 'partner_id/id': ref(self.TABLE_ACCOUNT,'account_id'),
562                 'phone': 'phone_work',
563                 'mobile': 'phone_mobile',
564                 'fax': 'phone_fax',
565                 'function': 'title',
566                 'street': 'primary_address_street',
567                 'zip': 'primary_address_postalcode',
568                 'city': 'primary_address_city',
569                 'country_id/id': 'country_id/id',
570                 'state_id/id': 'state_id/id',
571                 'email': self.get_email,
572                 'type': const('contact')
573             }
574         }
575     
576     """ 
577         import Account
578     """
579     def get_address_type(self, val, type):
580         if type == 'invoice':
581             type_address = 'billing'
582         else:
583             type_address = 'shipping'     
584     
585         map_partner_address = {
586             'name': 'name',
587             'phone': 'phone_office',
588             'mobile': 'phone_mobile',
589             'fax': 'phone_fax',
590             'type': 'type',
591             'street': type_address + '_address_street',
592             'zip': type_address +'_address_postalcode',
593             'city': type_address +'_address_city',
594              'country_id/id': 'country_id/id',
595              'type': 'type',
596             }
597         
598         if val.get(type_address +'_address_country'):
599             country_id = self.get_all_countries(val.get(type_address +'_address_country'))
600             state = self.get_all_states(val.get(type_address +'_address_state'), country_id)
601             val['country_id/id'] =  country_id
602             val['state_id/id'] =  state
603         val['type'] = type
604         val['id_new'] = val['id'] + '_address_' + type
605         return self.import_object_mapping(map_partner_address, val, 'res.partner.address', self.TABLE_CONTACT, val['id_new'], self.DO_NOT_FIND_DOMAIN) 
606     
607     def get_partner_address(self, val):
608         address_id=[]
609         type_dict = {'billing_address_street' : 'invoice', 'shipping_address_street' : 'delivery'}
610         for key, type_value in type_dict.items():
611             if val.get(key):
612                 id = self.get_address_type(val, type_value)
613                 address_id.append(id)
614           
615         return ','.join(address_id)
616     
617     def get_partner_mapping(self):
618         return {
619                 'model' : 'res.partner',
620                 'dependencies' : [self.TABLE_USER],
621                 'map' : {
622                     'name': 'name',
623                     'website': 'website',
624                     'user_id/id': ref(self.TABLE_USER,'assigned_user_id'),
625                     'ref': 'sic_code',
626                     'comment': ppconcat('description', 'employees', 'ownership', 'annual_revenue', 'rating', 'industry', 'ticker_symbol'),
627                     'customer': const('1'),
628                     'supplier': const('0'),
629                     'address/id':'address/id', 
630                     'parent_id/id_parent' : 'parent_id',
631                     'address/id' : self.get_partner_address,
632                 }
633         }
634
635     """
636         import Employee
637     """
638     def get_ressource(self, val):
639         map_resource = { 
640             'name': concat('first_name', 'last_name'),
641         }        
642         return self.import_object_mapping(map_resource, val, 'resource.resource', self.TABLE_RESSOURCE, val['id'], self.DO_NOT_FIND_DOMAIN)
643     
644     def get_job_id(self, val):
645         fields = ['name']
646         data = [val.get('title')]
647         return self.import_object(fields, data, 'hr.job', 'hr_job', val.get('title'))
648
649     def get_user_address(self, val):
650         map_user_address = {
651             'name': concat('first_name', 'last_name'),
652             'city': 'address_city',
653             'country_id/id': 'country_id/id',
654             'state_id/id': 'state_id/id',
655             'street': 'address_street',
656             'zip': 'address_postalcode',
657             'fax': 'fax',
658         }
659         
660         if val.get('address_country'):
661             country_id = self.get_all_countries(val.get('address_country'))
662             state_id = self.get_all_states(val.get('address_state'), country_id)
663             val['country_id/id'] =  country_id
664             val['state_id/id'] =  state_id
665             
666         return self.import_object_mapping(map_user_address, val, 'res.partner.address', self.TABLE_CONTACT, val['id'], self.DO_NOT_FIND_DOMAIN)
667     
668     def get_employee_mapping(self):
669         return {
670             'model' : 'hr.employee',
671             'dependencies' : [self.TABLE_USER],
672             'map' : {
673                 'resource_id/id': self.get_ressource, 
674                 'name': concat('first_name', 'last_name'),
675                 'work_phone': 'phone_work',
676                 'mobile_phone':  'phone_mobile',
677                 'user_id/id': ref(self.TABLE_USER, 'id'), 
678                 'address_home_id/id': self.get_user_address,
679                 'notes': 'description',
680                 'job_id/id': self.get_job_id,
681             }
682      }
683     
684     """
685         import user
686     """  
687     def import_user(self, val):
688         user_obj = self.obj.pool.get('res.users')
689         user_ids = user_obj.search(self.cr, self.uid, [('login', '=', val.get('user_name'))])
690         if user_ids: 
691             val['.id'] = str(user_ids[0])
692         else:
693             val['password'] = 'sugarcrm' #default password for all user #TODO needed in documentation
694             
695         val['context_lang'] = self.context.get('lang','en_US')
696         return val
697     
698     def get_users_department(self, val):
699         dep = val.get('department')
700         fields = ['name']
701         data = [dep]
702         if not dep:
703             return False
704         return self.import_object(fields, data, 'hr.department', 'hr_department_user', dep)
705
706     def get_user_mapping(self):
707         return {
708             'model' : 'res.users',
709             'hook' : self.import_user,
710             'map' : { 
711                 'name': concat('first_name', 'last_name'),
712                 'login': 'user_name',
713                 'context_lang' : 'context_lang',
714                 'password' : 'password',
715                 '.id' : '.id',
716                 'context_department_id/id': self.get_users_department,
717             }
718         }
719
720     def get_mapping(self):
721         return {
722             self.TABLE_USER : self.get_user_mapping(),
723             self.TABLE_EMPLOYEE : self.get_employee_mapping(),
724             self.TABLE_ACCOUNT : self.get_partner_mapping(),
725             self.TABLE_CONTACT : self.get_contact_mapping(),
726             self.TABLE_LEAD : self.get_lead_mapping(),
727             self.TABLE_OPPORTUNITY : self.get_opp_mapping(),
728             self.TABLE_MEETING : self.get_meeting_mapping(),
729             self.TABLE_CALL : self.get_calls_mapping(),
730             self.TABLE_TASK : self.get_task_mapping(),
731             self.TABLE_PROJECT : self.get_project_mapping(),
732             self.TABLE_PROJECT_TASK: self.get_project_task_mapping(),
733             self.TABLE_BUG: self.get_project_issue_mapping(),
734             self.TABLE_CASE: self.get_crm_claim_mapping(),
735             self.TABLE_NOTE: self.get_history_mapping()
736         }
737
738
739
740
741
742 class import_sugarcrm(osv.osv):
743     """Import SugarCRM DATA"""
744     
745     _name = "import.sugarcrm"
746     _description = __doc__
747     _columns = {
748         'opportunity': fields.boolean('Leads and Opportunities', help="If Opportunities are checked, SugarCRM opportunities data imported in OpenERP crm-Opportunity form"),
749         'user': fields.boolean('Users', help="If Users  are checked, SugarCRM Users data imported in OpenERP Users form"),
750         'contact': fields.boolean('Contacts', help="If Contacts are checked, SugarCRM Contacts data imported in OpenERP partner address form"),
751         'account': fields.boolean('Accounts', help="If Accounts are checked, SugarCRM  Accounts data imported in OpenERP partners form"),
752         'employee': fields.boolean('Employee', help="If Employees is checked, SugarCRM Employees data imported in OpenERP employees form"),
753         'meeting': fields.boolean('Meetings', help="If Meetings is checked, SugarCRM Meetings data imported in OpenERP meetings form"),
754         'call': fields.boolean('Calls', help="If Calls is checked, SugarCRM Calls data imported in OpenERP phonecalls form"),
755         'claim': fields.boolean('Claims', help="If Claims is checked, SugarCRM Claims data imported in OpenERP Claims form"),
756         'email': fields.boolean('Emails', help="If Emails is checked, SugarCRM Emails data imported in OpenERP Emails form"),
757         'project': fields.boolean('Projects', help="If Projects is checked, SugarCRM Projects data imported in OpenERP Projects form"),
758         'project_task': fields.boolean('Project Tasks', help="If Project Tasks is checked, SugarCRM Project Tasks data imported in OpenERP Project Tasks form"),
759         'task': fields.boolean('Tasks', help="If Tasks is checked, SugarCRM Tasks data imported in OpenERP Meetings form"),
760         'bug': fields.boolean('Bugs', help="If Bugs is checked, SugarCRM Bugs data imported in OpenERP Project Issues form"),
761         'attachment': fields.boolean('Attachments', help="If Attachments is checked, SugarCRM Notes data imported in OpenERP's Related module's History with attachment"),
762         'document': fields.boolean('Documents', help="If Documents is checked, SugarCRM Documents data imported in OpenERP Document Form"),
763         'username': fields.char('User Name', size=64),
764         'password': fields.char('Password', size=24),
765     }
766     _defaults = {#to be set to true, but easier for debugging
767        'opportunity': False,
768        'user' : False,
769        'contact' : False,
770        'account' : False,
771         'employee' : False,
772         'meeting' : False,
773         'task' : False,
774         'call' : False,
775         'claim' : False,    
776         'email' : False, 
777         'project' : False,   
778         'project_task': False,     
779         'bug': False,
780         'document': False
781     }
782     
783     def get_key(self, cr, uid, ids, context=None):
784         """Select Key as For which Module data we want import data."""
785         if not context:
786             context = {}
787         key_list = []
788         for current in self.browse(cr, uid, ids, context):
789             if current.opportunity:
790                 key_list.append('Leads')
791                 key_list.append('Opportunities')
792             if current.user:
793                 key_list.append('Users')
794             if current.contact:
795                 key_list.append('Contacts')
796             if current.account:
797                 key_list.append('Accounts') 
798             if current.employee:
799                 key_list.append('Employees')  
800             if current.meeting:
801                 key_list.append('Meetings')
802             if current.task:
803                 key_list.append('Tasks')
804             if current.call:
805                 key_list.append('Calls')
806             if current.claim:
807                 key_list.append('Cases')                
808             if current.email:
809                 key_list.append('Emails') 
810             if current.project:
811                 key_list.append('Project')
812             if current.project_task:
813                 key_list.append('ProjectTask')
814             if current.bug:
815                 key_list.append('Bugs')
816             if current.attachment:
817                 key_list.append('Notes')     
818             if current.document:
819                 key_list.append('Documents')                                                  
820         return key_list
821
822     def import_all(self, cr, uid, ids, context=None):
823         
824 #        """Import all sugarcrm data into openerp module"""
825         keys = self.get_key(cr, uid, ids, context)
826         imp = sugar_import(self, cr, uid, "sugarcrm", "import_sugarcrm", context)
827         imp.import_all(keys)
828         
829         obj_model = self.pool.get('ir.model.data')
830         model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','import.message.form')])
831         resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])
832         return {
833                 'view_type': 'form',
834                 'view_mode': 'form',
835                 'res_model': 'import.message',
836                 'views': [(resource_id,'form')],
837                 'type': 'ir.actions.act_window',
838                 'target': 'new',
839             }
840         
841 import_sugarcrm()