[MERGE] correction of mapping + draft common framework for import + self_dependencies
bzr revid: tfr@openerp.com-20110504100329-rqg7pa4fa1ynfpws
This commit is contained in:
commit
637075eb92
|
@ -23,3 +23,4 @@ import import_sugarcrm
|
|||
import sugar
|
||||
import wizard
|
||||
import sugarcrm_fields_mapping
|
||||
import import_framework
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
"Contacts", "Employees", Meetings, Phonecalls, Emails, and Project, Project Tasks Data into OpenERP Module.""",
|
||||
'author': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['project_timesheet', 'project_issue'],
|
||||
'depends': ['crm_claim', 'project_timesheet', 'project_issue', 'document'],
|
||||
'init_xml': [],
|
||||
'update_xml': ["wizard/sugarcrm_login_view.xml",
|
||||
"wizard/import_message_view.xml",
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
MODULE_NAME = 'sugarcrm_import'
|
||||
|
||||
|
||||
DO_NOT_FIND_DOMAIN = [('id', '=', 0)]
|
||||
|
||||
|
||||
def find_mapped_id(obj, cr, uid, res_model, xml_id, context=None):
|
||||
return obj.pool.get('ir.model.data')._get_id(cr, uid, MODULE_NAME, xml_id)
|
||||
|
||||
def xml_id_exist(obj, cr, uid, table, sugar_id, context=None):
|
||||
xml_id = generate_xml_id(sugar_id, table)
|
||||
id = obj.pool.get('ir.model.data')._get_id(cr, uid, MODULE_NAME, xml_id)
|
||||
return id and xml_id or False
|
||||
|
||||
|
||||
def mapped_id(obj, cr, uid, res_model, sugar_id, id, context=None):
|
||||
"""
|
||||
This function create the mapping between an already existing data and the similar data of sugarcrm
|
||||
@param res_model: model of the mapped object
|
||||
@param sugar_id: external sugar id
|
||||
@param id: id in the database
|
||||
|
||||
@return : the xml_id or sugar_id
|
||||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
ir_model_data_obj = obj.pool.get('ir.model.data')
|
||||
id = ir_model_data_obj._update(cr, uid, res_model,
|
||||
MODULE_NAME, {}, mode='update', xml_id=sugar_id,
|
||||
noupdate=True, res_id=id, context=context)
|
||||
return sugar_id
|
||||
|
||||
|
||||
|
||||
|
||||
def mapped_id_if_exist(sugar_obj, cr, uid, model, domain, xml_id, context=None):
|
||||
"""
|
||||
@param domain : search domain to find existing record, should return a unique record
|
||||
@param xml_id: xml_id give to the mapping
|
||||
|
||||
@return : the xml_id if the record exist in the db, False otherwise
|
||||
"""
|
||||
obj = sugar_obj.pool.get(model)
|
||||
ids = obj.search(cr, uid, domain, context=context)
|
||||
#print "ids", ids, "domain", domain
|
||||
if ids:
|
||||
return mapped_id(obj, cr, uid, model, xml_id, ids[0], context=context)
|
||||
return False
|
||||
|
||||
def import_object(sugar_obj, cr, uid, fields, data, model, table, name, domain_search=False, context=None):
|
||||
"""
|
||||
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
|
||||
use import_data that will take care to create/update or do nothing with the data
|
||||
this method return the xml_id
|
||||
@param fields: list of fields needed to create the object without id
|
||||
@param data: the list of the data, in the same order as the field
|
||||
ex : fields = ['firstname', 'lastname'] ; data = ['John', 'Mc donalds']
|
||||
@param model: the openerp's model of the create/update object
|
||||
@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
|
||||
@param unique_name: the name of the object that we want to create/update get the id
|
||||
@param domain_search : the domain that should find the unique existing record
|
||||
|
||||
@return: the xml_id of the ressources
|
||||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
domain_search = not domain_search and [('name', 'ilike', name)] or domain_search
|
||||
obj = sugar_obj.pool.get(model)
|
||||
xml_id = generate_xml_id(name, table)
|
||||
|
||||
xml_ref = mapped_id_if_exist(obj, cr, uid, model, domain_search, xml_id, context=context)
|
||||
fields.append('id')
|
||||
data.append(xml_id)
|
||||
obj.import_data(cr, uid, fields, [data], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
|
||||
return xml_ref or xml_id
|
||||
|
||||
|
||||
def add_m2o_data(data, fields, column, xml_ids):
|
||||
"""
|
||||
@param fields: list of fields
|
||||
@param data: the list of the data, in the same order as the field
|
||||
ex : fields = ['firstname', 'lastname'] ; data = ['John', 'Mc donalds']
|
||||
@param column : name of the column that will contains the xml_id of o2m data
|
||||
ex : contact_id/id
|
||||
@param xml_ids : the list of xml id of the data
|
||||
|
||||
@return fields and data with the last column "column", "xml_id1,xml_id2,xml_id3,.."
|
||||
"""
|
||||
fields.append(column)
|
||||
data.append(','.join(xml_ids))
|
||||
return fields, data
|
||||
|
||||
def import_self_dependencies(obj, cr, uid, parent_field, datas, context):
|
||||
"""
|
||||
@param parent_field: the name of the field that generate a self_dependencies, we call the object referenced in this
|
||||
field the parent of the object
|
||||
@param datas: a list of dictionnaries
|
||||
Dictionnaries need to contains
|
||||
id_new : the xml_id of the object
|
||||
field_new : the xml_id of the parent
|
||||
"""
|
||||
fields = ['id', parent_field]
|
||||
for data in datas:
|
||||
if data[parent_field + '_new']:
|
||||
values = [data['id_new'], data[parent_field + '_new']]
|
||||
obj.import_data(cr, uid, fields, [values], mode='update', current_module=MODULE_NAME, noupdate=True, context=context)
|
||||
|
||||
|
||||
def generate_xml_id(name, table):
|
||||
"""
|
||||
@param name: name of the object, has to be unique in for a given table
|
||||
@param table : table where the record we want generate come from
|
||||
@return: a unique xml id for record, the xml_id will be the same given the same table and same name
|
||||
To be used to avoid duplication of data that don't have ids
|
||||
"""
|
||||
sugar_instance = "sugarcrm" #TODO need to be changed we information is known in the wizard
|
||||
name = name.replace('.', '_')
|
||||
return sugar_instance + "_" + table + "_" + name
|
File diff suppressed because it is too large
Load Diff
|
@ -9,12 +9,14 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Import SugarCRM">
|
||||
<group colspan="4" width="500">
|
||||
<group colspan="4" width="700">
|
||||
<separator string="Select SugarCRM Module Name" colspan="4"/>
|
||||
<group colspan="4" col="6">
|
||||
<field name="opportunity" />
|
||||
<field name= "meeting" />
|
||||
<field name= "task" string="Meeting Tasks"/>
|
||||
<field name= "call" />
|
||||
<field name= "claim" />
|
||||
<field name= "account" />
|
||||
<field name= "contact" />
|
||||
<field name="user" />
|
||||
|
@ -23,7 +25,8 @@
|
|||
<field name= "project" />
|
||||
<field name= "project_task" />
|
||||
<field name= "bug" string="Project Issue"/>
|
||||
<field name= "attachment" />
|
||||
<field name= "document" />
|
||||
<field name= "attachment" string="History and Attachment" />
|
||||
</group>
|
||||
<field name="username" invisible="1"/>
|
||||
<field name="password" invisible="1"/>
|
||||
|
@ -32,7 +35,7 @@
|
|||
<group colspan="4" >
|
||||
<label string="" colspan="2"/>
|
||||
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
|
||||
<button name="import_all" string="Import"
|
||||
<button name="import_all" string="_Import"
|
||||
type="object" icon="terp-camera_test"/>
|
||||
</group>
|
||||
</form>
|
||||
|
|
|
@ -70,8 +70,10 @@ def attachment_search(portType, sessionid, module_name, module_id=None):
|
|||
se_req._module_name = module_name
|
||||
se_resp = portType.get_note_attachment(se_req)
|
||||
file = False
|
||||
filename = False
|
||||
file = se_resp._return._note_attachment.File
|
||||
return file
|
||||
filename = se_resp._return._note_attachment.Filename
|
||||
return file, filename
|
||||
|
||||
def user_get_attendee_list(portType, sessionid, module_name=None, module_id=None):
|
||||
se_req = get_attendee_listRequest()
|
||||
|
|
|
@ -18,8 +18,21 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
import tools
|
||||
import pytz
|
||||
import time
|
||||
from datetime import datetime, timedelta, date
|
||||
from dateutil import parser
|
||||
import dateutil
|
||||
|
||||
def sugarcrm_fields_mapp(dict_sugar, openerp_dict):
|
||||
def sugarcrm_fields_mapp(dict_sugar, openerp_dict, context=None):
|
||||
if not context:
|
||||
context = {}
|
||||
if 'tz' in context and context['tz']:
|
||||
time_zone = context['tz']
|
||||
else:
|
||||
time_zone = tools.get_server_timezone()
|
||||
au_tz = pytz.timezone(time_zone)
|
||||
fields=[]
|
||||
data_lst = []
|
||||
for key,val in openerp_dict.items():
|
||||
|
@ -30,6 +43,18 @@ def sugarcrm_fields_mapp(dict_sugar, openerp_dict):
|
|||
if len(val) >= 1 and val[0] == "__prettyprint__":
|
||||
val = val[1:]
|
||||
data_lst.append('\n\n'.join(map(lambda x : x + ": " + dict_sugar.get(x,''), val)))
|
||||
elif val[0] == '__datetime__':
|
||||
val = val[1]
|
||||
if dict_sugar.get(val) and len(dict_sugar.get(val))<=10:
|
||||
updated_dt = date.fromtimestamp(time.mktime(time.strptime(dict_sugar.get(val), '%Y-%m-%d'))) or False
|
||||
elif dict_sugar.get(val):
|
||||
convert_date = datetime.strptime(dict_sugar.get(val), '%Y-%m-%d %H:%M:%S')
|
||||
edate = convert_date.replace(tzinfo=au_tz)
|
||||
au_dt = au_tz.normalize(edate.astimezone(au_tz))
|
||||
updated_dt = datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
else:
|
||||
updated_dt = False
|
||||
data_lst.append(updated_dt)
|
||||
else:
|
||||
if key == 'duration':
|
||||
data_lst.append('.'.join(map(lambda x : dict_sugar.get(x,''), val)))
|
||||
|
|
Loading…
Reference in New Issue