Programacion Interactiva

Descubre una Nueva y Poderosa Herramienta.

FrameWork de Nueva Generacion

Acceso a tu Informacion desde cualquier Dispositivo con Navegador.

Enfoque en el Backend

Frontend de forma facil con Odoo y XML.

Creacion de Verticales

Creacion de nuevas Verticales Conquistando nuevos Mercados.

Tu marca aqui mismo

Llega a miles de personas.

Publicidad

Mostrando las entradas con la etiqueta programacion odoo. Mostrar todas las entradas
Mostrando las entradas con la etiqueta programacion odoo. Mostrar todas las entradas

martes, 4 de julio de 2017

Consulta de Fecha Actual a traves de la API de Odoo

Consulta de la Fecha Actual utilizando Odoo


    La API de Odoo incorpora en la clase fields la posibilidad de manipular los valores de los campos de tipo fecha/fecha hora, lo cual podemos utilizar para poder consultar la fecha actual en la zona horaria que deseemos:

Fields - Date

  • context_today Retorna la Fecha en Zona horaria del Usuario.
  • today Retorna la fecha del Sistema Operativo en un String
  • from_string Retorna una fecha desde un string a una instancia datetime.date() 
  • to_string rCaso contrario, devuelve una fecha en formato de texto desde una instancia de Fecha datetime.date()
Ejemplos GrĆ”ficos
>>> from openerp import fields

>>> adate = fields.Date()
>>> fields.Date.today()
'2014-06-15'
>>> fields.Date.context_today(self)
'2014-06-15'
>>> fields.Date.context_today(self, timestamp=datetime.datetime.now())
'2014-06-15'
>>> fields.Date.from_string(fields.Date.today())
datetime.datetime(2014, 6, 15, 19, 32, 17)
>>> fields.Date.to_string(datetime.datetime.today())
'2014-06-15'

Fields - Datetime

Los valores disponibles para fecha Hora son los siguientes:
  • context_timestamp Retorna la fecha y hora en formato de Zona Horaria del Usuario.
  • now Retorna la fecha y hora del Sistema Operativo
  • from_string Retorna la fecha y hora en formato de texto desde una instancia datetime.date
  • to_string Retorna una instancia de fecha en formato datetime.date desde una fecha de Texto.
Ejemplos GrƔficos:
>>> fields.Datetime.context_timestamp(self, timestamp=datetime.datetime.now())
datetime.datetime(2014, 6, 15, 21, 26, 1, 248354, tzinfo=<DstTzInfo 'Europe/Brussels' CEST+2:00:00 DST>)
>>> fields.Datetime.now()
'2014-06-15 19:26:13'
>>> fields.Datetime.from_string(fields.Datetime.now())
datetime.datetime(2014, 6, 15, 19, 32, 17)
>>> fields.Datetime.to_string(datetime.datetime.now())
'2014-06-15 19:26:13'

lunes, 3 de julio de 2017

Mensaje de Confirmación en la ejecución de Botones

Mensaje de Confirmación en funciones ejecutadas desde una Vista



    En la definición de Botones de Tipo Objeto podemos aƱadir un nuevo atributo el cual nos pedirĆ” una segunda confirmación para desencadenar el proceso que hayamos programado, el atributo es muy sencillo y tiene por nombre confirm mas el mensaje que deseamos enviar al Usuario, el fragmento es el siguiente:


<button name="mi_metodo_odoo" type="object" string="Ejecutar 
Proceso" confirm="Estas Seguro que deseas pulsar este Boton?" />

El Resultado durante la ejecución es la siguiente:


Como podemos observar existe una doble validación del botón para poder evitar algún click por accidente, este tipo de advertencias podrÔn utilizarse en procesos clave de nuestros desarrollos.




viernes, 10 de junio de 2016

Generación de Codigos de Barra PDF417 con Python y la libreria Elaphe

Códigos de Barra PDF 417 con Elaphe y Odoo



Instalamos la libreia elaphe la cual sera nuestra herramienta principal en este ejercicio:

sudo apt-get install python-elaphe

Si utilizamos el gestor de librerias Pip:

sudo pip install elaphe

Como cualquier otra libreria necesitamos importarla en nuestro codigo:
>>> from elaphe import barcode

Un ejemplo completo utilizando elaphe y codigo de barras pdf 417:

from elaphe import barcode
bc = barcode('pdf417', "Bienvenidos a poncesoft.blogspot.com", options=dict(eclevel=2, compact=True, columns=2, rows=10), margin=1, scale=2)
bc.save('test.png')

El primer parĆ”metro de la función barcode es el tipo de código de barras a generar, el segundo es la cadena que convertiremos a  imagen utilizando código de barras

Otros códigos de barra que podemos implementar con la librerĆ­a elaphe son:

from elaphe import barcode
barcode('qrcode', 'Hello Barcode Writer In Pure PostScript.', options=dict(version=9, eclevel='M'), margin=10, data_mode='8bits').show()
barcode('code128', '^104^102Count^0990123456789^101!', options=dict(includetext=True), scale=2, margin=1).show()
barcode('pdf417', '^453^178^121^239', options=dict(columns=2, rows=10), margin=1, scale=2).show()
barcode('upc', '78858101497', options=dict(includetext=True), scale=2, margin=1).show()
barcode('royalmail', 'LE28HS9Z', options=dict(includetext=False), scale=2, margin=1).show()
barcode('datamatrix', '^142^164^186', options=dict(columns=32, rows=32), margin=1, scale=2.0).show()
barcode('code11', '0123456789', options=dict(includetext=True), scale=2, margin=1).show()
barcode('code25', '0123456789', options=dict(includetext=False, includecheck=False), scale=2, margin=1).show()
barcode('code39', 'THIS IS CODE39', options=dict(includetext=True), scale=2, margin=1).show()
barcode('code93', 'THIS IS CODE93', options=dict(includetext=True), scale=2, margin=1).show()
barcode('japanpost', '1231FZ13XHS', options=dict(includetext=False), scale=2, margin=1).show()
barcode('azteccode', '00100111001000000101001101111000010100111100101000000110', margin=1).show()
barcode('auspost', '5956439111ABA 9', options=dict(includetext=False), scale=2, margin=1).show()
barcode('ean13', '977147396801', options=dict(includetext=True), scale=2, margin=1).show()
barcode('interleaved2of5', '24012345678905', options=dict(includetext=True), scale=2, margin=1).show()
barcode('raw', '331132131313411122131311333213114131131221323', options=dict(includetext=True), scale=2, margin=1).show()
barcode('kix', '1231FZ13XHS', options=dict(includetext=False), scale=2, margin=1).show()
barcode('postnet', '012345', options=dict(includetext=True), scale=2, margin=1).show()
barcode('pharmacode', '117480', options=dict(includetext=True), scale=2, margin=1).show()
barcode('plessey', '012345ABCD', options=dict(includetext=True), scale=2, margin=1).show()
barcode('symbol', 'fimd', options=dict(includetext=True), scale=2, margin=1).show()
barcode('onecode', '0123456709498765432101234567891', options=dict(includetext=True), scale=2, margin=1).show()
barcode('maxicode', '^059^042^041^059^040^03001^02996152382802^029840^029001^0291Z00004951^029UPSN^02906X610^029159^0291234567^0291^0471^029^029Y^029634 ALPHA DR^029PITTSBURGH^029PA^030^062^004^063', options=dict(mode=2), margin=1, scale=4).show()
barcode('msi', '0123456789', options=dict(includetext=True), scale=2, margin=1).show()
barcode('rss14', '24012345678905', options=dict(linkage=True, includetext=True), scale=2, margin=1).show()
barcode('rationalizedCodabar', 'A012345

Implementación con Odoo

Para nuestros módulos bÔsicamente es lo mismo, pero nos apoyaremos de otras librerias que nos ayudaran a generar archivos en la partición temporal del sistema, primero importamos:

from elaphe import barcode
import os
import base64
import hashlib
import tempfile

Un ejemplo es el siguiente:
# Instanciamos el metodo principal barcode
bc = barcode('pdf417', "Bienvenidos a poncesoft.blogspot.com", options=dict(eclevel=2, compact=False, columns=2, rows=10), margin=1, scale=2)
# Generamos un nombre y ruta temporal
fname=tempfile.NamedTemporaryFile(suffix='.png',delete=False)
# Asigamos el nombre temporal a una variable
temporal_name = fname.name
# Guardamos nuestra imagen generada con elaphe y la ruta temporal
bc.save(fname.name)
# Podemos manipular la imagen ya generada
f = open(fname.name, "r")
data = f.read()
f.close()

jueves, 9 de junio de 2016

Trabajando con Symfony2 y Odoo (OpenERP)

Symfony2 & Odoo (OpenERP)



    Symfony es un completo framework diseƱado para optimizar, gracias a sus caracterĆ­sticas, el desarrollo de las aplicaciones web. Para empezar, separa la lógica de negocio, la lógica de servidor y la presentación de la aplicación web. Usa un entorno de desarrollo MVC (Modelo Vista Controlador) similar al Framework de Odoo, este framework se usa para el desarrollo de aplicaciones en PHP.

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.