Search code examples
pythonormodooopenerp-8

Automated Action Birthday =19


I have a table called students and i need to check male students ages every day to know if they are more than 19 or not .i know i should run cron function to check the birth dates every day but i need to get the values in the birth dates column , do some operations to get the age more than 19 or not , add the students that have age more than 19 to another table.

here is what i did :D help me with what within the comments please :)

Python Code

def get_age_comp(self, cr, uid, birth_date,gender , context=None):


  # birth_date and gender are names of columns in fci.students table like :

  #'birth_date': fields.date(string='Birth Date', required=True)

  #'gender': fields.selection([('m', 'Male'), ('f', 'Female')], string='Gender', required=True)


  student_obj = self.pool.get('fci.student')

  current_date = datetime.now()

  current_year = current_date.year

  birth_dates = parser.parse(birth_date)

  current_age = current_year - birth_dates.year

  gender = student_obj.search(cr, uid, [('gender', '=', True), ('gender', 'like', 'm')])

  if current_age > 19 & gender=='m':


  #i don't know if i do it right and i need to insert these students (name ,age ) to table called 'stat'

XML CODE

<record id="ir_cron_actions" model="ir.cron">
  <field name="name">Check age Job</field>
  <field eval="True" name="active"/>
  <field name="user_id" ref="base.user_root"/>
  <field name="interval_number">1</field>
  <field name="interval_type">days</field>
  <field name="numbercall">-1</field>
  <field eval="'fci.student'" name="model"/>
  <field eval="'get_age_comp'" name="function"/>
  <field eval="'()'" name="args"/>
</record>

Solution

  • it might not be the brightiest way, but you should be able to do something like this :

    def get_age_comp(self, cr, uid, context=None):
        cr.execute('DELETE FROM stat;')
        cr.execute('''INSERT INTO stat(name, age)
                      SELECT name, date_part('years',age(birth_date))
                      FROM fci_student
                      WHERE gender='m'
                      AND date_part('years',age(birth_date)) > 18;''')
    

    if you don't want to drop existing stat rows each time, you could do something like in these answers about postgresql 'insert or update'

    edit : if you want to use the new api

    you could add these imports :

    from openerp import api
    from datetime import date
    from dateutil.relativedelta import relativedelta
    

    then the method could become :

    @api.model
    def get_age_comp(self):
        for student in self.search([('gender','=','m'), ('birth_date', '<=', date.today() - relativedelta(years=20))]):
            self.env.cr.execute('INSERT INTO stat VALUES(%s,%s)', (student.name, student.birthdate))
    

    since stat doesn't seem to be an odoo model, it's not accessible via the ORM API and we have to use sql.

    If I am mistaken and stat is an odoo model, the code could become :

    @api.model
    def get_age_comp(self):
        to_add = {}
        # getting all male older than 19 years from fci.student
        for student in self.search([('gender','=','m'), ('birth_date', '<=', date.today() - relativedelta(years=20))]):
            to_add[student.name] = student.birth_date
        # ignoring the students already in stat
        for stat in self.env['stat'].search([('name', 'in', to_add.keys())]):
            del to_add[stat.name]
        # adding the new ones
        for name, birth_date in to_add.iteritems():
            stat_model.create({'name': name, 'birth_date': birth_date})
    

    i didn't use age in stat here, since it's a bad practice ( it changes at least once every year for every people ) but you could see this question about calculating age from date and mix it in the code.

    edit : for the case added in comment

    create status in student table (underage-getCard-gotCard) if his age is less than 20, his status should be underage, if he is getting the card his status should be getCard, if he got the card the status should be gotCard..i want to know how to change status in the code :)

    if it was the only thing you wanted to do, it could be done with :

    @api.model
    def get_age_comp(self):
        self.search([('gender','=','m'), ('status', '=', 'underage'),
                     ('birth_date', '<=', date.today() - relativedelta(years=20))
                    ]).write({'status': 'getCard'})
    

    otherway, like done previously, you could loop on .search() result :

    @api.model
    def get_age_comp(self):
        for student in self.search([('gender','=','m'), ('birth_date', '<=', date.today() - relativedelta(years=20)), ('status', '=', 'underage')]):
            student.status = 'getCard'
            # do other things here