diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 2fcf91f1616..1331beec681 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -434,14 +434,14 @@ class orm_template(object): def __export_row(self, cr, uid, row, fields, context=None): - def check_type(type,r): - if type == 'float': + def check_type(field_type): + if field_type == 'float': return 0.0 - elif type == 'integer': + elif field_type == 'integer': return 0 - elif type == 'char': - return '' - return r + elif field_type == 'boolean': + return False + return '' lines = [] data = map(lambda x: '', range(len(fields))) @@ -452,14 +452,27 @@ class orm_template(object): r = row i = 0 while i < len(f): - r = r[f[i]] + if f[i] == 'db_id': + r = r['id'] + elif f[i] == 'id': + model_data = self.pool.get('ir.model.data') + data_ids = model_data.search(cr, uid, [('model','=',r._table_name),('res_id','=',r['id'])]) + if len(data_ids): + d = model_data.read(cr, uid, data_ids, ['name','module'])[0] + if d['module']: + r = '%s.%s'%(d['module'],d['name']) + else: + r = d['name'] + else: + break + else: + r = r[f[i]] if not r: if f[i] in self._columns: - r = check_type(self._columns[f[i]]._type,r) + r = check_type(self._columns[f[i]]._type) elif f[i] in self._inherit_fields: - r = check_type(self._inherit_fields[f[i]][2]._type,r) - - data[fpos] = tools.ustr(r) + r = check_type(self._inherit_fields[f[i]][2]._type) + data[fpos] = r break if isinstance(r, (browse_record_list, list)): first = True @@ -482,41 +495,65 @@ class orm_template(object): break i += 1 if i == len(f): + if isinstance(r, browse_record): + r = r.name data[fpos] = tools.ustr(r or '') return [data] + lines - def export_data(self, cr, uid, ids, fields, context=None): + def export_data(self, cr, uid, ids, fields_to_export, context=None, imp_comp= False): if not context: context = {} - fields = map(lambda x: x.split('/'), fields) + cols = self._columns.copy() + for f in self._inherit_fields: + cols.update({f: self._inherit_fields[f][2]}) + fields_to_export = map(lambda x: x.split('/'), fields_to_export) + fields_export = fields_to_export+[] + warning = '' + warning_fields = [] + for field in fields_export: + if imp_comp and len(field)>1: + warning_fields.append('/'.join(map(lambda x:x in cols and cols[x].string or x,field))) + elif len (field) <=1: + if imp_comp and cols.get(field and field[0],False): + if ((isinstance(cols[field[0]], fields.function) and not cols[field[0]].store) \ + or isinstance(cols[field[0]], fields.related)\ + or isinstance(cols[field[0]], fields.one2many)): + warning_fields.append('/'.join(map(lambda x:x in cols and cols[x].string or x,field))) datas = [] + if imp_comp and len(warning_fields): + warning = 'Following columns cannot be exported since you select to be import compatible.\n%s' %('\n'.join(warning_fields)) + cr.rollback() + return {'warning' : warning} for row in self.browse(cr, uid, ids, context): - datas += self.__export_row(cr, uid, row, fields, context) - return datas + datas += self.__export_row(cr, uid, row, fields_to_export, context) + return {'datas':datas} def import_data(self, cr, uid, fields, datas, mode='init', current_module='', noupdate=False, context=None, filename=None): if not context: context = {} fields = map(lambda x: x.split('/'), fields) logger = netsvc.Logger() - - def process_liness(self, datas, prefix, fields_def, position=0): + ir_model_data_obj = self.pool.get('ir.model.data') + def process_liness(self, datas, prefix, current_module, model_name, fields_def, position=0): line = datas[position] row = {} translate = {} todo = [] warning = '' data_id = False + data_res_id = False + is_xml_id = False + is_db_id = False + ir_model_data_obj = self.pool.get('ir.model.data') # # Import normal fields # for i in range(len(fields)): if i >= len(line): raise Exception(_('Please check that all your lines have %d columns.') % (len(fields),)) - field = fields[i] - if field == ["id"]: - data_id = line[i] + if not line[i]: continue + field = fields[i] if (len(field)==len(prefix)+1) and field[len(prefix)].endswith(':id'): res_id = False if line[i]: @@ -526,8 +563,7 @@ class orm_template(object): if '.' in word: module, xml_id = word.rsplit('.', 1) else: - module, xml_id = current_module, word - ir_model_data_obj = self.pool.get('ir.model.data') + module, xml_id = current_module, word id = ir_model_data_obj._get_id(cr, uid, module, xml_id) res_id2 = ir_model_data_obj.read(cr, uid, [id], @@ -540,8 +576,7 @@ class orm_template(object): if '.' in line[i]: module, xml_id = line[i].rsplit('.', 1) else: - module, xml_id = current_module, line[i] - ir_model_data_obj = self.pool.get('ir.model.data') + module, xml_id = current_module, line[i] id = ir_model_data_obj._get_id(cr, uid, module, xml_id) res_id = ir_model_data_obj.read(cr, uid, [id], ['res_id'])[0]['res_id'] @@ -554,6 +589,63 @@ class orm_template(object): continue if (len(field) == len(prefix)+1) and \ (prefix == field[0:len(prefix)]): + if field[len(prefix)] == "id": + # XML ID + db_id = False + is_xml_id = data_id = line[i] + d = data_id.split('.') + module = len(d)>1 and d[0] or '' + name = len(d)>1 and d[1] or d[0] + data_ids = ir_model_data_obj.search(cr, uid, [('module','=',module),('model','=',model_name),('name','=',name)]) + if len(data_ids): + d = ir_model_data_obj.read(cr, uid, data_ids, ['res_id'])[0] + db_id = d['res_id'] + if is_db_id and not db_id: + data_ids = ir_model_data_obj.search(cr, uid, [('module','=',module),('model','=',model_name),('res_id','=',is_db_id)]) + if not len(data_ids): + ir_model_data_obj.create(cr, uid, {'module':module, 'model':model_name, 'name':name, 'res_id':is_db_id}) + db_id = is_db_id + if is_db_id and int(db_id) != int(is_db_id): + warning += ("Id is not the same than existing one: " + str(is_db_id) + " !\n") + logger.notifyChannel("import", netsvc.LOG_ERROR, + "Id is not the same than existing one: " + str(is_db_id) + ' !\n') + continue + + if field[len(prefix)] == "db_id": + # Database ID + try: + line[i]= int(line[i]) + except Exception, e: + warning += (str(e) + "!\n") + logger.notifyChannel("import", netsvc.LOG_ERROR, + str(e) + '!\n') + continue + is_db_id = line[i] + obj_model = self.pool.get(model_name) + ids = obj_model.search(cr, uid, [('id','=',line[i])]) + if not len(ids): + warning += ("Database ID doesn't exist: " + model_name + ": " + str(line[i]) + " !\n") + logger.notifyChannel("import", netsvc.LOG_ERROR, + "Database ID doesn't exist: " + model_name + ": " + str(line[i]) + ' !\n') + continue + else: + data_res_id = ids[0] + data_ids = ir_model_data_obj.search(cr, uid, [('model','=',model_name),('res_id','=',line[i])]) + if len(data_ids): + d = ir_model_data_obj.read(cr, uid, data_ids, ['name','module'])[0] + data_id = d['name'] + if d['module']: + data_id = '%s.%s'%(d['module'],d['name']) + else: + data_id = d['name'] + if is_xml_id and not data_id: + data_id = is_xml_id + if is_xml_id and is_xml_id!=data_id: + warning += ("Id is not the same than existing one: " + str(line[i]) + " !\n") + logger.notifyChannel("import", netsvc.LOG_ERROR, + "Id is not the same than existing one: " + str(line[i]) + ' !\n') + + continue if fields_def[field[len(prefix)]]['type'] == 'integer': res = line[i] and int(line[i]) elif fields_def[field[len(prefix)]]['type'] == 'boolean': @@ -618,19 +710,20 @@ class orm_template(object): if field[0] not in todo: todo.append(field[len(prefix)]) # - # Import one2many fields + # Import one2many, many2many fields # nbrmax = 1 for field in todo: - newfd = self.pool.get(fields_def[field]['relation']).fields_get( + relation_obj = self.pool.get(fields_def[field]['relation']) + newfd = relation_obj.fields_get( cr, uid, context=context) - res = process_liness(self, datas, prefix + [field], newfd, position) - (newrow, max2, w2, translate2, data_id2) = res + res = process_liness(self, datas, prefix + [field], current_module, relation_obj._name, newfd, position) + (newrow, max2, w2, translate2, data_id2, data_res_id2) = res nbrmax = max(nbrmax, max2) - warning = warning + w2 - reduce(lambda x, y: x and y, newrow) + warning = warning + w2 + reduce(lambda x, y: x and y, newrow) row[field] = (reduce(lambda x, y: x or y, newrow.values()) and \ - [(0, 0, newrow)]) or [] + [(0, 0, newrow)]) or [] i = max2 while (position+i)