openerp-dev-web team mailing list archive
-
openerp-dev-web team
-
Mailing list archive
-
Message #05848
lp:~openerp-dev/openobject-addons/trunk-import_salesforce-punctual_import-jam into lp:~openerp-dev/openobject-addons/trunk-import_salesforce
Jigar Amin - OpenERP has proposed merging lp:~openerp-dev/openobject-addons/trunk-import_salesforce-punctual_import-jam into lp:~openerp-dev/openobject-addons/trunk-import_salesforce.
Requested reviews:
Bhumika (OpenERP) (sbh-openerp)
For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-import_salesforce-punctual_import-jam/+merge/58925
Hello,
Changes with merge Proposal:
+ Punctual Import wizard.
+ Cron Job to Import the Data.
Kindly Review this.
Thank You
--
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-import_salesforce-punctual_import-jam/+merge/58925
Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-addons/trunk-import_salesforce.
=== modified file 'import_salesforce/__openerp__.py'
--- import_salesforce/__openerp__.py 2011-04-11 06:40:28 +0000
+++ import_salesforce/__openerp__.py 2011-04-25 04:40:54 +0000
@@ -24,18 +24,18 @@
'version': '1.0',
'category': 'Generic Modules',
'description': """
-This Module Import SaleForce 'Leads', 'Opportunity', 'Contacts' , 'Cases', 'User',
+This Module Import SaleForce 'Leads', 'Opportunity', 'Contacts' , 'Cases', 'User',
'Events', 'Activity' and Other history Detail data into OpenERP Module.
""",
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
- 'depends': [ 'base','crm_claim'],
+ 'depends': ['base', 'crm_claim', 'document'],
'init_xml': [],
'update_xml': [
'import_sf_view.xml',
- 'wizard/import_salesforce_view.xml',
- 'wizard/sf_import_message_view.xml',
+ 'wizard/import_salesforce_view.xml',
+ 'wizard/sf_import_message_view.xml',
],
'demo_xml': [],
'test': [],
=== modified file 'import_salesforce/import_sf.py'
--- import_salesforce/import_sf.py 2011-04-19 06:45:07 +0000
+++ import_salesforce/import_sf.py 2011-04-25 04:40:54 +0000
@@ -20,20 +20,27 @@
##############################################################################
from datetime import datetime
+import time
from osv import osv
from osv import fields
from tools.translate import _
+
try:
import beatbox
from beatbox import SoapFaultError
except ImportError:
- raise osv.except_osv(_('BeaobtBox Import Error!'), _('Please install beatbox api for SaleForce - beatbox-20.0.zip.\nhttp://pypi.python.org/pypi/beatbox'))
+ raise osv.except_osv(_('BeatBox Import Error!'), _('Please install beatbox api for SaleForce - beatbox-20.0.zip.\nhttp://pypi.python.org/pypi/beatbox'))
import logging
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
ACT_TYPE = ''
+MODEL_LIST = [('lead', 'Lead'), ('opportunity', 'Opportunity'),
+ ('user', 'User'), ('contact', 'Partner/Contacts'),
+ ('case', 'Cases/Claim'), ('event', 'Event/Meetings'),
+ ('task', 'Activity/Task'), ('attachment', 'Attachment'),
+ ('folder', 'Folder/Directory'), ('document', 'Documents')]
def dataMapping(dictsf, dictoe):
@@ -88,10 +95,10 @@
try:
sfc = beatbox.PythonClient()
sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
- sqlStmt = prepareStatement(MODEL_MAP.get('Attachment').get('field_map'), 'Attachment')
+ sqlStmt = prepareStatement(MODEL_MAP.get('attachment').get('field_map'), 'Attachment')
sfVals = sfc.query(sqlStmt)
for rec in sfVals:
- fields = MODEL_MAP.get('Attachment').get('field_map')
+ fields = MODEL_MAP.get('attachment').get('field_map')
model_data = data_pool.search(cr, uid, [('name', '=', rec.get('ParentId', False))])
rec.update({'ParentId': False})
if model_data:
@@ -124,10 +131,10 @@
message_pool = sf_obj.pool.get('mailgate.message')
data_pool = sf_obj.pool.get('ir.model.data')
try:
- sqlStmt = prepareStatement(MODEL_MAP.get('Note').get('field_map'), 'Note')
+ sqlStmt = prepareStatement(MODEL_MAP.get('note').get('field_map'), 'Note')
sfVals = sfc.query(sqlStmt)
for rec in sfVals:
- fields = MODEL_MAP.get('Note').get('field_map')
+ fields = MODEL_MAP.get('note').get('field_map')
model_data = data_pool.search(cr, uid, [('name', '=', rec.get('ParentId', False))])
fields.update({'date': 'date'})
rec.update({'date': datetime.now().strftime(DATETIME_FORMAT)})
@@ -257,10 +264,10 @@
try:
sfc = beatbox.PythonClient()
sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
- sqlStmt = prepareStatement(MODEL_MAP.get('Lead').get('field_map'), 'Lead')
+ sqlStmt = prepareStatement(MODEL_MAP.get('lead').get('field_map'), 'Lead')
sfVals = sfc.query(sqlStmt)
for rec in sfVals:
- fields = MODEL_MAP.get('Lead').get('field_map')
+ fields = MODEL_MAP.get('lead').get('field_map')
rec.update({'Salutation': titleMapping(sf_obj, cr, uid, rec.get('Salutation', False), 'contact', context)})
rec.update({'Rating': priorityMapping(sf_obj, cr, uid, rec.get('Rating', False), context)})
fields.update({'state': 'state'})
@@ -288,15 +295,14 @@
def importUser(sf_obj, cr, uid, context):
if context == None:
context = {}
-
user_pool = sf_obj.pool.get('res.users')
try:
sfc = beatbox.PythonClient()
sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
- sqlStmt = prepareStatement(MODEL_MAP.get('User').get('field_map'), 'User')
+ sqlStmt = prepareStatement(MODEL_MAP.get('user').get('field_map'), 'User')
sfVals = sfc.query(sqlStmt)
for rec in sfVals:
- field, data = dataMapping(rec, MODEL_MAP.get('User').get('field_map'))
+ field, data = dataMapping(rec, MODEL_MAP.get('user').get('field_map'))
user_pool.import_data(cr, uid, field, [data], mode='update', current_module='import_salesforce', noupdate=True, context=context)
except SoapFaultError, sfe:
log = logging.getLogger('import.salesforce.SoapFaultError')
@@ -364,10 +370,10 @@
message_pool = sf_obj.pool.get('mailgate.message')
data_pool = sf_obj.pool.get('ir.model.data')
try:
- sqlStmt = prepareStatement(MODEL_MAP.get('OpportunityHistory').get('field_map'), 'OpportunityHistory')
+ sqlStmt = prepareStatement(MODEL_MAP.get('opportunityhistory').get('field_map'), 'OpportunityHistory')
sfVals = sfc.query(sqlStmt)
for rec in sfVals:
- fields = MODEL_MAP.get('OpportunityHistory').get('field_map')
+ fields = MODEL_MAP.get('opportunityhistory').get('field_map')
sfopp_id = rec.pop('OpportunityId')
opp_id = data_pool.search(cr, uid, [('model', '=', 'crm.lead'), ('name', '=', sfopp_id)])
if opp_id:
@@ -413,15 +419,15 @@
def importOpportunity(sf_obj, cr, uid, context):
if context == None:
context = {}
-
+
lead_pool = sf_obj.pool.get('crm.lead')
try:
sfc = beatbox.PythonClient()
sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
- sqlStmt = prepareStatement(MODEL_MAP.get('Opportunity').get('field_map'), 'Opportunity')
+ sqlStmt = prepareStatement(MODEL_MAP.get('opportunity').get('field_map'), 'Opportunity')
sfVals = sfc.query(sqlStmt)
for rec in sfVals:
- fields = MODEL_MAP.get('Opportunity').get('field_map')
+ fields = MODEL_MAP.get('opportunity').get('field_map')
rec.update({'type': 'opportunity'})
rec.update({'AccountId': getOpportunityPartner(sf_obj, cr, uid, sfc, rec.get('AccountId', False), context)})
lead = sfc.query("SELECT Id, Name, Status, Salutation, Title, Street, PostalCode, Country, State, Email, Fax, MobilePhone FROM Lead WHERE ConvertedOpportunityId = '%s'"%rec.get('Id'))
@@ -463,8 +469,8 @@
for fid in lead_fields:
fields.pop(fid)
fields.pop('state')
- MODEL_MAP['OpportunityHistory']['function'](sf_obj, cr, uid, sfc, context)
- MODEL_MAP['Note']['function'](sf_obj, cr, uid, sfc, context)
+ MODEL_MAP['opportunityhistory']['function'](sf_obj, cr, uid, sfc, context)
+ MODEL_MAP['note']['function'](sf_obj, cr, uid, sfc, context)
except SoapFaultError, sfe:
log = logging.getLogger('import.salesforce.SoapFaultError')
log.warning(str(sfe))
@@ -479,7 +485,7 @@
def importAddress(sf_obj, cr, uid, address, context):
if context == None:
context = {}
-
+
address_pool = sf_obj.pool.get('res.partner.address')
aids = []
for key, val in address.items():
@@ -537,7 +543,7 @@
sfc = beatbox.PythonClient()
sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
- sqlStmt = prepareStatement(MODEL_MAP.get('Contact').get('field_map'), 'Contact')
+ sqlStmt = prepareStatement(MODEL_MAP.get('contact').get('field_map'), 'Contact')
sfVals = sfc.query(sqlStmt)
for rec in sfVals:
add_dict = {}
@@ -551,14 +557,15 @@
if add in ['invoice', 'delivery']:
account = rec.get('Account')
nkey = key[1:]
- val = account.pop(vals)
- addr.update({nkey: val})
+ if account:
+ val = account.pop(vals)
+ addr.update({nkey: val})
addr.update({'type': add})
addr.update({'email': rec.get('Email')})
addr.update({'name': rec.get('Name')})
add_dict.update({add: addr})
rec.pop('Account')
- fields = MODEL_MAP.get('Contact').get('field_map')
+ fields = MODEL_MAP.get('contact').get('field_map')
rec.pop('Email')
addIds = importAddress(sf_obj, cr, uid, add_dict, context)
rec.update({'Title': titleMapping(sf_obj, cr, uid, rec.get('Title', False), 'partner', context)})
@@ -584,7 +591,7 @@
'''
if context == None:
context = {}
-
+
priMap = {
'High': '2',
'Medium': '3',
@@ -599,7 +606,7 @@
'''
if context == None:
context = {}
-
+
stateMap = {
'New': 'draft',
'Working': 'open',
@@ -616,10 +623,10 @@
message_pool = sf_obj.pool.get('mailgate.message')
data_pool = sf_obj.pool.get('ir.model.data')
try:
- sqlStmt = prepareStatement(MODEL_MAP.get('CaseComment').get('field_map'), 'CaseComment')
+ sqlStmt = prepareStatement(MODEL_MAP.get('casecomment').get('field_map'), 'CaseComment')
sfVals = sfc.query(sqlStmt)
for rec in sfVals:
- fields = MODEL_MAP.get('CaseComment').get('field_map')
+ fields = MODEL_MAP.get('casecomment').get('field_map')
claims = data_pool.search(cr, uid, [('model', '=', 'crm.claim'), ('name', '=', rec.get('ParentId'))])
if claims:
res = data_pool.browse(cr, uid, claims[0], context)
@@ -653,14 +660,14 @@
try:
sfc = beatbox.PythonClient()
sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
- sqlStmt = prepareStatement(MODEL_MAP.get('Case').get('field_map'), 'Case')
+ sqlStmt = prepareStatement(MODEL_MAP.get('case').get('field_map'), 'Case')
sfVals = sfc.query(sqlStmt)
for rec in sfVals:
rec.update({'Priority': claimPriorityMapping(sf_obj, cr, uid, rec.get('Priority', False), context)})
rec.update({'Status': claimStateMapping(sf_obj, cr, uid, rec.get('Status', False), context)})
rec.update({'Owner.Id': getUserId(sf_obj, cr, uid, rec.get('Owner', False), context)})
rec.update({'Contact.Id': getUserId(sf_obj, cr, uid, rec.get('Contact', False), context)})
- field, data = dataMapping(rec, MODEL_MAP.get('Case').get('field_map'))
+ field, data = dataMapping(rec, MODEL_MAP.get('case').get('field_map'))
claim_pool.import_data(cr, uid, field, [data], mode='update', current_module='import_salesforce', noupdate=True, context=context)
importCaseComment(sf_obj, cr, uid, sfc, context)
@@ -815,14 +822,14 @@
try:
sfc = beatbox.PythonClient()
sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
- sqlStmt = prepareStatement(MODEL_MAP.get('Event').get('field_map'), 'Event')
+ sqlStmt = prepareStatement(MODEL_MAP.get('event').get('field_map'), 'Event')
sfVals = sfc.query(sqlStmt)
new_sfVals = []
for i in sfVals:
if not i.get("RecurrenceActivityId") or i.get('Id') == i.get("RecurrenceActivityId"):
new_sfVals.append(i)
for rec in new_sfVals:
- fields= MODEL_MAP.get('Event').get('field_map')
+ fields= MODEL_MAP.get('event').get('field_map')
rec.pop('RecurrenceActivityId')
recurrence = '0'
if rec.get('IsRecurrence'):
@@ -874,7 +881,8 @@
rec.update({'Subject': rec.get('Subject')[0]})
field, data = dataMapping(rec, fields)
model_pool.import_data(cr, uid, field, [data], mode='update', current_module='import_salesforce', noupdate=True, context=context)
- fields.pop('categ_id/.id')
+ if 'categ_id/.id' in fields:
+ fields.pop('categ_id/.id')
except SoapFaultError, sfe:
log = logging.getLogger('import.salesforce.SoapFaultError')
log.warning(str(sfe))
@@ -896,7 +904,7 @@
try:
sfc = beatbox.PythonClient()
sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
- fields = MODEL_MAP.get('Task').get('field_map')
+ fields = MODEL_MAP.get('task').get('field_map')
if ACT_TYPE == 'wtype':
fields.update({'Type': 'Type'})
sqlStmt = prepareStatement(fields, 'Task')
@@ -952,30 +960,88 @@
else:
fields.update({'categ_id/.id': 'category_id'})
rec.update({'category_id': nid})
-
- rec.pop('WhatId')
- rec.pop('WhoId')
+ if 'WhatId' in rec:
+ rec.pop('WhatId')
+ if 'WhoId' in rec:
+ rec.pop('WhoId')
if rec.get('ActivityDate'):
rec.update({'ActivityDate': rec.get('ActivityDate').strftime(DATETIME_FORMAT)})
rec.update({'Owner.Id': getUserId(sf_obj, cr, uid, rec.get('Owner', False), context)})
rec.update({'ActivityDate': datetime.now().strftime(DATETIME_FORMAT)})
createActivity(sf_obj, cr, uid, fields, rec, model, context)
except SoapFaultError, sfe:
- if 'Type' in fields:
- fields.pop('Type')
- log = logging.getLogger('import.salesforce.SoapFaultError')
- log.warning(str(sfe))
- return False
- except Exception, e:
- if 'Type' in fields:
- fields.pop('Type')
- log = logging.getLogger('import.salesforce')
- log.warning(str(e))
- return False
- return True
+ log = logging.getLogger('import.salesforce.SoapFaultError')
+ log.warning(str(sfe))
+ return False
+ except Exception, e:
+ log = logging.getLogger('import.salesforce')
+ log.warning(str(e))
+ return False
+ return True
+
+
+def importFolder(sf_obj, cr, uid, context):
+ if context == None:
+ context = {}
+ document_pool = sf_obj.pool.get('document.directory')
+ try:
+ sfc = beatbox.PythonClient()
+ sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
+ fields = MODEL_MAP.get('folder').get('field_map')
+ sqlStmt = prepareStatement(fields, 'Folder')
+ sfVals = sfc.query(sqlStmt)
+ for rec in sfVals:
+ if rec.get('Type', False) == 'Document':
+ rec.update({'Type': 'directory'})
+ field, data = dataMapping(rec, fields)
+ document_pool.import_data(cr, uid, field, [data], mode='update', current_module='import_salesforce', noupdate=True, context=context)
+ except SoapFaultError, sfe:
+ log = logging.getLogger('import.salesforce.SoapFaultError')
+ log.warning(str(sfe))
+ return False
+ except Exception, e:
+ log = logging.getLogger('import.salesforce')
+ log.warning(str(e))
+ return False
+ return True
+
+
+def importDocument(sf_obj, cr, uid, context):
+ if context == None:
+ context = {}
+ attachment_pool = sf_obj.pool.get('ir.attachment')
+ try:
+ sfc = beatbox.PythonClient()
+ sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
+ fields = MODEL_MAP.get('document').get('field_map')
+ sqlStmt = prepareStatement(fields, 'Document')
+ sfVals = sfc.query(sqlStmt)
+ for rec in sfVals:
+ fields.update({'datas': 'Body'})
+ if rec.get('Type', False) == 'URL':
+ rec.update({'Type': 'url'})
+ else:
+ rec.update({'Type': 'binary'})
+ data = sfc.query("SELECT Body FROM Document WHERE id='%s'"%(rec.get('Id')))
+ if data:
+ data = data[0]
+ rec.update({'Body': data.get('Body')})
+ field, data = dataMapping(rec, fields)
+ attachment_pool.import_data(cr, uid, field, [data], mode='update', current_module='import_salesforce', noupdate=True, context=context)
+
+ except SoapFaultError, sfe:
+ log = logging.getLogger('import.salesforce.SoapFaultError')
+ log.warning(str(sfe))
+ return False
+ except Exception, e:
+ log = logging.getLogger('import.salesforce')
+ log.warning(str(e))
+ return False
+ return True
+
MODEL_MAP = {
- 'User': {
+ 'user': {
'dependencies': [],
'function': importUser,
'field_map': {
@@ -987,8 +1053,8 @@
'context_lang': 'LanguageLocaleKey',
}
},
- 'Attachment': {
- 'dependencies': ['User'],
+ 'attachment': {
+ 'dependencies': ['user'],
'function': importAttachment,
'field_map': {
'id': 'Id',
@@ -998,7 +1064,7 @@
'res_id/.id': 'ParentId',
}
},
- 'Note': {
+ 'note': {
'dependencies': [],
'function': importNote,
'field_map': {
@@ -1008,8 +1074,8 @@
'description': 'Body',
}
},
- 'Opportunity': {
- 'dependencies': ['Contact', 'User'],
+ 'opportunity': {
+ 'dependencies': ['contact', 'user'],
'function': importOpportunity,
'field_map': {
'id': 'Id',
@@ -1023,7 +1089,7 @@
'partner_id/.id': 'AccountId',
}
},
- 'OpportunityHistory': {
+ 'opportunityhistory': {
'dependencies': [],
'function': importOpportunityHistory,
'field_map': {
@@ -1033,8 +1099,8 @@
'res_id/.id': 'OpportunityId',
}
},
- 'Lead': {
- 'dependencies': ['User'],
+ 'lead': {
+ 'dependencies': ['user'],
'function': importLead,
'field_map': {
'id': 'Id',
@@ -1057,7 +1123,7 @@
'country_id/.id': 'Country',
}
},
- 'Contact': {
+ 'contact': {
'dependencies': [],
'function': importContact,
'field_map': {
@@ -1091,8 +1157,8 @@
'szip': 'Account.ShippingPostalCode',
}
},
- 'Case': {
- 'dependencies': ['User', 'Contact'],
+ 'case': {
+ 'dependencies': ['user', 'contact'],
'function': importCase,
'field_map': {
'id': 'Id',
@@ -1107,7 +1173,7 @@
'state': 'Status',
}
},
- 'CaseComment': {
+ 'casecomment': {
'dependencies': [],
'function': importCaseComment,
'field_map': {
@@ -1116,8 +1182,8 @@
'res_id': 'ParentId',
}
},
- 'Event': {
- 'dependencies': ['User', 'Contact'],
+ 'event': {
+ 'dependencies': ['user', 'contact'],
'function': importEvent,
'field_map': {
'id': 'Id',
@@ -1142,8 +1208,8 @@
'partner_id/id': 'WhoId',
}
},
- 'Task': {
- 'dependencies': ['Lead', 'Contact', 'Opportunity'],
+ 'task': {
+ 'dependencies': ['lead', 'contact', 'opportunity'],
'function': importActivity,
'field_map': {
'id': 'Id',
@@ -1156,6 +1222,29 @@
'WhoId': 'WhoId',
}
},
+ 'folder': {
+ 'dependencies': ['user'],
+ 'function': importFolder,
+ 'field_map': {
+ 'id': 'Id',
+ 'name': 'Name',
+ 'type': 'Type',
+ }
+ },
+ 'document': {
+ 'dependencies': ['folder', 'user'],
+ 'function': importDocument,
+ 'field_map': {
+ 'id': 'Id',
+ 'name': 'Name',
+ 'parent_id/id': 'FolderId',
+ 'type': 'Type',
+ 'user_id/id': 'AuthorId',
+ 'datas_fname': 'Name',
+ 'description': 'Description',
+ 'url': 'Url',
+ }
+ },
}
LOGIN_DATA = {
@@ -1172,27 +1261,37 @@
_description = 'Import SalesForce Data'
_columns = {
+ 'file_path': fields.binary('Select CSV file', filters='*.csv,*.xls'),
+ 'username': fields.char('Username/Email', size=255),
+ 'password': fields.char('Password', size=255),
+ 'token': fields.char('Security Token', size=255),
+ 'model_list': fields.selection(MODEL_LIST, 'Model'),
'lead': fields.boolean('Leads', help="If Leads is checked, SalesFroce Leads data imported to OpenERP CRM Leads"),
- 'opportunity': fields.boolean('Opportunities', help="If Opportunity is checked, SalesFroce Leads data imported to OpenERP CRM Opportunity."),
+ 'opportunity': fields.boolean('Opportunities', help="If Opportunity is checked, SalesForce Leads data imported to OpenERP CRM Opportunity."),
'users': fields.boolean('User', help="If Users is checked, SalesFroce Users data imported to OpenERP Users."),
'contact': fields.boolean('Partner/Contacts', help="If Partner/Contacts is checked, SalesFroce Contact data imported to OpenERP Partner and Partner Address."),
'case': fields.boolean('Cases/Claim', help="If Cases/Claim is checked, SalesFroce Cases data imported to OpenERP CRM Claim."),
'event': fields.boolean('Event/Meetings', help="If Event/Meetings is checked, SalesFroce Cases data imported to OpenERP Meetings."),
+ 'folder': fields.boolean('Folder/Directory', help="If Folder/Directory checked, SalesFroce Folder data imported to OpenERP Directory."),
+ 'document': fields.boolean('Document', help="If Documents checked, SalesFroce Folder data imported to OpenERP Document."),
'attachment': fields.boolean('Attachments', help="If Attachments is checked, SalesFroce attachments data will imported to OpenERP Attachemnt, and if resource of the attachment is imported and it will linked to the repective documents."),
'task': fields.boolean('Acivity', help="If Activity is checked, SalesFroce Activity data will imported to OpenERP Meetings and if you want ot import data in separate than selectd 'With Type' from below slection else select 'Without Type'.\nSalesForce Activity is comprised of Email, Call, Meeting."),
'task_type': fields.selection([('wttype', 'Without Type'), ('wtype', 'With Type')], 'Activity Type', invisible=True, help="In SalesForce Acivity > Task, the Field Lavel Security of the field 'Type' is set for all user levels than select the 'With Type' option else select 'With Type' option."),
+ 'model': fields.char('Model', size=255, help="Name of object whose function will be called when this scheduler will run. e.g. 'res.partener'"),
+ 'function': fields.char('Function', size=255, help="Name of the method to be called on the object when this scheduler is executed."),
+ 'interval_number': fields.integer('Interval Number', help="Repeat every x."),
+ 'interval_type': fields.selection([('minutes', 'Minutes'), ('hours', 'Hours'), ('work_days', 'Work Days'), ('days', 'Days'), ('weeks', 'Weeks'), ('months', 'Months')], 'Interval Unit'),
+ 'numbercall': fields.integer('Number of Calls', help='Number of time the function is called,\na negative number indicates no limit'),
+ 'nextcall': fields.datetime('Next Execution Date', required=True, help="Next planned execution date for this scheduler"),
}
_defaults = {
- 'attachment': True,
- 'lead': True,
- 'opportunity': True,
- 'users': True,
- 'contact': True,
- 'event': True,
- 'task': True,
- 'case': True,
- 'task_type': 'wttype',
+ 'model': 'import.sf',
+ 'function': '_do_import',
+ 'interval_number': lambda *x: 6,
+ 'interval_type': 'months',
+ 'numbercall': lambda *x: 2,
+ 'nextcall': lambda *x: time.strftime("%Y-%m-%d %H:%M:%S"),
}
def _get_nodes(self, cr, uid, ids, context=None):
@@ -1202,33 +1301,106 @@
nodes = []
for current in self.browse(cr, uid, ids, context):
if current.lead:
- nodes.append('Lead')
+ nodes.append('lead')
if current.opportunity:
- nodes.append('Opportunity')
+ nodes.append('opportunity')
if current.users:
- nodes.append('User')
+ nodes.append('user')
if current.contact:
- nodes.append('Contact')
+ nodes.append('contact')
if current.case:
- nodes.append('Case')
+ nodes.append('case')
if current.event:
- nodes.append('Event')
+ nodes.append('event')
if current.task:
- nodes.append('Task')
+ nodes.append('task')
global ACT_TYPE
ACT_TYPE = current.task_type
if current.attachment:
- nodes.append('Attachment')
+ nodes.append('attachment')
+ if current.folder:
+ nodes.append('folder')
+ if current.document:
+ nodes.append('document')
return nodes
+ def resolve_dependencies(self, cr, uid, model_map, dep, visited, flag, context=None):
+ '''
+ Method to Reolve the Dependencies of the Model to be imported.
+ @uid : Current UserID
+ @model_map : Fieald Mapping Dict
+ @dep : Dependencies List
+ @visited : Set of Visited Nodes
+ @flag : To Track Successfull Import
+ '''
+ if context == None:
+ context = {}
+ flag = flag
+ for dependency in dep:
+ if not dependency in visited:
+ self.resolve_dependencies(cr, uid, model_map, model_map[dependency]['dependencies'], visited, flag, context=context)
+ flag = model_map[dependency]['function'](self, cr, uid, context)
+ visited.add(dependency)
+ return flag
+
+ def _do_import(self, cr, uid, *args):
+ ''''
+ Method to be called by IrCron Job to initiate importing the data process
+ @uid : Current Userid
+ @args : it can have three parts
+ args[0] : list to model name to be imported
+ args[1] : Activty Type Field Detail
+ args[2] : SalesForce Login Deatil Id for the Schedular
+ '''
+ context = {}
+ flag = False
+ login_pool = self.pool.get('salesforce.login.services')
+ log = logging.getLogger('import.salesforce')
+ if args[2]:
+ try:
+ #Reloading new SF login configuration.
+ login = login_pool.browse(cr, uid, int(args[2]))
+ LOGIN_DATA.update({'username': login.name,
+ 'passToken': login.password+login.token})
+ sf_model = args[0]
+ task_type = args[1]
+ if 'task' in sf_model:
+ global ACT_TYPE
+ ACT_TYPE = task_type and task_type[0] or 'wttype'
+ visited = set() #To avoid the Multiple call for resloving dependencies
+ flag = False
+ for model in sf_model:
+ if not model in visited:
+ flag = self.resolve_dependencies(cr, uid, MODEL_MAP, MODEL_MAP[model]['dependencies'], visited, flag, context=context)
+ flag = MODEL_MAP[model]['function'](self, cr, uid, context)
+ visited.add(model)
+ except Exception, e:
+ log.warning(str(e))
+
+ else:
+ log.warning("Invalid Login : Login information for the scheduler is missing.")
+ if flag:
+ log.info("Data Imported Successfully from SalesForce.")
+ else:
+ log.Warning("Unkown Error During Importing Data from SalesForce Chake the server log for more.")
+ return flag
+
def sf_do_import(self, cr, uid, ids, context=None):
'''
Method to initiate data import from map dict
'''
if context == None:
context = {}
- LOGIN_DATA.update({'username': context.get('username', None),
- 'passToken': context.get('passToken', None)})
+ model_pool = self.pool.get('ir.model.data')
+ cron_pool = self.pool.get('ir.cron')
+ login_pool = self.pool.get('salesforce.login.services')
+
+ record = self.browse(cr, uid, ids, context=context)
+ choice = context.get('choice', False)
+ record = record[0]
+ LOGIN_DATA.update({'username': record.username,
+ 'passToken': record.password+record.token})
+
try:
sfc = beatbox.PythonClient()
sfc, sflogin = getSFLogin(sfc, LOGIN_DATA.get('username'), LOGIN_DATA.get('passToken'))
@@ -1236,41 +1408,92 @@
raise osv.except_osv(_('Error !'), _('%s.\n%s')%(sfe.faultCode, str(sfe.faultString)))
except Exception, e:
raise osv.except_osv(_('Error !'), _('%s')%(e.value))
- sf_model = self._get_nodes(cr, uid, ids, context)
+ sf_model = [record.model_list]
visited = set() #To avoid the Multiple call for resloving dependencies
flag = False
- for model in sf_model:
- if not model in visited:
- flag = self.resolve_dependencies(cr, uid, MODEL_MAP, MODEL_MAP[model]['dependencies'], visited, flag, context=context)
- flag = MODEL_MAP[model]['function'](self, cr, uid, context)
- visited.add(model)
- model_pool = self.pool.get('ir.model.data')
+
model_data_ids = model_pool.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'sf.import.message.form')])
resource_id = model_pool.read(cr, uid, model_data_ids, fields=['res_id'])
- if flag:
- context.update({'message': "Data Imported Successfully from Salesforce."})
+ #Import Via SalesForce WebServices
+ if record and choice == 'webservice':
+ if record.model_list == 'task':
+ global ACT_TYPE
+ ACT_TYPE = record.task_type
+ flag = False
+ for model in sf_model:
+ if not model in visited:
+ flag = self.resolve_dependencies(cr, uid, MODEL_MAP, MODEL_MAP[model]['dependencies'], visited, flag, context=context)
+ flag = MODEL_MAP[model]['function'](self, cr, uid, context)
+ visited.add(model)
+ if flag:
+ context.update({'message': "Data Imported Successfully from Salesforce."})
+ else:
+ context.update({'message': 'Error !\nError during importing data from salesforce. For more check server log.'})
+ return {
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'sf.import.message',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ 'context': context,
+ }
+
+ #Import SalesFroce data from Extranl file(eg CSV)
+ elif record and choice == 'file':
+ #TODO: Implementation for the import sf data form file
+ raise osv.except_osv(_('Error !'), _('Import Data from file is still not implemented'))
+
+ #Schduling Ir Cron Job for Imporing SalesForce Data
+ elif record and choice == 'schudule':
+ vals = {}
+ nodes = self._get_nodes(cr, uid, ids, context=None)
+ if not nodes:
+ raise osv.except_osv(_('Warning !'), _('No model is selected. select atleat one model.'))
+ task = []
+ if 'task' in nodes:
+ task=[record.task_type]
+
+ login_id = login_pool.create(cr, uid, {'name': record.username, 'password': record.password, 'token': record.token}, context=context)
+ if login_id:
+
+ args = (nodes, task, int(login_id))
+ vals.update({'name': 'Import Salesforce Datas',
+ 'interval_number': record.interval_number,
+ 'interval_type': record.interval_type,
+ 'numbercall': record.numbercall,
+ 'nextcall': record.nextcall,
+ 'doall': False,
+ 'model': record.model,
+ 'function': record.function,
+ 'args': args}),
+ cron_pool.create(cr, uid, vals, context=context)
+ context.update({'message': "Schdeular Created Successfully for slected Models. Go to Administartion > Configuration > Schdualar > Scheduled Actions for more settings."})
+ else:
+ context.update({'message': "Schdeuler Can not created. Please try again"})
+ return {
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'sf.import.message',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ 'context': context,
+ }
else:
- context.update({'message': 'Error !\nError during importing data from salesforce. For more check server log.'})
- return {
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'sf.import.message',
- 'views': [(resource_id, 'form')],
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'context': context,
- }
-
- def resolve_dependencies(self, cr, uid, model_map, dep, visited, flag, context=None):
- if context == None:
- context = {}
- flag = flag
- for dependency in dep:
- if not dependency in visited:
- self.resolve_dependencies(cr, uid, model_map, model_map[dependency]['dependencies'], visited, flag, context=context)
- flag = model_map[dependency]['function'](self, cr, uid, context)
- visited.add(dependency)
- return flag
+ raise osv.except_osv(_('Error !'), _('Incosistant or Wrong data.\nPlease try again'))
import_sf()
+
+
+class salesforce_login_services(osv.osv):
+ '''Object to Store the Login Information of the salesforce for Scheduler use.'''
+ _name = 'salesforce.login.services'
+ _description = 'SalesForce Login Service'
+ _columns = {
+ 'token': fields.char('Security Token', size=255),
+ 'name': fields.char('Username/Email', size=255),
+ 'password': fields.char('Password', size=255),
+ }
+salesforce_login_services()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== modified file 'import_salesforce/import_sf_view.xml'
--- import_salesforce/import_sf_view.xml 2011-04-19 04:54:08 +0000
+++ import_salesforce/import_sf_view.xml 2011-04-25 04:40:54 +0000
@@ -1,27 +1,53 @@
<?xml version="1.0"?>
<openerp>
<data>
- <!--Form View for the model import sf-->
- <record model="ir.ui.view" id="view_import_sf_form">
+ <!--Form View for the model import sf for webservices-->
+ <record model="ir.ui.view" id="view_import_sf_webservice_form">
+ <field name="name">import.sf.webservice.form</field>
+ <field name="model">import.sf</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Import SalesForce">
+ <group colspan="4" width="400">
+ <separator string="Login Detail" colspan='4'/>
+ <field name='username' colspan='4' required='True'/>
+ <field name='password' password='True' colspan='4' required='True'/>
+ <field name='token' password='True' colspan='4' required='True'/>
+ </group>
+ <group colspan="4" width="400">
+ <separator string="" colspan='4'/>
+ <field name='model_list' required='True'/>
+ <field name='task_type' attrs="{'invisible': [('model_list', '!=', 'task')], 'required':[('model_list', '=', 'task')]}" colspan="4"/>
+ </group>
+ <group colspan="4" width="400">
+ <separator colspan='4' />
+ <group colspan="2"/>
+ <group colspan="2">
+ <button icon="gtk-cancel" special="cancel" string="_Cancel"/>
+ <button icon="gtk-execute" string="_Import" name="sf_do_import" type="object"/>
+ </group>
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <!--Form View for the model import sf for file-->
+ <record model="ir.ui.view" id="view_import_sf_file_form">
<field name="name">import.sf.form</field>
<field name="model">import.sf</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Import SalesForce">
+ <group colspan="4">
+ <separator string="Select your file here" colspan='4'/>
+ <field name='file_path' required='True'/>
+ </group>
<separator string="Check Model to Import" colspan='4' />
- <group colspan="4" width="400" height="150">
- <field name='users' />
- <field name='contact'/>
- <field name='lead' />
- <field name='opportunity'/>
- <field name='case'/>
- <field name='event'/>
- <field name='attachment'/>
- <field name='task'/>
- <newline/>
- <field name='task_type' attrs="{'invisible': [('task', '!=', True)], 'required':[('task', '=', True)]}" colspan="4"/>
+ <group colspan="4" >
+ <field name='model_list' required='True' />
+ <field name='task_type' attrs="{'invisible': [('model_list', '!=', 'task')], 'required':[('model_list', '=', 'task')]}" colspan="4"/>
</group>
- <group colspan="4" width="400">
+ <group colspan="4">
<separator colspan='4' />
<group colspan="2"/>
<group colspan="2">
@@ -32,7 +58,83 @@
</form>
</field>
</record>
+
+ <!--Form View for the model import sf via Schedular-->
+ <record model="ir.ui.view" id="view_import_sf_schedular_form">
+ <field name="name">import.sf.schudule.form</field>
+ <field name="model">import.sf</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Import SalesForce">
+ <group colspan="4" col="2">
+ <separator string="Login Detail" colspan='4'/>
+ <field name='username' colspan='4' required='True'/>
+ <field name='password' password='True' colspan='4' required='True'/>
+ <field name='token' password='True' colspan='4' required='True'/>
+ </group>
+ <notebook colspan="4" >
+ <page string='Model'>
+ <separator string="Check model to import" colspan='4'/>
+ <field name='users' />
+ <field name='contact'/>
+ <field name='lead' />
+ <field name='opportunity'/>
+ <field name='case'/>
+ <field name='event'/>
+ <field name='folder'/>
+ <field name='document'/>
+ <field name='attachment'/>
+ <field name='task'/>
+ <newline/>
+ <field name='task_type' attrs="{'invisible': [('task', '!=', True)], 'required':[('task', '=', True)]}" colspan="4"/>
+ </page>
+ <page string='Schedular Data'>
+ <separator string="Information" colspan='4'/>
+ <field name='interval_number' required='1'/>
+ <field name='interval_type' required='1'/>
+ <field name='nextcall'/>
+ <field name='numbercall'/>
+ <separator string="Technical Data" colspan='4'/>
+ <field name='model' colspan='2' required='1'/>
+ <field name='function' colspan='2' required='1'/>
+ </page>
+ </notebook>
+ <group colspan="4">
+ <separator colspan='4' />
+ <group colspan="2"/>
+ <group colspan="2">
+ <button icon="gtk-cancel" special="cancel" string="_Cancel"/>
+ <button icon="gtk-execute" string="_Schedule" name="sf_do_import" type="object"/>
+ </group>
+ </group>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.ui.view" id="view_salesforce_login_services_form">
+ <field name="name">salesforce.login.services.form</field>
+ <field name="model">salesforce.login.services</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Import SalesForce">
+ <field name='name' colspan='4' required='True'/>
+ <field name='password' colspan='4' required='True'/>
+ <field name='token' colspan='4' required='True'/>
+ </form>
+ </field>
+ </record>
+ <record model="ir.ui.view" id="view_salesforce_login_services_tree">
+ <field name="name">salesforce.login.services.tree</field>
+ <field name="model">salesforce.login.services</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="Import SalesForce">
+ <field name='name'/>
+ <field name='password'/>
+ <field name='token'/>
+ </tree>
+ </field>
+ </record>
+
</data>
</openerp>
-
-
=== modified file 'import_salesforce/wizard/import_salesforce.py'
--- import_salesforce/wizard/import_salesforce.py 2011-04-19 07:22:17 +0000
+++ import_salesforce/wizard/import_salesforce.py 2011-04-25 04:40:54 +0000
@@ -19,62 +19,51 @@
#
##############################################################################
-import logging
from osv import osv
from osv import fields
-from tools.translate import _
-
-try:
- import beatbox
-except ImportError:
- raise osv.except_osv(_('BeatBox Import Error!'), _('Please install beatbox api for SaleForce - beatbox-20.0.zip.\nhttp://pypi.python.org/pypi/beatbox'))
-
-
-class salesforce_login(osv.osv):
+
+SERVICES = [('webservice', 'From Web Services'), ('file', 'From File'), ('schudule', 'Schedule Import')]
+
+
+class salesforce_services(osv.osv):
'''
SalesForce Login Form
- @name : Userlogin Name
- @password : User Password for login name
- @token : Security Token Provided bthe salesforce
+ @name : List of Services Which will be imports
'''
- _name = 'salesforce.login'
- _description = 'SalesForce Login'
+ _name = 'salesforce.services'
+ _description = 'SalesForce Data Import Service'
_columns = {
- 'name': fields.char('Username', size=255, required=True, help='Enter SalesForce login ussername.'),
- 'password': fields.char('Password', size=255, required=True, help='Enter valid password for the supplied username.'),
- 'token': fields.char('Scurity Token', size=255, required=True, help='Enter Security Token generated by salesforce for the above user.'),
- }
+ 'name': fields.selection(SERVICES, 'Import Data', required=True, help='Select the Service from selection and click Ok to Proceed import data through it.'),
+ }
- def sf_do_login(self, cr, uid, ids, context=None):
- '''
- Method Will validated the login of user.
- '''
+ def sf_do_select(self, cr, uid, ids, context=None):
+ '''
+ Method Will validated the login of user.
+ '''
+ if context == None:
+ context = {}
record = self.browse(cr, uid, ids, context=context)
+ choice = False
for rec in record:
- uname = rec.name
- passkey = rec.password + rec.token
- log = logging.getLogger('salesforce.login')
- try:
- sfc = beatbox.PythonClient()
- sfc.login(uname, passkey)
- log.info(_("Successful login to SalesForce WebServices with user - %s")%(uname))
- except Exception, e:
- log.warning(str(e))
- raise osv.except_osv(_('Error !'), _('Invalid login detail'))
-
+ choice = rec.name
+ views = {
+ 'webservice': 'view_import_sf_webservice_form',
+ 'file': 'view_import_sf_file_form',
+ 'schudule': 'view_import_sf_schedular_form',
+ }
model_pool = self.pool.get('ir.model.data')
- view_ids = model_pool.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'salesforce.login.form')])
- view_res_id = model_pool.read(cr, uid, view_ids, fields=['res_id'])
- context.update({'username': uname, 'passToken': passkey})
+ view_ids = model_pool.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', views.get(choice, False))])
+ view_res_id = model_pool.browse(cr, uid, view_ids[0], fields)
+ context.update({'choice': choice})
return {
- 'name': 'Import SalesForce',
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'import.sf',
- 'views': [(view_res_id, 'form')],
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'context': context,
- }
+ 'name': 'Import SalesForce',
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'import.sf',
+ 'views': [(view_res_id.res_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ 'context': context,
+ }
-salesforce_login()
+salesforce_services()
=== modified file 'import_salesforce/wizard/import_salesforce_view.xml'
--- import_salesforce/wizard/import_salesforce_view.xml 2011-04-11 11:20:17 +0000
+++ import_salesforce/wizard/import_salesforce_view.xml 2011-04-25 04:40:54 +0000
@@ -5,25 +5,22 @@
<menuitem id="menu_sf" name="Sales Force" parent="base.menu_base_partner" />
<!--form view for the SalesForce Login -->
- <record model="ir.ui.view" id="view_salesforce_login_form">
- <field name="name">salesforce.login.form</field>
- <field name="model">salesforce.login</field>
+ <record model="ir.ui.view" id="view_salesforce_service_form">
+ <field name="name">salesforce.services.form</field>
+ <field name="model">salesforce.services</field>
<field name="type">form</field>
<field name="arch" type="xml">
- <form string="SalesForce Login">
- <separator string="Login Detail" colspan='4' />
- <group colspan="4" width="400">
+ <form string="Select Service">
+ <group colspan="4" width="320">
<field name='name' colspan='4'/>
- <field name='password' password='True' colspan='4'/>
- <field name='token' password='True' colspan='4'/>
</group>
- <label string=" Enter Username, password and Security Token generated by SalesForce."/>
- <group colspan="4" width="400">
+ <label string=' Select Service from above selection through which data will be imported' colspan='4'/>
+ <group colspan="4" >
<separator colspan='4' />
<group colspan="2"/>
<group colspan="2">
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
- <button icon="terp-camera_test" string="_Login" name="sf_do_login" type="object"/>
+ <button icon="terp-camera_test" string="_Ok" name="sf_do_select" type="object"/>
</group>
</group>
</form>
@@ -31,17 +28,17 @@
</record>
<!--SalsForce Login Form Action-->
- <record model="ir.actions.act_window" id="action_view_salesforce_login">
+ <record model="ir.actions.act_window" id="action_view_salesforce_service">
<field name="name">SalesForce Login</field>
- <field name="res_model">salesforce.login</field>
+ <field name="res_model">salesforce.services</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
- <field name="view_id" ref="view_salesforce_login_form"/>
+ <field name="view_id" ref="view_salesforce_service_form"/>
<field name="target">new</field>
</record>
<!--wizard under importsalesforce menu-->
- <menuitem id="menu_sf_login" name="Import SalesForce" parent="menu_sf" action="action_view_salesforce_login" icon="STOCK_EXECUTE"/>
+ <menuitem id="menu_sf_service" name="Import SalesForce" parent="menu_sf" action="action_view_salesforce_service" icon="STOCK_EXECUTE"/>
</data>
</openerp>
=== modified file 'import_salesforce/wizard/sf_import_message.py'
--- import_salesforce/wizard/sf_import_message.py 2011-04-19 05:22:28 +0000
+++ import_salesforce/wizard/sf_import_message.py 2011-04-25 04:40:54 +0000
@@ -25,8 +25,9 @@
class sf_import_message(osv.osv):
"""Import Message"""
+
_name = "sf.import.message"
- _description = __doc__
+ _description = "Import Message"
_columns = {
'name': fields.text('Message', readonly=True),
}
Follow ups