我正在使用odoo11。我正在处理考勤模块,我想创建一个考勤修改请求,该请求由经理批准(创建新的考勤或修改已经存在的考勤),并且自动更新了考勤。问题是当我按批准时,我的请求得到批准,但出勤率没有更新(在hr。出席模式中)。任何帮助的想法请?? 这是我的代码
regularization.py
class Regular(models.Model):
_name = 'attendance.regular'
_rec_name = 'employee'
_description = 'Approval Request'
_inherit = ['mail.thread', 'mail.activity.mixin']
def _get_employee_id(self):
employee_rec = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
return employee_rec.id
reg_category = fields.Many2one('reg.categories',
string='Regularization Category', required=True)
from_date = fields.Datetime(string='Check in', required=False)
to_date = fields.Datetime(string='Check out', required=False)
reg_reason = fields.Text(string='Reason', required=False)
employee = fields.Many2one('hr.employee', string="Employee", default=_get_employee_id, readonly=False, required=True)
state_select = fields.Selection([('draft', 'Draft'), ('requested', 'Requested'), ('reject', 'Rejected'),
('approved', 'Approved')
], default='draft', track_visibility='onchange', string='State')
attendance_id = fields.Many2one('hr.attendance', string='Attendance')
@api.multi
def submit_reg(self):
self.ensure_one()
self.sudo().write({
'state_select': 'requested'
})
return
@api.multi
def regular_approval(self):
for record in self:
if self.reg_category.type ==" Check in":
record.attendance_id.check_in = record.from_date
record.attendance_id.employee_id = record.employee.id
elif self.reg_category.type ==" Check out":
record.attendance_id.check_out = record.to_date
record.attendance_id.employee_id = record.employee.id
return self.write({ 'state_select': 'approved' })
regularization.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="attendance_regular11" model="ir.ui.view">
<field name="name">attend.regular</field>
<field name="model">attendance.regular</field>
<field name="arch" type="xml">
<form string="Regularization">
<header>
<button name="submit_reg" string="Submit" type="object" class="btn-primary"
attrs="{'invisible': [('state_select','not in','draft')]}"/>
<button name="regular_approval" type="object" string="Approve" class="oe_highlight"
groups="hr_attendance.group_hr_attendance_manager"
attrs="{'invisible': [('state_select','not in','requested')]}"/>
<button name="regular_rejection" type="object" string="Reject" class="oe_highlight"
groups="hr_attendance.group_hr_attendance_manager"
attrs="{'invisible': [('state_select','not in','requested')]}"/>
<field name="state_select" widget="statusbar" statusbar_visible="draft,requested,approved"/>
</header>
<sheet>
<group col="4" colspan="4">
<field name="reg_category"/>
<field name="from_date" attrs="{'invisible':[('reg_category', '=',5)]}" />
<field name="reg_reason"/>
<field name="to_date" attrs="{'invisible':[('reg_category', '=',4)]}"/>
<field name="employee"/>
</group>
</sheet>
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread"/>
</form>
</field>
</record>
答案 0 :(得分:0)
我想问题是您选择fields.Many2one
的字段类型。
应该是m2m类型。
我有一个类似的例子给你。
<!--course-->
<record model="ir.ui.view" id="course_form_view">
<field name="name">course.form</field>
<field name="model">openacademy.course</field>
<field name="arch" type="xml">
<form string="Course Form">
<sheet>
<group>
<field name="name"/>
<field name="responsible_id"/>
</group>
<notebook>
<page string="Description">
<field name="description"/>
</page>
<page string="Sessions">
<field name="session_ids">
<tree string="Registered sessions">
<field name="name"/>
<field name="instructor_id"/>
</tree>
</field>
</page>
<page string="About">
This is an example of notebooks
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!--session-->
<record model="ir.ui.view" id="session_form_view">
<field name="name">session.form</field>
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
<form string="Session Form">
<header>
<button name="action_draft" type="object" string="Reset to draft" states="confirmed,done"/>
<button name="action_confirm" type="object" string="Confirm" states="draft" class="oe_highlight"/>
<button name="action_done" type="object" string="Mark as done" states="confirmed" class="oe_highlight"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group string="General">
<field name="course_id" options="{'limit': 3}"/>
<field name="name"/>
<field name="instructor_id"/>
<field name="active"/>
</group>
<group string="Schedule">
<field name="start_date"/>
<field name="duration"/>
<field name="seats"/>
<field name="taken_seats" widget="progressbar"/>
<!--<button type="action" name="%(launch_session_wizard)d" string="wizard" class="oe_highlight"/>-->
</group>
<label for="attendee_ids"/>
<field name="attendee_ids"/>
</sheet>
</form>
</field>
</record>
class Course(models.Model):
_name = 'openacademy.course'
name = fields.Char(string="Title", required=True)
description = fields.Text()
responsible_id = fields.Many2one('res.users', ondelete='set null', string="Responsible", index=True)
session_ids = fields.One2many('openacademy.session', 'course_id', string="Sessions")
# 去改寫action的Duplicate
@api.multi
def copy(self, default=None):
default = dict(default or {})
copied_count = self.search_count([('name', '=like', u"Copy of {}%".format(self.name))])
if not copied_count:
new_name = u"Copy of {}".format(self.name)
else:
new_name = u"Copy of {} ({})".format(self.name, copied_count)
default['name'] = new_name
return super(Course, self).copy(default)
# unlink 是 改寫Action的Delete
_sql_constraints = [
('name_description_check',
'CHECK(name != description)',
"The title of the course should not be the description"),
('name_unique',
'UNIQUE(name)',
"The course title must be unique"),
]
class Session(models.Model):
_name = 'openacademy.session'
name = fields.Char(required=True)
start_date = fields.Date(default=fields.Date.today)
duration = fields.Float(digits=(6, 2), help="Duration in days")
seats = fields.Integer(string="Number of seats")
active = fields.Boolean(default=True)
color = fields.Integer()
instructor_id = fields.Many2one('res.partner', string="Instructor", domain=['|', ('instructor', '=', True), ('category_id.name', 'ilike', "Teacher")])
course_id = fields.Many2one('openacademy.course', ondelete='cascade', string="Course", required=True)
attendee_ids = fields.Many2many('res.partner', string="Attendees")
taken_seats = fields.Float(string="Taken seats", compute='_taken_seats')
end_date = fields.Date(string="End Date", store=True, compute='_get_end_date', inverse='_set_end_date')
hours = fields.Float(string="Duration in hours", compute='_get_hours', inverse='_set_hours')
attendees_count = fields.Integer(string="Attendees count", compute='_get_attendees_count', store=True)
state = fields.Selection([('draft', "Draft"),('confirmed', "Confirmed"),('done', "Done"),], default='draft')
@api.multi
def action_draft(self):
self.state = 'draft'
@api.multi
def action_confirm(self):
self.state = 'confirmed'
@api.multi
def action_done(self):
self.state = 'done'
@api.depends('seats', 'attendee_ids')
def _taken_seats(self):
for r in self:
if not r.seats:
r.taken_seats = 0.0
else:
r.taken_seats = 100.0 * len(r.attendee_ids) / r.seats
@api.depends('attendee_ids')
def _get_attendees_count(self):
for r in self:
r.attendees_count = len(r.attendee_ids)
@api.depends('duration')
def _get_hours(self):
for r in self:
r.hours = r.duration * 24
def _set_hours(self):
for r in self:
r.duration = r.hours / 24
@api.depends('start_date', 'duration')
def _get_end_date(self):
for r in self:
if not (r.start_date and r.duration):
r.end_date = r.start_date
continue
start = fields.Datetime.from_string(r.start_date)
duration = timedelta(days=r.duration, seconds=-1)
r.end_date = start + duration
def _set_end_date(self):
for r in self:
if not (r.start_date and r.end_date):
continue
start_date = fields.Datetime.from_string(r.start_date)
end_date = fields.Datetime.from_string(r.end_date)
r.duration = (end_date - start_date).days + 1
@api.onchange('seats', 'attendee_ids')
def _verify_valid_seats(self):
if self.seats < 0:
return {
'warning': {
'title': "Incorrect 'seats' value",
'message': "The number of available seats may not be negative",
},
}
if self.seats < len(self.attendee_ids):
return {
'warning': {
'title': "Too many attendees",
'message': "Increase seats or remove excess attendees",
},
}
@api.constrains('instructor_id', 'attendee_ids')
def _check_instructor_not_in_attendees(self):
for r in self:
if r.instructor_id and r.instructor_id in r.attendee_ids:
raise exceptions.ValidationError("A session's instructor can't be an attendee")