Acceso a traves de la API de Odoo

        LINKS dE Documentación

        a) Documentación de API de odoo https://www.odoo.com/documentation/11.0/webservices/odoo.html
        Dentro del link de la documentación oficial va a encontrar casos de ejemplo para varios lenguajes de programación incluyendo: Python, Ruby, PHP y Java.

        b) Documentación de librería que la implementa y facilita su uso en python https://erppeek.readthedocs.io/en/latest/
        Si se va a implementar usando python recomendamos usar la librearía erppeek que facilita mucho la conexión a la base de datos y la llamada de los métodos.

        c) Para probar conectarte se debe usar cualquier base de entrenamiento. Debería solicitar una base, usuario y contraseña al líder de proyecto. IMPORTANTE: Si su base de datos de Odoo tiene varias compañías por favor notificar e indicar en cuales compañías va a operar. 

        EJEMPLOS DE CONEXIÓN

        Para conectarse se necesita los datos URL, nombre de la base de datos, usuario y contraseña.


        php

        Odoo recomienda utilizar librería Ripcord la cual provee una API simple para conexiones XML-RPC pero puede servir con la librería de su elección. Los ejemplos a continuación utilizan Ripcord la cual a su vez debe habilitar en su instalación PHP el soporte para XML-RPC.

        Debido a que necesita hacer llamadas via HTTPS necesita habilitar la extension OpenSSL

        $url = <insert server URL>;
        $db = <insert database name>;
        $username = "admin";
        $password = <insert password for your admin user (default: admin)>
        $common = ripcord::client("$url/xmlrpc/2/common");
        $common->version();
        {
            "server_version": "8.0",
            "server_version_info": [8, 0, 0, "final", 0],
            "server_serie": "8.0",
            "protocol_version": 1,
        }


        PYTHON

        Para la integración con Python se puede hacer usando librearía standard de python (xmlrpclib).

        import xmlrpc.client
        url = "https://...nubeadhoc.com"
        db = "train-..."
        username = "email@example.com"
        password = "password"
        common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url)) print(common.version())

        # Ejemplo para consulta
        uid = common.authenticate(db, username, password, {}) common.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True], ['customer', '=', True]]])

        No obstante recomendamos utilizar la librería de terceros erppeek ya que hace mucho mas sencillo las conexiones y consultas. una vez conseguido el cliente (conexión) podemos llamar directamente métodos definidos en Odoo sin tener que tomar en cuenta los datos para conectarse y tampoco seria necesario parsear los parámetros de los métodos que llamaremos desde el webserivce. Acá la diferencia entre ambas implementaciones:

        from erppeek import Client
        url = "https://train-....nubeadhoc.com"
        db = "train-..."
        username = "email@example.com"
        password = "password"
        client = Client(url, db, username, password)
        print(client.common.version())

        # Ejemplo para consulta
        client.model('res.partner').search([['is_company', '=', True], ['customer', '=', True]])

        Como se puede ver con python erppeek es mas claro ya que cuando se tiene la conexión activa (client) no es necesario manejar los otros datos de id de usuario, base de datos, contraseña, etc. A demás la llamada al ORM de Odoo es mas parecido a como funciona Odoo en realidad.

          ejemplos consultas

          Antes de entrar en estos ejemplos es necesario explicar un poco la estructura de Odoo. Los datos en Odoo se encuentran almacenas según modeló, cada modelo tiene sus propios campos y métodos que pueden aplicarse sobre el. Algunos de los modelos que seas podrían usar en una integración via API son:

          • Contactos (res.partner)

          • Productos (product.template) y Variantes de Productos (product.product)

          • Pedidos de Venta (sale.order)

          • Facturas de Cliente y de Proveedores (account.invoice).

          Por ejemplo:

          • En el modelo Productos vamos a tener campos descripción, tipo de producto, cantidad a mano, etc, Y vamos a tener la acción Actualizar inventario.

          • En el modelo Facturas vamos a tener lineas de factura, fecha de vencimiento, etc. y vamos a tener la acción Validar Factura, Cancelar, Enviar por Correo, etc.

          Para  construir una consulta siempre necesitamos:

          1) el modelo
          2) el método que llamaremos
          3) los parámetros que le pasaremos al método. 

          Importante hay par de métodos que están disponibles en todos los modelos, nosotros los llamamos métodos CRUD: Create, Read, Update, Delete (Crear, Leer, Actualizar, Eliminar), estos son lo que usaremos mayormente,

          Ejemplo, para buscar el producto con el nombre Mesa, en código Odoo sería algo como esto: 

          self.env['product.product'].search([('name', '=', 'Mesa')])

          donde  'product.product' seria el modelo, search seria la acción (Buscar) y el parámetro seria el criterio de búsqueda o lo que llamamos dominio donde menciona que condiciones debe de cumplir: en este caso que el nombre del producto sea Mesa.

          Esto mismo via webservice sería así: 

          # PYTHON (CON ERPPEEK)

          result = client.model('product.product').search([('name', '=', 'Mesa')])

          # PHP

          $uid = $common->authenticate($db, $username, $password, array());
          $models = ripcord::client("$url/xmlrpc/2/object"); $models->execute_kw($db, $uid, $password, 'res.partner', 'search', array(array(array('name', '=', 'Mesa'))));

          Estos son algunos ejemplos sueltos que podemos hacer via webservice

          # PYTHON

          # Consultar todos los productos activos y devolver el precio de venta
          product_data = client.model('product.product').search_read([['active', '=', True]], 'price')

          # Crear un nuevo contacto con nombre Johnh Doe.
          partner = client.model('res.partner').create({'name': 'John Doe', ...}) 

          # Crear orden de venta para el contacto (cliente) John Doe.
          product_data = client.model('sale.order').create({'partner_id': partner, 'order_line': ....}) 

          CONSULTAS DE PRODUCTOS

          Estos campos serian las mas comunes que podemos consultar en el modelo "product.product"

          • SKU

            • Referencia Interna (default_code): este es el campo en Odoo que se ve en la vista formulario y que generalmente se usa para guardar los SKU.

          • Precio: Existen varios campos que permiten calcular el precio de un producto

            • Precio de venta (list_price): Este equivale al precio de venta de un producto sin impuestos

            • Precio de venta con impuestos (taxed_lst_price): Este equivale al precio de venta de un producto con impuestos.

          • Stock

            • Cantidad a mano (qty_available): seria el campo para saber la cantidad disponible en mano de un producto. Considero que pueden utilizar este en primera instancia

            • Cantidad Prevista (virtual_available): Es el total de lo que esta en mano más lo que esta planificado o pronosticado. Puede ser que que haya un pedido de compra de dicho producto y que se estime que este por recibir nuevas unidades que pueden estimarse para vender. Esta cantidad podría ser negativa cuando se tiene una cantidad de producto comprometida a entregar mayor de la disponible (este caso puede suceder si venden sin tener disponibilidad de producto). Depende del ciclo de ventas que lleve el cliente podrían necesitar este campo.

            • Precio tarifa (price): Precio de un producto sin impuestos bajo una lista de precios especifica. Si el cliente utiliza lista de precios entonces debe utilizar este campo en su lugar y debe pasar por contexto la información del tipo de cliente que hace la operación 

          • Otros campos útiles

            • Name (name): campo char con el nombre del producto

            • Activo/Archivado (active): campo booleano indicando si el producto esta activo o no, generalmente solo los que están activos están disponible para la venta.

            • Descripción para Clientes (description_sale): es la descripción del producto a comunicar con el cliente, es un campo de texto sin formato donde están las características el producto. Generalmente esta info se auto agrega en la lineas de una orden de venta, factura, etc., dentro de Odoo. Tal vez pueden usarla para agregarla en la info que muestran en el e-commerce

          Ejemplo de consultas

          1. Para buscar todos los productos activos, esto devuelve una lista de ids

              $ids = $models->execute_kw($db, $uid, $password, 'product.product', 'search', array(array()));

          2. Para buscar un producto en especifico en Odoo conociendo el SKU, retorna una lista con un solo id

              $id = models->execute_kw($db, $uid, $password, 'product.product', 'search', array(array(array('default_code ', '=', $sku))), array('limit'=>1));

          3. Para leer valores de estos registros. el resultado serpa una lista con la info de cada registro consultado

              $product_values = $models->execute_kw(
                  $db, $uid, $password, 'product.product', 'read', 
                  array($ids),
                  array('fields'=>array('name', 'sku', 'list_price', 'qty_available')));

          4. Pueden hacer la búsqueda y lectura en una misma llamada si prefieren

              $product_values = $models->execute_kw(
                  $db, $uid, $password, 'product.product', 'search_read',
                  array(array(array('default_code ', 'in', $sku_list))),
                  array('fields'=>array('name', 'sku', 'list_price', 'qty_available'))
              );

          pedidos de venta

          Los pedidos en venta en Odoo están representados por el modelo "sale.order", y las líneas de los pedidos donde lista los productos del pedido están asociadas al modelo "sale.order.line".

          1. Para crear un pedido de venta en Odoo debemos llamar la método create y pasar un diccionario/colección con los valores de los campos para crear el pedido de venta.

          # PHP
          $sale_order_id = models->execute_kw(
              $db, $uid, $password, 'sale.order', 'create', array(array(
                  'fields'=>array('campo1'=> 'value1', 'campo2'=> 'value2, …),
              ))
          );

          # PYTHON
          sale_order_id = client.model('sale.order').create({'campo1':  'value1', 'campo2':  'value2'})

          2. Para la validación de los pedidos de ventas

          # PHP
          models->execute_kw($db, $uid, $password, 'sale.order', 'action_confirm', array(sale_order_id));

          # PYTHON
          client.model('sale.order').action_cofirm([sale_order_id])

          3. Para generación de facturas

          # PHP
          models.execute_kw(db, uid, password, 'sale.order', 'action_invoice_create_force', [sale_order_id])

          # Python
          client.model('sale.order').action_invoice_create_force([sale_order_id])

          CAMPOS

          • Cliente (partner_id): Este campo es requerido para crear el pedido de venta. Este es número entero que representa a un ID relacionado a la tabla del modelo res.partner (Contactos) el cual almacena la información del cliente (nombre, dirección, teléfono, email, etc).  Debido a que este campo es obligatorio tenemos un par de opciones:

            • Si necesita saber con detalle que cliente realizo el pedido de venta:

              • Puede revisar en Odoo si el cliente existe según algún criterio de preferencia (email o DNI) y asociar el pedido de venta a ID cliente (ver detalle en sección Creación de partners). Este seria un ejemplo de como buscar un cliente en Odoo:

                • partner = client.model('res.partner').search([('main_id_number', '=', dni_o_cuit_number)]
              • Puede siempre crear un nuevo contacto en Odoo con los datos que recibe en la plataforma a integrar.

            • Si no necesita saber con detalle que cliente realizado el pedido de venta.

              • En las bases de Odoo de ADHOC va a tener siempre disponible un contacto llamado  "Consumidor Final Anónimo"  el cual se puede usar para crear todos estos pedidos sin necesidad de crear nuevos partners

          • Lineas de Pedido de venta (order_line): este es un campo requerido y almacena la información de los productos vendidos, es una lista de uno o mas registros del modelo "sale.order.line" la cual tiene definido estos campos:

            • Producto (product_id): es un campo requerido. el ID del producto del modelo product.product.

            • Descripción (name): también requerido, este se auto completa con el nombre del producto agregado en product_id, pero también puede ser definido de manera particular.

            • Cantidad pedida (product_uom_qty): es requerido y representa la cantidad de productos que se esta solicitando, si no se envía en los datos de creación de la linea vamos Odoo supone que la cantidad es 1. Este es un número flotante.

            • Unidad de medida (product_uom): es requerido y se auto completa con la unidad de medida configurada en el producto definida en product_id

            • Precio unitario (price_unit); este es requerido y se auto completa conjugando la información del producto y de la lista de precios en el pedido de venta.

            • Pedido de venta (order_id): Esta campo es requerido pero no esta visible en vista, ya que desde la interfaz de Odoo el toma de una vez los valores del Pedido de Venta donde se están creando las lineas. Depende de como hagan las consultas vía webservice, si crean lineas de venta por separada van a necesitar pasar este valor (numero entero).

          Los siguientes campos son requeridos pero generalmente son auto completados con Odoo a través de valores por defectos o en base a otros campos suministrados:

          • Dirección de Facturación (partner_invoice_id) Este campo también es una relación a res.partner y es requerido. Depende de como lo manejen el flujo de ventas en Odoo, pueden crear un nuevo partner para indicar la dirección de facturación y vincularlo al pedido, o puede re usar el mismo partner_id definido en el campo  "Cliente". Por defecto Odoo auto llenara este campo con el mismo valor que esta en el campo "Cliente"

          • Dirección de Entrega (partner_shipping_id) Este campo también es una relación a res.partner y es requerido. Se refiere a la dirección de entrega del pedido en caso de haberla. Si no es necesaria puede re usar lo definido en el campo "Cliente". Por defecto Odoo auto llenara este campo con el mismo valor que esta en el campo "Cliente"

          • Lista de Precios / Tarifas  (pricelist_id): Este es requerido para la creación de pedidos de venta, ya que permite a Odoo calcular los precios de los productos. Si su cliente utiliza listas de precios la idea seria agregar acá el ID (numero entero) que identifica la lista de precios. Puede consultar las listas de precios que hay en el sistema y sus ID usando este comando:

            • pricelists = client.model('product.pricelist').search([]).read(['display_name'])

              Odoo por defecto siempre crea una lista de precio llamada "Tarifa Publica (ARS)" asi su cliente use o no listas de precios. En ese caso debe utilizar esta lista de precios. NOTA: las tarifas siempre vienen dada por las monedas que tenga configurada en el sistema, por favor tener en cuenta al momento de seleccionar la tarifa correcta.

          • Almacén (warehouse_id): Si en Odoo tiene instalado el modulo de inventario este campo va a ser requerido. Debe pasar el ID (numero entero) relacionado al almacén que tienen definido en Odoo. Al crear el pedido de venta desde webservice llenará este campo automáticamente con el primer almacén que consiga. Si quiere que el pedido salga de un almacén especifico debe pasar el ID del almacén. Para consultar los almacenes definidos puede correr este comando

            • warehouses = client.model('stock.warehouse').search([]).read(['display_name'])
              
          • Política de Entrega (picking_policy): este campo es requerido, tomar el valor por defecto configurado en la base de datos. las opciones son "Entregar cada producto cuando este disponible" y "Entregar todos los productos a la vez".

          • Fecha del Pedido (date_order): campo requerido, almacena la fecha y hora en que el pedido fue realizado. Esta también es auto completado con la fecha en la cual el pedido fue creado en Odoo.

          • Tipo (type_id): Al tener activo la opción "Tipos de Ventas" este campo va a ser requerido. 

          • Canal de venta (team_id): Este campo es opcional pero es aconsejado de usar, porque permite de alguna manera identificar cual desde cual canal de venta se genero el pedido. Recomendamos en Odoo crear un canal de ventas por cada integración. Ejemplos de equipos: Mercadolibre, Magento, E-commerce, etc. Al crear el pedido de venta via webservice asignar el ID del equipo que hace referencia. Para consultar los equipos existentes en el sistema puede utilizar este comando.

            • teams = client.model('crm.team').search([]).read(['display_name'])
          • Notas Internas (internal_notes) campo opcional que permite almacenar algún texto extra si desea puede ser util para almacenar datos que puedan servir de referencia a su aplicacíón


          • Acceso a traves de la API de Odoo