[MERGE] backlog correction by atp team + error reporting + soft dependency, if the module is not installed, ignore data
bzr revid: tfr@openerp.com-20110713135604-i4ydmqmyjt65e5f9
This commit is contained in:
commit
43e1fa4c54
|
@ -73,7 +73,6 @@
|
|||
|
||||
<record id="base_setup_installer_todo" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_base_setup_installer"/>
|
||||
<field name="category_id" ref="base.category_administration_config"/>
|
||||
<field name="sequence">2</field>
|
||||
<field name="type">normal_recurring</field>
|
||||
</record>
|
||||
|
@ -124,7 +123,6 @@
|
|||
|
||||
<record id="migrade_application_installer_modules_todo" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_migrade_application_installer_modules"/>
|
||||
<field name="category_id" ref="base.category_administration_config"/>
|
||||
<field name="type">normal</field>
|
||||
<field name="state">skip</field>
|
||||
</record>
|
||||
|
@ -144,7 +142,6 @@
|
|||
<!-- register configuration wizard -->
|
||||
<record id="config_wizard_action_import_create_installer" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_import_create_installer"/>
|
||||
<field name="category_id" ref="base.category_administration_config"/>
|
||||
<field name="type">normal</field>
|
||||
<field name="target">current</field>
|
||||
<field name="state">skip</field>
|
||||
|
@ -199,7 +196,6 @@
|
|||
|
||||
<record id="config_action_user_preferences_config_form" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_user_preferences_config_form"/>
|
||||
<field name="category_id" ref="base.category_administration_config"/>
|
||||
<field name="type">normal</field>
|
||||
<field name="state">skip</field>
|
||||
</record>
|
||||
|
@ -219,7 +215,6 @@
|
|||
|
||||
<record id="config_wizard_action_config_user_form" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_config_access_other_user"/>
|
||||
<field name="category_id" ref="base.category_administration_config"/>
|
||||
<field name="type">normal</field>
|
||||
<field name="target">current</field>
|
||||
<field name="sequence">1000</field>
|
||||
|
@ -230,7 +225,6 @@
|
|||
|
||||
<record id="config_wizard_action_res_company_logo" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_res_company_logo"/>
|
||||
<field name="category_id" ref="base.category_administration_config"/>
|
||||
<field name="type">normal</field>
|
||||
<field name="state">cancel</field>
|
||||
</record>
|
||||
|
@ -281,7 +275,6 @@
|
|||
|
||||
<record id="config_action_partner_terminology_config_form" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_partner_terminology_config_form"/>
|
||||
<field name="category_id" ref="base.category_administration_config"/>
|
||||
<field name="type">normal</field>
|
||||
<field name="state">skip</field>
|
||||
</record>
|
||||
|
@ -299,7 +292,6 @@
|
|||
|
||||
<record id="base_setup_company_todo" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_base_setup_company"/>
|
||||
<field name="category_id" ref="base.category_administration_config"/>
|
||||
<field name="sequence">1</field>
|
||||
<field name="type">normal</field>
|
||||
<field name="state">skip</field>
|
||||
|
|
|
@ -22,11 +22,13 @@ import pprint
|
|||
import mapper
|
||||
import pooler
|
||||
import tools
|
||||
|
||||
from tools.translate import _
|
||||
|
||||
from threading import Thread
|
||||
import datetime
|
||||
import logging
|
||||
import StringIO
|
||||
import traceback
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
|
||||
|
@ -58,6 +60,7 @@ class import_framework(Thread):
|
|||
self.context = context or {}
|
||||
self.email = email_to_notify
|
||||
self.table_list = []
|
||||
self.logger = logging.getLogger('import_framework')
|
||||
|
||||
"""
|
||||
Abstract Method to be implemented in
|
||||
|
@ -175,8 +178,9 @@ class import_framework(Thread):
|
|||
|
||||
model_obj = self.obj.pool.get(model)
|
||||
if not model_obj:
|
||||
raise ValueError("%s is not a valid model name" % model)
|
||||
|
||||
raise ValueError(_("%s is not a valid model name") % model)
|
||||
self.logger.debug(_("fields imported : "))
|
||||
self.logger.debug(fields)
|
||||
(p, r, warning, s) = model_obj.import_data(self.cr, self.uid, fields, res, mode='update', current_module=self.module_name, noupdate=True, context=self.context)
|
||||
for (field, field_name) in self_dependencies:
|
||||
self._import_self_dependencies(model_obj, field, datas)
|
||||
|
@ -311,6 +315,9 @@ class import_framework(Thread):
|
|||
"""
|
||||
domain_search = not domain_search and [('name', 'ilike', name)] or domain_search
|
||||
obj = self.obj.pool.get(model)
|
||||
if not obj: #if the model doesn't exist
|
||||
return False
|
||||
|
||||
xml_id = self._generate_xml_id(name, table)
|
||||
xml_ref = self.mapped_id_if_exist(model, domain_search, table, name)
|
||||
fields.append('id')
|
||||
|
@ -359,6 +366,7 @@ class import_framework(Thread):
|
|||
"""
|
||||
self.data_started = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.cr = pooler.get_db(self.cr.dbname).cursor()
|
||||
error = False
|
||||
try:
|
||||
self.initialize()
|
||||
result = []
|
||||
|
@ -369,16 +377,22 @@ class import_framework(Thread):
|
|||
res = self._resolve_dependencies(self.get_mapping()[table].get('dependencies', []), imported)
|
||||
result.extend(res)
|
||||
if to_import:
|
||||
self.logger.debug(_("import : ") + table )
|
||||
(position, warning) = self._import_table(table)
|
||||
result.append((table, position, warning))
|
||||
imported.add(table)
|
||||
self.cr.commit()
|
||||
|
||||
|
||||
except Exception, err:
|
||||
sh = StringIO.StringIO()
|
||||
traceback.print_exc(file=sh)
|
||||
error = sh.getvalue()
|
||||
print error
|
||||
finally:
|
||||
self.cr.close()
|
||||
|
||||
self.date_ended = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self._send_notification_email(result)
|
||||
|
||||
self._send_notification_email(result, error)
|
||||
|
||||
def _resolve_dependencies(self, dep, imported):
|
||||
"""
|
||||
|
@ -392,26 +406,29 @@ class import_framework(Thread):
|
|||
res = self._resolve_dependencies(self.get_mapping()[dependency].get('dependencies', []), imported)
|
||||
result.extend(res)
|
||||
if to_import:
|
||||
self.logger.debug("import dependency : " + dependency)
|
||||
r = self._import_table(dependency)
|
||||
(position, warning) = r
|
||||
result.append((dependency, position, warning))
|
||||
imported.add(dependency)
|
||||
return result
|
||||
|
||||
def _send_notification_email(self, result):
|
||||
if not self.email:
|
||||
def _send_notification_email(self, result, error):
|
||||
if not self.email or not self.email[0]:
|
||||
return False
|
||||
|
||||
tools.email_send(
|
||||
'import@module.openerp',
|
||||
self.email,
|
||||
self.get_email_subject(result),
|
||||
self.get_email_body(result),
|
||||
self.get_email_subject(result, error),
|
||||
self.get_email_body(result, error),
|
||||
)
|
||||
logger = logging.getLogger('import_sugarcam')
|
||||
logger.info("Import finished, notification email sended")
|
||||
if error:
|
||||
self.logger.error(_("Import failed due to an unexpected error"))
|
||||
else:
|
||||
self.logger.info(_("Import finished, notification email sended"))
|
||||
|
||||
def get_email_subject(self, result):
|
||||
def get_email_subject(self, result, error=False):
|
||||
"""
|
||||
This method define the subject of the email send by openerp at the end of import
|
||||
@param result: a list of tuple
|
||||
|
@ -419,9 +436,11 @@ class import_framework(Thread):
|
|||
@return the subject of the mail
|
||||
|
||||
"""
|
||||
return "Import of your data finished at %s" % self.date_ended
|
||||
if error:
|
||||
return _("Data Import failed at %s due to an unexpected error") % self.date_ended
|
||||
return _("Import of your data finished at %s") % self.date_ended
|
||||
|
||||
def get_email_body(self, result):
|
||||
def get_email_body(self, result, error=False):
|
||||
"""
|
||||
This method define the body of the email send by openerp at the end of import. The body is separated in two part
|
||||
the header (@see get_body_header), and the generate body with the list of table and number of record imported.
|
||||
|
@ -432,20 +451,23 @@ class import_framework(Thread):
|
|||
|
||||
"""
|
||||
|
||||
body = "started at %s and finished at %s \n" % (self.data_started, self.date_ended)
|
||||
body = _("started at %s and finished at %s \n") % (self.data_started, self.date_ended)
|
||||
if error:
|
||||
body += _("but failed, in consequence no data were imported to keep database consistency \n error : \n") + error
|
||||
|
||||
for (table, nb, warning) in result:
|
||||
if not warning:
|
||||
warning = "with no warning"
|
||||
warning = _("with no warning")
|
||||
else:
|
||||
warning = "with warning : %s" % warning
|
||||
body += "%s records were imported from table %s, %s \n" % (nb, table, warning)
|
||||
warning = _("with warning : %s") % warning
|
||||
body += _("%s records were imported from table %s, %s \n") % (nb, table, warning)
|
||||
return self.get_body_header(result) + "\n\n" + body
|
||||
|
||||
def get_body_header(self, result):
|
||||
"""
|
||||
@return the first sentences written in the mail's body
|
||||
"""
|
||||
return "The import of data \n instance name : %s \n" % self.instance_name
|
||||
return _("The import of data \n instance name : %s \n") % self.instance_name
|
||||
|
||||
|
||||
#TODO documentation test
|
||||
|
|
|
@ -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': ['import_base', 'crm_claim', 'project', 'project_issue', 'hr', 'document'],
|
||||
'depends': ['import_base','crm', 'document'],
|
||||
'init_xml': [],
|
||||
'update_xml': ["wizard/import_message_view.xml",
|
||||
"import_sugarcrm_view.xml"],
|
||||
|
|
|
@ -75,7 +75,6 @@ class sugar_import(import_framework):
|
|||
|
||||
def get_data(self, table):
|
||||
offset = 0
|
||||
|
||||
res = []
|
||||
while True:
|
||||
r = sugar.search(self.context.get('port'), self.context.get('session_id'), table, offset, self.MAX_RESULT_PER_PAGE)
|
||||
|
@ -157,6 +156,7 @@ class sugar_import(import_framework):
|
|||
|
||||
def import_document(self, val):
|
||||
File,Filename = sugar.get_document_revision_search(self.context.get('port'), self.context.get('session_id'), val.get('document_revision_id'))
|
||||
#File = base64.encodestring(File)
|
||||
res_id, res_model = self.import_related_document(val)
|
||||
val['res_id'] = res_id
|
||||
val['res_model'] = res_model
|
||||
|
@ -168,9 +168,10 @@ class sugar_import(import_framework):
|
|||
def get_document_mapping(self):
|
||||
return {
|
||||
'model' : 'ir.attachment',
|
||||
'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT,self.TABLE_CONTACT, self.TABLE_OPPORTUNITY, self.TABLE_CASE, self.TABLE_BUG],
|
||||
'dependencies' : [self.TABLE_USER],
|
||||
'hook' : self.import_document,
|
||||
'map' : {'name':'document_name',
|
||||
'map' : {
|
||||
'name':'document_name',
|
||||
'description': ppconcat('description'),
|
||||
'datas': 'datas',
|
||||
'datas_fname': 'datas_fname',
|
||||
|
@ -203,10 +204,11 @@ class sugar_import(import_framework):
|
|||
def get_email_mapping(self):
|
||||
return {
|
||||
'model' : 'mailgate.message',
|
||||
'dependencies' : [self.TABLE_USER, self.TABLE_PROJECT, self.TABLE_PROJECT_TASK, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD, self.TABLE_OPPORTUNITY, self.TABLE_MEETING, self.TABLE_CALL],
|
||||
'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD, self.TABLE_OPPORTUNITY, self.TABLE_MEETING, self.TABLE_CALL],
|
||||
'hook' : self.import_email,
|
||||
'map' : {'name':'name',
|
||||
'history' : const("1"),
|
||||
'map' : {
|
||||
'name':'name',
|
||||
'history' : const("1"),
|
||||
'date':'date_sent',
|
||||
'email_from': 'from_addr_name',
|
||||
'email_to': 'to_addrs_names',
|
||||
|
@ -245,7 +247,7 @@ class sugar_import(import_framework):
|
|||
def get_history_mapping(self):
|
||||
return {
|
||||
'model' : 'ir.attachment',
|
||||
'dependencies' : [self.TABLE_USER, self.TABLE_PROJECT, self.TABLE_PROJECT_TASK, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD, self.TABLE_OPPORTUNITY, self.TABLE_MEETING, self.TABLE_CALL, self.TABLE_EMAIL],
|
||||
'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD, self.TABLE_OPPORTUNITY, self.TABLE_MEETING, self.TABLE_CALL, self.TABLE_EMAIL],
|
||||
'hook' : self.import_history,
|
||||
'map' : {
|
||||
'name':'name',
|
||||
|
@ -880,7 +882,7 @@ class sugar_import(import_framework):
|
|||
'hook' : self.import_user,
|
||||
'map' : {
|
||||
'name': concat('first_name', 'last_name'),
|
||||
'login': 'user_name',
|
||||
'login': value('user_name', fallback='last_name'),
|
||||
'context_lang' : 'context_lang',
|
||||
'password' : 'password',
|
||||
'.id' : '.id',
|
||||
|
@ -914,7 +916,9 @@ class sugar_import(import_framework):
|
|||
"""
|
||||
Email notification
|
||||
"""
|
||||
def get_email_subject(self, result):
|
||||
def get_email_subject(self, result, error=False):
|
||||
if error:
|
||||
return "Sugarcrm data import failed at %s due to an unexpected error" % self.date_ended
|
||||
return "your sugarcrm data were successfully imported at %s" % self.date_ended
|
||||
|
||||
def get_body_header(self, result):
|
||||
|
@ -948,23 +952,42 @@ class import_sugarcrm(osv.osv):
|
|||
}
|
||||
|
||||
def _get_email_id(self, cr, uid, context=None):
|
||||
return self.pool.get('res.users').browse(cr, uid, uid, context=context).user_email
|
||||
return self.pool.get('res.users').browse(cr, uid, uid, context=context).user_email
|
||||
|
||||
def _module_installed(self, cr, uid, model, context=None):
|
||||
module_id = self.pool.get('ir.module.module').search(cr, uid, [('name', '=', model), ('state', "=", "installed")], context=context)
|
||||
return bool(module_id)
|
||||
|
||||
def _project_installed(self, cr, uid, context=None):
|
||||
return self._module_installed(cr,uid,'project',context=context)
|
||||
|
||||
def _crm_claim_installed(self, cr, uid, context=None):
|
||||
return self._module_installed(cr,uid,'crm_claim',context=context)
|
||||
|
||||
def _project_issue_installed(self, cr, uid, context=None):
|
||||
return self._module_installed(cr,uid,'project_issue',context=context)
|
||||
|
||||
def _hr_installed(self, cr, uid, context=None):
|
||||
return self._module_installed(cr,uid,'hr',context=context)
|
||||
|
||||
_defaults = {#to be set to true, but easier for debugging
|
||||
'opportunity': True,
|
||||
'contact' : True,
|
||||
'account' : True,
|
||||
'employee' : False,
|
||||
'employee' : _hr_installed,
|
||||
'meeting' : True,
|
||||
'call' : True,
|
||||
'claim' : True,
|
||||
'claim' : _crm_claim_installed,
|
||||
'email_history' : True,
|
||||
'project' : True,
|
||||
'project_task': True,
|
||||
'bug': True,
|
||||
'document': False,
|
||||
'project' : _project_installed,
|
||||
'project_task': _project_installed,
|
||||
'bug': _project_issue_installed,
|
||||
'document': True,
|
||||
'instance_name': 'sugarcrm',
|
||||
'email_from': _get_email_id,
|
||||
#'username' : 'admin',
|
||||
#'password' : '',
|
||||
#'url': "http://sugarcrm.example.com/soap.php"
|
||||
'username' : 'tfr',
|
||||
'password' : 'a',
|
||||
'url': "http://localhost/sugarcrm/soap.php"
|
||||
|
@ -987,8 +1010,6 @@ class import_sugarcrm(osv.osv):
|
|||
if not context:
|
||||
context = {}
|
||||
url = context.get('url')
|
||||
|
||||
|
||||
url_split = str(url).split('/')
|
||||
while len(url_split) >= 3:
|
||||
#3 case, soap.php is already at the end of url should be valid
|
||||
|
@ -1011,35 +1032,41 @@ class import_sugarcrm(osv.osv):
|
|||
if not context:
|
||||
context = {}
|
||||
key_list = []
|
||||
module = {}
|
||||
for current in self.browse(cr, uid, ids, context):
|
||||
context.update({'username': current.username, 'password': current.password, 'url': current.url, 'email_user': current.email_from or False, 'instance_name': current.instance_name or False})
|
||||
if current.opportunity:
|
||||
key_list.append('Leads')
|
||||
key_list.append('Opportunities')
|
||||
if current.contact:
|
||||
key_list.append('Contacts')
|
||||
if current.account:
|
||||
key_list.append('Accounts')
|
||||
key_list.append('Accounts')
|
||||
if current.opportunity:
|
||||
key_list.append('Leads')
|
||||
key_list.append('Opportunities')
|
||||
if current.employee:
|
||||
key_list.append('Employees')
|
||||
key_list.append('Employees')
|
||||
module.update({'Employees':'hr'})
|
||||
if current.meeting:
|
||||
key_list.append('Meetings')
|
||||
if current.call:
|
||||
key_list.append('Calls')
|
||||
if current.claim:
|
||||
key_list.append('Cases')
|
||||
key_list.append('Cases')
|
||||
module.update({'Cases':'crm_claim'})
|
||||
if current.email_history:
|
||||
key_list.append('Emails')
|
||||
key_list.append('Notes')
|
||||
if current.project:
|
||||
key_list.append('Project')
|
||||
module.update({'Project':'project'})
|
||||
if current.project_task:
|
||||
key_list.append('ProjectTask')
|
||||
module.update({'ProjectTask':'project'})
|
||||
if current.bug:
|
||||
key_list.append('Bugs')
|
||||
module.update({'Bugs':'project_issue'})
|
||||
if current.document:
|
||||
key_list.append('Documents')
|
||||
return key_list
|
||||
return key_list,module
|
||||
|
||||
|
||||
def do_import_all(self, cr, uid, *args):
|
||||
|
@ -1053,9 +1080,16 @@ class import_sugarcrm(osv.osv):
|
|||
return True
|
||||
|
||||
def import_from_scheduler_all(self, cr, uid, ids, context=None):
|
||||
keys = self.get_key(cr, uid, ids, context)
|
||||
keys, module_list = self.get_key(cr, uid, ids, context)
|
||||
if not keys:
|
||||
raise osv.except_osv(_('Warning !'), _('Select Module to Import.'))
|
||||
key_list = module_list.keys()
|
||||
for module in key_list :
|
||||
module = module_list[module]
|
||||
state = self.get_all(cr,uid,module,context=context)
|
||||
if state == False:
|
||||
keys = ', '.join(key_list)
|
||||
raise osv.except_osv(_('Error !!'), _("%s data required %s Module to be installed, Please install %s module") %(keys,module,module))
|
||||
cron_obj = self.pool.get('ir.cron')
|
||||
url = self.parse_valid_url(context)
|
||||
args = (keys,context.get('email_user'), context.get('instance_name'), url, context.get('username'), context.get('password') )
|
||||
|
@ -1068,18 +1102,25 @@ class import_sugarcrm(osv.osv):
|
|||
'res_id': new_create_id,
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
|
||||
|
||||
|
||||
def import_all(self, cr, uid, ids, context=None):
|
||||
|
||||
# """Import all sugarcrm data into openerp module"""
|
||||
keys = self.get_key(cr, uid, ids, context)
|
||||
keys, module_list = self.get_key(cr, uid, ids, context)
|
||||
if not keys:
|
||||
raise osv.except_osv(_('Warning !'), _('Select Module to Import.'))
|
||||
key_list = module_list.keys()
|
||||
for module in key_list :
|
||||
module = module_list[module]
|
||||
state = self._module_installed(cr,uid,module,context=context)
|
||||
if state == False:
|
||||
keys = ', '.join(key_list)
|
||||
raise osv.except_osv(_('Error !!'), _("%s data required %s Module to be installed, Please install %s module") %(keys,module,module))
|
||||
url = self.parse_valid_url(context)
|
||||
context.update({'url': url})
|
||||
imp = sugar_import(self, cr, uid, context.get('instance_name'), "import_sugarcrm", [context.get('email_user')], context)
|
||||
imp.set_table_list(keys)
|
||||
imp.start()
|
||||
|
||||
obj_model = self.pool.get('ir.model.data')
|
||||
model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','import.message.form')])
|
||||
resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
<group colspan="2" col="1" width="200">
|
||||
<label colspan="2" string="Import your data from SugarCRM :"/>
|
||||
<label colspan="2" string="" />
|
||||
<label colspan="2" string="Use the SugarSoap API URL (read tooltip), a full access Sugar login."/>
|
||||
<label colspan="2" string="Use the SugarSoap API URL (read tooltip) and a full access SugarCRM login."/>
|
||||
<label colspan="2" string="" />
|
||||
<label colspan="2" string="Choose groups of data you want to import. Click 'Import' to get data manually or click 'schedule reccurent import' to get recurrently and automatically data."/>
|
||||
<label colspan="2" string="Choose data you want to import. Click 'Import' to get data manually or 'Schedule Reccurent Import' to get recurrently and automatically data."/>
|
||||
<label colspan="2" string="" />
|
||||
<label colspan="2" string="If you make recurrent or ponctual import, data already imported in OpenERP will be erased by Sugar data."/>
|
||||
<label colspan="2" string="If you make recurrent or ponctual import, data already in OpenERP will be updated by SugarCRM data."/>
|
||||
<label colspan="2" string="" />
|
||||
<label colspan="2" string="Don't forget to add an address email to be notified of the success of the import."/>
|
||||
<label colspan="2" string="Do not forget the email address to be notified of the success of the import."/>
|
||||
<label colspan="2" />
|
||||
<label colspan="2" string="Online documentation:"/>
|
||||
<label colspan="2" string="(Comming Soon)"/>
|
||||
|
@ -74,8 +74,8 @@
|
|||
<group colspan="4" col="6">
|
||||
<label string="" colspan="2"/>
|
||||
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
|
||||
<button name="import_from_scheduler_all" string="_Schedule recurrent import"
|
||||
type="object" icon="gtk-execute"/>
|
||||
<button name="import_from_scheduler_all" groups="base.group_extended" string="_Schedule Recurrent Import"
|
||||
type="object" icon="gtk-execute" />
|
||||
<button name="import_all" string="_Import"
|
||||
type="object" icon="terp-camera_test"/>
|
||||
</group>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Import Message">
|
||||
<label colspan="4" nolabel="1" string="Import Data Launch: The Import Process is running in the background. You'll receive an email soon when import will be finished"/>
|
||||
<label colspan="4" nolabel="1" string="Data are importing, the process is running in the background, You will receive an email at the end of the import."/>
|
||||
<separator string="" colspan="4" />
|
||||
<button icon="gtk-ok" special="cancel" string="_Ok"/>
|
||||
</form>
|
||||
|
|
Loading…
Reference in New Issue