【问题标题】:Odoo 13 : create multiple records via create functionOdoo 13:通过创建功能创建多个记录
【发布时间】:2021-11-26 14:57:01
【问题描述】:

这是我在 Odoo13 中编写的第一个创建函数。我想得到 begin_dateend_date 两个日期之间的时间段,日期应保存在列表中。从这个列表中,我想为列表中的每一天为单个员工创建记录。但我的代码似乎不正确,我收到这种错误:AttributeError: 'NoneType' object has no attribute 'id'

这是我的代码:

from datetime import timedelta, datetime, date
from calendar import monthrange


from odoo import api, fields, models, tools
from odoo.exceptions import UserError, AccessError, ValidationError
from odoo.tools import date_utils


class TimeOff(models.Model):
    _name = 'project.timeoff'
    _rec_name = 'employ_id'

    employ_id = fields.Many2one('hr.employee', string='Employee', required='1')

    date = fields.Date('Date', required=True, index=True,
                       default=fields.Date.context_today)

    begin_date = fields.Datetime(
        'First Day of Leave', required='1')

    day_hours = fields.Integer('Off hours per day', default='8', required='1')
    end_date = fields.Datetime(
        'Last Day of Leave')

###### create function #######
    @api.model
    def create(self, vals):
        range_date = []    # empty list
        if self.employ_id: # check if field has value
            if self.begin_date and self.end_date: # check if field has value
                range_date = self.calc_dates(
                    self.begin_date, self.end_date, mode='date') # call custom function and expect a list to be returned
                if range_date is None:
                    raise ValidationError("Something went wrong") # list is empty
                else: # iterate through list and create record for each date 
                    for day in range_date:
                        vals = {
                            'employ_id': self.employ_id,
                            'begin_date': day}
                        return super(TimeOff, self).create(vals)

### custom function to get all dates between begin_date and end_date #####

    def calc_dates(self, date1, date2, mode='date'):
        date_from = fields.Date.from_string(date1)
        date_to = fields.Date.from_string(date2)

        delta = date_to - date_from

        if delta.days < 0: 
            return None

        dates = []

        for n in range(delta.days + 1):
            if mode == 'date':  # returns dates as date format
                dates.append(date_from + timedelta(days=n))
            if mode == 'string': # returns dates as string format
                dates.append(fields.Date.to_string(
                    date_from + timedelta(days=n)))
        return dates


所以当我按下创建时,我得到了这个错误:

Error:
Odoo Server Error

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 624, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 310, in _handle_exception
    raise pycompat.reraise(type(exception), exception, sys.exc_info()[2])
  File "/usr/lib/python3/dist-packages/odoo/tools/pycompat.py", line 14, in reraise
    raise value
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 669, in dispatch
    result = self._call_function(**self.params)
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 350, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/odoo/service/model.py", line 94, in wrapper
    return f(dbname, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 339, in checked_call
    result = self.endpoint(*a, **kw)
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 915, in __call__
    return self.method(*args, **kw)
  File "/usr/lib/python3/dist-packages/odoo/http.py", line 515, in response_wrap
    response = f(*args, **kw)
  File "/usr/lib/python3/dist-packages/odoo/addons/web/controllers/main.py", line 1327, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "/usr/lib/python3/dist-packages/odoo/addons/web/controllers/main.py", line 1319, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/usr/lib/python3/dist-packages/odoo/api.py", line 385, in call_kw
    result = _call_kw_model_create(method, model, args, kwargs)
  File "/usr/lib/python3/dist-packages/odoo/api.py", line 366, in _call_kw_model_create
    return result.id if isinstance(args[0], Mapping) else result.ids
AttributeError: 'NoneType' object has no attribute 'id'

要么我不能在这个问题中使用 self 要么返回有问题

【问题讨论】:

    标签: python date odoo record odoo-13


    【解决方案1】:

    对于遇到相同问题并希望自动创建记录的每个人,这是我的解决方案:

    from datetime import timedelta, datetime, date
    from calendar import monthrange
    
    
    from odoo import api, fields, models, tools
    from odoo.exceptions import UserError, AccessError, ValidationError
    from odoo.tools import date_utils
    
    
    class TimeOff(models.Model):
        _name = 'project.timeoff'
        _rec_name = 'employ_id'
    
        employ_id = fields.Many2one('hr.employee', string='Employee', required='1')
    
        date = fields.Date('Date', required=True, index=True,
                           default=fields.Date.context_today)
    
        begin_date = fields.Datetime(
            'First Day of Leave', required='1')
    
        day_hours = fields.Integer('Off hours per day', default='8', required='1')
        end_date = fields.Datetime(
            'Last Day of Leave')
    ############################################ create um zw periode von datum, records zu erstellen ##############################################
    
        def update_record(self):
            range_date = []
            for rec in self:
                if rec.employ_id:
                    if rec.begin_date and rec.end_date:
                        range_date = rec.calc_dates(
                            rec.begin_date, rec.end_date)
                        if range_date is None:
                            raise ValidationError("Something went wrong")
                        else:
                            for day in range_date:
                                val = {
                                    'employ_id': rec.employ_id.id,
                                    'begin_date': day}
                                self.create(val)
                                self._cr.commit()
    
    
    ################################################### funktion um periode mit datum zw begin und end_date auzugeben (als liste) ########################################################################
    
    
        def calc_dates(self, date1, date2):
            date_from = date1
            date_to = date2
    
            delta = date_to - date_from
    
            if delta.days < 0:
                return None
    
            dates = []
    
            for n in range(delta.days + 1):
                dates.append(date_from + timedelta(days=n))
    
            return dates 
    

    不要忘记创建自定义按钮并调用函数:

      <record id="project_timeoff_tree_view" model="ir.ui.view">
              <field name="name">view.project.timeoff.tree</field>
              <field name="model">project.timeoff</field>
              <field name="arch" type="xml">
                <tree string="TimeOff">
                  <field name="employ_id" string="Employee"/>
                  <field name="begin_date"/>
                  <field name="end_date"/> 
                  <field name="day_hours"/>
                  <!-- <field name="requested_hours"/> -->
                  <button name="update_record" string="Update" class="btn-primary" type="object" />
                </tree>
              </field>
      </record>
    
    

    PS:树形视图中每条记录后都会显示该按钮,我还没有找到将其放在标题中的解决方案

    【讨论】:

      【解决方案2】:

      由于self是一个空记录集,self.employ_id将被评估为False,Odoo不会执行if语句,然后将返回默认值None

      您可以使用 val 列表调用 super(不返回结果),但这会改变 create 方法的行为,它应该从 vals 变为 return the created record

      您可以使用向导创建project.timeoff 记录。

      【讨论】:

      • 非常感谢您的帮助。问题是记录的值稍后将通过 csv 文件导入。在那个 csv 文件中,从开始到结束只有一段时间。我必须在网格视图中显示它,因为网格视图(企业)中的每个单元格都与一条记录匹配,我必须自动创建记录。就像 Mitchel Admin 从 01.10 到 06.10 一样,因此应该用日期填充空白,并且对于每个日期,最后应该有同一个人的一条记录。可以用向导做吗?
      • 以后是否需要重用向导来导入类似的 CSV 文件?我认为最好在导入 CSV 文件之前对其进行转换。
      • 是的,它应该能够使用相同的 csv 文件更新数据,但无需 d 将记录加倍。不幸的是,我无法手动转换 CSV,因为文件是从其他地方自动生成的,而且我的同事对 csv 文件没有经验。
      • 我现在要做的是不要修改create函数。相反,我会将我的代码放在自定义方法中并创建一个按钮来调用该方法
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2018-12-14
      • 2023-01-12
      相关资源
      最近更新 更多