Conectar OpenERP/ODOO y Magento sin un módulo de Magento


Magento
es una web eCommerce que se ha hecho conocer y mantenerse en primer lugar entre las tiendas virtuales más usado en el mundo. Su fama se debe a la solidez de la aplicación y su seguridad, aunque ello también implicaba una dificultad en su instalación y su usabilidad. Gracias a esta aplicación y sus exigencias, otras aplicaciones están poniendo su esfuerzo para estar a su altura, un ejemplo muy bueno sería Prestashop.

openERP-ODOO-con-magentoEn este apartado contaré mi experiencia con esta aplicación y cómo sincronizar Magento con OpenERP/ODOO (concretamente yo lo hago con OpenERP 7.0. Si te animas a probar otras versiones de OpenERP/ODOO, sería genial que nos contaras tu experiencia en los comentarios). A pesar de que ya existen módulos o extensiones que permiten una sincronización entre ambas aplicaciones como OpenERP Connector por OpenLab, este módulo seguro te ahorraría trabajo, siempre y cuando, ambas aplicaciones funcionasen con su código nativo. Esto es una situación que a veces no suele pasar cuando se trata de aplicaciones de código abierto como Magento o OpenERP. Se podría decir que existirían modificaciones directas, a nivel de código, en ambas aplicaciones para cumplir funciones nuevas y específicas que requiera una empresa determinada.

OpenERP 7.0 + Magento en PHP

En mi caso, he tenido que lidiar con ambas situaciones con un OpenERP que cumplía funciones específicas o reglas para registrar determinados datos y un Magento que tenía que adaptarse al sistema de datos de dicho OpenERP. Así que para ello he tenido hacer uso de un plugin funcional con PHP que me ofrecía los parámetros básicos para conectarme a un OpenERP de manera sencilla  y buscar los respectivos parámetros, que la aplicación ofrece, y hacer uso de ello en el Magento.

Para ello, he hecho uso de un plugin muy útil llamado openerp-php-connector en github. El plugin puede ser instalado sin problemas vía composer y viene estructurado para trabajar de manera ordenada sobre módulos, por ejemplo, carpetas nombradas con los siguientes nombres: Accounting, Events, HumanResource, Knwoledgebase, Lunch, Projects, etc.

Con el plugin solo nos enfocaremos y conoceremos las funciones básicas para obtener, guardar y buscar datos en el OpenERP, nombrados por la api, de la siguiente manera:

  • Read: Obtienes todos o parcialmente los parámetros de la sección del openERP que te interesa con solo indicar el modelo y las IDs (o una sola ID).
  • Create: Crea un dato para una sección del openERP.
  • Write: Actualiza un dato para una sección del openERP en el que uno de sus parámetros tiene que ser la ID del producto.
  • Search: Permite obtener solo las IDs cuyo parámetro (o parámetros) cumplan con la condición que se le manda. Se puede expresar de manera similar a una query de mysql.

Otras funciones útiles que también trae son:

  • Unlink: Borra un dato por ID o IDs.
  • Search count: Te devuelve la cantidad de IDs que cumplen con la condición que se le manda.
  • Search read: Es una combinación de las funciones SEARCH + READ.

Bueno, ahora después de la teoría viene la práctica. Recordemos que el openERP tiene muchos modelos por ejemplo existe las siguientes secciones:

  • Productos: product.product
  • Clientes: res.partner
  • Pedidos o ventas: sale.order
  • Categorías de los productos: product.category
  • Proveedores de los productos: product.supplierinfo

Si se requiere saber los nombre de los otros modelos, solo hace falta en ir en dicha sección desde la interfaz del OpenERP y ver el modelo en la url de la misma. Por ejemplo, el de proyecto sería de la siguiente manera:

http://myopenerp.com/?db=mydatabase#view_type=example&model=project.project&menu_id=77&action=15

model = project.project

Conexión de Magento con OpenERP

Después de instalar el plugin con composer del git que mencioné anteriormente, empezamos agregando los datos de un usuario con permisos de administrador en el config.php. Agregando a nuestro dominio principal la ruta xmlrpc/.

<?php
define('SERVER', 'http://myopenerp.com/xmlrpc/');
define('DATABASE', 'mydatabase');
define('USERNAME', 'admin');
define('PASSWORD', 'myPass');

Instanciamos el Magento, el config.php y el plugin:

<?php
require 'app/Mage.php';
require_once 'openerpConnector/config.php';
require_once 'openerpConnector/vendor/autoload.php';

Mage::app();

Como ejemplo, registramos un producto de Magento a OpenERP, para ello, crearemos un módulo de producto en la siguiente ubicación “openerpConnector/OpenErp/Modules/Sales/Product.php”

Hago una breve explicación de cada una de las funciones en los comentarios del código.

<?php
namespace OpenErp\Modules\Sales;


use OpenErp\Modules\Modules;
use OpenErp\OpenErp;


class Product extends Modules
{

    /*
     * BUSCAR PRODUCTO
     * $data es un array que debe contener todas las condiciones necesarias que el producto debe cumplir para obtener su ID.
     * Las condiciones pueden expresarse con un "=", "!=" o un "like" en un array con 3 valores: campo, tipo de condición y valor
     * Por ejemplo: $data = array(array('email','like','%@correo.com'),array('is_company','=',1));
     */

    public function search($data)
    {
        $limit = 2000;
        $search = $this->erp->search('product.product',$data,0,$limit);
        return $search;
    }

    /*
     * OBTENER PRODUCTO POR ID
     * $ids es un array, se tiene que indicar todas los productos que se necesita según por su id.
     * $fields tambiéns es un array pero es opcional, se puede indicar los campos necesarios que se requiere por cada llamada. 
     * Si no se indica el $fields, devolverá todos los campos del producto,
     * esto significaría una conexión más lenta si los productos necesarios fueran muchos.
     */

    public function read($ids,$fields = array())
    {
        if (is_array($ids) && count($ids) > 0) {
            $details = $this->erp->read('product.product', $ids, $fields);
            return $details;
        }

        return false;
    }

    /*
     * CREAR PRODUCTO
     * $data son los parámetros necesarios para registrar un producto, normalmente son los mismos parámetros que 
     * la función READ te muestra. Con la diferencia, que no es necesario la ID y algunos campos con opcionales. Devuelve la id del producto que se creo.
     */

    public function create($data)
    {
        $create = $this->erp->create('product.product', $data);
        return $create;
    }

    /*
     * ACTUALIZAR PRODUCTO
     * $id es un número entero existente de un producto del OpenERP
     * $data son los parámetros necesarios para actualizar el producto, normalmente son los mismos parámetros que 
     * la función READ te muestra. Sin indicar la ID del producto aquí.
     */

    public function write($id, $fields = array())
    {
        $details = $this->erp->write('product.product', array($id), $fields);
        return $details[0];
    }
}

Un ejemplo, donde reunimos todo lo visto, sería el siguiente:

<?php

require 'app/Mage.php';
require_once 'openerpConnector/config.php';
require_once 'openerpConnector/vendor/autoload.php';

use OpenErp\Modules\Sales\Product;

Mage::app();

// Id de un producto de magento
$idProduct = 10;

// Datos del producto en Magento
$productMagento = Mage::getModel('catalog/product')->load($idProduct);

// Obtenemos los mismos datos en un array
$productMagento = $productMagento->getData();

// Verificamos si el producto existe en el OpenERP por su SKU
$idProductOpen = $connectOpen->search(array(array('default_code','=',$productMagento['sku'])));

// Si no llegase a existir $idProductOpen, crearemos un nuevo producto, sino solo lo actualizaremos.
if (!$idProductOpen) { // CREAR UN NUEVO PRODUCTO
    $product = array(
                    'list_price' => $productMagento['price'],
                    'lst_price' => $productMagento['price'],
                    'code' => $productMagento['sku'],
                    'default_code' => $productMagento['sku'],
                    'name_template' => htmlspecialchars($productMagento['name']),
                    'name' => htmlspecialchars($productMagento['name']),
                    'type' => 'product',
                    'sale_ok' => 1,
                    'message_is_follower' => 1,
                    'purchase_ok' => 1,
                    'product_manager' => 0,
                    'magento_product_type' => 'simple',
                    'description' => htmlspecialchars(strip_tags($productMagento['description'])),
                    'active' => 1,
                    'loc_row' => 0,
                    'seller_delay' => 1,
                    'rental' => 0,
                    'loc_case' => 0,
                    'mes_type' => 'fixed',
                    'description_sale' => 0,
                    'weight' => '0.0',
                    'name_changed' => 1,
                    'price_changed' => 1
    );

    // Si guarda con éxito el producto, obtendremos su ID
    $idProductOpen = $connectOpen->create($product);
} else { // ACTUALIZAMOS EL PRODUCTO
    $product = array(
                    'name' => htmlspecialchars($productMagento['name']),
                    'description' => htmlspecialchars(strip_tags($productMagento['description'])),
                    'list_price' => $productMagento['price'],
                    'lst_price' => $productMagento['price'],
                    'active' => 1,
                    'overwrite' => 1,
                    'name_changed' => 1,
                    'price_changed' => 1
    );

    // Si la actualización es un éxito, nos devuelve un TRUE.
    $productOpen = $connectOpen->write($idProductOpen,$product);
}

En conclusión, este método es similar en todas las secciones del OpenERP, así que se podría aplicar sin problemas a clientes, proyectos o pedidos. También es una forma de hacer funciones más específicas que el propio módulo no ofrecería.



¿Te gusta este post? Es solo un ejemplo de cómo podemos ayudar a tu empresa...
Sobre Victor Vargas

Desarrollador de aplicaciones web y móviles. Mi experiencia se extiende en el desarrollo de módulos, plugins, scripts y temas para diversas plataformas como Wordpress, Prestashop, Magento, MediaWiki, CRM, Odoo, etc.

1 Comentario

¿Por qué no comentas tú también?


  • Impresionante el post! Enhorabuena!!

    Community Manager Girona Hace 8 años Responde


  • Hola, buén post.

    Tengo una pregunta, esta libreria soporta metodos on_change?

    El tema es que necesito introducir pedidos de venta para un cliente en concreto desde Magento.

    La orden me la crea pero en la linea de venta no se aplica la lista de precios que tiene el cliente establecida.

    ¿Alguna sugerencia?

    Gracias.

    David Hace 8 años Responde


    • Tienes los productos también registrados en el openERP?

      Victor Vargas Hace 8 años Responde


      • Hola, si, es decir:

        Registro la orden con el id de usuario que me interesa, me crea un presupuesto con su numeración. Us na vez creada, le introduzco las lineas, en este caso primero hago una busqueda que me relaciona el sku de magento con el default_code de erp, me devuelve el ID del producto que es lo que pongo en la linea de venta, entiendo que aquí es cuando debería aplicarse la tarifa… aunque no se si lo estoy haciendo bien, te paso un enlace para que veas lo que tengo. Tu lo has podido hacer?

        http://pastebin.com/UBk4XGXh

        Gracias.

        David Hace 8 años Responde


        • Quizás te falta introducir algunos parámetros más. Yo he tenido que usar los siguientes parámetros para que vaya acorde con los pedidos anteriormente registrados:

          $productData = array(
          ‘company_id’=> 1, // ID DE LA EMPRESA
          ‘delay’=> 1, // FIJO
          ‘name’=> ‘[‘.$product->getSku().’] ‘.$product->getName(), // NOMBRE PARA IDENTIFICAR
          ‘order_id’=> $idOrderOpen, // ID DEL PEDIDO DEL OPENERP
          ‘order_partner_id’=> $customerId, // ID DEL CUSTOMER
          ‘price_unit’=> $product->getPrice(), // PRECIO DEL PRODUCTO
          ‘product_id’=> $productOpenId, // ID DEL PRODUCTO
          ‘product_uom’=> 1, // ATRIBUTO DEFAULT
          ‘product_uom_qty’=> $product->getQtyOrdered(), // CANTIDAD COMPRADAS
          ‘state’=> ‘done’
          );

          Victor Vargas Hace 8 años Responde


Queremos tu opinión :)