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

viernes, 31 de enero de 2014

Corregir Error Time Zone en Odoo (OpenERP 8.0)

Corregir el Error de la Zona Horario en Odoo (OpenERP 8.0)


    Se que muchos habrĆ”n notado que al crear registros despuĆ©s de las 6:00 PM los campos de Fecha/Fecha y Hora suelen cambiar para el siguiente dĆ­a, esto es debido a que el ORM de OPEN utiliza el tipo de fecha y hora llamado 'UTC' en base de Datos, para corregir este error tenemos que hacer lo siguiente:

Tenemos que corregir el Archivo fields.py

Este archivo se localiza en la ruta server/openerp/osv/fields.py

Dentro del Archivo buscar 'UTC' y reemplazarlo por 'SCT'


Nota: 

Esto se Repite con todas las coincidencias que encuentre en el editor en ese archivo fields.py

Adicional a esto es muy importante indicar nuestra zona horaria en la variable de este archivo:

utc = pytz.timezone('UTC')

Aqui debemos indicar la zona horaria de nuestra preferencia, por ejemplo:


utc = pytz.timezone('America/Mexico_City')

 Una vez hecho esto guardamos, reiniciamos el server de Odoo (OPENERP 8.0) Ć© intentamos nuevamente crear los Registros y vamos a poder observar que ahora se insertan correctamente los campos de Fecha y Hora.

lunes, 27 de enero de 2014

Crear Demonio de Arranque Odoo (OPENERP 8.0)

Hacer Funcionar Odoo (OPENERP 8.0) como un Servicio del Sistema

    Para que openerp-server pueda funcionar como un servicio de cualquier S.O. en Linux tenemos que entrar en la ruta:

/etc/init.d/

    Dentro de esta ruta debemos crear nuestro demonio le pondremos como nombre openerp-server-70 como referencia que es la versión 7.0 de OPENERP, y asĆ­ poder tener distintos demonios para versiones diferentes,  para crear el archivo usamos el comando:

sudo nano openerp-server

    Damos Ctrl+O y Enter para guardar el archivo ahora tendremos en la ruta /etc/init.d nuestro demonio openerp-server-70, como la siguiente imagen:


viernes, 24 de enero de 2014

Redes Sociales en nuestros Modelos en OpenERP 7.0 y Odoo (OpenERP 8.0)

Agregar Redes Sociales en OpenERP 7.0 y Odoo (OpenERP 8.0)



    Desde la Versión 7.0 de OpenERP podemos observar en el pie de cualquier formulario la parte de Redes Sociales que de alguna manera de da un Plus a cualquier modelo de datos, para que podamos tener esa aplicación al momento de crear nuestros módulos en OpenERP tendrĆ­amos que agregar en nuestras clases el código siguiente:

1.- En la declaracion de nuestra Clase OSV tendriamos que agregar la linea:

    _inherit = ['mail.thread', 'ir.needaction_mixin'] ### Redes Sociales
  

lunes, 20 de enero de 2014

ENTENTIENDO LOS WORLFLOWS EN ODoo (OPENERP)

WORKFLOWS (FLUJOS DE TRABAJO).


    Los flujos de trabajo pueden ser asociados a cualquier objeto en OpenERP, y son enteramente personalizables.

Se utilizan para estructurar, y gestionar los ciclos de vida de objetos, y documentos.
Definiendo transiciones, trigger (eventos), etc. etc. con herramientas grƔficas.
Como de costumbre, los flujos de trabajo, sus actividades (acciones o nodos), y sus transiciones (condiciones), se declaran como un fichero XML.

HERENCIA DE VISTAS Odoo (OPENERP)

HERENCIA DE VISTAS.

Igual que podemos heredar objetos, tambiƩn podemos heredar vistas de la siguiente manera:
<?xml version="1.0" encoding="UTF­8"?>
<openerp>
   <data>
<!­­--

id='res_partner_xxxxx_form_view_inh'
 
Este es el nuevo identificador que identifica a la vista que estamos  definiendo. Tener en cuenta que termina en 'form_view_inh', esto lo hacemos por norma, para identificar que esta vista, es una vista que
hereda De otra.
'name': Mismo nombre que el ID pero separado por '.'
'res.partner': Objeto al que pertenece la vista de la cuĆ”l estamos  heredando.
'inherid_id': AquĆ­ le indicamos el ID de la vista que estamos heredando. La '<carpetapadre> es la primera carpeta que se encuentra  en ADDONS, en la cuĆ”l se encuentra el fichero xml, en el que estĆ”
definida la vista.
-->

<record model="ir.ui.view" id="res_partner_form_view_inh">
      <field name="name">res.partner.form.view.inh</field>
      <field name="model">res.partner</field>
      <field name="type">form</field>
      <field name="inherit_id" ref="carpetapadre.idVistaPadre" />
      <field name="arch" type="xml">
 
         <field name="campoareemplazar" position="after">
 
                  <field name="nuevocampo" />
         </field>
         <notebook position="inside">
               <page string="Literal para la nueva pestaƱa">
                  <group col="2" colspan="2">
                        <separator string="Literal del separador" colspan="2"/>
                        <field name="nuevocampo2"/>
                        <field name="nuevocampo3" nolabel="1"/>
                  </group>
               </page>
         </notebook>
   </field>
   </record>
   </data>
</openerp>

RELACIONES ENTRE OBJETOS.

MANEJO DE CAMPOS RELACIONALES EN Odoo (OPENERP)


one2many (de uno a muchos).

Una relación de uno a muchos sería por ejemplo la relación entre autores y libros. Un autor puede tener escritos varios libros, y varios libros pueden pertenecer a un autor. La relación sería de 1 a N.

Ejemplo de definición de la clase autor:

class mybookstore_author(osv.osv):
   _name ='mybookstore.author'
   _description ='Autores'
   _columns= {
      'name': fields.char('Name', size=64, required="True"),
      'active': fields.boolean('Active'),
      'book_ids': fields.one2many('mybookstore.book', 'author_id', 'Books'),
   }

mybookstore_author()

Atributos en Formularios de Odoo (OPENERP)

ATRIBUTOS DEL ELEMENTO DE FORMULARIO <FIELD>


attrs (condiciones de solo lectura, invisible, y requerido).

Cuando definimos un atributo 'attr' a un campo <field>, estamos definiendo una condición.

          Las condiciones que podemos definir es que el campo sea solo de lectura, requerido, o invisible.
Supongamos que tenemos definido en nuestro archivo de Phyton una clase con los siguientes campos:

'historial': fields.boolean('Historial', help="Marque casilla si historial"),
'historial_desc': fields.char('Description', size=64),

Y en la vista, esta es la definición de los campos:

<field name="historial"/>
<field name="historial_desc" attrs="{'invisible': [('historial, '=', False)]}"/>

El campo 'historial_desc' serĆ” invisible si el campo 'historial' (booleano) es igual a 'False'.

on_change (trigger que ejecuta una función cuando el valor del campo cambia).


    Cuando el valor del 'field' cambia, automĆ”ticamente ejecuta la función que definamos en el atributo 'onchange'. La funcion 'onchange' SIEMPRE DEVUELVE EL PARAMETRO 'value'.

Ejemplo:

<field name="historial"/>
<field name="historial_des" on_change="onchange_historial_des(historial_desc)"     attrs="{'invisible': [('historial', '=', False)]}"/>

Cuando el valor del campo 'onchange_historial_desc'. 'historial_desc' cambie, ejecutaremos la función :

def onchange_historial_desc(self, cr, uid, ids, historial_desc, context={}):
    res = {}
    for xxxx in self.browse(cr, uid, ids):
            res = {
                'historial_desc': (xxxx.historial_desc or '') + _('\n') +  (historial_desc or ''),
            }
        return {'value': res}

    En esta primera opción, no estoy haciendo caso al parĆ”metro 'historial_des', ya que en este campo no viene un ID, sino un texto. Por lo tanto, hago referencia al parĆ”metro de entrada 'ids'.

Opción 2 de la función:

def onchange_historial_des(self, cr, uid, ids, historial_id, context={}):
    res = {}
    if historial_id:
       xx_obj = self.pool.get('xxxx')
       xx = xxxx_obj.browse(cr, uid, historial_id)
       res = {
                'historial_des': (xxxx.historial_desc or '') + _('\n') +  (historial_des or ''),
          }
       return {'value': res

Como Funciona la Herencia en Odoo (OpenERP)


HERENCIA DE CLASES Y METODOS Odoo (OPENERP)

_inherit (Herencia de objetos).

    Al hacer referencia a este atributo, hacemos referencia a la HERENCIA. Un hijo hereda
todos los campos, y funciones de su padre.

Ejemplo: 

    Como todos sabemos, existe una clase que se llama “res.partner”. En el siguiente ejemplo vamos a crear una nueva clase que herede de “res.partner”. A esta nueva clase le aƱadiremos 2 Campos uno para Identificar que elementos de "res.partner" (Clientes/Proveedores) tienen facebook y cual seria el facebook de dichos registros:

 Esta serĆ­a la declaración de la nueva clase:

class res_partner(osv.osv):

<!--­­ Aqui indico el atributo 'name' del Objeto Padre ­­-->

_inherit ='res.partner'
     
<!--­­ Nuevo campo que voy a aƱadir al Objeto res.partner ­­-->
   
_columns= {
    'facebook': fields.boolean('Facebook'),
    'facebook_description': fields.boolean('URL Facebook'),
}
 
res_partner()

 Heredar funciones, y llamar a funciones padre con SUPER.

     A veces nos puede interesar heredar una función de una clase, para poder modificarla. Vamos a poner como ejemplo la función 'onchange_xxxxx' que estĆ” definida en la clase 'mi.clase'.

       Esta función se ejecuta cada vez que cambiemos el id de “mi.clase”, asĆ­ que imaginemos que queremos cambiar el funcionamiento de dicha función. Teniendo en cuenta que en mi.clase existe la función onchange_xxxxx(self, cr, uid, ids, part), vamos a ver el siguiente ejemplo:

class mi_clase(osv.osv):

    <!--­­ HEREDAMOS DE LA CLASE ­­-->

    _inherit = 'mi.clase'

    <!--­­ DECLARAMOS OTRA VEZ LA FUNCIƓN QUE VAMOS A MODIFICAR --­­>
 
    def onchange_xxxxx(self, cr, uid, ids, part):
        value = {}
        miclase_obj = self.pool.get('mi.clase')

  <!­­-- LLAMAMOS A LA FUNCION PADRE ­­-->

  <!­­-- super(mi_clase,self): De esta manera llamamos a la función padre.   Hay que pasarle 2 parĆ”metro: la clase padre, y 'self' ­­ -->

        res = super(mi_clase, self).onchange_xxxxx(cr, uid, ids, part)
        value = res['value']
        if part:
            miclase = miclase_obj.browse(cr, uid, part)

<!--­­  Modificamos 'value', si en value existe 'client_order_ref'  modifica su valor, si no existe, lo crea  dentro de value  -->
            value.update({
               'client_order_ref': miclase.name,
            })
  <!­­ La función 'onchange' siempre devuelve un value ­­>

return {'value': value}
 
sale_order()

lunes, 13 de enero de 2014

Reglas en Odoo (OpenERP) utilizando campos Many2Many y One2Many



Reglas con Campos Many2Many y One2Many


    Durante la creación de Reglas para Grupos en OpenERP en ocasiones tenemos que utilizar  campos many2many ó one2many para comparar que un valor se encuentre dentro de una lista de valores.

    Por ejemplo cuando trabajamos en un entorno MulticompaƱia en OpenERP en ocasiones tenemos errores durante el manejo de Modelos que tengan Acceso a campos que utilicen la campos con referencia a compaƱƭa, por ejemplo si queremos la comprobación de que un elemento se encuentra dentro de una lista ó que un campo compaƱia se encuentre dentro del campo company_ids que se encuentra en Usuarios y que contiene una lista de compaƱias a las cuales el usuario puede tener acceso, tendrĆ­amos que agregar en la creación de regla el dominio siguiente:

[('company_id','in',[x.id for x in user.company_ids])]

 - company_id: Es el campo que encuentra en el modelo OpenERP al cual quiero ligar con mi regla.

 - in: Es el la palabra reservada para comparar que un elemento se encuentra dentro de una lista.

 - [x.id for x in user.company_ids]: En esta linea  utilizamos un poco de código Python para crear una lista con los valores para la comparación de mi dominio, x.id es el valor obtenido de un ciclo for utilizando una variable x para la iterar dentro de el campo user.company_ids que contiene la relación many2many con el modelo de compaƱia. Al Final nos quedarĆ­a en ejecución algo como lo siguiente [('10','in',[1,5,15,10,25,35,2])], esto da como resultado True o False depensiendo si el valor 10 se encuentra dentro de los valores 1, 5, 15, 10, 25, 35, 2. A este proceso se le conoce en Python como Listas de Comprensión 


jueves, 9 de enero de 2014

Manejo de Campos many2many en Odoo (OPENERP)

Manejo de Campos many2many 



    En OPENERP es muy comĆŗn que encontrĆ”semos en el código de algunos módulos la utilización de campos relacionales may2many, los cuales contienen la siguiente sintaxis:

(0, 0, { fields }) Crear nuevos registros con la lista de campos.
(1, ID, { fields }) Modificar la lista de campos.
(2, ID) Borrar un id de la relación many2many.
(3, ID) Quitar (desvincular) un id de la relación manay2many.
(4, ID) Vincular un id
(5, ID) Desvincular todas las veces que aparece un id
(6,?, IDS) Establecer una lista de enlaces

    Por ejemplo para enlazar los impuestos de un producto al crear una linea en pedidos de venta o en lineas de factura nuestros valores quedarĆ­an de la siguiente manera:

pedido_padre_id = 65
product_obj = self.pool.get('product.product')
product_id = product_obj.search(cr, uid, [('name','=','Soda 2.5 Litros')])
product_browse = product_obj.browse(cr, uid, product_id, context=None)[0]

 linea_venta = {
                'product_id'           :  product_browse.id,
                'product_uom_qty' :  1,
                'product_uom'     : product_browse.uom_id.id,
                'product_uos_qty' : 1,
                'price_unit'          : product_browse.list_price,
                'name'                 : product_browse.name,
                'type'                   : 'make_to_stock',
                'default_code'      : product_browse.default_code,
                'tax_id'                : [(6, 0, [x.id for x in line.product_id.taxes_id])],
                'order_id'             :  pedido_padre_id,
            })

 order_line_id = self.pool.get('sale.order.line').create(cr, uid, linea_venta, context=None)

   Que pasa en este ejemplo estoy creando una linea para el pedido de venta con el ID 65 en la cual estoy pasando la información del producto 'Soda de 2.5 Litros' hacia mi linea, el punto mas importante en este ejemplo ó la que estamos estudiando es  'tax_id' : [(6, 0, [x.id for x in line.product_id.taxes_id])], que estamos haciendo en esta parte del código, estamos enlazando los impuestos del producto anterior en mi linea de pedido, Ć©sto nos evita que nosotros realicemos la creación de cada impuesto al momento de mandar cada linea a un pedido de venta.