Importando y actualizando productos con xmlrpc y archivos xlsx

7 de julio de 2023 por
Gustavo Orrillo
| Sin comentarios aún
 

Frecuentemente se deben actualizar los datos maestros de Odoo (por ejemplo productos y clientes) con archivos Excel (formato xlsx u csv). El archivo de Excel es un standard de-facto en la indústria. 

Para actualizar los productos uno puede utilizar la interface de importación de Odoo. Pero la interface de importación no puede acomodar lógica para la transformación de los datos a cargar y no puede acomodar lógica del negocio para procesar las actualizaciones y encima de todo tiene problemas cuando se deben actualizar miles de registros. 

Una opción frente a estas limitaciones es utilizar scripts de python con xmlrpc. En Python podemos leer archivos de Excel desde hace rato(para eso hay librerías como xlrd, openpyxl o pandas que permiten hacerlo). Entonces la idea es habiendo leído el archivo de Excel con Python, actualizar o crear dichos productos en Odoo mediante xmlrpc. 

Para este ejemplo tomaremos un archivo de productos con tres columnas: nombre, código y precio. Y con el mismo actualizaremos el maestro de productos de Odoo.


En este archivo solo tenemos tres columnas las cuales se mapean al objeto product.template de la siguiente manera:

  • Nombre: name
  • Referencia: default_code
  • Precio: list_price

Y este es el código del script que podemos usar para leer el archivo y recorrer sus contenidos:

#!/usr/bin/python3

from xmlrpc import client
import openpyxl

url = 'http://localhost:8069'
common = client.ServerProxy('{}/xmlrpc/2/common'.format(url))

res = common.version()
dbname = 'mrputilsv1'
user = 'admin'
pwd = 'admin'
uid = common.authenticate(dbname, user, pwd, {})

# prints Odoo version and UID to make sure we are connected
print(res)
print(uid)

models = client.ServerProxy('{}/xmlrpc/2/object'.format(url))

# Define la variable para leer el workbook y lee el archivo
workbook = openpyxl.load_workbook("demo_products.xlsx")
# Define variable para la planilla activa
worksheet = workbook.active

# Itera las filas para leer los contenidos de cada celda
rows = worksheet.rows
for x,row in enumerate(rows):
# Saltea la primer fila porque tiene el nombre de las columnas
if x == 0:
continue
# Lee cada una de las celdas en la fila
for i,cell in enumerate(row):
print(i,cell.value)

Como podemos ver, el codigo lista el contenido de las celdas de la planilla. Tenemos la siguiente salida por la terminal:


Ahora necesitamos para cada fila de la planilla, crear un diccionario de Python con el valor de los campos a actualizar en Odoo

# Lee cada una de las celdas en la fila
vals = {}
for i,cell in enumerate(row):
if i == 0:
col = 'name'
if i == 1:
col = 'default_code'
if i == 2:
col = 'list_price'
vals[col] = cell.value

El resultado de este código es un diccionario con los valores que deberán insertarse o actualizarse en Odoo. El paso siguiente, es buscar el código del producto y determinar si se va a actualizar o crear el producto (esto es fundamental, ya que garantiza que se pueda ejecutar los scripts de importación múltiples veces sin comprometer la integridad de los datos (que se corrompe al duplicarse la información).

# Busca el codigo de producto
product_tmpl_id = models.execute_kw(dbname,uid,pwd,'product.template','search',[[['default_code','=',vals.get('default_code')]]])
# si no se encuentra el producto, lo crea. Caso contrario lo actualiza
if not product_tmpl_id:
return_id = models.execute_kw(dbname,uid,pwd,'product.template','create',[vals])
else:
return_id = models.execute_kw(dbname,uid,pwd,'product.template','write',[product_tmpl_id,vals])
print(return_id)

Lo que al ejecutarse, actualiza los productos en Odoo y deja este resultado final


El código de este ejemplo lo podemos ver en nuestro github. El paso siguiente (en otro post) es leer los datos de PostgreSQL.




Gustavo Orrillo 7 de julio de 2023
Compartir
Archivar
Identificarse dejar un comentario