Cálculo de edad en OpenERP (Odoo)

En algunos casos debemos autorellenar campos cuando se ingresa el valor de un campo padre, por así decirlo. Si se presenta el caso de generar o calcular la edad de una persona que se registra en el sistema mediante el ingreso de su fecha de nacimiento, se pueden usar varias formas, acá está un ejemplo sencillo que se pudiera usar para realizar dicha operación.

En el archivo xml se pueden tener los campos asociados a la edad con patrón parecido a lo siguiente:

<field name="fecha_nacimiento" string="Fecha de nacimiento" on_change="on_change_fecha_nac(fecha_nacimiento)"/>
<field name="edad" string="Edad"/>

Y en el archivo .py donde está la clase asociada a dicha vista xml, podemos usar un método parecido al siguiente:

def on_change_fecha_nac(self, cr, uid, ids, fecha_nacimiento, context=None):
    res = {}
    if fecha_nacimiento:
        edad = (datetime.now().date() - datetime.strptime(fecha_nacimiento, '%Y-%m-%d').date()).days / 365
        if edad < 0:
            edad = 0
        res = { 'edad': edad }
    return { 'value': res }

Cuando la persona que realiza el registro de la persona en el sistema carga la fecha de nacimiento, automáticamente se llenará el campo de la edad con la edad de dicha persona, igualmente, si se desea fijar una edad manualmente, el campo será de tipo char y deja esa opción abierta de modificar la edad.

Advertisements

About felixurbina

Humano con todos los defectos y virtudes que vienen de fábrica.
This entry was posted in Odoo, OpenERP. Bookmark the permalink.

35 Responses to Cálculo de edad en OpenERP (Odoo)

  1. Pingback: Mostrar advertencias en OpenERP (Odoo) | Satélite Guayana

  2. Gio says:

    Buen día, estoy haciendo un módulo parecido pero con salarios, en un formulario ingreso un salario mensual y que automaticamente se llene el salario diario, ¿Donde debo poner el onchange de la vista xml? ¿En el salario diario o del mensual?
    Gracias de antemano.

    • felixurbina says:

      Hola Gio.

      Si estás trabajando en la versión 7, debes colocar el on_change en el primer campo que se requiere, es decir, si para el cálculo del salario diario debes llenar previamente el campo de salario mensual, el on_change lo colocas en el campo de salario mensual, luego, el método del on_change hace el cálculo del salario diario y retorna el valor al campo correspondiente.

      También dependerá si ambos campos están en el mismo formulario, porque si no están, haces el on_change en el campo de salario mensual, y en lugar de retornar el resultado, lo insertas o lo actualizas en el registro del salario diario del registro del empleado en donde se desea insertar el salario diario.

      Saludos.

  3. Gio says:

    Al tratar de instalarlo me da un error:
    “IndentationError: unindent does not match any outer indentation level”

    Así definí la función:

    def on_change_month_wage(self, cr, uid, ids, month_wage, context=None):
    res = {}
    diary_wage = month_wage / 30
    res = {‘diary_wage’: diary_wage}
    return {‘value’: res}

    Así los puse en la vista xml:

    • felixurbina says:

      En python existe una indentación específica que interpreta el programa, tomando tu mismo código por ejemplo:

      def on_change_month_wage(self, cr, uid, ids, month_wage, context=None):
      res = {}
      diary_wage = month_wage / 30
      res = {‘diary_wage’: diary_wage}
      return {‘value’: res}

      A cada línea dentro del método, le agregas 4 espacio por línea al principio, tu márgen debe estar relacionado con el “def” de la declaración del método.

      Saludos.

    • felixurbina says:

      Por lo visto, tampoco se reflejó la indentación en mi respuesta anterior, bueno, el caso es que el error que te muestra, parece estar relacionado con la indentación. Es tener en cuenta que el margen izquierdo del comienzo de cada línea asociada al método, debe llevar 4 espacios, no tabulación, espacios.

  4. Gio says:

    ¿Donde estoy fallando?

  5. Gio says:

    Buen día bro, ya conseguí instalarlo y todo, pero cuando quiero guardar el registro me sale este error:

    “TypeError: on_change_month_wage() takes at most 6 arguments (7 given)”

    • felixurbina says:

      Qué tal Gio.

      Eso es porque en tu método estás incluyendo probablemente 6 argumentos de entrada y estás enviando 7 argumentos desde la vista.

      Si tienes:

      def metodo(self, cr, uid, ids, dato, context=None)

      En tu vista deberías enviar:

      on_change_campo(dato)

      Así cuando el método lee o captura los datos, solo debe capturar el campo que le estás pasando que sería “dato” en este ejemplo.

      Saludos.

  6. Juan says:

    Esta estupendo el articulo

    Me gustaría saber si quiero sacar también los días y semanas en el calculo como lo haría?

    ejemplo: 30 años 3 semanas 12 dias

    Gracias

    • felixurbina says:

      Qué tal Juan, en ese caso sería hacer modificaciones al script python, si tengo chance de sacarlo te aviso y lo publico.

      Saludos.

      • Juan says:

        Te lo agradecería mucho ya le llevo dando vueltas al tema pero nada

        Desde ya agradecido por la respuesta y quedo a la espera de alguna novedad.

        Saludos.

  7. Hola utiliza tu codigo pero me sale object has no attribute on_change al córrelo

    • felixurbina says:

      Qué tal Rafael, es cuestión de que revises el código y que integres el on_change tanto en el xml como en el py para que se relacionen, si solo está en el xml y no está en el py te va a dar un error. Cualquier cosa avisas.

  8. Buenas, tiempo sin entrar por acá, en la empresa entán migrando de la versión 7 a a 8 y estoy aplicando el código publicado, pero me sale un error al crear un nuevo registro, me sale : “” TypeError: must be string, not bool “” :

    Lo muestro a continuación:

    Traceback (most recent call last):
    File “/home/gio666/odoo/openerp/http.py”, line 537, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
    File “/home/gio666/odoo/openerp/http.py”, line 574, in dispatch
    result = self._call_function(**self.params)
    File “/home/gio666/odoo/openerp/http.py”, line 310, in _call_function
    return checked_call(self.db, *args, **kwargs)
    File “/home/gio666/odoo/openerp/service/model.py”, line 113, in wrapper
    return f(dbname, *args, **kwargs)
    File “/home/gio666/odoo/openerp/http.py”, line 307, in checked_call
    return self.endpoint(*a, **kw)
    File “/home/gio666/odoo/openerp/http.py”, line 803, in __call__
    return self.method(*args, **kw)
    File “/home/gio666/odoo/openerp/http.py”, line 403, in response_wrap
    response = f(*args, **kw)
    File “/home/gio666/odoo/openerp/addons/web/controllers/main.py”, line 948, in call_kw
    return self._call_kw(model, method, args, kwargs)
    File “/home/gio666/odoo/openerp/addons/web/controllers/main.py”, line 940, in _call_kw
    return checked_call(request.db, *args, **kwargs)
    File “/home/gio666/odoo/openerp/service/model.py”, line 113, in wrapper
    return f(dbname, *args, **kwargs)
    File “/home/gio666/odoo/openerp/addons/web/controllers/main.py”, line 939, in checked_call
    return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
    File “/home/gio666/odoo/openerp/api.py”, line 241, in wrapper
    return old_api(self, *args, **kwargs)
    File “/home/gio666/odoo/openerp/api.py”, line 363, in old_api
    result = method(recs, *args, **kwargs)
    File “/home/gio666/odoo/openerp/models.py”, line 5897, in onchange
    record._onchange_eval(name, field_onchange[name], result)
    File “/home/gio666/odoo/openerp/models.py”, line 5815, in _onchange_eval
    method_res = getattr(self._model, method)(*args)
    File “/home/gio666/odoo/openerp/api.py”, line 241, in wrapper
    return old_api(self, *args, **kwargs)
    File “/home/gio666/odoo/openerp/addons/hr_recruitment/hr_recruitment.py”, line 364, in onchange_edad
    edad = (datetime.now().date() – datetime.strptime(fecha_nacimiento, ‘%Y-%m-%d’).date()).days / 365
    TypeError: must be string, not bool

    he tratado de solventarlo pero nada ha funcionado, creo que tiene que ver con que el campo fecha_nacimiento está vacío… ¿algún consejo?

  9. Dani López says:

    Hola Felix, tengo el mismo problema que Giovanny, he modificado la función como indicáis, pero sigo con el error. Te pego el código y el error:

    edat = (datetime.now().date() – datetime.strptime(naixement, ‘%Y-%m-%d’).date()).days/365
    TypeError: must be string, not bool

    http://pastebin.com/YMvvQ5Ud

    Gracias por tu ayuda.
    Dani

  10. Dani López says:

    Hola Felix,

    Estoy intentando hacer la función que indicas, pero me sale el mismo error que a giovanny. Te copio el código de lo que estoy haciendo con el error:
    Error:
    edat = (datetime.now().date() – datetime.strptime(naixement, ‘%Y-%m-%d’).date()).days/365
    TypeError: must be string, not bool

    Código:
    http://pastebin.com/YMvvQ5Ud

    Gracias por tu ayuda,
    Dani

    • felixurbina says:

      Hola Dani, estoy revisando y tienes declarado el tipo de campo “naixement” como “datetime”, si puedes, haz una prueba declarándolo como “date”. Cualquier cosa me avisas. Saludos.

      • Dani López says:

        Hola de nuevo Felix y gracias por contestar, con el cambio a Date ha ido perfecto, muchas gracias! y pensar que todo el tiempo que me ha costado y era por esto…
        Muchas gracias de nuevo!

    • He visto que declaraste ‘edat’ como char. cambialo a integer

      • Dani López says:

        Hola Giovanny, muchas gracias por contestar, lo declaré como integer y seguía con el mismo error, luego leí en el post que podía ser un char y seguía igual.

      • Dani López says:

        Hola Giovanny, con el cambio que me ha comentado Felix se ha solucionado, gracias por tu ayuda también.

    • felixurbina says:

      Qué bueno Dani, me alegra que funcionó. Siempre a la orden. Saludos.

    • Jorge says:

      Como haces para que cambie el campo ‘edat’ apartir de la funcion? puedes postear el fichero .xml?

      Gracias

    • gasiopeo says:

      Hola Daniel,
      Como haces para que se efectue el cambio en el campo ‘edat’?, Puedes pasar el fichero xml.

      Gracias.

  11. jordi says:

    Hola, en el fichero .xml como se llama a la funcion?

  12. Jorge says:

    Dani, como haces para te cambie el campo ‘edat’?, puedes postear el fichero .xml.

    Gracias.

  13. Pedro says:

    Dani López puedes para el otro fichero, el xml, gracias.

    • Dani L says:

      Hola, en el XML tenéis que poner lo siguiente: ….nombre del campo onchange=”nombrefuncion(atributo)”. En el atributo tenéis que poner el atributo que cuando sufra un cambio, llame a la función. Espero que os sirva!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s