OpenERP cambia su nombre a Odoo

Aunque se venía gestando desde hacía algún tiempo, ayer saltó noticia oficialmente, en primera instancia para los partners oficiales de OpenERP / Odoo, y seguidamente se propagó rápidamente por las redes sociales. A fecha de hoy el cambio ya está realizado, y apenas queda rastro de OpenERP en su web oficial.

El motivo del cambio es principalmente desvincular la palabra “ERP” del nombre, debido a que OpenERP ya se había convertido en mucho más que eso, especialmente desde la nueva versión 8.0, que trae nuevas incorporaciones web como el CMS, eCommerce o gestor de eventos.

Además del cambio de nombre, el cambio más relevante es que los repositorios de código pasan de estar en Launchpad (bzr) a Github (git), lo que supone una mejora sustancial en la herramienta de control de versiones (falta confirmar como se gestionarán las traducciones en adelante) y mayor rapidez en la descarga del código.

Por supuesto, Odoo seguirá siendo software libre 100% licenciado bajo AGPL.

Aunque OpenERP s.a (todavía se llama así) nos ha dado un margen de tiempo para adaptar las localizaciones a los cambios, la comunidad española ya nos hemos puesto en marcha para organizar la creación de las listas a  odoo-spain@googlegroups.com y odoo-spain-users@googlegroups.com, migrar el código de los módulos españoles a Github y adaptar textos y artículos de portales comunitarios.

La información principal se resume el siguiente correo enviado por Anthony Lesuisse a la comunidad mundial:

  • github.com/odoo/odoo es ahora el repositorio oficial. Se ha realizado un merge de histórico de las 3 ramas.
  • el Bug Tracker de Github reemplaza al de Launchpad, se utilizarán etiquetas para filtrar y ordenar los errores.
  • las traducciones todavía permanecen en Rosetta de Launchpad  (Olivier Dony sincronizará manualmente los archivos .pot and .po). Más adelante se hará una transición a otra plataforma (probablemente transifex).
  • Se publicará una herramienta para convertir una rama funcional de Launchpad a una rama Git
  • Los namespaces se renombrarán a Odoo manteniendo compatibilidad hacia atrásgithub.com/odoo-dev/odoo es un repositorio bifurcado donde se alojarán todas las ramas de desarrollos de OpenERP s.a (la compañía cambiará su nombre más adelante). Todos los desarrollos permanecen públicos.
  • runbot es reemplazado por runbot https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-runbot-al
  • help es ahora mantenido por el módulo de odoo website_forum
  • la lista de correo se gestionará con el módulo web website_mail_group
  • se publicará un nuevo tutorial de desarrollo
  • la documentación de referencia será actualizada, el memento técnico se convertirá a rst, se mantendrá el archivo .rst en odoo o en el repositorio wiki de github

pantallazo odoo

Las 3 ramas con su historia completa están en el repositorio de Odoo. Probablemente se moverá /addons/* a odoo/addons/ por lo que ‘base’ estará con el resto de módulos
Como ahora es fácil mover código entre el servidor y los addons, probablemente se moverá res.partner res.bank etc.. a un módulo partner (res.partner queda en base por res.users pero pronto será un modelo vacío)

También se han borrado muchos blobs innecesario del histórico. El repositorio completo tiene cerca de 400mb, que es un tercio del tamaño bzr. Unir los 3 históricos ha sido un logo técnico. Todo el trabajo duro fue realizado por Xavier Morel(xmo)

En breve se ofrecerá información mucho más completa en los canales habituales.

odoo_formerly_openerp

Gestión ágil de proyectos en OpenERP

login timetracker

Una vez creado el Proyecto y las distintas tareas que pueda tener el proyecto, el usuario puede acceder a la plataforma web – intranet, donde se le mostrará una tabla con las tareas que tiene asignadas este usuario, ordenadas dentro de sus respectivos proyectos y unas casillas por día, para poder imputar las horas realizadas cada día en cada tarea y añadir algún comentario a dicha imputación. También se puede navegar dentro de la intranet por semanas para poder imputar horas realizadas días atrás o previsión para días posteriores.

horas timetracker

Estas horas imputadas aparecerán reflejadas en el proyecto que tenemos en OpenERP como si las hubiéramos introducido desde dentro de la aplicación, y donde podremos gestionar con automáticamente el resto de procesos analíticos, etc. que OpenERP ofrece y que deseemos controlar.

Proyectos OpenERP

La plataforma ha sido desarrollada utilizando html5 y Javascript, por lo que puede estar alojada en un servidor o distribuirse como una aplicación multiplataforma para ejecutarse en cualquier sistema operativo que lo soporte. Para conseguirlo hemos desarrollado una librería Javascript que conecta por medio de Json-RPC con el servidor de OpenERP. Esto permite crear una sesión y hacer llamadas a cualquier objeto de OpenERP de la misma forma que lo hace el propio cliente web.

En próximas versiones se incorporará un acceso a clientes (extranet) para que puedan visualizar de manera sencilla el tiempo empleado y el coste de las tareas en sus proyectos.

Fases de una implantación ERP (desde la perspectiva del cliente)

2. Selección de paquetes: un ERP está formado por muchos y muy diversos módulos en cada una de sus áreas funcionales. A partir de un estudio y boceto previo que la empresa prepara para el implantador, se debe realizar una selección de paquetes, donde los módulos que no son adecuados deben ser eliminados, y los paquetes elegidos deben ser cuidadosamente seleccionados y probados. Una correcta selección creará un esqueleto que servirá como base para construir el resto.

3. Análisis GAP: se podría definir GAP como las adaptaciones que del ERP que requieren programación necesarias para cubrir las necesidades funcionales. Este proceso es tan necesario como crítico, pues hay que describir muy bien los requerimientos y definir muy claramente los objetivos de todos los desarrollos. Prácticamente todas las implantaciones de cierto tamaño o que cubren procesos muy específicos necesitan análisis GAP. Debemos involucrar a los responsables de cada departamento para conseguir identificar todos los GAP correctamente.

4. Reingeniería: la reingeniería de procesos es aconsejable, aunque implica muchos cambios y resulta más incómoda para el cliente que para el implantador del ERP. Durante esta etapa, pueden variar las responsabilidades de los empleados, así como algunas de sus tareas habituales. Aunque esta fase es una de las más complicadas, es muy aconsejable para mejorar la eficacia de los procesos de negocio.

5. Formación: el momento de la formación a empleados llega cuando se finaliza la etapa de desarrollo por parte del implantador y se realizan las entregas de los nuevos módulos. La formación se debe realizar en primera instancia a los usuarios clave en cada departamento, que habrán sido a su vez los que hayan ayudado a definir y validar sus respectivas áreas, y posteriormente al resto de usuarios. Es crucial que la formación final a toda la plantilla se realice en un período de tiempo cercano a la puesta en marcha para que no se olviden los conocimientos adquiridos.

6. Preproducción: este paso es crítico para depurar los posibles errores y que éstos puedan ser encontrados y resueltos antes de la puesta en producción del programa. El entorno debe ser lo más parecido posible al final, con los datos de las viejas aplicaciones ya migrados.

7. Puesta en producción: éste es el paso clave, tras haber probado todo el entorno y el correcto funcionamiento de todos los flujos de trabajo. Lo habitual es elegir un período que coincida con un cambio fiscal a fin de minimizar las tareas de migración, o en un momento que se prevean menos picos de trabajo en la empresa, ya que el momento del cambio requerirá mucho tiempo por parte de la plantilla. Es el momento mas crucial para el implantador, que debe contar con una disponibilidad total para apoyar a los usuarios y dar soporte técnico y funcional si fuera necesario.
Tras la puesta en marcha, el entorno de pruebas puede ser eliminado, si bien se recomienda en todo momento contar con un entorno para desarrollo, caso de requerir más adelante nuevas funcionalidades o integraciones. Sería en éste entorno donde se realizaran dichas pruebas, nunca en el entorno de trabajo real. Si los sistemas están virtualizados, no obstante, se podría replicar en cualquier momento.

8. Mantenimiento: El mantenimiento se realiza en la fase posterior a la ejecución del ciclo de vida de la aplicación ERP. Los problemas se identifican y los empleados a aprender cómo lidiar con él. El mantenimiento es una etapa crucial durante el ciclo de vida. Es crucial que durante esta etapa, el sistema sea actualizado con regularidad para mantenerse al día con los cambios en la tecnología.

Es importante implicar también no sólo al personal propio, sino al conjunto de proveedores y/o clientes que interactúan con el sistema, como la Gestoría / Asesoría, clientes con acceso a una Extranet, proveedores logísticos, etc…

Módulo de OpenERP para EDI – Edicom

Actualmente el módulo se encarga de la exportación de facturas de OpenERP a Ediwin, a futuro se contempla la importación de pedidos y exportación de albaranes.

El funcionamiento del módulo es muy sencillo, una vez se valida una factura aparece un nuevo botón en el formulario que permite la exportación a Ediwin.

EDI OpenERP 01

Al hacer clic sobre este botón se generará un fichero que será importado por Ediwin, para que esto funcione será necesario que se haya indicado el directorio de exportación en el servidor de OpenERP y que apunte al directorio de importación de Ediwin. También será necesario completar algunos datos como el código EDI del cliente y de la propia compañía, y otros datos como CIFs, direcciones de la compañía y las empresas y ean13 de los productos.

Una vez generado el fichero, para facilitar el proceso de exportación se genera un nuevo objeto en OpenERP, que contiene todos los campos que solicita Ediwin. De esta forma en caso de que Ediwin no sea capaz de importar el fichero siempre se podrá consultar desde OpenERP los datos que está exportando, se podrá también modificar y volver a generar el fichero para su correcta importación.

EDI OpenERP 02

El código del proyecto se ha liberado en Launchpad y se puede descargar de https://launchpad.net/openerp-edicom

Localización española para OpenERP 8

Hasta este momento se han migrado y testeado los siguientes módulos:

  • l10n_es
  • l10n_es_account
  • l10n_es_account_invoice_sequence
  • l10n_es_fiscal_year_closing
  • l10n_es_toponyms
  • l10n_es_partner
  • l10n_es_partner_seq
  • l10n_es_account_balance_report
  • account_balance_reporting
  • l10n_es_bank_statement
  • l10n_es_payment_order
  • l10n_es_aeat
  • l10n_es_aeat_mod340
  • l10n_es_aeat_mod347

Para la instalación de l10n_es_toponyms, l10n_es_partner y l10n_es_partner_seq es necesario instalar el módulo base_location de la rama partner-contact-management, que es compatible en su versión 7.

Para la instalación de l10n_es_payment_order es necesario instalar el módulo account_payment_extension, pero el disponible en la rama account-payment no es instalable en la versión 8, así que hemos actualizado el módulo, los cambios están en la rama lp:~domatix/account-payment/8.0.

Para la instalación de l10n_es_aeat, l10n_es_aeat_mod340 y l10n_es_aeat_mod347 es necesario instalar el módulo account_chart_update de la rama account-financial-tools, que es compatibble en su versión 7. También es necesario instalar el módulo refund_original cuya versión mas actualizada se encuentra en repositorios de Acysos, pero que no es instalable en la versión 8, por lo que lo hemos migrado y está disponible en lp:~domatix/acysos/8.0.

Novedades del módulo de gestión de almacén en OpenERP v8

  • Gestión de almacenes y coste mediante los métodos FIFO/LIFO/medio/FEFO.

Y por supuesto con la escalabilidad y posibilidad de adaptaciones que siempre ha caracterizado a OpenERP.

Esto es sólo una pequeña parte de todo lo que parece que nos aguarda en la versión 8 de OpenERP respecto al módulo de gestión de almacén.

En el siguiente slideshare, podemos encontrar información mas detallada:

Fuente: slideshare.net extraído de OpenERP.tv

Uruguay y la ley de software libre y formatos abiertos.

¿Cuales son los pilares fundamentales?

  1. Los Poderes Ejecutivo, Legislativo y Judicial, los entes autónomos, los organismos descentralizados, las empresas donde el Estado posea mayoría accionaria, los Gobiernos Departamentales, las Juntas Departamentales, el Tribunal de lo Contencioso Administrativo, la Corte Electoral y los organismos de contralor del Estado, deberán distribuir toda información en al menos un formato abierto, estándar y libre. Todo pedido de información deberá ser aceptado en al menos un formato abierto y estándar.
  2. En las instituciones y dependencias del Estado mencionadas en el artículo 1º, cuando se contraten licencias de software se dará preferencia a licenciamientos de software libre. En caso que se opte por software privativo se deberá fundamentar la razón. En caso de que el Estado contrate o desarrolle software, el mismo al ser distribuido, se licenciará como software libre. El intercambio de información realizado con el Estado, a través de Internet, deberá ser posible en, al menos, un programa licenciado como software libre.
  3. Se considera de interés general que el sistema educativo proceda a promover el uso de software libre.
  4. El Poder Ejecutivo reglamentará en un plazo de 180 (ciento ochenta) días las condiciones, tiempos y formas en que se efectuará la transición de la situación actual a una que satisfaga las condiciones de la presente ley y orientará, en tal sentido, las licitaciones y contrataciones futuras de programas de computación (software) realizadas a cualquier título.
  5. Definiciones a los efectos de la presente ley:
  1. El software libre es el que está licenciado de forma que cumpla simultáneamente las siguientes condiciones.
    1. Pueda ser usado para cualquier propósito
    2. Tenga acceso a su código fuente de forma que pueda ser estudiado y cambiado para adaptarlo a las necesidades.
    3. Pueda ser copiado y distribuido.
    4. Sea posible la mejora del programa y la liberación de dichas mejoras a la ciudadanía.
  2. El software privativo es todo software que prive de alguna de las cuatro condiciones o libertades inherentes al software libre.
  3. Los formatos abiertos son formas de manejo y almacenamiento de los datos en los que se conoce su estructura y se permite su modificación y acceso no imponiéndose ninguna restricción para su uso. Los datos almacenados en formatos abiertos no requieren de software privativo para ser utilizados.
  4. Formatos estándar son los que han sido aprobados por una entidad internacional de certificación de estándares.

Según las palabras de la diputada Daisy Torné, Cuando uno quiere lograr que el Estado funcione de determinada manera lo tiene que decir por ley. Lo que queremos es que el Estado utilice el software libre, que lo promueva, que lo promueva en el sistema educativo, que prefiera utilizar formatos estándar abiertos y libres, antes de privativos. Por lo tanto, si no lo hace, tiene que ser por una razón muy fundada y lo tendrá que poner por escrito. Tenemos que darle una discrecionalidad, no creemos en el mercado libre que ya demostró lo que es.”

La ley contiene varias ventajas para la administración pública y la ciudadanía:

Ahorro en gasto público: el gasto en licencias de software privativo es un lastre para las administraciones públicas difícilmente justificable desde el punto de vista técnico.
Mejora de seguridad: la liberación de documentos de la NSA por parte de Edward Snowden evidenció la necesidad de contar con mayor soberanía informática. El software libre por definición es más seguro y está libre de puertas traseras.

Interoperabilidad: el uso de ficheros de formatos privativos dependientes de una o varias empresas, es complejo y costoso de mantener. Los formatos abiertos y estándares fomenta la interoperabilidad entre las dependencias y asegura el intercambio de archivos eficientemente.

Transparencia: difundir la información pública en un formato abierto permite la transparencia y el libre acceso a los datos por parte de la ciudadanía.

Con esta ley, Uruguay se adelanta a otros países latinoamericanos que ya han optado por software libre, pero que no han legislado a su favor, como Brasil, Ecuador, México o Argentina.
Enhorabuena a Uruguay y esperamos que sea el pionero de otros muchos paises en el futuro.

Conectar Symfony2 con OpenERP

1. Que es Symfony y su instalación

Symfony es un framework de muy potente para desarrollo de aplicaciones web en el lenguaje de programación Php. Esta basado en el patrón Modelo Vista Controlador y proporciona un conjunto de herramientas para facilitar los desarrollos web complejos.
El siguiente documento muestra como realizar una instalación de Symfony nueva y realizar la conexión a Openerp.

1.1. Instalación de LAMP

LAMP son las siglas de linux apache mysql php. Symfony necesita de un servidor LAMP para poder funcionar. A continuación veremos como instalar un servidor LAMP en nuestro sistema. En primer lugar instalaremos apache:

$ sudo apt-get install apache2

Posteriomente instalamos php:

$ sudo apt-get install php5 libapache2-mod-php5 php-cli php-mysql

y reiniciamos apache:

$ sudo service apache2 restart

por último instalamos mysql:

$ sudo apt-get install mysql-server mysql-client libmysqlclient-dev

durante el proceso de instalación nos pedirá que asignemos contraseña al usuario root de mysql.

Adicionalmente, podemos instalar también phpmyadmin para ayudarnos con la configuración de mysql:

$ sudo apt-get install phpmyadmin

y creamos un enlace simbólico para acceder:

$ sudo ln -s /usr/share/phpmyadmin /var/www

Ahora podremos acceder mediante la url 192.168.0.122/phpmyadmin.

1.2. Instalación de composer

Composer es un gestor de dependencias para un proyecto php. Para instalar composer primero debemos instalar curl

$ sudo apt-get install curl

Posteriomente instalamos composer:

$ curl -s https://getcomposer.org/installer | php

Si todo ha funcionado bien, en el directorio donde te encuentras veras un nuevo fichero llamado composer.phar. Para comprobar que se ha instalado correctamente, ejecuta el siguiente comando que muestra el menú de opciones de Composer:

$ php composer.phar

Instalar Composer de esta manera es correcto, pero te obliga a realizar una nueva instalación para cada proyecto Symfony2. Si tienes muchos proyectos, es mucho mejor que instales Composer de forma global en tu ordenador, para que todos los proyectos utilicen la misma versión de Composer.

Para instalar Composer globalmente, mueve el archivo composer.phar a algún directorio ejecutable del sistema, como por ejemplo:

$ sudo mv composer.phar /usr/local/bin/composer

Comprueba que todo funciona bien ejecutando el comando composer sin opciones desde cualquier directorio del sistema. La instalación global de Composer también facilita su mantenimiento, ya que sólo hay que ejecutar el siguiente comando para actualizar la versión de Composer de todos los proyectos:

$ sudo composer self-update

1.3. Instalación de Symfony

Gracias a composer la instalación de Symfony se reduce a un simple comando de consola:

php composer.phar create-project symfony/framework-standard-edition nuestra_ruta/ 2.3.6

por ejemplo:

php composer.phar create-project symfony/framework-standard-edition /home/user/openerp/ 2.3.6

En caso de haber instalado composer globalmente:

composer create-project symfony/framework-standard-edition nuestra_ruta/ 2.3.6

El proceso de instalación nos ira pidiendo los datos de configuración de nuestro servidor. Podemos introducirlos en el momento o introducirlos a mano en el fichero app/config/parameters.yml

Una vez instalado, hay que borrar el bundle AcmeDemo:

Eliminar carpeta AcmeBundle de src
Eliminar $bundles[] = new AcmeDemoBundleAcmeDemoBundle(); del fichero app/AppKernel.php
Eliminar bloque referente AcmeDemo en app/config/routing_dev.yml

2. Conectar Symfony con OpenErp

Ya tenemos instalado Symfony en nuestro sistema, ahora vamos a ver como realizar la conexión con nuestro OpenErp.

2.1. Crear bundle conexión OpenERP

Un bundle se Symfony es el equivalente de un módulo de OpenERP, contiene todos los ficheros que proporcionan una nueva funcionalidad a nuestra aplicación web.

Para generar un bundle, debemos ejecutar en el directorio de nuestro proyecto Symfony:

$ php app/console generate:bundle

Esto nos mostrara un asistente para generar nuestro bundle:

Bundle Namespace: Openerp/ConnectBundle
Bundle Name: ConnectBundle
Target directory: Pulsamos enter (valor por defecto)
Configuration format: yml
Do you want to generate the whole directory structure?: pulsamos enter (valor por defecto)
Do you confirm generator?: pulsamos enter (valor por defecto)
Confirm automatic update of your kernel?: Pulsamos enter (valor por defecto)

Si vamos a la carpeta src de nuestro proyecto, podremos ver como se ha generado el nuevo Bundle, OpenERP.

connect

2.2. Generar entidad datos OpenERP

Una opción de configuración que podemos utilizar para no tener que introducir los datos de conexión en cada acceso, es generar una entidad de conexión a OpenERP para almacenar los parámetros de conexión. Una entidad es un fichero php que se encarga de interactuar con la base de datos de nuestro proyecto.

Para generar esta entidad debemos ejecutar en el directorio de nuestro proyecto Symfony el siguiente comando:

$ php app/console doctrine:generate:entity

Esto nos mostrara un asistente para generar nuestra entidad:

The Entity shortcut name: ConnectBundle:OpenERP
Configuration format (yml, xml, php, or annotation) [annotation]: pulsamos enter 

New field name (press  to stop adding fields): server
Field type [string]: pulsamos enter
Field length [255]: 100

New field name (press  to stop adding fields): bda
Field type [string]: pulsamos enter
Field length [255]: 100

New field name (press  to stop adding fields): username
Field type [string]: pulsamos enter
Field length [255]: 100

New field name (press  to stop adding fields): password
Field type [string]: pulsamos enter
Field length [255]: 255

New field name (press  to stop adding fields): pulsamos enter

Do you want to generate an empty repository class [no]? No 

Do you confirm generation [yes]? Yes

Con esto ya hemos generado el código de nuestra endidad, el cual podremos ver en la carpeta Entity de nuestro bundle.

Si queremos mapear esta entidad con nuestra base de datos, debemos ejecutar el siguiente comando en la consola:

$ php app/console doctrine:schema:create

Una vez creada la entidad, podemos crear datos de conexión para nuestra entidad mediante el phpmyadmin indicando la url de nuestro servidor, la base de datos a la cual nos vamos a conectar, el usuario y la contraseña.

2.3. Generar controlador OpenERP

Un controlador es un fichero que incluye la funcionalidad de nuestro bundle. Normalmente un controlador accede a la entidad de nuestro bundle, para acceder a la información de nuestra base de datos, y devuelve una vista, que muestra en pantalla esta información. Vamos a generar un controlador nuevo para conectar a OpenERP.

El primer paso sería descargar la liberia de conexion a OpenERP de la siguiente url https://github.com/tejastank/openerp-php-connector e incluirla en la carpeta controller de nuestro bundle.

require_once __DIR__.'/openerp/openerp.class.php';

En este ejemplo la libreria de conexión a OpenERP se ha guardado en la carpeta openerp del controlador.

Con todo esto, podemos desarrollar nuestra conexión simple mediante el siguiente controlador:

<?php
    namespace OpenerpConnectBundleController;

    use SymfonyBundleFrameworkBundleControllerController;
    use OpenerpConnectBundleEntityOpenerp;
    use SymfonyComponentHttpFoundationRequest;

   require_once __DIR__.'/openerp/openerp.class.php';

   class DefaultController extends Controller
   {

       public function indexAction($name)
        {
           return $this->render('ConnectBundle:Default:index.html.twig', array('name' => $name));
       }

       public function loginAction(Request $request)
       {

           $openerp = new Openerp();
           $form = $this->createFormBuilder($openerp)
             ->add('username', 'text')
             ->add('password', 'password')
             ->getForm();

           if ($request->isMethod('POST')) 
           {
                $form->bind($request);
              if ($form->isValid()) 
              {
                    $em = $this->getDoctrine()->getManager();
                    $shop = $em->getRepository('ConnectBundle:Openerp')->findOneBy(array('id' => 1));
                 $rpc = new OpenERP();
                 $uid = $rpc->login($shop->getUsername(), $shop->getPassword(), $shop->getBda());
                 $name = $rpc->read(array($uid), array('name'), 'res.users');
                 return $this->render('ConnectBundle:Default:welcome.html.twig', array(
                    'name' => $name[0]['name'],));
              }
           }
          return $this->render('ConnectBundle:Default:login.html.twig', array(   
          'form' => $form->createView(),
            ));
       }
    }

Este controlador genera un formulario simple para introducir el usuario y contraseña de un usuario de OpenERP. Una vez validado el formulario, busca el nombre del usuario que se ha conectado y devuelve una página con el mensaje “Bienvenido” mas el nombre de este usuario.

Las vistas para este controlador son las que se devuelven en el return:

return $this->render('ConnectBundle:Default:login.html.twig', array('form' => $form->createView(),));
return $this->render('ConnectBundle:Default:welcome.html.twig', array('name' => $name[0]['name'],));

Y se deben crear en la carpeta Resources/views del bundle, conteniendo el siguiente código:

<!-- login.html.twig -->
<form action="{{ path('portada')}}" method="post" {{ form_enctype(form)}}>
{{ form_widget(form)}}
<input type="submit"/>
</form>
<!-- welcome.html.twig -->
<h1>Bienvenido {{ name}}</h1>

Por último, hay que crear el path del controlador. Para ello hay que añadir las siguientes líneas en el fichero routing.yml que se encuentra en la carpeta app/config de nuestro proyecto:

portada:
path: /
defaults: { _controller: ConnectBundle:Default:login}

Ahora si accedemos a 192.168.0.122/symfony/web/app_dev.php podremos ver nuestro formularío de acceso.

Con todo esto hemos conseguido generar un bundle de conexión a OpenERP que puede ser incluido en otros bundles facilitando con esto acceder a los datos de OpenERP.

3. Conexión OpenERP con Symfony

Symfony funciona como un servicio rest, el cual nos permite acceder a la información mediante una url que accede a un método definido en un controlador. A continuación veremos un ejemplo de como conectar OpenERP con Symfony.

En primer lugar vamos a crear un módulo de OpenERP que genere una vista con un boton que nos permita enviar todos los productos de nuestro sistema a Symfony.

Definimos la clase:

class symfony(osv.osv_memory):
 _name = 'symfony'
symfony()

Con su vista asociada:

<?xml version="1.0" encoding="UTF-8"?>
    <openerp>
        <data>
            <record id="sync_products_form" model="ir.ui.view">
                <field name="name">sync.products.form</field>
                <field name="model">symfony</field>
                <field name="type">form</field>
                <field name="arch"type="xml">
                    <form string = "Sync Products">
                        <button name="sync_products" string="Sync" type="object" icon="gtk-apply"/>
                    </form>
                </field>
           </record>
         <record id="action_sync_products" model="ir.actions.act_window">
              <field name="name">Sync Products</field>
              <field name="type">ir.actions.act_window</field>
              <field name="res_model">symfony</field>
              <field name="view_type">form</field>
              <field name="view_mode">form</field>
              <field name="view_id" ref="sync_products_form"/>
              <field name="target">new</field>
          </record>
          <menuitem id="menu_sync_product" name="Sync Products"
          parent="stock.menu_stock_product" sequence="6"
          action="action_sync_products"/>
      </data>
    </openerp>

Y el metódo de sincronización:

def sync_products(self, cr, uid, ids, context = None):
   product_obj = self.pool.get("product.template")
      product_ids = product_obj.search(cr, uid, [], context = context)
   products = []

   for product in product_obj.browse(cr, uid, product_ids, context = context):
       product_dict = {}
        product_dict['name'] = product.name
                product_dict['list_price'] = product.list_price
                product_dict['standard_price'] = product.standard_price
                product_dict['description'] = product.description
                products.append(product_dict)

    products_json = json.dumps(products)
    url = "http://192.168.0.122/symfony/web/app_dev.php/get_products"
        f = urllib2.urlopen(url, products_json)
    response = f.read()
    f.close()

Como podemos observar el método recupera todos los productos que tenemos en el sistema, los codifica en json y los envia al controlador get_products.

El siguiente paso seria definir este controlador en nuestro sistema Symfony:

public function get_productsAction()
{
    $em = $this->getDoctrine()->getManager(); 
    $products = json_decode($this->get('request')->getContent(), true);
        foreach ($products as $p)
       {
        $product = new Product();
                $product->setName($p['name']);
                $product->setListPrice($p['list_price']);
                $product->setStandardPrice($p['standard_price']);
                $product->setDescription($p['description']);
                $em->persist($product);
   }
   $em->flush();
      return new Response("ok");
}

Y añadirlo a nuestro routing.yml:

getProducts:
    path: /get_products
    defaults: { _controller: ConnectBundle:Default:get_products}

Como podemos observar en el código de nuestro controlador, existe una nueva entidad llamada Product que es la que se encarga de almacenar los productos. Para generarla utilizaremos la consola de Symfony:

$ php app/console doctrine:generate:entity

The Entity shortcut name: ConnectBundle:Product
Configuration format (yml, xml, php, or annotation) [annotation]: 
pulsamos enter

New field name (press  to stop adding fields): name
Field type [string]: 
pulsamos enter

Field length [255]: 
pulsamos enter

New field name (press  to stop adding fields): list_price
Field type [string]: decimal

New field name (press  to stop adding fields): standard_price
Field type [string]: decimal

New field name (press  to stop adding fields): description
Field type [string]: text

New field name (press  to stop adding fields): 
pulsamos enter

Do you want to generate an empty repository class [no]? 
pulsamos enter

Do you confirm generation [yes]? 
pulsamos enter

Por último, actualizamos el esquema de nuestra base de datos.

$ php app/console doctrine:schema:update --force

Con esto ya podemos ejecutar nuestro módulo de OpenERP y realizar la conexión que nos importara todos los productos.

productos

4. Conclusiones

Como hemos podido observar en este artículo, la conexión a OpenERP con Symfony es muy sencilla. Debemos incluir la librería de conexión de php a OpenERP en un nuevo bundle de conexión. Este nuevo bundle podra ser incluido en otros bundles facilitando con esto el acceso de Symfony a OpenErp.

En cuanto a la conexión de OpenErp con Symfony, también hemos podido comprobar que es bastante sencilla ya que Symfony actua como un servicio rest muy facil de acceder. Simplemente debemos llamar desde OpenErp al método de Symfony que queramos acceder.

En resumen, generar un nuevo proyecto web con Symfony que acceda a OpenERP es muy sencillo, lo cual nos permite generar proyectos como tiendas online mediante el respaldo de OpenERP.

5. Bibliografia

Symfony 2.3, el libro oficial.

http://librosweb.es/symfony_2_3/

Desarrollo web ágil con Symfony2
http://symfony.es/noticias/2013/08/27/desarrollo-web-agil-con-symfony-2-3/

Integración Django-CMS y REST Framework

1. SISTEMAS

Xubuntu-12.04.3-desktop-i386

2. INSTALACION DJANGO-CMS

2.1 Instalando requerimientos de Django-CMS (todos los requerimientos):

$ sudo apt-get install python2.7
$ sudo apt-get install python-pip
$ sudo pip install django-cms south

Debemos obtener algo tal que así:

Successfully installed django-cms south Django django-classy-tags html5lib django-mptt django-sekizai six
Cleaning up...

Asegurarnos de que no falta ningún requerimiento.

Creamos un proyecto de prueba y vemos que todo funciona correctamente, para ello

 $ cd ~/workspace
 $ django-admin.py startproject myproject
 $ cd myproject
 $ python manage.py runserver

Probamos que se está escuchando redireccionando 127.0.0.1:8000

django-cms-introduction

2.2 Instalar y configurar POSTGRES

Primero instalar Postgres y PGadmin

$ sudo apt-get install postgresql pgadmin3

Continuamos instalando el Driver de la base de datos

$ sudo apt-get install python-psycopg2

Creamos el usuario Postgres

developer@developer-VirtualBox:~$ sudo su postgres -c psql

psql (9.1.3)
Type "help" for help.
postgres=# ALTER USER postgres WITH PASSWORD 'your_password';

A continuación en el sistema operativo:

$ sudo passwd -d postgres
$ sudo su postgres
$ passwd

Reiniciamos el servicio y comprobamos que todo va bien:

developer@developer-VirtualBox:~$ sudo /etc/init.d/postgresql restart
* Restarting PostgreSQL 9.1 database server [ OK ]

Configurar postgres añadiendo al archivo pg_hba.conf esta configuración:

$ sudo gedit /etc/postgresql/9.1/main/pg_hba.conf

Añadir esta lí­nea al final del archivo:

local all all md5

Finalmente se volverá a  reinicar postgres

$ sudo /etc/init.d/postgresql restart

A continuación creamos el usuario propietario de la base de datos de django_cms

$ sudo -u postgres createuser --createdb --no-superuser --no-createrole --pwprompt django
$ sudo -u postgres psql -d postgres
$ postgres=# ALTER USER django WITH PASSWORD 'django_password';

A continuación la base de datos con el propietario creado

postgres=# CREATE DATABASE django_cms OWNER django;
postgres=# q

Ya sería posible añadir al archivo settings.py del CMS todo lo relativo a la base de datos que va a utilizar:

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_p$
'NAME': 'django_cms', # Or path to database file i$
'USER': 'django', # Not used with sqlite3.
'PASSWORD': 'django_password', # Not used with sqlite3.
'HOST': '192.168.0.122', # Set to empty string for 192.168.0.122. N$
'PORT': '', # Set to empty string for default. Not$
 }

2.3 Configurar Django-CMS

Modificamos la cabecera del archivo settings.py

# -*- coding: utf-8 -*-
 import os
 gettext = lambda s: s
 PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))

Añadimos las siguientes aplicaciones a la sección INSTALLED_APPS:

INSTALLED_APPS = (
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'cms',
 'mptt',
 'menus',
 'south',
 'sekizai',
 'django.contrib.admin',
 # Uncomment the next line to enable admin documentation:
 # 'django.contrib.admindocs',
 )

También añadimos los plugins que sean necesarios:

-'cms.plugins.file'
 'cms.plugins.flash'
 'cms.plugins.googlemap'
 'cms.plugins.link'
 'cms.plugins.picture'
 'cms.plugins.snippet'
 'cms.plugins.teaser'
 'cms.plugins.text'
 'cms.plugins.video'
 'cms.plugins.twitter'

Por tanto, la sección de aplicaciones instaladas para el CMS quedaría tal que así:

INSTALLED_APPS = (
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'cms',
 'mptt',
 'menus',
 'south',
 'sekizai',
 'django.contrib.admin',
 'cms.plugins.file',
 'cms.plugins.flash',
 'cms.plugins.googlemap',
 'cms.plugins.link',
 'cms.plugins.picture',
 'cms.plugins.snippet',
 'cms.plugins.teaser',
 'cms.plugins.text',
 'cms.plugins.video',
 'cms.plugins.twitter',
# Uncomment the next line to enable admin documentation:
 # 'django.contrib.admindocs',
 )

Añadir las clases que hacen de Middleware:

MIDDLEWARE_CLASSES = (
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.doc.XViewMiddleware',
 'django.middleware.common.CommonMiddleware',
 'cms.middleware.page.CurrentPageMiddleware',
 'cms.middleware.user.CurrentUserMiddleware',
 'cms.middleware.toolbar.ToolbarMiddleware',
 'cms.middleware.language.LanguageCookieMiddleware',
 )

y de procesadores:

TEMPLATE_CONTEXT_PROCESSORS = (
 'django.contrib.auth.context_processors.auth',
 'django.core.context_processors.i18n',
 'django.core.context_processors.request',
 'django.core.context_processors.media',
 'django.core.context_processors.static',
 'cms.context_processors.media',
 'sekizai.context_processors.sekizai',
 )

Referenciamos los futuros archivos estáticos, y no olvidar crear dicho directorio en el proyecto con permiso de escritura

STATIC_ROOT = os.path.join(PROJECT_PATH, "static")
STATIC_URL = "/static/"

Los mismo para los archivos multimedia:

MEDIA_ROOT = os.path.join(PROJECT_PATH, "media")
MEDIA_URL = "/media/"

De igual forma en lo relativo al directorio que contendrá los Templates:

TEMPLATE_DIRS = (
 # The docs say it should be absolute path: PROJECT_PATH is precisely one.
 # Life is wonderful!
 os.path.join(PROJECT_PATH, "templates"),
 )

Añadimos un template en la configuración:

CMS_TEMPLATES = (
 ('template_1.html', 'Template One'),
 )

Creamos dicho template a partir de un template base:

base.html

{% load cms_tags sekizai_tags %}
 <html>
 <head>
 {% render_block "css" %}
 </head>
 <body>
 {% cms_toolbar %}
 {% placeholder base_content %}
 {% block base_content %}{% endblock %}
 {% render_block "js" %}
 </body>
 </html>

template1.html

{% extends "base.html" %}
 {% load cms_tags %}
{% block base_content %}
 {% placeholder template_1_content %}
 {% endblock %}

Sincronizar la base de datos y crear usuario administrador de Django:

sincronizacion django

 

3. Django-Rest Framework

3.1 Instalación

 $ sudo pip install djangorestframework
 $ sudo pip install markdown # Markdown support for the browsable API.
 $ sudo pip install django-filter # Filtering support

A continuación, añadir al settings la aplicación rest-framework

INSTALLED_APPS = (
 ...
 'rest_framework',
 )

Añadir los permisos, en mi caso decidí no añadir los hyperlinked por un problema que tuve así que quedaría tal que así:

REST_FRAMEWORK = {
 # Use hyperlinked styles by default.
 # Only used if the `serializer_class` attribute is not set on a view.
 #'DEFAULT_MODEL_SERIALIZER_CLASS':
 # 'rest_framework.serializers.HyperlinkedModelSerializer',
# Use Django's standard `django.contrib.auth` permissions,
 # or allow read-only access for unauthenticated users.
 'DEFAULT_PERMISSION_CLASSES': [
 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
 ]
 }

Configurar el archivo urls.py obteniendo finalmente la url por defecto del cms, la de administrador /admin, y la escucha en /rest

urls.py

 from django.conf.urls.i18n import i18n_patterns
 from django.contrib import admin
 from django.conf.urls import patterns, url, include
 from django.contrib.auth.models import User
 from rest_framework import routers,viewsets
 from django.conf import settings
admin.autodiscover()
urlpatterns = i18n_patterns('',
 url(r'^admin/', include(admin.site.urls)),
 url(r'^', include('cms.urls')),
 )
# ViewSets define the view behavior.
 class UserViewSet(viewsets.ModelViewSet):
 model = User
router = routers.DefaultRouter()
 router.register(r'users', UserViewSet)
# Wire up our API using automatic URL routing.
 # Additionally, we include login URLs for the browseable API.
 urlpatterns += patterns('',
 url(r'^rest/', include(router.urls)),
 url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
 )
if settings.DEBUG:
 urlpatterns = patterns('',
 url(r'^media/(?P<path>.*)$', 'django.views.static.serve',
 {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
 url(r'', include('django.contrib.staticfiles.urls')),
 ) + urlpatterns

Podemos comprobar el web-service 192.168.0.122:8000/rest

rest-example

3.2 Explotación del Servicio REST

En caso de no disponer del comando curl lo instalamos

$ sudo apt-get install curl

Por último hacemos la prueba, enviando una parte de un formulario y utilizando el usuario administrador de django_cms que creamos previamente:

curl -X POST -H "Content-Type: application/json" -d '
 {
 "username": "PedroOERP",
 "password": "password"
 }' -u usuario:password http://127.0.0.1:8000/rest/users/

Y este sería el resultado del método GET

rest-get-example

 

 

4. LINKS:

Django
http://django-cms.readthedocs.org/en/latest/getting_started/tutorial.html

Rest
http://django-rest-framework.org/

Nuevo proyecto de ZOOOK esale

Instalación de Django y ZOOOK

ZOOOK es una aplicación de Django, pero no es compatible con la versión 1.5, por lo que lo primero que habrá que hacer es instalar la versión 1.4. Se puede instalar ejecutando:

$ sudo pip install django==1.4

En el manual anterior se instalaban todas las dependencias de forma manual, en este se va a utilizar el instalador del proyecto para instalar todas las dependencias. Para descargar e instalar el proyecto:

$ bzr branch lp:zoook-esale/6.1 django-zoook
$ cd django-zoook
$ sudo python setup.py install

Para poder ejecutar ZOOOK será necesario crear la base de datos con su acceso y configurarlo, para que Django cree los datos necesarios.

Se crea el usuario con acceso a la base de datos:

$ sudo -u postgres createuser --createdb --no-superuser --no-createrole --pwprompt zoook

Se crea la base de datos para este usuario:

$ sudo -u postgres psql -d postgres
postgres=# CREATE DATABASE dj_zoook OWNER zoook;
postgres=# q

Por último habrá que configurar ZOOOK, para esto hay que editar el fichero config.py.

Indicar la base de datos:

DATABASES = { 
 'default': { 
 'ENGINE': 'django.db.backends.postgresql_psycopg2', 
 'NAME': 'dj_zoook', 
 'USER': 'zoook', 
 'PASSWORD': 'zoook', 
 'HOST': '192.168.0.122', 
 'PORT': '5432', 
 } 
}

La configuración de OpenERP:

OERP_CONF = { 
 'username':'admin', 
 'password':'admin', 
 'dbname':'openerp', 
 'protocol':'xmlrpc', #xmlrpc 
 'uri':'http://192.168.0.122', #xmlrpc 
 'port':8069, #xmlrpc 
}

En el fichero de configuración se indica la posibilidad de utilizar pyro, pero esta opción no está disponible en OpenERP 6.1

Se puede configurar los idiomas para la web:

LANGUAGE_CODE = 'es' 
LANGUAGES = ( 
 ('en', ugettext('English')), 
 ('es', ugettext('Spanish')), 
) 
DEFAULT_LANGUAGE = 1 
LOCALE_URI = True 
LOCALEURL_USE_ACCEPT_LANGUAGE = True 
LOCALES = { 
 'en':'en_US', 
 'es':'es_ES', 
}

En la configuración se indica también la o las tiendas de OpenERP a las que tiene acceso la web, se indica el identificador interno.

OERP_SALE = 1 #Sale Shop. All price, orders, ... use this Sale Shop ID. 
OERP_SALES = [1] #Sale Shops. Orders by Sale Shops

Por último se puede indicar la configuración para el envío de correos

EMAIL_USE_TLS = True 
EMAIL_HOST = 'smtp.gmail.com' 
EMAIL_HOST_USER = 'myemailuserXXX' 
EMAIL_HOST_PASSWORD = 'mypasswordXXX' 
EMAIL_PORT = 587

Antes de ejecutar por primera vez la aplicación será necesario crear el fichero de log y configurarlo.

Se puede crear por ejemplo, dentro de la carpeta django-zoook principal del proyecto, un directorio para log con un fichero zoook.log

$ mkdir log
$ touch log/zoook.log

En el fichero logconfig.py se indicará donde se encuentra este fichero en esta linea

LOGFILE = os.path.join(zoook_root, 'log', 'zoook.log') #path sync log

Una vez está todo configurado se pueden crear las tablas en la base de datos necesarias para ejecutar la web.

$ python manage.py syncdb

La primera vez que se ejecute syncdb creará un usuario de administración para Django, habrá que indicar el nombre de usuario y su contraseña.

Antes de arrancar la web habrá que configurar la tienda con:

$ ./configuration.py

Por ultimo se arranca la web con:

python manage.py runserver

En caso de error puede ser debido a la falta de algún módulo de django, se puede comentar en settings.py o instalarlo con pip.

Instalación de ZOOOK en OpenERP

Se instalará ZOOOK sobre OpenERP 6.1.

Para facilitar la instalación se han creado nuevos repositorios, uno con el propio ZOOOK y otro con los addons extra necesarios.

Para descargar los repositorios:

$ bzr branch lp:~zoook-community/zoook-esale/zoook-6.1 
$ bzr branch lp:~zoook-community/zoook-esale/zoook-extra-addons-6.1

La instalación de ZOOOK en OpenERP será igual que cualquier otro módulo, añadiendo los módulos descargados al addons_path, y desde el propio OpenERP actualizando la lista de módulos disponibles e instalando el módulo zoook. Importante al añadir en el archivo de configuración el extra-addons de zoook hacerlo antes del extra-addons genérico, con esto se consigue cargar los módulos de zoook antes.

Configuración de ZOOOK en OpenERP

Una vez instalado el módulo en Ventas/Configuración/Ventas/Tienda podemos configurar los parámetros de la tienda que se quiera sincronizar con ZOOOK.

zoook-OpenERP-01-tienda

Al marcar la opción OpenERP e-sale se podrán configura el resto de parámetros.

La conexión SSH será necesaria para sincronizar ZOOOK

En la solapa de acciones están los procesos para actualizar zook, exportar categorías, productos, imágenes y configuración global.

Para exportar el árbol de categorías, se indicará la categoría raíz en la solapa configuración y habrá que marcar como exportable cada categoría.