自动操作生日 =19

Automated Action Birthday =19

我有一个叫学生的 table,我需要每天检查男学生的年龄,以了解他们是否超过 19 岁。我知道我应该 运行 cron 功能来检查每天的出生日期,但我需要获取出生日期列中的值,做一些操作来确定年龄是否超过 19 岁,将年龄超过 19 岁的学生添加到另一个 table.

这是我所做的 :D 请在评论中帮助我 :)

Python代码

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 代码

<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>

这可能不是最明智的方法,但您应该可以这样做:

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;''')

如果你不想每次都删除现有的统计行,你可以像 these answers about postgresql 'insert or update'

编辑:如果你想使用 new api

您可以添加这些导入:

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

那么方法可以变成:

@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))

由于 stat 似乎不是 odoo 模型,因此无法通过 ORM API 访问它,我们必须使用 sql.

如果我记错了 stat 是一个 odoo 模型,代码可能变成:

@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})

我没有在这里使用 stat 中的年龄,因为这是一个不好的做法(每个人每年至少更改一次)但是你可以看到这个关于 calculating age from date 的问题并混合它在代码中。

编辑:对于评论中添加的案例

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 :)

如果这是您唯一想做的事情,可以通过以下方式完成:

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

否则,就像之前所做的那样,您可以循环 .search() 结果:

@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