Migrando mensajes y attachments

10 de junio de 2024 por
Gustavo Orrillo
| Sin comentarios aún
 

Una tarea única de Odoo es la migración de mensajes y attachments, por la simple razón que solo Odoo implementa esta tan poco conocida (desde el punto de vista técnico, ya que cuantos customizan el chatter? o implementan workflows utilizando actividades?). Muy util por lo cierto. Los mensajes, junto con las actividades y los archivos anexados los podemos tener en cada uno de los modelos y podemos verlos de esta manera (una distorsionada vista de las reparaciones).


Ahora, como hacemos para migrar dichos mensajes? Si tenemos que hacerlo desde otro sistema Odoo? Una opción facil es xmlrpc. Para ello primero tenemos que migrar el modelo de los mensajes. Y dichos mensajes tienen los siguientes campos (a modo de ejemplo):

    vals = {
​ 'res_model': message_data.get('res_model'),
'res_id': res_id[0],
'body': message_data.get('body'),
'subject': message_data.get('subject') or '',
'date': message_data.get('create_date'),
'create_date': message_data.get('create_date'),
'write_date': message_data.get('create_date'),
'old_id': message,
​ 'author_id': author_id,
}

De los que vale la pena destacar los campos res_model y res_id (modelo y ID del registro al que pertenecen los mensajes). Luego tenemos el campo author_id, el cual es el autor del mensaje (un campo many2one que apunta al modelo res.users) y los campos con el mensaje mismo (body y subject).

Como se migran? se los migra como cualquier modelo con xmlrpc. Nada nuevo hasta entonces. Luego tenemos los attachments, los que se persisten en el modelo ir.attachment y contiene los siguientes campos:

vals = {
'res_model': res_model,
'res_id': res_id[0],
'datas': attachment_data.get('datas'),
'name': attachment_data.get('name'),
'description': attachment_data.get('description'),
'create_date': attachment_data.get('create_date'),
'old_id': attach,
}

Los attachments al igual que los mensajes tienen dos campos para relacionarlo con cualquier modelo y registro (res_model y res_id). Luego tenemos un campo binario llamado datas, el cual contiene el attachment en si mismo. Y el campo name que contiene el nombre del attachment (el cual sería el nombre del archivo almacenado). Los attachments se migran con xmlrpc como cualquier modelo. No tienen grandes secretos.

Por último, como se relacionan los mensajes con los attachments? Cada mensaje tiene una columna llamada attachment_ids, que es del tipo many2many. La cual permite relacionar un mensaje con múltiples archivos. Esto se lo puede hacer con la siguiente actualización:

vals['attachment_ids'] = [(6,0,[lista con los IDs de los attachments])]

Ahora, vamos a juntar todos estos conocimientos y mostrar como se hace para tomar los mensajes del modelo sale.order junto con sus attachments, todo esto con mediante xmlrpc. 

messages = models_old.execute_kw(dbname_old,uid_old,pwd_old,'mail.message','search',[[['model','in',['sale.order']]]])
return_id = None
for i,message in enumerate(messages):
print(i,message,len(messages))
message_data = models_old.execute_kw(dbname_old,uid_old,pwd_old,'mail.message','read',[[message],fields])
message_data = message_data[0]
author_id = False
if message_data.get('author_id'):
author_id = models.execute_kw(dbname,uid,pwd,'res.partner','search',[[['old_id','=',message_data.get('author_id')[0]]]])
res_id = models.execute_kw(dbname,uid,pwd,'sale.order','search',[[['old_id','=',message_data.get('res_id')]]])
msg_id = models.execute_kw(dbname,uid,pwd,'mail.message','search',[[['old_id','=',message]]])
vals = {
'res_id': res_id[0],
'body': message_data.get('body'),
'subject': message_data.get('subject') or '',
'date': message_data.get('create_date'),
'create_date': message_data.get('create_date'),
'write_date': message_data.get('create_date'),
'old_id': message,
}
vals['model'] = message_data.get('model')
if author_id:
vals['author_id'] = author_id[0]
 if not msg_id:
return_id = models.execute_kw(dbname,uid,pwd,'mail.message','create',[vals],{'context': {'write_metadata': True}})
  msg_id = return_id
else:
return_id = models.execute_kw(dbname,uid,pwd,'mail.message','write',[msg_id,vals],{'context': {'write_metadata': True}})
if message_data.get('attachment_ids'):
attachments = []
for attach in message_data.get('attachment_ids'):
print(i,message,len(messages))
fields_attach = ['res_model','name','res_id','description','datas','create_date']
attachment_data = models_old.execute_kw(dbname_old,uid_old,pwd_old,'ir.attachment','read',[[attach],fields_attach])
attachment_data = attachment_data[0]
res_model = attachment_data.get('res_model')
​ res_id = models.execute_kw(dbname,uid,pwd,res_model,'search',[[['old_id','=',attachment_data.get('res_id')]]])
attachment_id = models.execute_kw(dbname,uid,pwd,'ir.attachment','search',[[['old_id','=',attach]]])
vals = {
'res_model': res_model,
'res_id': res_id[0],
'datas': attachment_data.get('datas'),
'name': attachment_data.get('name'),
'description': attachment_data.get('description'),
'create_date': attachment_data.get('create_date'),
'old_id': attach,
}
if not attachment_id:
attachment_id = models.execute_kw(dbname,uid,pwd,'ir.attachment','create',[vals],{'context': {'write_metadata': True}})
else:
return_id = models.execute_kw(dbname,uid,pwd,'ir.attachment','write',[attachment_id,vals],{'context': {'write_metadata': True}})
attachment_id = attachment_id[0]
attachments.append(attachment_id)
if attachments:
vals = {'attachment_ids': [(6,0,attachments)]}
return_id = models.execute_kw(dbname,uid,pwd,'mail.message','write',[msg_id,vals],{'context': {'write_metadata': True}})


Gustavo Orrillo 10 de junio de 2024
Compartir
Archivar
Identificarse dejar un comentario