Openerp: campos función

Bien veamos esto de los campos función, un tipo función puede devolver todos los tipos de datos soportados por OpenERP desde un simple campo char hasta un tipo many2many y este se va a ejecutar siempre que se llame a las intancias de las clases, me explico si yo declaro un campo tipo función de tipo float que realiza un cálculo como un total de una factura por ejemplo pues cada vez que se requiera mostar dicho campo pues se va a ejecutar la función que lo calcula, lo mismo para campos tipos many2one y esto último es muy util por ejemplo cuando solo se tiene definido el campo tipo many2one en tus registros pero no uno many2one en el registro relacionado por ejemplo si yo quisiera saber las facturas de un cliente, pero lo que yo queiro saber son los detalles me refiero a que yo quiero que se muestren todos los productos que compró un cliente y los quiero tener en una pestaña pues puedo definir un campo función que devuelva eso y para ello vamos a hacer lo siguiente, invocar al método search de el objeto factura de venta y que me devuelva la lista de facturas del cliente X ya con eso hacer un bucle contra lo que devuelva el método browse de las facturas y sacar uno a uno los ids de las lineas del detalle de la factura y luego ponerlos en una lista y esta devolverla, con eso ya tenemos para nuestro campo, bien esa es la teoría, pero como vamos a hacerlo pues manos en el teclado y a crear código.

Para definir un campo función debes de tener en cuenta que tienen que estar definidos como todos los campos de openerp un campo tipo función simple es aquel que devuelve tipos sencillos como char, text, float, integer o boolean y no hay mucha dificultad en ello y se definen de esta manera:

‘total’:fields.function(totalizar,type=float,string=’Total’,store=True)

Bien ahora lo primero es el nombre de la función que se va a ejecutar, lo siguiente el tipo que se va a devolver y dependiendo del tipo de dato tenemos las propiedades que podemos trabajar así si devolvemos un tipo chart pues podemos definir el tamaño del campo (size=n), o en el caso de un float podriamos definir la presición decimal (digits=(x,y)) o usar una presición ya preestablecida y configurable con digits_compute=dp.get_precision(‘nombre presición’), el caso de one2many y many2many lo veo luego, ahora la propiedad “store” bien esto indica si el campo va o no a existir en la base de datos, si configuramos este a verdadero crea el campo en la tabla y lo contrario si es falso, pero tenga en cuenta que si se le marca en verdadero, este valor solo se va a recalcular cuando se llamen a los métodos write o create en otras palabras el valor no va a cambiar automáticamnete que si lo hace cuando el campo no se graba en la tabla.

veamos la definición de la función de nuestro campo “TOTAL” que asumo que esta en un objeto factura y que el campo de tipo one2many se llama line y que estetine un campo importe:

def totalizar(self, cr, uid, ids, field_name, arg, context= None):

result = {}

for factura in self.browse(cr,uid,ids,context)

total =0
for linea in factura.line:

total=total+linea.importe

result[factura.id]=total

return result

Con eso ya tengo mi campo función terminado, ahora vamos a complicarnos algo más vamos aun campo tipo one2many, bien no voy a inventar nada voy a copiar el código que tengo de una aplicación que hace lo siguiente la clase “account.analytic.account” que es la que maneja las cuentas analíticas de la contabilidad y que tambien es usada para manejar los contratos en ventas le adicioné un campo llamado sale_id que es de tipo many2one hacia la clase sale.order que son las ordenes de venta y quiero solo mostrar las líneas (el detalle de la venta) para ello creo un campo tipo función que me devuelva un one2many.

‘sale_id’:fields.many2one(‘sale.order’,’Cotizacion’, readonly=True)  #esa es la deficion del campo hacia las ordenes de venta
‘sale_lines_id’:fields.function(getdetails,type=’one2many’,relation=’sale.order.line’,string=’Servicios’,store=True)  # esta la definción para obtener las líneas fijense en atributo “relation” que apunta a la clase ‘sale.order.line’ es obligatorio indicarle al framework cunado se fenintipos many2one, one2many o many2many el atributo relation

Bien ahora la función:

def getdetails(self, cr, uid, ids, field_name=None, arg=None, context=None):

result = {}
if not ids: return result

for id in ids:

element=self.pool.get(‘account.analytic.account’).browse(cr,uid,id,context)

lista=[]

for linea in element.sale_id.order_line:

lista.append(linea.id)

result[id] = lista

return result

Como pueden ver lo que en realidad devuelve esta función es una lista de ids que corresponden a los ids de la clase sale.order.line.

Ahora un ejemplo mucho más complicado es el de los many2many y para ello tenemos un buen ejemplo en la clase “groups_implied” que se encuentra en módulo base de OpenERP y se define de esta forma:

‘trans_implied_ids’: fields.function(_get_trans_implied, type=’many2many’, relation=’res.groups’, string=’Transitively inherits’)

bien ahora la definción de la función:

def _get_trans_implied(self, cr, uid, ids, field, arg, context=None):

“computes the transitive closure of relation implied_ids”
memo = {} # use a memo for performance and cycle avoidance
def computed_set(g):

if g not in memo:

memo[g] = cset(g.implied_ids)
for h in g.implied_ids:

computed_set(h).subsetof(memo[g])

return memo[g]

res = {}
for g in self.browse(cr, SUPERUSER_ID, ids, context):

res[g.id] = map(int, computed_set(g))

return res

Pues creo con esto ya tenemos para hacer cualquier tipo de campo tipo funcion.

Acerca de

Antes que nada voy a dejar en claro algo, en este blog escribo como se me place, asi que no busquen errores de ortografia o de redaccion que los van a encontrar a montones y tampoco me critiquen o me digan nada sobre ellos pues no tengo intencion alguna de cambiarlos, lo que escribo lo dejo asi y no lo corrijo,claro esta a menos que sean lineas de codigo. Jorge Prado Anci, profesional en desarrollo de aplicaciones, en especial las dirigidas a bases de datos. He trabajado con VFP en casi todas sus versiones, se algo de Java (que no me gusta, es eso solo no me gusta, es bueno pero no me gusta), lo suficiente de PHP como para tener mi propio CMS(es que sigue sin gustarme por la capacidad de desorden que te permite este “lenguaje”), VB lo conoci y lo deteste tanto que lo olvide al punto de no querer adoptar ni por obligacion a su reemplazante VB .NET (por lo mismo de Java) y si C# este si me encanta y aun que conozco bastante bien el lenguaje, la verdad es que me falta mucho del Framework (del 100% estare en un 65%). Soy un apasionado por el orden (en los proyectos de desarrollo), de la programacion en capas (de MVC conozco pero no he aplicado mucho), los estandares y las condenadas pruebas unitaria. Venga creo que ya con esto fue suficiente.

Tagged with: , ,
Publicado en OpenERP

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Escribe tu dirección de correo electrónico para suscribirte a este blog, y recibir notificaciones de nuevos mensajes por correo.

Únete a otros 441 seguidores

Blog Stats
  • 304,391 hits
A %d blogueros les gusta esto: