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 api odoo. Mostrar todas las entradas
Mostrando las entradas con la etiqueta api odoo. Mostrar todas las entradas

miƩrcoles, 25 de octubre de 2017

Obtener ID en Metodos Onchange API Odoo

Obtener el ID del Registro que ejecuta un metodo Onchange


Anteriormente con OpenERP podriamos acceder a los parametros base de una forma facil ya que estos tenian estar implicitos en la declaración de los metodos en  cada una de nuestras clases, este panorama obtiene un cambio radical con la llegada de la nueva API, anteriormente podiamos acceder a los IDS del registro que ejecutaba un metodo onchange de forma facil, pero cambia en la programación con la API de Odoo.

Al ejecutar la siguiente instrucción en un metodo onchange:

self.id

Obtendremos:

<odoo.models.NewId object at 0x7fd5a8048ed0>

Esto en algĆŗn momento me ha llegado a limitar al realizar consultas o actualizaciones por Query duro, ya que es una instancia lo que estamos recibiendo y no un valor Numerico.

Existe una solución muy simple y es una variable del entorno de desarrollo de la API (Environment):

self._origin.id

La instrucción anterior nos dara el ID del Registro que esta ejecutando el metodo onchange.

viernes, 10 de marzo de 2017

Herencia de propiedades en Vistas Formulario

Recepción de Propiedades mediante el contexto Odoo de las Vistas Formulario


Una propiedad muy interesante en la programación Odoo es poder heredar propiedades, valores, etc.
Esto es posible gracias a un parametro heredable en todos los aspectos de Odoo (Funciones, Vistas, Acciones de Ventana. etc..) llamado context.

Existe una infinidad de usos que podemos darle al contexto de odoo, desde enviar una cantidad infinita de variables en este parÔmetro dentro de una función, hasta la posibilidad de heredar valores desde la vista formulario en campos relación.

Dentro de nuestro formulario podemos enviar valores al contexto como lo mencione anteriormente, por ejemplo en la relación de lineas de pedido (order_line_ids) enviare el Almacén del Pedido, esto lo haria en la vista de esta manera:

<field name="order_line_ids" context ="{'warehouse_id': warehouse_id} />

En este ejemplo el campo warehouse_id es necesario que exista en la vista de donde lo enviamos, acto seguido si definimos cualquier mƩtodo dentro del registro de ventas, podemos observar dentro del contexto el campo warehouse_id con el AlmacƩn del Pedido de Venta.



viernes, 2 de diciembre de 2016

Invocando Acciones en los Flujos de Odoo

Ejecutar una Transición de Estado con la API Odoo



    Para todos los que venimos de la programación con el Framework de OpenERP hacia la API de Odoo, observamos que todo es mas sencillo, se eliminaron pasos, parĆ”metros, etc., bueno  esto cambio tambiĆ©n en la invocación de flujos (workflow), ahora ejecutar la transición de un estado a otro en las clases que utilizan aĆŗn estos se realiza de la siguiente manera:

# -*- coding: utf-8 -*-

invoice_obj = self.env['account.invoice'].sudo()

invoice_br = invoice_obj.browse([id_factura])

invoice_br.signal_workflow('invoice_open')

La parte clave para ejecutar la transicion es el mĆ©todo signal_workflow propio de las clase principal models.Model de la API.

Anteriormente utilizĆ”bamos la herramienta netsvc de Odoo, la cual fue eliminada a partir de la versión Odoo 8.0


jueves, 7 de mayo de 2015

API ODOO: Metaclases y Decodarores

Implementación de la API de Odoo Utilizando Metaclases y Decoradores



API:

    API por sus siglas en Ingles Application Programming Interface ( Interfaz de Programación de Aplicaciones), es el conjunto de subrutinas, funciones y procedimientos (o mĆ©todos, en la programación orientada a objetos) que ofrece cierta biblioteca para ser utilizado por otro software como una capa de abstracción. Son usadas generalmente en las bibliotecas. Fuente: wikipedia.org

Metaclases:

    A metaclase puede definirse como   "Una clase de Clases". En programación orientada a objetos, una metaclase es una clase cuyas instancias son clases. En otras palabras, como los objetos son instancias de una clase, las clases son instancias de una metaclase.

Detalles para Implementar la API en sus Desarrollos:

 Odoo provee 2 formas de Implementar las Clases (Modelos), para la generación de Formularios, podrĆ­amos llamarlas como la forma "Tradicional" y a travĆ©s de "Recordsets". Un recordset es la instancia de una clase, con la referencia del registro en Base de Datos (ID).

    En la forma tradicional utilizamos siempre los parĆ”metros cursor de la base de datos (cr), id usuario (uid), un listado de los Registros (ids) y context, cada vez que definimos un MĆ©todo de la Clase. Utilizando el mĆ©todo por Recordsets mediante Decoradores, estos parĆ”metros estĆ”n ImplĆ­citos dentro de la API, aquĆ­ debemos comprender que si se trabaja con la API de Odoo, todo lo que sea retornado mediante los mĆ©todos del ORM siempre serĆ”n records.

Ejemplo con el Metodo Tradicional:

    modelo = self.pool.get(Modelo.) # Instanciamos una Clase (Modelo)
    ids = modelo.search(cr, uid, [Dominio con Condiciones para la Busqueda], context=context) 
    # Una funcion search con la forma Tradicional siempre Rertorna una lista de IDS
    for rec in modelo.browse(cr, uid, ids, context=context):
        print rec.name
    modelo.write(cr, uid, ids, {Diccionario de Valores a Actualizar}, context=context)

Ejemplo Utilizando la API de Odoo:

    env = env(cr, uid, context)         # cr, uid, context, implicitos en la instancia env
    recs = env[Modelo]                    # Instanciamos una Clase(Modelo) de Odoo
    recs = recs.search([Dominio con Condiciones para la Busqueda de Registros])          
   #  Una busqueda utilizando env y la API, siempre retornada una lista de Recordsets.
    for rec in recs:                             # Podemos recorrer cada record para poder trabajar con ellos.
        print rec.name
    recs.write({Diccionario de Valores a Actualizar})

Como pudimos observar, los parƔmetros tradicionales (cr, uid, ids, context) estƔn Implƭcitos al trabajar con la API de Odoo, algo que puede confundirnos es al momento de trabajar con Ambas.

Decoradores:

Los decoradores en Odoo, son utilizados para tratar de enviar los argumentos que el Sistema sabe que tiene que recibir de forma Obligatoria como el Ejemplo Anterior (cr, uid, ids, context).

Los Decoradores con la API Odoo, nos ayudan a Decorar las funciones tradicionales y a Implementar una nueva Funcionalidad.

Ejemplos:
    
1. @api.cr:

Para decorar funciones que siempre Reciben Como Parametro CR, utilizariamos este Decorador.

    # recs = modelo.browse(cr, uid, ids, context)
    recs.method(args)
    model.method(cr, args)

2. @api.cr_context:

Decoramos Funciones que utilizan siempre 'cr', 'context' como Parametros.
  
3. @api.cr_uid:

Decoramos Funciones que utilizan siempre 'cr', 'uid' como Parametros.

4. @api.cr_uid_context:

Decoramos Funciones que utilizan siempre 'cr', 'uid', 'context' como Parametros. 

    # recs = modelo.browse(cr, uid, ids, context)
    recs.method(args)

    modelo.metodo(cr, uid, args, context=context)

5. @api.cr_uid_id:

Decoramos Funciones que utilizan siempre 'cr', 'uid', 'ids' como Parametros. Podriamos utilizar un Decorador de este tipo para retornar siempre un Recordset sin tener que generar la instancia y pasar los Parametros.


6. @api.cr_uid_id:

Este Ejemplo seria el mas claro si estamos acostumbrados a definir funciones con OpenERP, en donde siempre eran requeridos los parametros 'cr', 'uid', 'id':

    @api.cr_uid_id
    def metodo(self, cr, uid, id, args, context=None):
        ...

7. @api.cr_uid_ids:

Este Decorador seria el mismo que el anterior solo que aquƭ se enviarƭa el parƔmetro IDS con un listado de Registros, en el anterior solo podrƭamos enviar un solo ID.

8. @api.cr_uid_ids_context:

Este Decorador como su nombre lo describe, recibe todos los parametros para poder generar Funciones. Recibe 'cr', 'uid', 'ids', 'context', parametros que siempre necesitamos para trabajar con Odoo.

Decoradores que utiliza la API de Odoo

1. @api.model:

Este Decorador solo genera una Instancia de una Clase en Odoo (Modelo). Su sintaxis es la siguiente:

    @api.model
    def metodo(self, args):
        ...



2. @api.one:

Este decorador sirve para poder obtener un recordset de la Clase, siempre que sea utilizado en un Metodo. Es equivalente a realizar un browse de una Clase de Odoo (self.browse(cr, uid, id, context=None) ), con este decorador podriamos obtener un valor de esa Clase simplemente con retornar self.campo_a_obtener. Su sintaxis es la siguiente:

    @api.one
    def metodo(self, args):
        return self.name

Con el MƩtodo Tradicional Seria:

    def metodo(self, cr, uid, id, context=None):
        inst = self.browse(cr, uid, id, context=None)
        return inst.name

3. @api.multi:

Este Decorador es similar al anterior, solo que aquĆ­ retorna un listado de recordsets. Su sintaxis es la siguiente:

    @api.multi
    def method(self, args):
        ...
       

En la forma tradicional seria definir un ciclo con el metodo Browse:
    
    def metodo(self, cr, uid, ids, context=None):
        for rec in self.browse(cr, uid, ids, context=None)
             print "#### Campo Name de cada Registro >>> ", rec.name
        return True

En la forma tradicional solƭamos obtener los ids a recorrer usando el mƩtodo Search.

4. @api.constrains:

Como podemos observar por su nombre, este decorador nos permite decorar funciones para crear Restricciones a la Inserción de Información, los llamados Constraints. Su sintaxis es la siguiente:

    @api.one
    @api.constrains('name', 'description')
    def _check_description(self):
        if self.name == self.description:
            raise ValidationError("Los Campos Nombre y Descripción no pueden ser los Mismos")

Para que quede claro, un ejemplo con la Forma tradicional:

    def _check_description(self, cr, uid, ids, context=None):
        for rec in self.browse(cr, uid, ids, context=None):
            if rec.name == rec.description:
                 return False
         return True

_constraints = [(_check_description, 'Error: Los Campos Nombre y Descripcion No pueden ser Iguales', ['name','description']), ] 

5. @api.onchange:

    Si has llegado a este Decorador ya tienes la idea de lo que ah tratado de hacer Odoo, que es tratar de Optimizar el Código enfocĆ”ndonos directamente en la lógica del requerimiento, sin tener que ser recurrentes con los parĆ”metros, este Decorador nos sirve para poder crear mĆ©todos on_change (MĆ©todos que se ejecutar al cambiar un Valor del Formulario en donde este asignado este Metodo).
Su sintaxis es la siguiente:

    @api.onchange('partner_id')
    def _onchange_partner(self):
        recs = env['res.partner']                    
        recs = recs.search([('parent_id','=',self.partner_id)]) 

        self.partner_id = recs[0].id

Observamos que ahora ya no es necesario retornar Valores en un diccionario del tipo {'value':{Campos a Actualizar}. Observamos que el Decorador recibe parĆ”metros, que en este caso son los campos que necesitamos para poder trabajar como es  'partner_id'.

Ejemplo con la forma Tradicional:
    def _onchange_partner(self, cr, uid, ids, partner_id, context=None):
          partner_id = self.pool.get('res.partner').search(cr, uid, [('parent_id','=',partner_id)], context)
          if partner_id:
               return {'value':{'partner_id': partner_id[0]}}
          return {}

     

6. @api.depends:

Este Decorador es utilizado para campos Calculados, o campos que requieran obtener un listado de valores:

    pname = fields.Char(compute='_compute_pname')

    @api.one
    @api.depends('partner_id.name', 'partner_id.is_company')
    def _compute_pname(self):
        if self.partner_id.is_company:
            self.pname = (self.partner_id.name or "").upper()
        else:
            self.pname = self.partner_id.name

7.@api.returns:

Decorador que permite retornar instancias de un Modelo. Sus sintaxis es:

    @model
    @returns('res.partner') # Modelo a Recibir
    def find_partner(self, arg):
        ...     # retorna algun recordset


Decoradores para Interactuar con los Nuevos estilos utilizando una version Tradicional.

1. @api.v7:

Este Decorador permite utilizar metodos de la Nueva API, generando Clases (Modelos) de la forma Tradicional. Su sintaxis es:

    @api.v7
    def foo(self, cr, uid, ids, context=None):
        ...

    @api.v8
    def foo(self):
        ...


Decoradores para Interactuar con el estilo Tradicional utilizando una version con la nueva API.

1. @api.v8:

    @api.v8
    def foo(self):
        ...

    @api.v7
    def foo(self, cr, uid, ids, context=None):
        ...

Espero que les pueda ayudar a comprender la nueva API, aun me faltan muchas cosas por Comprender que estarƩ subiendo.


miƩrcoles, 4 de marzo de 2015

Definicion de Clases Api Odoo

API Odoo



    Como todos sabemos Odoo anteriormente OpenERP, ah modificado su NĆŗcleo de desarrollo, ofreciendo nuevas alternativas para la creación de Módulos para este ERP, ahora trae a nosotros los modulos Website, que permiten integrar una e-shop, un sitio web, aƱadir temas, chat de contacto, etc.
Podemos observar tambiĆ©n modificaciones al Framework de Desarrollo de Módulos, una nueva Api que cambia el Aspecto del desarrollo, pero que es compatible con el Framework de la versión 7 de OpenERP,  mis proximas entradas seran con aspectos importantes de esta nueva Version.

Definición de Clases con la nueva API (Odoo)

Para la creación de una clase con la Api de Odoo se utiliza el código siguiente:

from openerp.osv import fields, osv
from datetime import datetime
import time


class mi_clase_odoo(osv.osv):
    _name = 'mi.clase.odoo'
    #Definicion de Campos
    name = fields.Char('Nombre del Alumno', required=True)
    date_act = fields.Date('Fecha')
    _defaults = {  
        'date_act': lambda *a: time.strftime('%Y-%m-%d'),  
        }
mi_clase_odoo()

En OpenERP 7 se crearía con el código:


from openerp.osv import fields, osv
from datetime import datetime
import time


class mi_clase_odoo(osv.osv):
    _name = 'mi.clase.odoo'
    #Definicion de Campos
    _description = 'Grupos'
    _columns = {
        'name':fields.char('Nombre', size=64), 
        'date_act': fields.date('Fecha'),
    }
    _defaults = {  
        'date_act': lambda *a: time.strftime('%Y-%m-%d'),  
        }
mi_clase_odoo()

Ambas formas son Validas en el desarrollo para Odoo, ya que tiene retrocompatibilidad con la definición de clases osv.osv.

Diferencias Odoo y OpenERP7:
  • La primer diferencia es la importación de las librerĆ­as, ahora importamos api y no osv.
  • Al definir la clase heredamos models.Model y en OpenERP osv.osv.
  • Para definir un campo en Odoo, ya no es necesario ingresarlo en un diccionario, ahora se define directamente, primer elemento nombre del campo y seguido del tipo de campo a definir, en OpenERP7 utilizamos el _columns{}.
  • Definir campos por defecto se utiliza de la misma manera.
Este es mi primer Aporte sobre la Api de Odoo, espero que sea de su agrado.

Restaurar Respaldo de Odoo desde Terminal (Archivos *.dump)

Creación y restauración de respaldo Odoo desde Terminal.


    Buenos dĆ­as lectores, gracias por los comentarios y los correos, espero que este Blog los haya sacado de algĆŗn problema, hoy vengo con una entrada similar a una ya escrita en mi blog, respecto al tema de Respaldar y Restaurar bases de Odoo desde una terminal, pero ahora con algunos cambios importantes, como es ignorar tablas.

Creación del respaldo


         ParĆ”metros:

  • -i

        -- ignore-version
        Se ignora la versión de la base de datos

  • -h

       -host
       Especifica el nombre del equipo en que corre el servidor.

  • -p

       -port
       Por defecto siempre usamos el puerto 5432 por el cual podemos acceder a PostgreSQL.

  • -U

       --username
       Usuario de Postgres para generar el backup, aqui debemos revisar el archivo .conf de Odoo, o podemos siempre utilizar el Usuario postgres que trae por defecto.


  • -F

       --format
       Seleccionar el Formato de salida.

  • -b

       --blobs
       Para incluir tablas muy extensas en el dump sin errores.

  • -v

       --verbose
       Permite crear los respaldos a detalle en el dump.

  • -f

       --file
       Enviar el respaldo a un Archivo X.dump

Ejemplo:

pg_dump -i -h localhost -p 5432 -U odoo -F c -b -v -f "/opt/odoo/backups/Odoo_Test.backup" Odoo_Test


Con el fragmento anterior creamos un archivo llamado "Odoo_Test.backup" en mi ruta /opt/odoo/backups, de la base de datos Odoo_Test.

Para excluir alguna tabla, como puede ser la tabla ir_attachment, que contiene los datos adjuntos que aumenta el tamaño de la Base de Datos, quedaría el siguiente código:

pg_dump -i -h localhost -p 5432 -U odoo -F c -b -v -f "/opt/odoo/backups/Odoo_Test.backup" Odoo_Test -T ir_attachment


Como vemos solo agregamos  -T y el nombre de la tabla.

Restauración de la Base de Datos

Para poder restaurar el archivo dump o backup, es necesario crear una Base de Datos en blanco utilizamos el comando:

sudo su postgres

Una vez dentro del prompt de Postgres ejecutamos el comando para la creacion de la Base:

createdb Odoo_Resturacion -O odoo

    createdb: Indicamos el nombre de la Base Nueva.
    -O: Indicamos el usuario postgres al que pertenecerĆ” la Base que estamos creando en PostgreSQL se conoce como Owner (Propietario).

Una vez creada la Base de Datos, ejecutamos el siguiente fragmento de código, para comenzar con la Restauración:

pg_restore -i -h localhost -p 5432 -U odoo -d Odoo_Restauracion -v "/opt/odoo/bakcups/Odoo_Test.backup"

    -d: Base de Datos para restaurar la Información
    -v: Especificamos la ruta del Archivo de Respaldo.

Con esto iniciara la restauración de nuestra base de Datos.